Skip to content
This repository has been archived by the owner on Sep 2, 2024. It is now read-only.

tweaks to disable date functionality to slightly simplify things #80

Merged
merged 5 commits into from
Jun 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 12 additions & 52 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -603,65 +603,25 @@ Please note that you must provide the entirety of the localization properties in

Duet Date Picker allows you to disable the selection of specific days. Below is an example of a date picker that is disabling weekends.

Be aware, this only disables selection of dates in the popup calendar. You must still handle the case where a user manually enters a disallowed date into the input.

```html
<label for="date">Choose a date</label>
<duet-date-picker identifier="date"></duet-date-picker>

<script>
const pickerDisableWeekend = document.querySelector("duet-date-picker")
const DATE_FORMAT = /^(\d{4})-(\d{1,2})-(\d{1,2})$/

pickerDisableWeekend.dateAdapter = {
parse() {
var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ""
var createDate = arguments.length > 1 ? arguments[1] : undefined
var matches = value.match(DATE_FORMAT)

if (matches) {
return createDate(matches[3], matches[2], matches[1])
}
},
format(date) {
return `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`
},
isDateDisabled(date, focusedDay) {
return (
date.getDay() === 0 ||
date.getDay() === 6 ||
// disable next and previous month (default behaviour)
!(date.getFullYear() === focusedDay.getFullYear() && date.getMonth() === focusedDay.getMonth())
)
},
function isWeekend(date) {
return date.getDay() === 0 || date.getDay() === 6
}

pickerDisableWeekend.localization = {
buttonLabel: "Choose date",
placeholder: "YYYY-MM-DD",
selectedDateMessage: "Selected date is",
prevMonthLabel: "Previous month",
nextMonthLabel: "Next month",
monthSelectLabel: "Month",
yearSelectLabel: "Year",
closeLabel: "Close window",
keyboardInstruction: "You can use arrow keys to navigate dates",
calendarHeading: "Choose a date",
dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
monthNames: [
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December",
],
monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
}
const pickerDisableWeekend = document.querySelector("duet-date-picker")
pickerDisableWeekend.isDateDisabled = isWeekend

pickerDisableWeekend.addEventListener("duetChange", function(e) {
if (isWeekend(e.detail.valueAsDate)) {
alert("Please select a weekday")
}
})
</script>
```

Expand Down
132 changes: 22 additions & 110 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -534,124 +534,36 @@ <h2>Required atrribute</h2>
<label for="dateDisabledWeekend">Choose a date</label>
<duet-date-picker class="picker-disabled-weekend" identifier="dateDisabledWeekend"></duet-date-picker>
<script>
const pickerDisableWeekend = document.querySelector(".picker-disabled-weekend")
const PICKER_DISABLED_DATE_FORMAT = /^(\d{4})-(\d{1,2})-(\d{1,2})$/

pickerDisableWeekend.dateAdapter = {
parse: function parse() {
var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ""
var createDate = arguments.length > 1 ? arguments[1] : undefined
var matches = value.match(PICKER_DISABLED_DATE_FORMAT)

if (matches) {
return createDate(matches[3], matches[2], matches[1])
}
},
format: function format(date) {
return ""
.concat(date.getFullYear(), "-")
.concat(date.getMonth() + 1, "-")
.concat(date.getDate())
},
isDateDisabled: function isDateDisabled(date, focusedDay) {
return (
date.getDay() === 0 ||
date.getDay() === 6 ||
!(date.getFullYear() === focusedDay.getFullYear() && date.getMonth() === focusedDay.getMonth())
)
},
function isWeekend(date) {
return date.getDay() === 0 || date.getDay() === 6
}

pickerDisableWeekend.localization = {
buttonLabel: "Choose date",
placeholder: "YYYY-MM-DD",
selectedDateMessage: "Selected date is",
prevMonthLabel: "Previous month",
nextMonthLabel: "Next month",
monthSelectLabel: "Month",
yearSelectLabel: "Year",
closeLabel: "Close window",
keyboardInstruction: "You can use arrow keys to navigate dates",
calendarHeading: "Choose a date",
dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
monthNames: [
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December",
],
monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
}
const pickerDisableWeekend = document.querySelector(".picker-disabled-weekend")
pickerDisableWeekend.isDateDisabled = isWeekend

pickerDisableWeekend.addEventListener("duetChange", function(e) {
if (isWeekend(e.detail.valueAsDate)) {
alert("Please select a weekday")
}
})
</script>
<pre><code class="html">&lt;label for="date"&gt;Choose a date&lt;/label&gt;
&lt;duet-date-picker first-day-of-week="0" identifier="date"&gt;&lt;/duet-date-picker&gt;
&lt;duet-date-picker identifier="date"&gt;&lt;/duet-date-picker&gt;

&lt;script&gt;
const pickerDisableWeekend = document.querySelector(".picker-disabled-weekend")
const PICKER_DISABLED_DATE_FORMAT = /^(\d{4})-(\d{1,2})-(\d{1,2})$/

pickerDisableWeekend.dateAdapter = {
parse: function parse() {
var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ""
var createDate = arguments.length > 1 ? arguments[1] : undefined
var matches = value.match(PICKER_DISABLED_DATE_FORMAT)

if (matches) {
return createDate(matches[3], matches[2], matches[1])
}
},
format: function format(date) {
return ""
.concat(date.getFullYear(), "-")
.concat(date.getMonth() + 1, "-")
.concat(date.getDate())
},
isDateDisabled: function isDateDisabled(date, focusedDay) {
return (
date.getDay() === 0 ||
date.getDay() === 6 ||
!(date.getFullYear() === focusedDay.getFullYear() && date.getMonth() === focusedDay.getMonth())
)
},
function isWeekend(date) {
return date.getDay() === 0 || date.getDay() === 6
}

picker.localization = {
buttonLabel: "Choose date",
placeholder: "YYYY-MM-DD",
selectedDateMessage: "Selected date is",
prevMonthLabel: "Previous month",
nextMonthLabel: "Next month",
monthSelectLabel: "Month",
yearSelectLabel: "Year",
closeLabel: "Close window",
keyboardInstruction: "You can use arrow keys to navigate dates",
calendarHeading: "Choose a date",
dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
monthNames: [
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December",
],
monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
}
&lt;/script&gt;</code></pre> -->
const pickerDisableWeekend = document.querySelector(".picker-disabled-weekend")
pickerDisableWeekend.isDateDisabled = isWeekend

pickerDisableWeekend.addEventListener("duetChange", function(e) {
if (isWeekend(e.detail.valueAsDate)) {
alert("Please select a weekday")
}
})
&lt;/script&gt;</code></pre>-->
<br />
<p>
© 2020 LocalTapiola Services Ltd /
Expand Down
1 change: 0 additions & 1 deletion src/components/duet-date-picker/date-adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ export type DuetDateFormatter = (date: Date) => string
export interface DuetDateAdapter {
parse: DuetDateParser
format: DuetDateFormatter
isDateDisabled?: (date: Date, focusedDate: Date) => boolean
}

const isoAdapter: DuetDateAdapter = { parse: parseISODate, format: printISODate }
Expand Down
29 changes: 2 additions & 27 deletions src/components/duet-date-picker/date-picker-day.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,44 +35,19 @@ export const DatePickerDay: FunctionalComponent<DatePickerDayProps> = ({
onDaySelect(e, day)
}

if (disabled) {
return (
<span
class={{
"duet-date__day": true,
"is-outside": isOutsideRange,
"is-disabled": disabled,
"is-today": isToday,
"is-month": isMonth,
}}
role="button"
tabIndex={isFocused ? 0 : -1}
onKeyDown={onKeyboardNavigation}
aria-pressed="false"
aria-disabled="true"
ref={el => {
if (isFocused && el && focusedDayRef) {
focusedDayRef(el)
}
}}
>
<span aria-hidden="true">{day.getDate()}</span>
<span class="duet-date__vhidden">{dateFormatter.format(day)}</span>
</span>
)
}

return (
<button
class={{
"duet-date__day": true,
"is-outside": isOutsideRange,
"is-today": isToday,
"is-month": isMonth,
"is-disabled": disabled,
}}
tabIndex={isFocused ? 0 : -1}
onClick={handleClick}
onKeyDown={onKeyboardNavigation}
aria-disabled={disabled ? "true" : undefined}
WickyNilliams marked this conversation as resolved.
Show resolved Hide resolved
disabled={isOutsideRange}
type="button"
aria-pressed={isSelected ? "true" : "false"}
Expand Down
3 changes: 2 additions & 1 deletion src/components/duet-date-picker/date-picker-month.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { h, FunctionalComponent } from "@stencil/core"
import { DuetLocalizedText } from "./date-localization"
import { DatePickerDay, DatePickerDayProps } from "./date-picker-day"
import { getViewOfMonth, inRange, DaysOfWeek, isEqual } from "./date-utils"
import { DateDisabledPredicate } from "./duet-date-picker"

function chunk<T>(array: T[], chunkSize: number): T[][] {
const result = []
Expand Down Expand Up @@ -29,7 +30,7 @@ type DatePickerMonthProps = {
min?: Date
max?: Date
dateFormatter: Intl.DateTimeFormat
isDateDisabled: (date: Date) => boolean
isDateDisabled: DateDisabledPredicate
onDateSelect: DatePickerDayProps["onDaySelect"]
onKeyboardNavigation: DatePickerDayProps["onKeyboardNavigation"]
focusedDayRef: (element: HTMLElement) => void
Expand Down
34 changes: 5 additions & 29 deletions src/components/duet-date-picker/duet-date-picker.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -368,35 +368,11 @@ describe("duet-date-picker", () => {
it("supports navigating to disabled dates", async () => {
const page = await generatePage({ value: "2020-01-01" })

// add dateAdapter to disable weekends
await page.addScriptTag({
content: `
const datepicker = document.querySelector("duet-date-picker");
datepicker.dateAdapter = {
parse: function parse() {
var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ""
var createDate = arguments.length > 1 ? arguments[1] : undefined
var matches = value.match(/^(\d{4})-(\d{1,2})-(\d{1,2})$/)

if (matches) {
return createDate(matches[3], matches[2], matches[1])
}
},
format: function format(date) {
return ""
.concat(date.getFullYear(), "-")
.concat(date.getMonth() + 1, "-")
.concat(date.getDate())
},
isDateDisabled: function isDateDisabled(date, focusedDay) {
return (
date.getDay() === 0 ||
date.getDay() === 6 ||
!(date.getFullYear() === focusedDay.getFullYear() && date.getMonth() === focusedDay.getMonth())
)
},
}
`,
// disable weekends
await page.$eval("duet-date-picker", async (picker: HTMLDuetDatePickerElement) => {
picker.isDateDisabled = function isWeekend(date) {
return date.getDay() === 0 || date.getDay() === 6
}
})

const picker = await getPicker(page)
Expand Down
34 changes: 18 additions & 16 deletions src/components/duet-date-picker/duet-date-picker.scss
Original file line number Diff line number Diff line change
Expand Up @@ -229,9 +229,7 @@
border-radius: 50%;
color: var(--duet-color-text);
cursor: pointer;
display: inline-flex;
align-items: center;
justify-content: center;
display: inline-block;
font-family: var(--duet-font);
font-size: 0.875rem;
font-variant-numeric: tabular-nums;
Expand Down Expand Up @@ -279,33 +277,37 @@
z-index: 200;
}

&:focus,
&.is-disabled[tabindex="0"] {
&:focus {
box-shadow: 0 0 5px var(--duet-color-primary);
z-index: 200;
}

&.is-disabled.is-today {
box-shadow: 0 0 0 1px var(--duet-color-primary);
&:not(.is-month) {
box-shadow: none;
}

&:not(.is-month),
&.is-disabled {
&[aria-disabled="true"] {
background: transparent;
box-shadow: none;
color: var(--duet-color-text);
cursor: default;
opacity: 0.5;
}

&.is-today.is-disabled:focus {
box-shadow: 0 0 5px var(--duet-color-primary);
background: var(--duet-color-primary);
color: var(--duet-color-text-active);
}
&[aria-disabled="true"] {
&.is-today {
box-shadow: 0 0 0 1px var(--duet-color-primary);

&.is-disabled:not(.is-today)::before {
display: none;
&:focus {
box-shadow: 0 0 5px var(--duet-color-primary);
background: var(--duet-color-primary);
color: var(--duet-color-text-active);
}
}

&:not(.is-today)::before {
display: none;
}
}

&.is-outside {
Expand Down
Loading