-
Notifications
You must be signed in to change notification settings - Fork 83
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
feat: Allow disabling arbitrary dates in vaadin-date-picker via isDateAvailable property #5252
Conversation
I went ahead and pushed up a draft of my changes even though I haven't added the tests yet. I wanted a starting point to discuss issue #1820, specifically the comments in the related Our team doesn't use the Java/hilla code at all, but we understand the general use case for validators that are hosted on the API side. However, for this specific use-case, we all questioned why anyone would really want a server-side |
Kudos, SonarCloud Quality Gate passed! |
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.
Sorry for the late review.
The overall approach of introducing a customizable function makes sense to me, and should be a sufficient basis for introducing the same feature in the Flow API. Some API could be improved, and there are some missing tests.
@@ -235,6 +235,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 comment
The reason will be displayed to describe this comment to others. Learn more.
Let's use the same description as in the JSDoc here.
/** | ||
* A function that is used to determine if a date should be disabled. | ||
* | ||
* @type {function(Date): boolean | undefined} | ||
*/ | ||
isDateAvailable: { | ||
type: Function, | ||
}, |
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.
-
Since the main purpose of the new feature is to disable specific dates, I think it would make more sense to name this to
isDateDisabled
. -
While passing a date instance is reasonable, I think for consistency we should align this with other functions that can be configured currently:
formatDate
andparseDate
via thei18n
property. Those take and return an object of the form:{ year: number, month: number, day: number }
. -
The param should also be documented in some detail in the JSDoc.
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.
Commenting here even though I'm moving to a new PR. Are you sure we should make the object sent to the isDateDisabled
function the DatePickerDate
interface? The reason I ask is the main place this gets called is in vaadin-date-picker-helper
in the dateAllowed
function. That function receives a Javascript Date
rather than a vaadin DatePickerDate
shape.
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 comment
The reason will be displayed to describe this comment to others. Learn more.
const dateIsAvailable = isDateAvailable && typeof isDateAvailable === 'function' ? isDateAvailable(date) : true; | |
const dateIsAvailable = typeof isDateAvailable === 'function' ? isDateAvailable(date) : true; |
The typeof
check should be enough.
@@ -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) { |
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.
const minMaxValid = !this._selectedDate || dateAllowed(this._selectedDate, this._minDate, this._maxDate); | ||
const isDateAvailableValid = this.isDateAvailable ? this.isDateAvailable(this._selectedDate) : 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.
Since dateAllowed
is capable of checking for whether the date should be disabled, it seems unnecessary to call isDateAvailable
separately. Instead, I would suggest to pass the function into dateAllowed
, and generalize the constant name from minMaxValid
to something more general like isDateValid
.
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.
Much cleaner.
_dateAllowed(date, min = this.minDate, max = this.maxDate) { | ||
return (!min || date >= min) && (!max || date <= max); | ||
_dateAllowed(date, min = this.minDate, max = this.maxDate, isDateAvailable = this.isDateAvailable) { | ||
return (!min || date >= min) && (!max || date <= max) && (!isDateAvailable || isDateAvailable(date)) |
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.
I would suggest to reuse the typeof
check here, as it's more precise than checking for a falsy value.
} | ||
|
||
__getDayAriaDisabled(date, min, max) { | ||
__getDayAriaDisabled(date, min, max, isDateAvailable) { |
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.
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 part
and aria-disabled
are currently covered by snapshot tests, so a new snapshot test should be added there.
@@ -214,6 +214,24 @@ describe('validation', () => { | |||
datePicker._overlayContent._selectDate(new Date('2017-01-01')); // Invalid | |||
}); | |||
|
|||
it('should reflect correct invalid value on value-changed eventListener when using isDateAvailable', (done) => { |
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.
There are some additional tests for the max
attribute, respective tests for the new function should be added:
web-components/packages/date-picker/test/validation.test.js
Lines 61 to 67 in 877d1d2
it('should validate when the field has max', async () => { datePicker.max = '2020-01-01'; document.body.appendChild(datePicker); await nextRender(); expect(validateSpy.calledOnce).to.be.true; }); web-components/packages/date-picker/test/validation.test.js
Lines 132 to 142 in 877d1d2
it('should not validate on max change when no value is provided', () => { datePicker.max = '2020-01-01'; expect(validateSpy.called).to.be.false; }); it('should validate on max change when a value is provided', () => { datePicker.value = '2020-01-01'; validateSpy.resetHistory(); datePicker.max = '2020-01-01'; expect(validateSpy.calledOnce).to.be.true; });
The company I work for has pivoted away from using the vaadin-date-picker so we don't have cycles to put to this PR. I'm closing it and if anyone wants to pick up the work they are free to take the work done here and update it per the review comments. |
Re-opening. We have pivoted back to this web component so we'll polish up the PR and get the remaining tests working so we can have this functionality working. |
Co-authored-by: A.J. Roberts <arobertsbnr@users.noreply.github.com>
Kudos, SonarCloud Quality Gate passed! |
I'll create a new PR. Needed to rebase and the renaming of |
Description
This change updates the
vaadin-date-picker
to allow disabling arbitrary dates via a new isDateAvailable property. This property is a functionFixes #1820 but see this platform issue for specific discussion: vaadin/platform#2867
This PR only addresses the UX-frontend portion. This PR does not attempt to address the Java API side.
Type of change
Checklist
Additional for
Feature
type of change