-
Couldn't load subscription status.
- Fork 87
feat: Allow disabling arbitrary dates in vaadin-date-picker via isDateAvailable property #5252
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
2f732de
c90717f
119e21c
b1e9d3b
6a2c028
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -61,8 +61,9 @@ export function dateEquals(date1, date2) { | |||||
| * @param {Date} max Range end | ||||||
| * @return {boolean} True if the date is in the range | ||||||
| */ | ||||||
| export function dateAllowed(date, min, max) { | ||||||
| return (!min || date >= min) && (!max || date <= max); | ||||||
| export function dateAllowed(date, min, max, isDateAvailable) { | ||||||
| const dateIsAvailable = isDateAvailable && typeof isDateAvailable === 'function' ? isDateAvailable(date) : true; | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
The |
||||||
| return (!min || date >= min) && (!max || date <= max) && dateIsAvailable; | ||||||
| } | ||||||
|
|
||||||
| /** | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -237,6 +237,11 @@ export declare class DatePickerMixinClass { | |
| */ | ||
| max: string | undefined; | ||
|
|
||
| /** | ||
| * Function to override the default function for determining if a date is available. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's use the same description as in the JSDoc here. |
||
| */ | ||
| isDateAvailable: (date: Date) => boolean; | ||
|
|
||
| /** | ||
| * Opens the dropdown. | ||
| */ | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,7 +18,7 @@ import { | |
| extractDateParts, | ||
| getAdjustedYear, | ||
| getClosestDate, | ||
| parseDate, | ||
| parseDate | ||
| } from './vaadin-date-picker-helper.js'; | ||
|
|
||
| /** | ||
|
|
@@ -302,6 +302,15 @@ export const DatePickerMixin = (subclass) => | |
| sync: true, | ||
| }, | ||
|
|
||
| /** | ||
| * A function that is used to determine if a date should be disabled. | ||
| * | ||
| * @type {function(Date): boolean | undefined} | ||
| */ | ||
| isDateAvailable: { | ||
| type: Function, | ||
| }, | ||
|
Comment on lines
+305
to
+312
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Commenting here even though I'm moving to a new PR. Are you sure we should make the object sent to the |
||
|
|
||
| /** | ||
| * The earliest date that can be selected. All earlier dates will be disabled. | ||
| * @type {Date | undefined} | ||
|
|
@@ -365,7 +374,7 @@ export const DatePickerMixin = (subclass) => | |
| return [ | ||
| '_selectedDateChanged(_selectedDate, i18n)', | ||
| '_focusedDateChanged(_focusedDate, i18n)', | ||
| '__updateOverlayContent(_overlayContent, i18n, label, _minDate, _maxDate, _focusedDate, _selectedDate, showWeekNumbers)', | ||
| '__updateOverlayContent(_overlayContent, i18n, label, _minDate, _maxDate, _focusedDate, _selectedDate, showWeekNumbers, isDateAvailable)', | ||
| '__updateOverlayContentTheme(_overlayContent, _theme)', | ||
| '__updateOverlayContentFullScreen(_overlayContent, _fullscreen)', | ||
| ]; | ||
|
|
@@ -591,6 +600,7 @@ export const DatePickerMixin = (subclass) => | |
| const inputValue = this._inputElementValue; | ||
| const inputValid = !inputValue || (!!this._selectedDate && inputValue === this.__formatDate(this._selectedDate)); | ||
| const minMaxValid = !this._selectedDate || dateAllowed(this._selectedDate, this._minDate, this._maxDate); | ||
| const isDateAvailableValid = this.isDateAvailable ? this.isDateAvailable(this._selectedDate) : true; | ||
|
Comment on lines
602
to
+603
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Much cleaner. |
||
|
|
||
| let inputValidity = true; | ||
| if (this.inputElement) { | ||
|
|
@@ -602,7 +612,7 @@ export const DatePickerMixin = (subclass) => | |
| } | ||
| } | ||
|
|
||
| return inputValid && minMaxValid && inputValidity; | ||
| return inputValid && minMaxValid && inputValidity && isDateAvailableValid; | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -812,7 +822,7 @@ export const DatePickerMixin = (subclass) => | |
|
|
||
| /** @private */ | ||
| // eslint-disable-next-line max-params | ||
| __updateOverlayContent(overlayContent, i18n, label, minDate, maxDate, focusedDate, selectedDate, showWeekNumbers) { | ||
| __updateOverlayContent(overlayContent, i18n, label, minDate, maxDate, focusedDate, selectedDate, showWeekNumbers, isDateAvailable) { | ||
| if (overlayContent) { | ||
| overlayContent.i18n = i18n; | ||
| overlayContent.label = label; | ||
|
|
@@ -821,6 +831,7 @@ export const DatePickerMixin = (subclass) => | |
| overlayContent.focusedDate = focusedDate; | ||
| overlayContent.selectedDate = selectedDate; | ||
| overlayContent.showWeekNumbers = showWeekNumbers; | ||
| overlayContent.isDateAvailable = isDateAvailable; | ||
| } | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -49,12 +49,12 @@ class MonthCalendar extends MonthCalendarMixin(ThemableMixin(PolymerElement)) { | |
| <template is="dom-repeat" items="[[week]]"> | ||
| <td | ||
| role="gridcell" | ||
| part$="[[__getDatePart(item, focusedDate, selectedDate, minDate, maxDate)]]" | ||
| part$="[[__getDatePart(item, focusedDate, selectedDate, minDate, maxDate, isDateAvailable)]]" | ||
| date="[[item]]" | ||
| tabindex$="[[__getDayTabindex(item, focusedDate)]]" | ||
| disabled$="[[__isDayDisabled(item, minDate, maxDate)]]" | ||
| disabled$="[[__isDayDisabled(item, minDate, maxDate, isDateAvailable)]]" | ||
| aria-selected$="[[__getDayAriaSelected(item, selectedDate)]]" | ||
| aria-disabled$="[[__getDayAriaDisabled(item, minDate, maxDate)]]" | ||
| aria-disabled$="[[__getDayAriaDisabled(item, minDate, maxDate, isDateAvailable)]]" | ||
| aria-label$="[[__getDayAriaLabel(item)]]" | ||
| >[[_getDate(item)]]</td | ||
| > | ||
|
|
@@ -75,7 +75,7 @@ class MonthCalendar extends MonthCalendarMixin(ThemableMixin(PolymerElement)) { | |
| /** @protected */ | ||
| _days: { | ||
| type: Array, | ||
| computed: '_getDays(month, i18n, minDate, maxDate)', | ||
| computed: '_getDays(month, i18n, minDate, maxDate, isDateAvailable)', | ||
| }, | ||
|
|
||
| /** @protected */ | ||
|
|
@@ -87,7 +87,18 @@ class MonthCalendar extends MonthCalendarMixin(ThemableMixin(PolymerElement)) { | |
| disabled: { | ||
| type: Boolean, | ||
| reflectToAttribute: true, | ||
| computed: '_isDisabled(month, minDate, maxDate)', | ||
| computed: '_isDisabled(month, minDate, maxDate, isDateAvailable)', | ||
| }, | ||
|
|
||
| /** | ||
| * A function to be used to determine whether the user can select a given date. | ||
| * Receives the `Date` object of the date to be selected and should return a | ||
| * boolean. | ||
| * @type {Function | undefined} | ||
| */ | ||
| isDateAvailable: { | ||
| type: Function, | ||
| value: () => true, | ||
| }, | ||
| }; | ||
| } | ||
|
|
@@ -106,10 +117,10 @@ class MonthCalendar extends MonthCalendarMixin(ThemableMixin(PolymerElement)) { | |
| } | ||
|
|
||
| /** @private */ | ||
| __getDatePart(date, focusedDate, selectedDate, minDate, maxDate) { | ||
| __getDatePart(date, focusedDate, selectedDate, minDate, maxDate, isDateAvailable) { | ||
| const result = ['date']; | ||
|
|
||
| if (this.__isDayDisabled(date, minDate, maxDate)) { | ||
| if (this.__isDayDisabled(date, minDate, maxDate, isDateAvailable)) { | ||
| result.push('disabled'); | ||
| } | ||
|
|
||
|
|
@@ -147,16 +158,16 @@ class MonthCalendar extends MonthCalendarMixin(ThemableMixin(PolymerElement)) { | |
|
|
||
| /** @private */ | ||
| __isDayDisabled(date, minDate, maxDate) { | ||
| return !dateAllowed(date, minDate, maxDate); | ||
| return !dateAllowed(date, minDate, maxDate, isDateAvailable); | ||
| } | ||
|
|
||
| /** @private */ | ||
| __getDayAriaDisabled(date, min, max) { | ||
| __getDayAriaDisabled(date, min, max, isDateAvailable) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Doesn't look like the new function is properly passed to this method. Also indicates a missing test, it looks like month calendar attributes like |
||
| if (date === undefined || min === undefined || max === undefined) { | ||
| return; | ||
| } | ||
|
|
||
| if (this.__isDayDisabled(date, min, max)) { | ||
| if (this.__isDayDisabled(date, min, max, isDateAvailable)) { | ||
| return 'true'; | ||
| } | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's add the new parameter to the JSDoc.