-
Notifications
You must be signed in to change notification settings - Fork 281
feat(ui5-calendar): add disabled dates functionality #12691
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
1bcb6fa
11564ac
8c7ad66
8c5a832
33fef50
2e28efc
fc93ee4
343304a
68f9479
284dc14
71a2180
51bb17c
57e74a9
d9960c7
8d66860
6d4c853
138dc54
0c444cb
a62fe8b
fff4dfe
41899dd
666825c
f30b9e4
e143612
555c611
5decd79
9d30dc5
e601fb8
3e02970
058b171
7da49e3
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 |
|---|---|---|
|
|
@@ -40,6 +40,7 @@ import DateFormat from "@ui5/webcomponents-localization/dist/DateFormat.js"; | |
| import CalendarSelectionMode from "./types/CalendarSelectionMode.js"; | ||
| import CalendarPart from "./CalendarPart.js"; | ||
| import type { | ||
| DisabledDateRangeT, | ||
| ICalendarPicker, | ||
| SpecialCalendarDateT, | ||
| } from "./Calendar.js"; | ||
|
|
@@ -196,6 +197,14 @@ class DayPicker extends CalendarPart implements ICalendarPicker { | |
| @property({ type: Array }) | ||
| specialCalendarDates: Array<SpecialCalendarDateT> = []; | ||
|
|
||
| /** | ||
| * Array of disabled date ranges that cannot be selected. | ||
| * Each range can have a start and/or end date value. | ||
| * @private | ||
| */ | ||
| @property({ type: Array }) | ||
| disabledDates: Array<DisabledDateRangeT> = []; | ||
|
|
||
| @query("[data-sap-focus-ref]") | ||
| _focusableDay!: HTMLElement; | ||
|
|
||
|
|
@@ -231,8 +240,6 @@ class DayPicker extends CalendarPart implements ICalendarPicker { | |
| const tempDate = this._getFirstDay(); // date that will be changed by 1 day 42 times | ||
| const todayDate = CalendarDate.fromLocalJSDate(UI5Date.getInstance(), this._primaryCalendarType); // current day date - calculate once | ||
| const calendarDate = this._calendarDate; // store the _calendarDate value as this getter is expensive and degrades IE11 perf | ||
| const minDate = this._minDate; // store the _minDate (expensive getter) | ||
| const maxDate = this._maxDate; // store the _maxDate (expensive getter) | ||
|
|
||
| const tempSecondDate = this.hasSecondaryCalendarType ? this._getSecondaryDay(tempDate) : undefined; | ||
|
|
||
|
|
@@ -255,7 +262,7 @@ class DayPicker extends CalendarPart implements ICalendarPicker { | |
| const isSelectedBetween = this._isDayInsideSelectionRange(timestamp); | ||
| const isOtherMonth = tempDate.getMonth() !== calendarDate.getMonth(); | ||
| const isWeekend = this._isWeekend(tempDate); | ||
| const isDisabled = tempDate.valueOf() < minDate.valueOf() || tempDate.valueOf() > maxDate.valueOf(); | ||
| const isDisabled = !this._isDateEnabled(tempDate); | ||
| const isToday = tempDate.isSame(todayDate); | ||
| const isFirstDayOfWeek = tempDate.getDay() === firstDayOfWeek; | ||
|
|
||
|
|
@@ -818,6 +825,59 @@ class DayPicker extends CalendarPart implements ICalendarPicker { | |
| || (iWeekendEnd < iWeekendStart && (iWeekDay >= iWeekendStart || iWeekDay <= iWeekendEnd)); | ||
| } | ||
|
|
||
| /** | ||
| * Checks if a given date is enabled (selectable). | ||
| * A date is considered disabled if: | ||
| * - It falls outside the min/max date range defined by the component | ||
| * - It matches a single disabled date | ||
| * - It falls within a disabled date range (exclusive of start and end dates) | ||
| * @param date - The date to check | ||
| * @returns `true` if the date is enabled (selectable), `false` if disabled | ||
| * @private | ||
| */ | ||
| _isDateEnabled(date: CalendarDate): boolean { | ||
| if ((this._minDate && date.isBefore(this._minDate)) | ||
| || (this._maxDate && date.isAfter(this._maxDate))) { | ||
| return false; | ||
| } | ||
|
|
||
| const dateTimestamp = date.valueOf() / 1000; | ||
|
|
||
| return !this.disabledDates.some(range => { | ||
| const startTimestamp = this._getTimestampFromDateValue(range.startValue); | ||
| const endTimestamp = this._getTimestampFromDateValue(range.endValue); | ||
|
|
||
| if (endTimestamp) { | ||
| return dateTimestamp > startTimestamp && dateTimestamp < endTimestamp; | ||
| } | ||
|
|
||
| return startTimestamp && dateTimestamp === startTimestamp; | ||
| }); | ||
| } | ||
|
|
||
| /** | ||
| * Converts a date value string to a timestamp. | ||
| * @param dateValue - Date string to convert | ||
| * @returns timestamp in seconds, or 0 if invalid | ||
| * @private | ||
| */ | ||
| _getTimestampFromDateValue(dateValue?: string): number { | ||
| if (!dateValue) { | ||
| return 0; | ||
| } | ||
|
|
||
| try { | ||
|
Contributor
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. Are we sure that either of the methods throw an error to be caught? If not we can just go for: const jsDate = this.getValueFormat().parse(dateValue); And if needed to check if there's calendarDate before returning it.
Contributor
Author
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. fromLocalJSDate method throws exception. |
||
| const jsDate = this.getValueFormat().parse(dateValue) as Date; | ||
| const calendarDate = CalendarDate.fromLocalJSDate( | ||
| jsDate, | ||
| this._primaryCalendarType, | ||
| ); | ||
| return calendarDate.valueOf() / 1000; | ||
| } catch { | ||
| return 0; | ||
| } | ||
| } | ||
|
|
||
| _isDayPressed(target: HTMLElement): boolean { | ||
| const targetParent = target.parentNode as HTMLElement; | ||
| return (target.className.indexOf("ui5-dp-item") > -1) || (targetParent && targetParent.classList && targetParent.classList.contains("ui5-dp-item")); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.