@vaadin/date-picker 25.3.0-alpha6 → 25.3.0-dev.1fa5a51482

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.
@@ -106,6 +106,38 @@ export const DatePickerOverlayContentMixin = (superClass) =>
106
106
  type: Function,
107
107
  },
108
108
 
109
+ /**
110
+ * A batch function that fetches metadata (disabled state, custom part names, ...) for a
111
+ * range of dates the calendar is about to render. Returns, or resolves with, an array of
112
+ * `DatePickerDateMetadata` objects.
113
+ *
114
+ * @type {function(DatePickerDateRange): Array<DatePickerDateMetadata> | Promise<Array<DatePickerDateMetadata>> | undefined}
115
+ */
116
+ dateMetadataProvider: {
117
+ type: Function,
118
+ },
119
+
120
+ /**
121
+ * Reflected while data is being loaded, so the overlay can show a loading spinner.
122
+ * Currently set while the date metadata provider is resolving.
123
+ */
124
+ loading: {
125
+ type: Boolean,
126
+ value: false,
127
+ reflectToAttribute: true,
128
+ },
129
+
130
+ /**
131
+ * Bumped whenever the disabled dates controller's cache or loading state changes, to
132
+ * re-run `__updateCalendars` and push the new state to the rendered months.
133
+ * @private
134
+ */
135
+ _dateMetadataVersion: {
136
+ type: Number,
137
+ value: 0,
138
+ attribute: false,
139
+ },
140
+
109
141
  enteredDate: {
110
142
  type: Date,
111
143
  sync: true,
@@ -138,9 +170,10 @@ export const DatePickerOverlayContentMixin = (superClass) =>
138
170
 
139
171
  static get observers() {
140
172
  return [
141
- '__updateCalendars(calendars, i18n, minDate, maxDate, selectedDate, focusedDate, showWeekNumbers, _ignoreTaps, _theme, isDateDisabled, enteredDate)',
173
+ '__updateCalendars(calendars, i18n, minDate, maxDate, selectedDate, focusedDate, showWeekNumbers, _ignoreTaps, _theme, isDateDisabled, _dateMetadataVersion, enteredDate)',
174
+ '__loadingChanged(loading)',
142
175
  '__updateCancelButton(_cancelButton, i18n)',
143
- '__updateTodayButton(_todayButton, i18n, minDate, maxDate, isDateDisabled)',
176
+ '__updateTodayButton(_todayButton, i18n, minDate, maxDate, isDateDisabled, _dateMetadataVersion)',
144
177
  '__updateYears(years, selectedDate, _theme)',
145
178
  ];
146
179
  }
@@ -299,6 +332,17 @@ export const DatePickerOverlayContentMixin = (superClass) =>
299
332
  }
300
333
  }
301
334
 
335
+ /** @private */
336
+ __loadingChanged(loading) {
337
+ // Mark the calendar region as busy while data is being loaded so assistive technology knows
338
+ // the content is still updating.
339
+ if (loading) {
340
+ this.setAttribute('aria-busy', 'true');
341
+ } else {
342
+ this.removeAttribute('aria-busy');
343
+ }
344
+ }
345
+
302
346
  // eslint-disable-next-line @typescript-eslint/max-params
303
347
  __updateCalendars(
304
348
  calendars,
@@ -311,6 +355,7 @@ export const DatePickerOverlayContentMixin = (superClass) =>
311
355
  ignoreTaps,
312
356
  theme,
313
357
  isDateDisabled,
358
+ dateMetadataVersion,
314
359
  enteredDate,
315
360
  ) {
316
361
  if (calendars?.length) {
@@ -319,6 +364,8 @@ export const DatePickerOverlayContentMixin = (superClass) =>
319
364
  calendar.minDate = minDate;
320
365
  calendar.maxDate = maxDate;
321
366
  calendar.isDateDisabled = isDateDisabled;
367
+ calendar.dateMetadataController = this._dateMetadataController;
368
+ calendar.__dateMetadataVersion = dateMetadataVersion;
322
369
  calendar.focusedDate = focusedDate;
323
370
  calendar.selectedDate = selectedDate;
324
371
  calendar.showWeekNumbers = showWeekNumbers;
@@ -331,7 +378,46 @@ export const DatePickerOverlayContentMixin = (superClass) =>
331
378
  calendar.removeAttribute('theme');
332
379
  }
333
380
  });
381
+
382
+ this.__ensureVisibleDateMetadataLoaded();
383
+ }
384
+ }
385
+
386
+ /**
387
+ * Asks the disabled dates controller to load the range of months currently rendered by the
388
+ * scroller. The controller expands the range with a prefetch buffer and skips months that are
389
+ * already loaded or in flight, so one request covers the whole visible range.
390
+ * @private
391
+ */
392
+ __ensureVisibleDateMetadataLoaded() {
393
+ const controller = this._dateMetadataController;
394
+ if (!controller?.provider || !this.calendars || this.calendars.length === 0) {
395
+ return;
334
396
  }
397
+ const indexes = this.calendars
398
+ .map((calendar) => calendar.month)
399
+ .filter(Boolean)
400
+ .map((month) => month.getFullYear() * 12 + month.getMonth());
401
+ if (indexes.length === 0) {
402
+ return;
403
+ }
404
+ const min = Math.min(...indexes);
405
+ const max = Math.max(...indexes);
406
+ controller.ensureRangeLoaded(
407
+ new Date(Math.floor(min / 12), min % 12, 1),
408
+ new Date(Math.floor(max / 12), max % 12, 1),
409
+ );
410
+ }
411
+
412
+ /**
413
+ * Debounced variant used on scroll, so a continuous scroll only triggers one load once it
414
+ * settles instead of a request per intermediate position.
415
+ * @private
416
+ */
417
+ __scheduleVisibleDateMetadataLoad() {
418
+ this._loadDateMetadataDebouncer = Debouncer.debounce(this._loadDateMetadataDebouncer, timeOut.after(200), () =>
419
+ this.__ensureVisibleDateMetadataLoaded(),
420
+ );
335
421
  }
336
422
 
337
423
  /** @private */
@@ -357,6 +443,11 @@ export const DatePickerOverlayContentMixin = (superClass) =>
357
443
  if (!this._dateAllowed(dateToSelect)) {
358
444
  return false;
359
445
  }
446
+ // Block dates disabled by the provider, or in a month whose provider result has not loaded
447
+ // yet, so they cannot be selected via keyboard or the today button either.
448
+ if (this._dateMetadataController?.isDateBlocked(dateToSelect)) {
449
+ return false;
450
+ }
360
451
  this.selectedDate = dateToSelect;
361
452
  this.dispatchEvent(
362
453
  new CustomEvent('date-selected', { detail: { date: dateToSelect }, bubbles: true, composed: true }),
@@ -452,12 +543,17 @@ export const DatePickerOverlayContentMixin = (superClass) =>
452
543
  const monthPosition = this._monthScroller.position;
453
544
  this._visibleMonthIndex = Math.floor(monthPosition);
454
545
  this._yearScroller.position = (monthPosition + this._originDate.getMonth()) / 12;
546
+ // Called from every navigation path (month scroll, year click, reveal), so this is the
547
+ // single place to keep the disabled dates loaded for the newly visible months. Debounced
548
+ // so a continuous scroll only triggers one load once it settles.
549
+ this.__scheduleVisibleDateMetadataLoad();
455
550
  }
456
551
 
457
552
  /** @private */
458
553
  _repositionMonthScroller() {
459
554
  this._monthScroller.position = this._yearScroller.position * 12 - this._originDate.getMonth();
460
555
  this._visibleMonthIndex = Math.floor(this._monthScroller.position);
556
+ this.__scheduleVisibleDateMetadataLoad();
461
557
  }
462
558
 
463
559
  /** @private */
@@ -831,6 +927,33 @@ export const DatePickerOverlayContentMixin = (superClass) =>
831
927
  this.focusDate(getClosestDate(focus, [this.minDate, this.maxDate]));
832
928
  }
833
929
 
930
+ /**
931
+ * Returns the nearest date to the given one that can actually be selected: inside min/max, not
932
+ * disabled by `isDateDisabled`, and not disabled by a resolved `dateMetadataProvider`. Scans a
933
+ * year in both directions and returns `undefined` if none is found, so the caller can leave the
934
+ * focus untouched.
935
+ * @private
936
+ */
937
+ __closestSelectableDate(date) {
938
+ const controller = this._dateMetadataController;
939
+ const isSelectable = (candidate) =>
940
+ this._dateAllowed(candidate) && !(controller?.provider && controller.isDateDisabled(candidate));
941
+
942
+ if (isSelectable(date)) {
943
+ return date;
944
+ }
945
+ for (let offset = 1; offset <= 366; offset++) {
946
+ for (const direction of [1, -1]) {
947
+ const candidate = new Date(date);
948
+ candidate.setDate(candidate.getDate() + offset * direction);
949
+ if (isSelectable(candidate)) {
950
+ return candidate;
951
+ }
952
+ }
953
+ }
954
+ return undefined;
955
+ }
956
+
834
957
  /** @private */
835
958
  _focusAllowedDate(dateToFocus, diff, keepMonth) {
836
959
  // For this check we do consider the isDateDisabled function because disabled dates are allowed to be focused, just not outside min/max
@@ -918,7 +1041,12 @@ export const DatePickerOverlayContentMixin = (superClass) =>
918
1041
 
919
1042
  /** @private */
920
1043
  _isTodayAllowed(min, max, isDateDisabled) {
921
- return this._dateAllowed(this._getTodayMidnight(), min, max, isDateDisabled);
1044
+ const today = this._getTodayMidnight();
1045
+ if (!this._dateAllowed(today, min, max, isDateDisabled)) {
1046
+ return false;
1047
+ }
1048
+ // Today is not selectable while it is disabled by the provider or its month is still loading.
1049
+ return !this._dateMetadataController?.isDateBlocked(today);
922
1050
  }
923
1051
 
924
1052
  /** @private */
@@ -12,12 +12,14 @@ import { html, LitElement } from 'lit';
12
12
  import { defineCustomElement } from '@vaadin/component-base/src/define.js';
13
13
  import { DirMixin } from '@vaadin/component-base/src/dir-mixin.js';
14
14
  import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
15
+ import { loaderStyles } from '@vaadin/component-base/src/styles/loader-styles.js';
15
16
  import { LumoInjectionMixin } from '@vaadin/vaadin-themable-mixin/lumo-injection-mixin.js';
16
17
  import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
17
18
  import { overlayContentStyles } from './styles/vaadin-date-picker-overlay-content-base-styles.js';
18
19
  import { DatePickerOverlayContentMixin } from './vaadin-date-picker-overlay-content-mixin.js';
19
20
 
20
21
  /**
22
+ * @attr {string} theme - The theme variants to apply to the component.
21
23
  * @customElement vaadin-date-picker-overlay-content
22
24
  * @extends HTMLElement
23
25
  * @private
@@ -30,7 +32,7 @@ class DatePickerOverlayContent extends DatePickerOverlayContentMixin(
30
32
  }
31
33
 
32
34
  static get styles() {
33
- return overlayContentStyles;
35
+ return [loaderStyles, overlayContentStyles];
34
36
  }
35
37
 
36
38
  static get lumoInjector() {
@@ -43,6 +45,8 @@ class DatePickerOverlayContent extends DatePickerOverlayContentMixin(
43
45
  <slot name="months"></slot>
44
46
  <slot name="years"></slot>
45
47
 
48
+ <div part="loader" aria-hidden="true"></div>
49
+
46
50
  <div role="toolbar" part="toolbar">
47
51
  <slot name="today-button"></slot>
48
52
  <div
@@ -16,6 +16,7 @@ import { DatePickerOverlayMixin } from './vaadin-date-picker-overlay-mixin.js';
16
16
  /**
17
17
  * An element used internally by `<vaadin-date-picker>`. Not intended to be used separately.
18
18
  *
19
+ * @attr {string} theme - The theme variants to apply to the component.
19
20
  * @customElement vaadin-date-picker-overlay
20
21
  * @extends HTMLElement
21
22
  * @private
@@ -13,6 +13,7 @@ import { datePickerYearStyles } from './styles/vaadin-date-picker-year-base-styl
13
13
  /**
14
14
  * An element used internally by `<vaadin-date-picker>`. Not intended to be used separately.
15
15
  *
16
+ * @attr {string} theme - The theme variants to apply to the component.
16
17
  * @customElement vaadin-date-picker-year
17
18
  * @extends HTMLElement
18
19
  * @private
@@ -7,7 +7,12 @@ import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
7
7
  import { InputControlMixin } from '@vaadin/field-base/src/input-control-mixin.js';
8
8
  import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
9
9
  import { DatePickerMixin } from './vaadin-date-picker-mixin.js';
10
- export { DatePickerDate, DatePickerI18n } from './vaadin-date-picker-mixin.js';
10
+ export {
11
+ DatePickerDate,
12
+ DatePickerDateMetadata,
13
+ DatePickerDateRange,
14
+ DatePickerI18n,
15
+ } from './vaadin-date-picker-mixin.js';
11
16
 
12
17
  /**
13
18
  * Fired when the user commits a value change.
@@ -148,12 +153,17 @@ export interface DatePickerEventMap extends HTMLElementEventMap, DatePickerCusto
148
153
  * `week-number` | Week number element
149
154
  * `date` | Date element
150
155
  * `disabled` | Disabled date element
156
+ * `pending` | Date element in a month whose date metadata provider result is still loading
151
157
  * `focused` | Focused date element
152
158
  * `selected` | Selected date element
153
159
  * `today` | Date element corresponding to the current day
154
160
  * `past` | Date element corresponding to the date in the past
155
161
  * `future` | Date element corresponding to the date in the future
156
162
  *
163
+ * Custom part names returned per date by `dateMetadataProvider` (the `part` metadata field) are
164
+ * also added to the matching date elements, so specific dates can be styled with
165
+ * `vaadin-month-calendar::part(<name>)`.
166
+ *
157
167
  * In order to style year scroller elements, use `<vaadin-date-picker-year>` shadow DOM parts:
158
168
  *
159
169
  * Part name | Description
@@ -92,6 +92,7 @@ import { DatePickerMixin } from './vaadin-date-picker-mixin.js';
92
92
  * ----------------------|--------------------
93
93
  * `years-toggle-button` | Fullscreen mode years scroller toggle
94
94
  * `toolbar` | Toolbar with slotted buttons
95
+ * `loader` | Loading spinner shown while data is being loaded, for example while the disabled dates provider resolves
95
96
  *
96
97
  * The following state attributes are available on the `<vaadin-date-picker-overlay-content>` element:
97
98
  *
@@ -100,6 +101,7 @@ import { DatePickerMixin } from './vaadin-date-picker-mixin.js';
100
101
  * `desktop` | Set when the overlay content is in desktop mode
101
102
  * `fullscreen` | Set when the overlay content is in fullscreen mode
102
103
  * `years-visible` | Set when the year scroller is visible in fullscreen mode
104
+ * `loading` | Set while data is being loaded, for example while the disabled dates provider resolves
103
105
  *
104
106
  * In order to style the month calendar, use `<vaadin-month-calendar>` shadow DOM parts:
105
107
  *
@@ -112,12 +114,17 @@ import { DatePickerMixin } from './vaadin-date-picker-mixin.js';
112
114
  * `week-number` | Week number element
113
115
  * `date` | Date element
114
116
  * `disabled` | Disabled date element
117
+ * `pending` | Date element in a month whose date metadata provider result is still loading
115
118
  * `focused` | Focused date element
116
119
  * `selected` | Selected date element
117
120
  * `today` | Date element corresponding to the current day
118
121
  * `past` | Date element corresponding to the date in the past
119
122
  * `future` | Date element corresponding to the date in the future
120
123
  *
124
+ * Custom part names returned per date by `dateMetadataProvider` (the `part` metadata field) are
125
+ * also added to the matching date elements, so specific dates can be styled with
126
+ * `vaadin-month-calendar::part(<name>)`.
127
+ *
121
128
  * In order to style year scroller elements, use `<vaadin-date-picker-year>` shadow DOM parts:
122
129
  *
123
130
  * Part name | Description
@@ -150,6 +157,7 @@ import { DatePickerMixin } from './vaadin-date-picker-mixin.js';
150
157
  * @fires {CustomEvent} value-changed - Fired when the `value` property changes.
151
158
  * @fires {CustomEvent} validated - Fired whenever the field is validated.
152
159
  *
160
+ * @attr {string} theme - The theme variants to apply to the component.
153
161
  * @customElement vaadin-date-picker
154
162
  * @extends HTMLElement
155
163
  */
@@ -87,6 +87,28 @@ export const MonthCalendarMixin = (superClass) =>
87
87
  value: () => false,
88
88
  },
89
89
 
90
+ /**
91
+ * The shared controller that resolves and caches the dates disabled by the date-picker's
92
+ * `dateMetadataProvider`. Set by the overlay content; used to look up the disabled state
93
+ * of this month's dates.
94
+ * @type {object | undefined}
95
+ * @private
96
+ */
97
+ dateMetadataController: {
98
+ type: Object,
99
+ attribute: false,
100
+ },
101
+
102
+ /**
103
+ * Bumped by the overlay content whenever the controller's cache or loading state changes,
104
+ * to trigger a re-render of this month.
105
+ * @private
106
+ */
107
+ __dateMetadataVersion: {
108
+ type: Number,
109
+ attribute: false,
110
+ },
111
+
90
112
  enteredDate: {
91
113
  type: Date,
92
114
  },
@@ -100,7 +122,8 @@ export const MonthCalendarMixin = (superClass) =>
100
122
  /** @protected */
101
123
  _days: {
102
124
  type: Array,
103
- computed: '__computeDays(month, i18n, minDate, maxDate, isDateDisabled)',
125
+ computed:
126
+ '__computeDays(month, i18n, minDate, maxDate, isDateDisabled, dateMetadataController, __dateMetadataVersion)',
104
127
  },
105
128
 
106
129
  /** @protected */
@@ -345,6 +368,10 @@ export const MonthCalendarMixin = (superClass) =>
345
368
  result.push('disabled');
346
369
  }
347
370
 
371
+ if (date && this.__isMonthLoading()) {
372
+ result.push('pending');
373
+ }
374
+
348
375
  if (dateEquals(date, focusedDate) && (hasFocus || dateEquals(date, enteredDate))) {
349
376
  result.push('focused');
350
377
  }
@@ -365,6 +392,13 @@ export const MonthCalendarMixin = (superClass) =>
365
392
  result.push('future');
366
393
  }
367
394
 
395
+ // Custom part names supplied per date by `dateMetadataProvider`, so a theme can style
396
+ // specific dates (e.g. mark a date as busy or almost fully booked) via `::part()`.
397
+ const part = date && this.dateMetadataController?.getMetadata(date)?.part;
398
+ if (part) {
399
+ result.push(...(Array.isArray(part) ? part : String(part).split(' ')).filter(Boolean));
400
+ }
401
+
368
402
  return result.join(' ');
369
403
  }
370
404
 
@@ -378,9 +412,24 @@ export const MonthCalendarMixin = (superClass) =>
378
412
  return String(this.__isDaySelected(date, selectedDate));
379
413
  }
380
414
 
415
+ /**
416
+ * Whether the provider result for the currently displayed month is still pending. The overlay
417
+ * drives loading for the whole visible range; here we only reflect the controller's state.
418
+ * @private
419
+ */
420
+ __isMonthLoading() {
421
+ const controller = this.dateMetadataController;
422
+ return !!controller?.provider && this.month !== undefined && !controller.isMonthLoaded(this.month);
423
+ }
424
+
381
425
  /** @private */
382
426
  __isDayDisabled(date, minDate, maxDate, isDateDisabled) {
383
- return !dateAllowed(date, minDate, maxDate, isDateDisabled);
427
+ if (!dateAllowed(date, minDate, maxDate, isDateDisabled)) {
428
+ return true;
429
+ }
430
+ // A date is blocked while its month is pending (whole month non-selectable) or once the
431
+ // resolved provider result marks it disabled.
432
+ return !!this.dateMetadataController?.isDateBlocked(date);
384
433
  }
385
434
 
386
435
  /** @private */
@@ -12,6 +12,7 @@ import { monthCalendarStyles } from './styles/vaadin-month-calendar-base-styles.
12
12
  import { MonthCalendarMixin } from './vaadin-month-calendar-mixin.js';
13
13
 
14
14
  /**
15
+ * @attr {string} theme - The theme variants to apply to the component.
15
16
  * @customElement vaadin-month-calendar
16
17
  * @extends HTMLElement
17
18
  * @private
package/web-types.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/web-types",
3
3
  "name": "@vaadin/date-picker",
4
- "version": "25.3.0-alpha6",
4
+ "version": "25.3.0-dev.1fa5a51482",
5
5
  "description-markup": "markdown",
6
6
  "contributions": {
7
7
  "html": {
8
8
  "elements": [
9
9
  {
10
10
  "name": "vaadin-date-picker",
11
- "description": "`<vaadin-date-picker>` is an input field that allows to enter a date by typing or by selecting from a calendar overlay.\n\n```html\n<vaadin-date-picker label=\"Birthday\"></vaadin-date-picker>\n```\n```js\ndatePicker.value = '2016-03-02';\n```\n\nWhen the selected `value` is changed, a `value-changed` event is triggered.\n\n### Styling\n\nThe following custom properties are available for styling:\n\nCustom property | Description | Default\n-------------------------------|----------------------------|---------\n`--vaadin-field-default-width` | Default width of the field | `12em`\n\nThe following shadow DOM parts are available for styling:\n\nPart name | Description\n---------------------|----------------\n`label` | The label element\n`input-field` | The element that wraps prefix, value and buttons\n`field-button` | Set on both clear and toggle buttons\n`clear-button` | The clear button\n`error-message` | The error message element\n`helper-text` | The helper text element wrapper\n`required-indicator` | The `required` state indicator element\n`toggle-button` | The toggle button\n`backdrop` | Backdrop of the overlay\n`overlay` | The overlay container\n`content` | The overlay content\n\nThe following state attributes are available for styling:\n\nAttribute | Description\n---------------------|---------------------------------\n`disabled` | Set when the element is disabled\n`has-value` | Set when the element has a value\n`has-label` | Set when the element has a label\n`has-helper` | Set when the element has helper text or slot\n`has-error-message` | Set when the element has an error message\n`has-tooltip` | Set when the element has a slotted tooltip\n`invalid` | Set when the element is invalid\n`focused` | Set when the element is focused\n`focus-ring` | Set when the element is keyboard focused\n`readonly` | Set when the element is readonly\n`opened` | Set when the overlay is opened\n`week-numbers` | Set when week numbers are shown in the calendar\n\n### Internal components\n\nIn addition to `<vaadin-date-picker>` itself, the following internal\ncomponents are themable:\n\n- `<vaadin-date-picker-overlay-content>`\n- `<vaadin-date-picker-month-scroller>`\n- `<vaadin-date-picker-year-scroller>`\n- `<vaadin-date-picker-year>`\n- `<vaadin-month-calendar>`\n\nIn order to style the overlay content, use `<vaadin-date-picker-overlay-content>` shadow DOM parts:\n\nPart name | Description\n----------------------|--------------------\n`years-toggle-button` | Fullscreen mode years scroller toggle\n`toolbar` | Toolbar with slotted buttons\n\nThe following state attributes are available on the `<vaadin-date-picker-overlay-content>` element:\n\nAttribute | Description\n----------------|-------------------------------------------------\n`desktop` | Set when the overlay content is in desktop mode\n`fullscreen` | Set when the overlay content is in fullscreen mode\n`years-visible` | Set when the year scroller is visible in fullscreen mode\n\nIn order to style the month calendar, use `<vaadin-month-calendar>` shadow DOM parts:\n\nPart name | Description\n----------------------|--------------------\n`month-header` | Month title\n`weekdays` | Weekday container\n`weekday` | Weekday element\n`week-numbers` | Week numbers container\n`week-number` | Week number element\n`date` | Date element\n`disabled` | Disabled date element\n`focused` | Focused date element\n`selected` | Selected date element\n`today` | Date element corresponding to the current day\n`past` | Date element corresponding to the date in the past\n`future` | Date element corresponding to the date in the future\n\nIn order to style year scroller elements, use `<vaadin-date-picker-year>` shadow DOM parts:\n\nPart name | Description\n----------------------|--------------------\n`year-number` | Year number\n`year-separator` | Year separator\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.\n\n### Change events\n\nDepending on the nature of the value change that the user attempts to commit e.g. by pressing Enter,\nthe component can fire either a `change` event or an `unparsable-change` event:\n\nValue change | Event\n:------------------------|:------------------\nempty => parsable | change\nempty => unparsable | unparsable-change\nparsable => empty | change\nparsable => parsable | change\nparsable => unparsable | change\nunparsable => empty | unparsable-change\nunparsable => parsable | change\nunparsable => unparsable | unparsable-change",
11
+ "description": "`<vaadin-date-picker>` is an input field that allows to enter a date by typing or by selecting from a calendar overlay.\n\n```html\n<vaadin-date-picker label=\"Birthday\"></vaadin-date-picker>\n```\n```js\ndatePicker.value = '2016-03-02';\n```\n\nWhen the selected `value` is changed, a `value-changed` event is triggered.\n\n### Styling\n\nThe following custom properties are available for styling:\n\nCustom property | Description | Default\n-------------------------------|----------------------------|---------\n`--vaadin-field-default-width` | Default width of the field | `12em`\n\nThe following shadow DOM parts are available for styling:\n\nPart name | Description\n---------------------|----------------\n`label` | The label element\n`input-field` | The element that wraps prefix, value and buttons\n`field-button` | Set on both clear and toggle buttons\n`clear-button` | The clear button\n`error-message` | The error message element\n`helper-text` | The helper text element wrapper\n`required-indicator` | The `required` state indicator element\n`toggle-button` | The toggle button\n`backdrop` | Backdrop of the overlay\n`overlay` | The overlay container\n`content` | The overlay content\n\nThe following state attributes are available for styling:\n\nAttribute | Description\n---------------------|---------------------------------\n`disabled` | Set when the element is disabled\n`has-value` | Set when the element has a value\n`has-label` | Set when the element has a label\n`has-helper` | Set when the element has helper text or slot\n`has-error-message` | Set when the element has an error message\n`has-tooltip` | Set when the element has a slotted tooltip\n`invalid` | Set when the element is invalid\n`focused` | Set when the element is focused\n`focus-ring` | Set when the element is keyboard focused\n`readonly` | Set when the element is readonly\n`opened` | Set when the overlay is opened\n`week-numbers` | Set when week numbers are shown in the calendar\n\n### Internal components\n\nIn addition to `<vaadin-date-picker>` itself, the following internal\ncomponents are themable:\n\n- `<vaadin-date-picker-overlay-content>`\n- `<vaadin-date-picker-month-scroller>`\n- `<vaadin-date-picker-year-scroller>`\n- `<vaadin-date-picker-year>`\n- `<vaadin-month-calendar>`\n\nIn order to style the overlay content, use `<vaadin-date-picker-overlay-content>` shadow DOM parts:\n\nPart name | Description\n----------------------|--------------------\n`years-toggle-button` | Fullscreen mode years scroller toggle\n`toolbar` | Toolbar with slotted buttons\n`loader` | Loading spinner shown while data is being loaded, for example while the disabled dates provider resolves\n\nThe following state attributes are available on the `<vaadin-date-picker-overlay-content>` element:\n\nAttribute | Description\n----------------|-------------------------------------------------\n`desktop` | Set when the overlay content is in desktop mode\n`fullscreen` | Set when the overlay content is in fullscreen mode\n`years-visible` | Set when the year scroller is visible in fullscreen mode\n`loading` | Set while data is being loaded, for example while the disabled dates provider resolves\n\nIn order to style the month calendar, use `<vaadin-month-calendar>` shadow DOM parts:\n\nPart name | Description\n----------------------|--------------------\n`month-header` | Month title\n`weekdays` | Weekday container\n`weekday` | Weekday element\n`week-numbers` | Week numbers container\n`week-number` | Week number element\n`date` | Date element\n`disabled` | Disabled date element\n`pending` | Date element in a month whose date metadata provider result is still loading\n`focused` | Focused date element\n`selected` | Selected date element\n`today` | Date element corresponding to the current day\n`past` | Date element corresponding to the date in the past\n`future` | Date element corresponding to the date in the future\n\nCustom part names returned per date by `dateMetadataProvider` (the `part` metadata field) are\nalso added to the matching date elements, so specific dates can be styled with\n`vaadin-month-calendar::part(<name>)`.\n\nIn order to style year scroller elements, use `<vaadin-date-picker-year>` shadow DOM parts:\n\nPart name | Description\n----------------------|--------------------\n`year-number` | Year number\n`year-separator` | Year separator\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.\n\n### Change events\n\nDepending on the nature of the value change that the user attempts to commit e.g. by pressing Enter,\nthe component can fire either a `change` event or an `unparsable-change` event:\n\nValue change | Event\n:------------------------|:------------------\nempty => parsable | change\nempty => unparsable | unparsable-change\nparsable => empty | change\nparsable => parsable | change\nparsable => unparsable | change\nunparsable => empty | unparsable-change\nunparsable => parsable | change\nunparsable => unparsable | unparsable-change",
12
12
  "attributes": [
13
13
  {
14
14
  "name": "accessible-name",
@@ -213,9 +213,7 @@
213
213
  "description": "The theme variants to apply to the component.",
214
214
  "value": {
215
215
  "type": [
216
- "string",
217
- "null",
218
- "undefined"
216
+ "string"
219
217
  ]
220
218
  }
221
219
  },
@@ -303,6 +301,17 @@
303
301
  ]
304
302
  }
305
303
  },
304
+ {
305
+ "name": "dateMetadataProvider",
306
+ "description": "A batch function that fetches metadata for a range of dates the calendar is about to\nrender. It receives a `DatePickerDateRange` object (`{ start, end }` of `DatePickerDate`)\nand returns, or resolves with, an array of metadata objects — a `DatePickerDate` extended\nwith metadata fields such as `disabled` and custom `part` names, e.g.\n`{ year, month, day, disabled: true, part: 'busy' }` — for the dates that have metadata\nwithin that range.\n\nUnlike `isDateDisabled`, which is called once per date, this function is called for a\nrange of dates at a time, and again as the calendar renders further dates. The size of\nthe range is decided by the calendar and may span multiple months. It may return a\n`Promise`, in which case the affected dates render in a non-selectable pending state\nuntil it resolves.\n\n`disabled` from the metadata is combined with `min`, `max` and `isDateDisabled`: a date\nis disabled if it is out of the min/max range, or `isDateDisabled` returns `true`, or its\nmetadata marks it disabled. `part` names are added to the date cell's `part` attribute so\na theme can style specific dates via `::part()`.\n\nBoth `disabled` and `part` are returned by this one function, rather than by separate\ngenerators, so a single backend query (for example in Flow) can answer both at once\ninstead of being split into two passes over the same data.\n\nKeep a stable reference to the function. Assigning a new function resets the internal\ncache and re-fetches every visible range. To reload after the underlying data changes\nwhile keeping the same function, call `clearCache()`.",
307
+ "value": {
308
+ "type": [
309
+ "function DatePickerDateRange: Array<DatePickerDateMetadata>",
310
+ "Promise<Array<DatePickerDateMetadata>>",
311
+ "undefined"
312
+ ]
313
+ }
314
+ },
306
315
  {
307
316
  "name": "disabled",
308
317
  "description": "If true, the user cannot interact with this element.",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/web-types",
3
3
  "name": "@vaadin/date-picker",
4
- "version": "25.3.0-alpha6",
4
+ "version": "25.3.0-dev.1fa5a51482",
5
5
  "description-markup": "markdown",
6
6
  "framework": "lit",
7
7
  "framework-config": {
@@ -16,7 +16,7 @@
16
16
  "elements": [
17
17
  {
18
18
  "name": "vaadin-date-picker",
19
- "description": "`<vaadin-date-picker>` is an input field that allows to enter a date by typing or by selecting from a calendar overlay.\n\n```html\n<vaadin-date-picker label=\"Birthday\"></vaadin-date-picker>\n```\n```js\ndatePicker.value = '2016-03-02';\n```\n\nWhen the selected `value` is changed, a `value-changed` event is triggered.\n\n### Styling\n\nThe following custom properties are available for styling:\n\nCustom property | Description | Default\n-------------------------------|----------------------------|---------\n`--vaadin-field-default-width` | Default width of the field | `12em`\n\nThe following shadow DOM parts are available for styling:\n\nPart name | Description\n---------------------|----------------\n`label` | The label element\n`input-field` | The element that wraps prefix, value and buttons\n`field-button` | Set on both clear and toggle buttons\n`clear-button` | The clear button\n`error-message` | The error message element\n`helper-text` | The helper text element wrapper\n`required-indicator` | The `required` state indicator element\n`toggle-button` | The toggle button\n`backdrop` | Backdrop of the overlay\n`overlay` | The overlay container\n`content` | The overlay content\n\nThe following state attributes are available for styling:\n\nAttribute | Description\n---------------------|---------------------------------\n`disabled` | Set when the element is disabled\n`has-value` | Set when the element has a value\n`has-label` | Set when the element has a label\n`has-helper` | Set when the element has helper text or slot\n`has-error-message` | Set when the element has an error message\n`has-tooltip` | Set when the element has a slotted tooltip\n`invalid` | Set when the element is invalid\n`focused` | Set when the element is focused\n`focus-ring` | Set when the element is keyboard focused\n`readonly` | Set when the element is readonly\n`opened` | Set when the overlay is opened\n`week-numbers` | Set when week numbers are shown in the calendar\n\n### Internal components\n\nIn addition to `<vaadin-date-picker>` itself, the following internal\ncomponents are themable:\n\n- `<vaadin-date-picker-overlay-content>`\n- `<vaadin-date-picker-month-scroller>`\n- `<vaadin-date-picker-year-scroller>`\n- `<vaadin-date-picker-year>`\n- `<vaadin-month-calendar>`\n\nIn order to style the overlay content, use `<vaadin-date-picker-overlay-content>` shadow DOM parts:\n\nPart name | Description\n----------------------|--------------------\n`years-toggle-button` | Fullscreen mode years scroller toggle\n`toolbar` | Toolbar with slotted buttons\n\nThe following state attributes are available on the `<vaadin-date-picker-overlay-content>` element:\n\nAttribute | Description\n----------------|-------------------------------------------------\n`desktop` | Set when the overlay content is in desktop mode\n`fullscreen` | Set when the overlay content is in fullscreen mode\n`years-visible` | Set when the year scroller is visible in fullscreen mode\n\nIn order to style the month calendar, use `<vaadin-month-calendar>` shadow DOM parts:\n\nPart name | Description\n----------------------|--------------------\n`month-header` | Month title\n`weekdays` | Weekday container\n`weekday` | Weekday element\n`week-numbers` | Week numbers container\n`week-number` | Week number element\n`date` | Date element\n`disabled` | Disabled date element\n`focused` | Focused date element\n`selected` | Selected date element\n`today` | Date element corresponding to the current day\n`past` | Date element corresponding to the date in the past\n`future` | Date element corresponding to the date in the future\n\nIn order to style year scroller elements, use `<vaadin-date-picker-year>` shadow DOM parts:\n\nPart name | Description\n----------------------|--------------------\n`year-number` | Year number\n`year-separator` | Year separator\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.\n\n### Change events\n\nDepending on the nature of the value change that the user attempts to commit e.g. by pressing Enter,\nthe component can fire either a `change` event or an `unparsable-change` event:\n\nValue change | Event\n:------------------------|:------------------\nempty => parsable | change\nempty => unparsable | unparsable-change\nparsable => empty | change\nparsable => parsable | change\nparsable => unparsable | change\nunparsable => empty | unparsable-change\nunparsable => parsable | change\nunparsable => unparsable | unparsable-change",
19
+ "description": "`<vaadin-date-picker>` is an input field that allows to enter a date by typing or by selecting from a calendar overlay.\n\n```html\n<vaadin-date-picker label=\"Birthday\"></vaadin-date-picker>\n```\n```js\ndatePicker.value = '2016-03-02';\n```\n\nWhen the selected `value` is changed, a `value-changed` event is triggered.\n\n### Styling\n\nThe following custom properties are available for styling:\n\nCustom property | Description | Default\n-------------------------------|----------------------------|---------\n`--vaadin-field-default-width` | Default width of the field | `12em`\n\nThe following shadow DOM parts are available for styling:\n\nPart name | Description\n---------------------|----------------\n`label` | The label element\n`input-field` | The element that wraps prefix, value and buttons\n`field-button` | Set on both clear and toggle buttons\n`clear-button` | The clear button\n`error-message` | The error message element\n`helper-text` | The helper text element wrapper\n`required-indicator` | The `required` state indicator element\n`toggle-button` | The toggle button\n`backdrop` | Backdrop of the overlay\n`overlay` | The overlay container\n`content` | The overlay content\n\nThe following state attributes are available for styling:\n\nAttribute | Description\n---------------------|---------------------------------\n`disabled` | Set when the element is disabled\n`has-value` | Set when the element has a value\n`has-label` | Set when the element has a label\n`has-helper` | Set when the element has helper text or slot\n`has-error-message` | Set when the element has an error message\n`has-tooltip` | Set when the element has a slotted tooltip\n`invalid` | Set when the element is invalid\n`focused` | Set when the element is focused\n`focus-ring` | Set when the element is keyboard focused\n`readonly` | Set when the element is readonly\n`opened` | Set when the overlay is opened\n`week-numbers` | Set when week numbers are shown in the calendar\n\n### Internal components\n\nIn addition to `<vaadin-date-picker>` itself, the following internal\ncomponents are themable:\n\n- `<vaadin-date-picker-overlay-content>`\n- `<vaadin-date-picker-month-scroller>`\n- `<vaadin-date-picker-year-scroller>`\n- `<vaadin-date-picker-year>`\n- `<vaadin-month-calendar>`\n\nIn order to style the overlay content, use `<vaadin-date-picker-overlay-content>` shadow DOM parts:\n\nPart name | Description\n----------------------|--------------------\n`years-toggle-button` | Fullscreen mode years scroller toggle\n`toolbar` | Toolbar with slotted buttons\n`loader` | Loading spinner shown while data is being loaded, for example while the disabled dates provider resolves\n\nThe following state attributes are available on the `<vaadin-date-picker-overlay-content>` element:\n\nAttribute | Description\n----------------|-------------------------------------------------\n`desktop` | Set when the overlay content is in desktop mode\n`fullscreen` | Set when the overlay content is in fullscreen mode\n`years-visible` | Set when the year scroller is visible in fullscreen mode\n`loading` | Set while data is being loaded, for example while the disabled dates provider resolves\n\nIn order to style the month calendar, use `<vaadin-month-calendar>` shadow DOM parts:\n\nPart name | Description\n----------------------|--------------------\n`month-header` | Month title\n`weekdays` | Weekday container\n`weekday` | Weekday element\n`week-numbers` | Week numbers container\n`week-number` | Week number element\n`date` | Date element\n`disabled` | Disabled date element\n`pending` | Date element in a month whose date metadata provider result is still loading\n`focused` | Focused date element\n`selected` | Selected date element\n`today` | Date element corresponding to the current day\n`past` | Date element corresponding to the date in the past\n`future` | Date element corresponding to the date in the future\n\nCustom part names returned per date by `dateMetadataProvider` (the `part` metadata field) are\nalso added to the matching date elements, so specific dates can be styled with\n`vaadin-month-calendar::part(<name>)`.\n\nIn order to style year scroller elements, use `<vaadin-date-picker-year>` shadow DOM parts:\n\nPart name | Description\n----------------------|--------------------\n`year-number` | Year number\n`year-separator` | Year separator\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.\n\n### Change events\n\nDepending on the nature of the value change that the user attempts to commit e.g. by pressing Enter,\nthe component can fire either a `change` event or an `unparsable-change` event:\n\nValue change | Event\n:------------------------|:------------------\nempty => parsable | change\nempty => unparsable | unparsable-change\nparsable => empty | change\nparsable => parsable | change\nparsable => unparsable | change\nunparsable => empty | unparsable-change\nunparsable => parsable | change\nunparsable => unparsable | unparsable-change",
20
20
  "extension": true,
21
21
  "attributes": [
22
22
  {
@@ -68,6 +68,13 @@
68
68
  "kind": "expression"
69
69
  }
70
70
  },
71
+ {
72
+ "name": ".dateMetadataProvider",
73
+ "description": "A batch function that fetches metadata for a range of dates the calendar is about to\nrender. It receives a `DatePickerDateRange` object (`{ start, end }` of `DatePickerDate`)\nand returns, or resolves with, an array of metadata objects — a `DatePickerDate` extended\nwith metadata fields such as `disabled` and custom `part` names, e.g.\n`{ year, month, day, disabled: true, part: 'busy' }` — for the dates that have metadata\nwithin that range.\n\nUnlike `isDateDisabled`, which is called once per date, this function is called for a\nrange of dates at a time, and again as the calendar renders further dates. The size of\nthe range is decided by the calendar and may span multiple months. It may return a\n`Promise`, in which case the affected dates render in a non-selectable pending state\nuntil it resolves.\n\n`disabled` from the metadata is combined with `min`, `max` and `isDateDisabled`: a date\nis disabled if it is out of the min/max range, or `isDateDisabled` returns `true`, or its\nmetadata marks it disabled. `part` names are added to the date cell's `part` attribute so\na theme can style specific dates via `::part()`.\n\nBoth `disabled` and `part` are returned by this one function, rather than by separate\ngenerators, so a single backend query (for example in Flow) can answer both at once\ninstead of being split into two passes over the same data.\n\nKeep a stable reference to the function. Assigning a new function resets the internal\ncache and re-fetches every visible range. To reload after the underlying data changes\nwhile keeping the same function, call `clearCache()`.",
74
+ "value": {
75
+ "kind": "expression"
76
+ }
77
+ },
71
78
  {
72
79
  "name": "?disabled",
73
80
  "description": "If true, the user cannot interact with this element.",