@vaadin/date-picker 25.3.0-dev.3a3c2d7d2a → 25.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/custom-elements.json +556 -205
- package/package.json +13 -13
- package/src/styles/vaadin-date-picker-overlay-content-base-styles.js +0 -3
- package/src/styles/vaadin-month-calendar-base-styles.js +3 -0
- package/src/vaadin-date-metadata-controller.d.ts +94 -0
- package/src/vaadin-date-metadata-controller.js +268 -0
- package/src/vaadin-date-picker-helper.d.ts +144 -13
- package/src/vaadin-date-picker-helper.js +119 -15
- package/src/vaadin-date-picker-mixin.d.ts +87 -15
- package/src/vaadin-date-picker-mixin.js +129 -121
- package/src/vaadin-date-picker-overlay-content-mixin.js +144 -163
- package/src/vaadin-date-picker-overlay-content.js +1 -0
- package/src/vaadin-date-picker-overlay.js +1 -0
- package/src/vaadin-date-picker-year.js +4 -1
- package/src/vaadin-date-picker.d.ts +73 -7
- package/src/vaadin-date-picker.js +67 -9
- package/src/vaadin-infinite-scroller.js +21 -6
- package/src/vaadin-month-calendar-mixin.js +43 -59
- package/src/vaadin-month-calendar.js +5 -0
- package/web-types.json +37 -21
- package/web-types.lit.json +18 -11
- package/src/vaadin-disabled-dates-controller.d.ts +0 -66
- package/src/vaadin-disabled-dates-controller.js +0 -241
|
@@ -5,23 +5,25 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { hideOthers } from '@vaadin/a11y-base/src/aria-hidden.js';
|
|
7
7
|
import { DelegateFocusMixin } from '@vaadin/a11y-base/src/delegate-focus-mixin.js';
|
|
8
|
-
import { isKeyboardActive } from '@vaadin/a11y-base/src/focus-utils.js';
|
|
8
|
+
import { isElementFocused, isKeyboardActive } from '@vaadin/a11y-base/src/focus-utils.js';
|
|
9
9
|
import { KeyboardMixin } from '@vaadin/a11y-base/src/keyboard-mixin.js';
|
|
10
10
|
import { isIOS } from '@vaadin/component-base/src/browser-utils.js';
|
|
11
|
+
import { setOrRemoveAttribute } from '@vaadin/component-base/src/dom-utils.js';
|
|
11
12
|
import { I18nMixin } from '@vaadin/component-base/src/i18n-mixin.js';
|
|
12
13
|
import { MediaQueryController } from '@vaadin/component-base/src/media-query-controller.js';
|
|
13
14
|
import { InputConstraintsMixin } from '@vaadin/field-base/src/input-constraints-mixin.js';
|
|
14
15
|
import { VirtualKeyboardController } from '@vaadin/field-base/src/virtual-keyboard-controller.js';
|
|
16
|
+
import { DateMetadataController } from './vaadin-date-metadata-controller.js';
|
|
15
17
|
import {
|
|
16
18
|
dateAllowed,
|
|
17
19
|
dateEquals,
|
|
20
|
+
dateSelectable,
|
|
18
21
|
extractDateParts,
|
|
19
22
|
formatISODate,
|
|
20
23
|
getAdjustedYear,
|
|
21
24
|
getClosestDate,
|
|
22
25
|
parseDate,
|
|
23
26
|
} from './vaadin-date-picker-helper.js';
|
|
24
|
-
import { DisabledDatesController } from './vaadin-disabled-dates-controller.js';
|
|
25
27
|
|
|
26
28
|
export const datePickerI18nDefaults = Object.freeze({
|
|
27
29
|
monthNames: [
|
|
@@ -43,6 +45,7 @@ export const datePickerI18nDefaults = Object.freeze({
|
|
|
43
45
|
firstDayOfWeek: 0,
|
|
44
46
|
today: 'Today',
|
|
45
47
|
cancel: 'Cancel',
|
|
48
|
+
dialogAccessibleName: 'Calendar',
|
|
46
49
|
referenceDate: '',
|
|
47
50
|
formatDate(d) {
|
|
48
51
|
const yearStr = String(d.year).replace(/\d+/u, (y) => '0000'.substr(y.length) + y);
|
|
@@ -60,7 +63,7 @@ export const datePickerI18nDefaults = Object.freeze({
|
|
|
60
63
|
date = parseInt(parts[1]);
|
|
61
64
|
year = parseInt(parts[2]);
|
|
62
65
|
if (parts[2].length < 3 && year >= 0) {
|
|
63
|
-
const usedReferenceDate =
|
|
66
|
+
const usedReferenceDate = parseDate(this.referenceDate) || new Date();
|
|
64
67
|
year = getAdjustedYear(usedReferenceDate, year, month, date);
|
|
65
68
|
}
|
|
66
69
|
} else if (parts.length === 2) {
|
|
@@ -203,6 +206,10 @@ export const DatePickerMixin = (subclass) =>
|
|
|
203
206
|
* Receives a `DatePickerDate` object of the date to be selected and should return a
|
|
204
207
|
* boolean.
|
|
205
208
|
*
|
|
209
|
+
* The function is called once per date and has to answer synchronously. Use
|
|
210
|
+
* `dateMetadataProvider` when the answer has to be loaded first, or when dates also need
|
|
211
|
+
* custom part names. A date is disabled when either of the two disables it.
|
|
212
|
+
*
|
|
206
213
|
* @type {function(DatePickerDate): boolean | undefined}
|
|
207
214
|
*/
|
|
208
215
|
isDateDisabled: {
|
|
@@ -210,27 +217,45 @@ export const DatePickerMixin = (subclass) =>
|
|
|
210
217
|
},
|
|
211
218
|
|
|
212
219
|
/**
|
|
213
|
-
* A
|
|
214
|
-
*
|
|
215
|
-
* `
|
|
216
|
-
*
|
|
220
|
+
* A function that provides metadata for the dates the calendar is about to render: whether they
|
|
221
|
+
* are disabled, and CSS `part` names for styling from outside using the `::part()` selector.
|
|
222
|
+
* Unlike `isDateDisabled`, which is called once per date, the metadata provider is called for
|
|
223
|
+
* a range of dates at a time, and again as the calendar renders further dates.
|
|
224
|
+
*
|
|
225
|
+
* It receives a `DatePickerDateRange` and returns an array of `DatePickerDateMetadata` objects
|
|
226
|
+
* for the dates in that range that have metadata. It can return a `Promise` to load the metadata
|
|
227
|
+
* asynchronously, and `null` or `undefined` when no date in the range has metadata.
|
|
228
|
+
*
|
|
229
|
+
* The returned array has the following structure:
|
|
230
|
+
*
|
|
231
|
+
* ```js
|
|
232
|
+
* [
|
|
233
|
+
* // The date is an ISO 8601 string.
|
|
234
|
+
* { date: '2026-01-01', disabled: true },
|
|
217
235
|
*
|
|
218
|
-
*
|
|
219
|
-
*
|
|
220
|
-
*
|
|
221
|
-
*
|
|
222
|
-
* until it resolves.
|
|
236
|
+
* // Adds a custom part name to the date.
|
|
237
|
+
* { date: '2026-01-02', part: 'busy' },
|
|
238
|
+
* ]
|
|
239
|
+
* ```
|
|
223
240
|
*
|
|
224
|
-
*
|
|
225
|
-
*
|
|
226
|
-
*
|
|
241
|
+
* A date is disabled if its metadata marks it disabled, or `isDateDisabled` returns `true`, or
|
|
242
|
+
* it is outside `min` and `max`. Disabled dates are not selectable, and typing a disabled date in
|
|
243
|
+
* the field makes it invalid. The provider does not affect which date is focused when opening the
|
|
244
|
+
* overlay. Use `initialPosition` property to provide a selectable date.
|
|
227
245
|
*
|
|
228
|
-
*
|
|
229
|
-
*
|
|
246
|
+
* While a returned `Promise` is pending, the dates it covers are not disabled yet and render with
|
|
247
|
+
* the `loading` part. If the function throws or rejects, corresponding dates are requested again
|
|
248
|
+
* the next time the user navigates.
|
|
230
249
|
*
|
|
231
|
-
*
|
|
250
|
+
* The provider is used for validation also when the overlay is closed. Date is considered valid
|
|
251
|
+
* while the provider is pending, and is re-validated again after the metadata is loaded.
|
|
252
|
+
*
|
|
253
|
+
* Keep a stable reference to the function: assigning a new one clears the cache and re-fetches
|
|
254
|
+
* visible range. Call `clearCache()` to re-fetch when the data behind the same function changed.
|
|
255
|
+
*
|
|
256
|
+
* @type {DatePickerDateMetadataProvider | null | undefined}
|
|
232
257
|
*/
|
|
233
|
-
|
|
258
|
+
dateMetadataProvider: {
|
|
234
259
|
type: Function,
|
|
235
260
|
},
|
|
236
261
|
|
|
@@ -287,8 +312,7 @@ export const DatePickerMixin = (subclass) =>
|
|
|
287
312
|
return [
|
|
288
313
|
'_selectedDateChanged(_selectedDate, __effectiveI18n)',
|
|
289
314
|
'_focusedDateChanged(_focusedDate, __effectiveI18n)',
|
|
290
|
-
'__updateOverlayContent(_overlayContent, __effectiveI18n, label, _minDate, _maxDate, _focusedDate, _selectedDate, showWeekNumbers, isDateDisabled,
|
|
291
|
-
'__disabledDatesProviderChanged(disabledDatesProvider)',
|
|
315
|
+
'__updateOverlayContent(_overlayContent, __effectiveI18n, label, _minDate, _maxDate, _focusedDate, _selectedDate, showWeekNumbers, isDateDisabled, __enteredDate)',
|
|
292
316
|
'__updateOverlayContentTheme(_overlayContent, _theme)',
|
|
293
317
|
'__updateOverlayContentFullScreen(_overlayContent, _fullscreen)',
|
|
294
318
|
];
|
|
@@ -299,7 +323,7 @@ export const DatePickerMixin = (subclass) =>
|
|
|
299
323
|
}
|
|
300
324
|
|
|
301
325
|
static get constraints() {
|
|
302
|
-
return [...super.constraints, 'min', 'max'];
|
|
326
|
+
return [...super.constraints, 'min', 'max', 'dateMetadataProvider'];
|
|
303
327
|
}
|
|
304
328
|
|
|
305
329
|
constructor() {
|
|
@@ -307,6 +331,9 @@ export const DatePickerMixin = (subclass) =>
|
|
|
307
331
|
|
|
308
332
|
this._boundOnClick = this._onClick.bind(this);
|
|
309
333
|
this._boundOnScroll = this._onScroll.bind(this);
|
|
334
|
+
|
|
335
|
+
this._dateMetadataController = new DateMetadataController(this, () => this.__onDateMetadataChanged());
|
|
336
|
+
this.addController(this._dateMetadataController);
|
|
310
337
|
}
|
|
311
338
|
|
|
312
339
|
/**
|
|
@@ -349,6 +376,10 @@ export const DatePickerMixin = (subclass) =>
|
|
|
349
376
|
* // Translation of the Cancel button text.
|
|
350
377
|
* cancel: 'Cancel',
|
|
351
378
|
*
|
|
379
|
+
* // Accessible name of the overlay content, announced by screen readers
|
|
380
|
+
* // when the overlay opens.
|
|
381
|
+
* dialogAccessibleName: 'Calendar',
|
|
382
|
+
*
|
|
352
383
|
* // Used for adjusting the year value when parsing dates with short years.
|
|
353
384
|
* // The year values between 0 and 99 are evaluated and adjusted.
|
|
354
385
|
* // Example: for a referenceDate of 1970-10-30;
|
|
@@ -428,7 +459,10 @@ export const DatePickerMixin = (subclass) =>
|
|
|
428
459
|
super._onFocus(event);
|
|
429
460
|
|
|
430
461
|
if (this._noInput && !isKeyboardActive()) {
|
|
462
|
+
// Blur to hide the virtual keyboard, but do not validate.
|
|
463
|
+
this.__ignoreInternalBlur = true;
|
|
431
464
|
event.target.blur();
|
|
465
|
+
this.__ignoreInternalBlur = false;
|
|
432
466
|
}
|
|
433
467
|
}
|
|
434
468
|
|
|
@@ -439,6 +473,10 @@ export const DatePickerMixin = (subclass) =>
|
|
|
439
473
|
_onBlur(event) {
|
|
440
474
|
super._onBlur(event);
|
|
441
475
|
|
|
476
|
+
if (this.__ignoreInternalBlur) {
|
|
477
|
+
return;
|
|
478
|
+
}
|
|
479
|
+
|
|
442
480
|
if (!this.opened) {
|
|
443
481
|
this.__commitParsedOrFocusedDate();
|
|
444
482
|
|
|
@@ -464,13 +502,6 @@ export const DatePickerMixin = (subclass) =>
|
|
|
464
502
|
|
|
465
503
|
this.addController(new VirtualKeyboardController(this));
|
|
466
504
|
|
|
467
|
-
// Owns the cache of dates resolved by `disabledDatesProvider`. It lives on the date-picker
|
|
468
|
-
// rather than the overlay content so validation works even when the overlay is never opened.
|
|
469
|
-
// The open overlay reads the same controller to render months and show the loading spinner.
|
|
470
|
-
this._disabledDatesController = new DisabledDatesController(this, () => this.__onDisabledDatesChanged());
|
|
471
|
-
this.addController(this._disabledDatesController);
|
|
472
|
-
this._disabledDatesController.setProvider(this.disabledDatesProvider);
|
|
473
|
-
|
|
474
505
|
this._overlayElement = this.$.overlay;
|
|
475
506
|
}
|
|
476
507
|
|
|
@@ -478,6 +509,11 @@ export const DatePickerMixin = (subclass) =>
|
|
|
478
509
|
updated(props) {
|
|
479
510
|
super.updated(props);
|
|
480
511
|
|
|
512
|
+
if (props.has('dateMetadataProvider')) {
|
|
513
|
+
this._dateMetadataController.setProvider(this.dateMetadataProvider);
|
|
514
|
+
this.__reloadDateMetadata();
|
|
515
|
+
}
|
|
516
|
+
|
|
481
517
|
if (props.has('showWeekNumbers') || props.has('__effectiveI18n')) {
|
|
482
518
|
// Currently only supported for locales that start the week on Monday.
|
|
483
519
|
this.toggleAttribute('week-numbers', this.showWeekNumbers && this.__effectiveI18n.firstDayOfWeek === 1);
|
|
@@ -520,6 +556,28 @@ export const DatePickerMixin = (subclass) =>
|
|
|
520
556
|
this.$.overlay.close();
|
|
521
557
|
}
|
|
522
558
|
|
|
559
|
+
/**
|
|
560
|
+
* Clears the `dateMetadataProvider` cache and reloads the date metadata.
|
|
561
|
+
*/
|
|
562
|
+
clearCache() {
|
|
563
|
+
this._dateMetadataController.clearCache();
|
|
564
|
+
this.__reloadDateMetadata();
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
/**
|
|
568
|
+
* Asks for what the dropped cache was holding: the months the overlay is showing, and the month
|
|
569
|
+
* of the value being validated. Requested from here rather than from the controller's
|
|
570
|
+
* notification, which would turn a provider that keeps failing into an endless retry, since a
|
|
571
|
+
* failed month is dropped and so becomes missing again.
|
|
572
|
+
* @private
|
|
573
|
+
*/
|
|
574
|
+
__reloadDateMetadata() {
|
|
575
|
+
if (this.opened) {
|
|
576
|
+
this._overlayContent?.loadVisibleDateMetadata();
|
|
577
|
+
}
|
|
578
|
+
this.__ensureSelectedDateLoaded();
|
|
579
|
+
}
|
|
580
|
+
|
|
523
581
|
/** @private */
|
|
524
582
|
__ensureContent() {
|
|
525
583
|
if (this._overlayContent) {
|
|
@@ -613,8 +671,13 @@ export const DatePickerMixin = (subclass) =>
|
|
|
613
671
|
const inputValid = !inputValue || (!!this._selectedDate && inputValue === this.__formatDate(this._selectedDate));
|
|
614
672
|
const isDateValid =
|
|
615
673
|
!this._selectedDate ||
|
|
616
|
-
(
|
|
617
|
-
|
|
674
|
+
dateSelectable(
|
|
675
|
+
this._selectedDate,
|
|
676
|
+
this._minDate,
|
|
677
|
+
this._maxDate,
|
|
678
|
+
this.isDateDisabled,
|
|
679
|
+
this._dateMetadataController,
|
|
680
|
+
);
|
|
618
681
|
|
|
619
682
|
let inputValidity = true;
|
|
620
683
|
if (this.inputElement && this.inputElement.checkValidity) {
|
|
@@ -625,90 +688,44 @@ export const DatePickerMixin = (subclass) =>
|
|
|
625
688
|
}
|
|
626
689
|
|
|
627
690
|
/**
|
|
628
|
-
*
|
|
629
|
-
*
|
|
630
|
-
*
|
|
631
|
-
* overlay is closed is re-validated once the provider answers (see `__onDisabledDatesChanged`).
|
|
632
|
-
* Until then the date is treated as allowed, matching the overlay's rendering.
|
|
691
|
+
* Asks the controller for the month holding the selected date, so a value that was set or typed
|
|
692
|
+
* without ever opening the overlay is still checked against the provider. Validation is re-run
|
|
693
|
+
* from the host callback once the month resolves.
|
|
633
694
|
* @private
|
|
634
695
|
*/
|
|
635
|
-
|
|
636
|
-
const controller = this.
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
this._disabledDatesController.setProvider(disabledDatesProvider);
|
|
645
|
-
this.__ensureSelectedDateLoaded();
|
|
696
|
+
__ensureSelectedDateLoaded() {
|
|
697
|
+
const controller = this._dateMetadataController;
|
|
698
|
+
const awaiting = !!(controller?.provider && this._selectedDate && !controller.isMonthLoaded(this._selectedDate));
|
|
699
|
+
// Always assigned, so clearing the value or removing the provider while a request is in
|
|
700
|
+
// flight disarms the pending re-validation, and a later answer for some other month does not
|
|
701
|
+
// re-validate a value that never waited for it.
|
|
702
|
+
this.__awaitingProviderValidation = awaiting;
|
|
703
|
+
if (awaiting) {
|
|
704
|
+
controller.ensureRangeLoaded(this._selectedDate, this._selectedDate);
|
|
646
705
|
}
|
|
647
706
|
}
|
|
648
707
|
|
|
649
708
|
/**
|
|
650
|
-
*
|
|
651
|
-
*
|
|
652
|
-
*
|
|
709
|
+
* Called by the date metadata controller, one microtask after its state changed
|
|
710
|
+
* and coalesced, so this never writes reactive state from inside an update. The
|
|
711
|
+
* rendered months refresh on their own because they subscribe to the controller.
|
|
653
712
|
* @private
|
|
654
713
|
*/
|
|
655
|
-
|
|
656
|
-
const controller = this.
|
|
657
|
-
if (controller?.provider && this._selectedDate && !controller.isMonthLoaded(this._selectedDate)) {
|
|
658
|
-
this.__awaitingProviderValidation = true;
|
|
659
|
-
controller.ensureRangeLoaded(this._selectedDate, this._selectedDate);
|
|
660
|
-
}
|
|
661
|
-
}
|
|
714
|
+
__onDateMetadataChanged() {
|
|
715
|
+
const controller = this._dateMetadataController;
|
|
662
716
|
|
|
663
|
-
|
|
664
|
-
__onDisabledDatesChanged() {
|
|
665
|
-
const controller = this._disabledDatesController;
|
|
666
|
-
// Push the new loading and cache state to the open overlay so it re-renders the months and
|
|
667
|
-
// updates the spinner. When the overlay is closed there is nothing to update.
|
|
717
|
+
// Only the open overlay has a spinner to update and a today button to re-evaluate.
|
|
668
718
|
if (this._overlayContent) {
|
|
669
|
-
this._overlayContent.loading = controller.
|
|
670
|
-
this._overlayContent.
|
|
719
|
+
this._overlayContent.loading = controller.isLoading();
|
|
720
|
+
this._overlayContent.updateTodayButton();
|
|
671
721
|
}
|
|
672
|
-
|
|
673
|
-
//
|
|
722
|
+
|
|
723
|
+
// Runs whether or not the overlay was ever opened, which is the case this exists for: a value
|
|
724
|
+
// set or typed with the overlay closed is reported invalid as soon as its month answers.
|
|
674
725
|
if (this.__awaitingProviderValidation && this._selectedDate && controller.isMonthLoaded(this._selectedDate)) {
|
|
675
726
|
this.__awaitingProviderValidation = false;
|
|
676
727
|
this._requestValidation();
|
|
677
728
|
}
|
|
678
|
-
|
|
679
|
-
this.__adjustInitialFocusForProvider();
|
|
680
|
-
}
|
|
681
|
-
|
|
682
|
-
/**
|
|
683
|
-
* Moves the overlay's initial focus off a date the provider turns out to disable, once the
|
|
684
|
-
* provider has answered for that month. Only touches the auto-picked initial date and only
|
|
685
|
-
* while the user has not navigated away, so disabled dates the user focuses on purpose (which
|
|
686
|
-
* stay keyboard-focusable) are left alone.
|
|
687
|
-
* @private
|
|
688
|
-
*/
|
|
689
|
-
__adjustInitialFocusForProvider() {
|
|
690
|
-
const content = this._overlayContent;
|
|
691
|
-
const controller = this._disabledDatesController;
|
|
692
|
-
const initial = this.__initialFocusDate;
|
|
693
|
-
if (!content || !initial || !controller.provider) {
|
|
694
|
-
return;
|
|
695
|
-
}
|
|
696
|
-
// The user has moved focus; stop trying to adjust the initial date.
|
|
697
|
-
if (!dateEquals(content.focusedDate, initial)) {
|
|
698
|
-
this.__initialFocusDate = null;
|
|
699
|
-
return;
|
|
700
|
-
}
|
|
701
|
-
// Wait until the provider has answered for the initial month.
|
|
702
|
-
if (!controller.isMonthLoaded(initial)) {
|
|
703
|
-
return;
|
|
704
|
-
}
|
|
705
|
-
this.__initialFocusDate = null;
|
|
706
|
-
if (controller.isDateDisabled(initial)) {
|
|
707
|
-
const closest = content.__closestSelectableDate(initial);
|
|
708
|
-
if (closest) {
|
|
709
|
-
content.focusDate(closest);
|
|
710
|
-
}
|
|
711
|
-
}
|
|
712
729
|
}
|
|
713
730
|
|
|
714
731
|
/**
|
|
@@ -894,14 +911,12 @@ export const DatePickerMixin = (subclass) =>
|
|
|
894
911
|
this._applyInputValue(selectedDate);
|
|
895
912
|
}
|
|
896
913
|
|
|
897
|
-
// Preload the provider's answer for the selected month so the value can be validated even
|
|
898
|
-
// when the overlay is never opened.
|
|
899
|
-
this.__ensureSelectedDateLoaded();
|
|
900
|
-
|
|
901
914
|
this.value = this._formatISO(selectedDate);
|
|
902
915
|
this._ignoreFocusedDateChange = true;
|
|
903
916
|
this._focusedDate = selectedDate;
|
|
904
917
|
this._ignoreFocusedDateChange = false;
|
|
918
|
+
|
|
919
|
+
this.__ensureSelectedDateLoaded();
|
|
905
920
|
}
|
|
906
921
|
|
|
907
922
|
/** @private */
|
|
@@ -969,13 +984,11 @@ export const DatePickerMixin = (subclass) =>
|
|
|
969
984
|
selectedDate,
|
|
970
985
|
showWeekNumbers,
|
|
971
986
|
isDateDisabled,
|
|
972
|
-
disabledDatesProvider,
|
|
973
987
|
enteredDate,
|
|
974
988
|
) {
|
|
975
989
|
if (overlayContent) {
|
|
976
|
-
//
|
|
977
|
-
|
|
978
|
-
overlayContent._disabledDatesController = this._disabledDatesController;
|
|
990
|
+
// Reuse the date-picker's controller so the overlay shares the same cache.
|
|
991
|
+
overlayContent._dateMetadataController = this._dateMetadataController;
|
|
979
992
|
overlayContent.i18n = effectiveI18n;
|
|
980
993
|
overlayContent.label = label;
|
|
981
994
|
overlayContent.minDate = minDate;
|
|
@@ -984,7 +997,6 @@ export const DatePickerMixin = (subclass) =>
|
|
|
984
997
|
overlayContent.selectedDate = selectedDate;
|
|
985
998
|
overlayContent.showWeekNumbers = showWeekNumbers;
|
|
986
999
|
overlayContent.isDateDisabled = isDateDisabled;
|
|
987
|
-
overlayContent.disabledDatesProvider = disabledDatesProvider;
|
|
988
1000
|
overlayContent.enteredDate = enteredDate;
|
|
989
1001
|
}
|
|
990
1002
|
}
|
|
@@ -992,11 +1004,7 @@ export const DatePickerMixin = (subclass) =>
|
|
|
992
1004
|
/** @private */
|
|
993
1005
|
__updateOverlayContentTheme(overlayContent, theme) {
|
|
994
1006
|
if (overlayContent) {
|
|
995
|
-
|
|
996
|
-
overlayContent.setAttribute('theme', theme);
|
|
997
|
-
} else {
|
|
998
|
-
overlayContent.removeAttribute('theme');
|
|
999
|
-
}
|
|
1007
|
+
setOrRemoveAttribute(overlayContent, 'theme', theme);
|
|
1000
1008
|
}
|
|
1001
1009
|
}
|
|
1002
1010
|
|
|
@@ -1033,12 +1041,6 @@ export const DatePickerMixin = (subclass) =>
|
|
|
1033
1041
|
content.focusedDate = scrollFocusDate;
|
|
1034
1042
|
this._ignoreFocusedDateChange = false;
|
|
1035
1043
|
|
|
1036
|
-
// When opening without a selected value, remember the auto-picked initial date so it can be
|
|
1037
|
-
// moved off a provider-disabled date once the provider answers (see __onDisabledDatesChanged).
|
|
1038
|
-
// A date the user selected themselves is left in place even if the provider disables it.
|
|
1039
|
-
this.__initialFocusDate = this._selectedDate ? null : scrollFocusDate;
|
|
1040
|
-
this.__adjustInitialFocusForProvider();
|
|
1041
|
-
|
|
1042
1044
|
window.addEventListener('scroll', this._boundOnScroll, true);
|
|
1043
1045
|
|
|
1044
1046
|
if (this._focusOverlayOnOpen) {
|
|
@@ -1102,7 +1104,7 @@ export const DatePickerMixin = (subclass) =>
|
|
|
1102
1104
|
|
|
1103
1105
|
/** @protected */
|
|
1104
1106
|
_onOverlayClosed() {
|
|
1105
|
-
this.
|
|
1107
|
+
this._overlayContent?.cancelLoadVisibleDateMetadata();
|
|
1106
1108
|
|
|
1107
1109
|
// Reset `aria-hidden` state.
|
|
1108
1110
|
if (this.__showOthers) {
|
|
@@ -1122,6 +1124,12 @@ export const DatePickerMixin = (subclass) =>
|
|
|
1122
1124
|
if (!this.value && !this._keyboardActive) {
|
|
1123
1125
|
this._requestValidation();
|
|
1124
1126
|
}
|
|
1127
|
+
|
|
1128
|
+
// Focusout events while closing arrive with `opened` still true and keep the focused state.
|
|
1129
|
+
// Clear it here unless focus was restored to the input, as at a wide viewport or on Esc.
|
|
1130
|
+
if (!this.inputElement || !isElementFocused(this.inputElement)) {
|
|
1131
|
+
this._setFocused(false);
|
|
1132
|
+
}
|
|
1125
1133
|
}
|
|
1126
1134
|
|
|
1127
1135
|
/** @private */
|