@vaadin/date-picker 25.3.0-alpha8 → 25.3.0-beta1
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 +550 -15
- package/package.json +13 -13
- package/src/styles/vaadin-date-picker-overlay-content-base-styles.js +9 -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 +100 -0
- package/src/vaadin-date-picker-mixin.js +150 -8
- package/src/vaadin-date-picker-overlay-content-mixin.js +152 -50
- package/src/vaadin-date-picker-overlay-content.js +4 -1
- package/src/vaadin-date-picker-year.js +3 -1
- package/src/vaadin-date-picker.d.ts +73 -7
- package/src/vaadin-date-picker.js +66 -6
- package/src/vaadin-infinite-scroller.js +19 -6
- package/src/vaadin-month-calendar-mixin.js +55 -29
- package/web-types.json +37 -8
- package/web-types.lit.json +20 -6
|
@@ -5,10 +5,22 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { timeOut } from '@vaadin/component-base/src/async.js';
|
|
7
7
|
import { Debouncer } from '@vaadin/component-base/src/debounce.js';
|
|
8
|
+
import { setOrRemoveAttribute } from '@vaadin/component-base/src/dom-utils.js';
|
|
8
9
|
import { addListener } from '@vaadin/component-base/src/gestures.js';
|
|
9
10
|
import { MediaQueryController } from '@vaadin/component-base/src/media-query-controller.js';
|
|
10
11
|
import { SlotController } from '@vaadin/component-base/src/slot-controller.js';
|
|
11
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
createDate,
|
|
14
|
+
dateAfterXMonths,
|
|
15
|
+
dateAllowed,
|
|
16
|
+
dateEquals,
|
|
17
|
+
dateSelectable,
|
|
18
|
+
firstOfMonth,
|
|
19
|
+
getClosestDate,
|
|
20
|
+
lastOfMonth,
|
|
21
|
+
monthDate,
|
|
22
|
+
monthIndex,
|
|
23
|
+
} from './vaadin-date-picker-helper.js';
|
|
12
24
|
|
|
13
25
|
export const DatePickerOverlayContentMixin = (superClass) =>
|
|
14
26
|
class DatePickerOverlayContentMixin extends superClass {
|
|
@@ -106,6 +118,17 @@ export const DatePickerOverlayContentMixin = (superClass) =>
|
|
|
106
118
|
type: Function,
|
|
107
119
|
},
|
|
108
120
|
|
|
121
|
+
/**
|
|
122
|
+
* Reflected while data is being loaded, so the overlay can show a loading spinner.
|
|
123
|
+
* Currently set while the date metadata provider is resolving.
|
|
124
|
+
* @protected
|
|
125
|
+
*/
|
|
126
|
+
loading: {
|
|
127
|
+
type: Boolean,
|
|
128
|
+
value: false,
|
|
129
|
+
reflectToAttribute: true,
|
|
130
|
+
},
|
|
131
|
+
|
|
109
132
|
enteredDate: {
|
|
110
133
|
type: Date,
|
|
111
134
|
sync: true,
|
|
@@ -124,6 +147,18 @@ export const DatePickerOverlayContentMixin = (superClass) =>
|
|
|
124
147
|
type: Object,
|
|
125
148
|
},
|
|
126
149
|
|
|
150
|
+
/**
|
|
151
|
+
* The date-picker's date metadata controller, assigned by the host. Declared as a property,
|
|
152
|
+
* and a dependency of `__updateCalendarsConfig` below, so that the calendars are handed it
|
|
153
|
+
* and subscribed whenever it arrives, rather than relying on the host assigning it before
|
|
154
|
+
* the properties that happen to trigger that observer.
|
|
155
|
+
* @protected
|
|
156
|
+
*/
|
|
157
|
+
_dateMetadataController: {
|
|
158
|
+
type: Object,
|
|
159
|
+
sync: true,
|
|
160
|
+
},
|
|
161
|
+
|
|
127
162
|
calendars: {
|
|
128
163
|
type: Array,
|
|
129
164
|
value: () => [],
|
|
@@ -138,14 +173,47 @@ export const DatePickerOverlayContentMixin = (superClass) =>
|
|
|
138
173
|
|
|
139
174
|
static get observers() {
|
|
140
175
|
return [
|
|
141
|
-
'__updateCalendarsConfig(calendars, i18n, minDate, maxDate, showWeekNumbers, isDateDisabled, _theme)',
|
|
176
|
+
'__updateCalendarsConfig(calendars, i18n, minDate, maxDate, showWeekNumbers, isDateDisabled, _theme, _dateMetadataController)',
|
|
142
177
|
'__updateCalendarsState(calendars, selectedDate, focusedDate, enteredDate, _ignoreTaps)',
|
|
143
178
|
'__updateCancelButton(_cancelButton, i18n)',
|
|
144
|
-
'__updateTodayButton(_todayButton, i18n, minDate, maxDate, isDateDisabled)',
|
|
145
179
|
'__updateYears(years, selectedDate, _theme)',
|
|
146
180
|
];
|
|
147
181
|
}
|
|
148
182
|
|
|
183
|
+
/** @protected */
|
|
184
|
+
disconnectedCallback() {
|
|
185
|
+
super.disconnectedCallback();
|
|
186
|
+
|
|
187
|
+
this.cancelLoadVisibleDateMetadata();
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/** @protected */
|
|
191
|
+
updated(props) {
|
|
192
|
+
super.updated(props);
|
|
193
|
+
|
|
194
|
+
if (props.has('loading')) {
|
|
195
|
+
setOrRemoveAttribute(this, 'aria-busy', this.loading);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (props.has('i18n')) {
|
|
199
|
+
setOrRemoveAttribute(this, 'aria-label', this.i18n?.dialogAccessibleName);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
if (props.has('calendars') || props.has('_dateMetadataController')) {
|
|
203
|
+
this.loadVisibleDateMetadata();
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (
|
|
207
|
+
props.has('_todayButton') ||
|
|
208
|
+
props.has('i18n') ||
|
|
209
|
+
props.has('minDate') ||
|
|
210
|
+
props.has('maxDate') ||
|
|
211
|
+
props.has('isDateDisabled')
|
|
212
|
+
) {
|
|
213
|
+
this.updateTodayButton();
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
149
217
|
/**
|
|
150
218
|
* Whether to scroll to a sub-month position when scrolling to a date.
|
|
151
219
|
* This is active if the month scroller is not large enough to fit a
|
|
@@ -200,6 +268,8 @@ export const DatePickerOverlayContentMixin = (superClass) =>
|
|
|
200
268
|
|
|
201
269
|
reset() {
|
|
202
270
|
this._closeYearScroller();
|
|
271
|
+
this._monthScroller?.reset();
|
|
272
|
+
this._yearScroller?.reset();
|
|
203
273
|
}
|
|
204
274
|
|
|
205
275
|
/**
|
|
@@ -292,14 +362,44 @@ export const DatePickerOverlayContentMixin = (superClass) =>
|
|
|
292
362
|
}
|
|
293
363
|
}
|
|
294
364
|
|
|
295
|
-
/**
|
|
296
|
-
|
|
365
|
+
/**
|
|
366
|
+
* Applies the today button's label and whether today can be selected.
|
|
367
|
+
*/
|
|
368
|
+
updateTodayButton() {
|
|
369
|
+
const todayButton = this._todayButton;
|
|
297
370
|
if (todayButton) {
|
|
298
|
-
todayButton.textContent = i18n?.today;
|
|
299
|
-
todayButton.disabled = !this._isTodayAllowed(
|
|
371
|
+
todayButton.textContent = this.i18n?.today;
|
|
372
|
+
todayButton.disabled = !this._isTodayAllowed();
|
|
300
373
|
}
|
|
301
374
|
}
|
|
302
375
|
|
|
376
|
+
/**
|
|
377
|
+
* Requests the date metadata for the months currently rendered. Months already loaded or in flight
|
|
378
|
+
* are skipped.
|
|
379
|
+
*/
|
|
380
|
+
loadVisibleDateMetadata() {
|
|
381
|
+
const controller = this._dateMetadataController;
|
|
382
|
+
if (!controller) {
|
|
383
|
+
return;
|
|
384
|
+
}
|
|
385
|
+
// Reduced to month indexes so the outermost months can be picked with plain arithmetic.
|
|
386
|
+
const indexes = (this.calendars ?? [])
|
|
387
|
+
.map((calendar) => calendar.month)
|
|
388
|
+
.filter(Boolean)
|
|
389
|
+
.map((month) => monthIndex(month));
|
|
390
|
+
if (indexes.length === 0) {
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
controller.ensureRangeLoaded(monthDate(Math.min(...indexes)), monthDate(Math.max(...indexes)));
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* Drops a date metadata load that navigating has scheduled but that has not run yet.
|
|
398
|
+
*/
|
|
399
|
+
cancelLoadVisibleDateMetadata() {
|
|
400
|
+
this._loadDateMetadataDebouncer?.cancel();
|
|
401
|
+
}
|
|
402
|
+
|
|
303
403
|
/**
|
|
304
404
|
* Config that changes rarely (locale, allowed range, week numbers, theme).
|
|
305
405
|
* Split from the interaction state below so a keyboard/selection update
|
|
@@ -307,24 +407,43 @@ export const DatePickerOverlayContentMixin = (superClass) =>
|
|
|
307
407
|
* @private
|
|
308
408
|
*/
|
|
309
409
|
// eslint-disable-next-line @typescript-eslint/max-params
|
|
310
|
-
__updateCalendarsConfig(
|
|
410
|
+
__updateCalendarsConfig(
|
|
411
|
+
calendars,
|
|
412
|
+
i18n,
|
|
413
|
+
minDate,
|
|
414
|
+
maxDate,
|
|
415
|
+
showWeekNumbers,
|
|
416
|
+
isDateDisabled,
|
|
417
|
+
theme,
|
|
418
|
+
dateMetadataController,
|
|
419
|
+
) {
|
|
311
420
|
if (calendars?.length) {
|
|
312
421
|
calendars.forEach((calendar) => {
|
|
313
422
|
calendar.i18n = i18n;
|
|
314
423
|
calendar.minDate = minDate;
|
|
315
424
|
calendar.maxDate = maxDate;
|
|
316
425
|
calendar.isDateDisabled = isDateDisabled;
|
|
426
|
+
calendar._dateMetadataController = dateMetadataController;
|
|
427
|
+
// Subscribe to controller updates (subscribing again is a no-op).
|
|
428
|
+
dateMetadataController?.subscribe(calendar);
|
|
317
429
|
calendar.showWeekNumbers = showWeekNumbers;
|
|
318
430
|
|
|
319
|
-
|
|
320
|
-
calendar.setAttribute('theme', theme);
|
|
321
|
-
} else {
|
|
322
|
-
calendar.removeAttribute('theme');
|
|
323
|
-
}
|
|
431
|
+
setOrRemoveAttribute(calendar, 'theme', theme);
|
|
324
432
|
});
|
|
325
433
|
}
|
|
326
434
|
}
|
|
327
435
|
|
|
436
|
+
/**
|
|
437
|
+
* Debounced variant used while navigating, so a continuous scroll triggers one load once it
|
|
438
|
+
* settles instead of a request per intermediate position.
|
|
439
|
+
* @private
|
|
440
|
+
*/
|
|
441
|
+
__scheduleLoadVisibleDateMetadata() {
|
|
442
|
+
this._loadDateMetadataDebouncer = Debouncer.debounce(this._loadDateMetadataDebouncer, timeOut.after(200), () =>
|
|
443
|
+
this.loadVisibleDateMetadata(),
|
|
444
|
+
);
|
|
445
|
+
}
|
|
446
|
+
|
|
328
447
|
/**
|
|
329
448
|
* Interaction state that changes often (focus, selection, entered date, taps).
|
|
330
449
|
* @private
|
|
@@ -346,11 +465,7 @@ export const DatePickerOverlayContentMixin = (superClass) =>
|
|
|
346
465
|
years.forEach((year) => {
|
|
347
466
|
year.selectedDate = selectedDate;
|
|
348
467
|
|
|
349
|
-
|
|
350
|
-
year.setAttribute('theme', theme);
|
|
351
|
-
} else {
|
|
352
|
-
year.removeAttribute('theme');
|
|
353
|
-
}
|
|
468
|
+
setOrRemoveAttribute(year, 'theme', theme);
|
|
354
469
|
});
|
|
355
470
|
}
|
|
356
471
|
}
|
|
@@ -360,7 +475,7 @@ export const DatePickerOverlayContentMixin = (superClass) =>
|
|
|
360
475
|
* @protected
|
|
361
476
|
*/
|
|
362
477
|
_selectDate(dateToSelect) {
|
|
363
|
-
if (!this.
|
|
478
|
+
if (!this._dateSelectable(dateToSelect)) {
|
|
364
479
|
return false;
|
|
365
480
|
}
|
|
366
481
|
this.selectedDate = dateToSelect;
|
|
@@ -426,11 +541,7 @@ export const DatePickerOverlayContentMixin = (superClass) =>
|
|
|
426
541
|
* @private
|
|
427
542
|
*/
|
|
428
543
|
_calculateWeekScrollOffset(date) {
|
|
429
|
-
|
|
430
|
-
const temp = new Date(0, 0);
|
|
431
|
-
temp.setFullYear(date.getFullYear());
|
|
432
|
-
temp.setMonth(date.getMonth());
|
|
433
|
-
temp.setDate(1);
|
|
544
|
+
const temp = firstOfMonth(date);
|
|
434
545
|
// Determine week (=row index) of date within the month
|
|
435
546
|
let week = 0;
|
|
436
547
|
while (temp.getDate() < date.getDate()) {
|
|
@@ -458,12 +569,14 @@ export const DatePickerOverlayContentMixin = (superClass) =>
|
|
|
458
569
|
const monthPosition = this._monthScroller.position;
|
|
459
570
|
this._visibleMonthIndex = Math.floor(monthPosition);
|
|
460
571
|
this._yearScroller.position = (monthPosition + this._originDate.getMonth()) / 12;
|
|
572
|
+
this.__scheduleLoadVisibleDateMetadata();
|
|
461
573
|
}
|
|
462
574
|
|
|
463
575
|
/** @private */
|
|
464
576
|
_repositionMonthScroller() {
|
|
465
577
|
this._monthScroller.position = this._yearScroller.position * 12 - this._originDate.getMonth();
|
|
466
578
|
this._visibleMonthIndex = Math.floor(this._monthScroller.position);
|
|
579
|
+
this.__scheduleLoadVisibleDateMetadata();
|
|
467
580
|
}
|
|
468
581
|
|
|
469
582
|
/** @private */
|
|
@@ -630,8 +743,7 @@ export const DatePickerOverlayContentMixin = (superClass) =>
|
|
|
630
743
|
|
|
631
744
|
/** @private */
|
|
632
745
|
_differenceInMonths(date1, date2) {
|
|
633
|
-
|
|
634
|
-
return months - date2.getMonth() + date1.getMonth();
|
|
746
|
+
return monthIndex(date1) - monthIndex(date2);
|
|
635
747
|
}
|
|
636
748
|
|
|
637
749
|
/** @private */
|
|
@@ -859,13 +971,11 @@ export const DatePickerOverlayContentMixin = (superClass) =>
|
|
|
859
971
|
|
|
860
972
|
/** @private */
|
|
861
973
|
_getDateDiff(months, days) {
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
}
|
|
868
|
-
return date;
|
|
974
|
+
return createDate(
|
|
975
|
+
this.focusedDate.getFullYear(),
|
|
976
|
+
this.focusedDate.getMonth() + months,
|
|
977
|
+
days ? this.focusedDate.getDate() + days : 1,
|
|
978
|
+
);
|
|
869
979
|
}
|
|
870
980
|
|
|
871
981
|
/** @private */
|
|
@@ -895,16 +1005,7 @@ export const DatePickerOverlayContentMixin = (superClass) =>
|
|
|
895
1005
|
|
|
896
1006
|
/** @private */
|
|
897
1007
|
_moveFocusInsideMonth(focusedDate, property) {
|
|
898
|
-
const dateToFocus =
|
|
899
|
-
dateToFocus.setFullYear(focusedDate.getFullYear());
|
|
900
|
-
|
|
901
|
-
if (property === 'minDate') {
|
|
902
|
-
dateToFocus.setMonth(focusedDate.getMonth());
|
|
903
|
-
dateToFocus.setDate(1);
|
|
904
|
-
} else {
|
|
905
|
-
dateToFocus.setMonth(focusedDate.getMonth() + 1);
|
|
906
|
-
dateToFocus.setDate(0);
|
|
907
|
-
}
|
|
1008
|
+
const dateToFocus = property === 'minDate' ? firstOfMonth(focusedDate) : lastOfMonth(focusedDate);
|
|
908
1009
|
|
|
909
1010
|
if (this._dateAllowed(dateToFocus)) {
|
|
910
1011
|
this.focusDate(dateToFocus);
|
|
@@ -923,17 +1024,18 @@ export const DatePickerOverlayContentMixin = (superClass) =>
|
|
|
923
1024
|
}
|
|
924
1025
|
|
|
925
1026
|
/** @private */
|
|
926
|
-
|
|
927
|
-
return
|
|
1027
|
+
_dateSelectable(date) {
|
|
1028
|
+
return dateSelectable(date, this.minDate, this.maxDate, this.isDateDisabled, this._dateMetadataController);
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
/** @private */
|
|
1032
|
+
_isTodayAllowed() {
|
|
1033
|
+
return this._dateSelectable(this._getTodayMidnight());
|
|
928
1034
|
}
|
|
929
1035
|
|
|
930
1036
|
/** @private */
|
|
931
1037
|
_getTodayMidnight() {
|
|
932
1038
|
const today = new Date();
|
|
933
|
-
|
|
934
|
-
todayMidnight.setFullYear(today.getFullYear());
|
|
935
|
-
todayMidnight.setMonth(today.getMonth());
|
|
936
|
-
todayMidnight.setDate(today.getDate());
|
|
937
|
-
return todayMidnight;
|
|
1039
|
+
return createDate(today.getFullYear(), today.getMonth(), today.getDate());
|
|
938
1040
|
}
|
|
939
1041
|
};
|
|
@@ -12,6 +12,7 @@ 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';
|
|
@@ -31,7 +32,7 @@ class DatePickerOverlayContent extends DatePickerOverlayContentMixin(
|
|
|
31
32
|
}
|
|
32
33
|
|
|
33
34
|
static get styles() {
|
|
34
|
-
return overlayContentStyles;
|
|
35
|
+
return [loaderStyles, overlayContentStyles];
|
|
35
36
|
}
|
|
36
37
|
|
|
37
38
|
static get lumoInjector() {
|
|
@@ -44,6 +45,8 @@ class DatePickerOverlayContent extends DatePickerOverlayContentMixin(
|
|
|
44
45
|
<slot name="months"></slot>
|
|
45
46
|
<slot name="years"></slot>
|
|
46
47
|
|
|
48
|
+
<div part="loader" aria-hidden="true"></div>
|
|
49
|
+
|
|
47
50
|
<div role="toolbar" part="toolbar">
|
|
48
51
|
<slot name="today-button"></slot>
|
|
49
52
|
<div
|
|
@@ -18,7 +18,7 @@ import { datePickerYearStyles } from './styles/vaadin-date-picker-year-base-styl
|
|
|
18
18
|
* @extends HTMLElement
|
|
19
19
|
* @private
|
|
20
20
|
*/
|
|
21
|
-
|
|
21
|
+
class DatePickerYear extends ThemableMixin(PolylitMixin(LumoInjectionMixin(LitElement))) {
|
|
22
22
|
static get is() {
|
|
23
23
|
return 'vaadin-date-picker-year';
|
|
24
24
|
}
|
|
@@ -64,3 +64,5 @@ export class DatePickerYear extends ThemableMixin(PolylitMixin(LumoInjectionMixi
|
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
defineCustomElement(DatePickerYear);
|
|
67
|
+
|
|
68
|
+
export { DatePickerYear };
|
|
@@ -7,7 +7,13 @@ 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 {
|
|
10
|
+
export {
|
|
11
|
+
DatePickerDate,
|
|
12
|
+
DatePickerDateMetadata,
|
|
13
|
+
DatePickerDateMetadataProvider,
|
|
14
|
+
DatePickerDateRange,
|
|
15
|
+
DatePickerI18n,
|
|
16
|
+
} from './vaadin-date-picker-mixin.js';
|
|
11
17
|
|
|
12
18
|
/**
|
|
13
19
|
* Fired when the user commits a value change.
|
|
@@ -72,12 +78,6 @@ export interface DatePickerEventMap extends HTMLElementEventMap, DatePickerCusto
|
|
|
72
78
|
*
|
|
73
79
|
* ### Styling
|
|
74
80
|
*
|
|
75
|
-
* The following custom properties are available for styling:
|
|
76
|
-
*
|
|
77
|
-
* Custom property | Description | Default
|
|
78
|
-
* -------------------------------|----------------------------|---------
|
|
79
|
-
* `--vaadin-field-default-width` | Default width of the field | `12em`
|
|
80
|
-
*
|
|
81
81
|
* The following shadow DOM parts are available for styling:
|
|
82
82
|
*
|
|
83
83
|
* Part name | Description
|
|
@@ -111,6 +111,69 @@ export interface DatePickerEventMap extends HTMLElementEventMap, DatePickerCusto
|
|
|
111
111
|
* `opened` | Set when the overlay is opened
|
|
112
112
|
* `week-numbers` | Set when week numbers are shown in the calendar
|
|
113
113
|
*
|
|
114
|
+
* The following custom CSS properties are available for styling:
|
|
115
|
+
*
|
|
116
|
+
* Custom CSS property |
|
|
117
|
+
* :----------------------------------------------------------|
|
|
118
|
+
* | `--vaadin-date-picker-date-border-radius` |
|
|
119
|
+
* | `--vaadin-date-picker-date-disabled-color` |
|
|
120
|
+
* | `--vaadin-date-picker-date-height` |
|
|
121
|
+
* | `--vaadin-date-picker-date-selected-background` |
|
|
122
|
+
* | `--vaadin-date-picker-date-selected-color` |
|
|
123
|
+
* | `--vaadin-date-picker-date-today-color` |
|
|
124
|
+
* | `--vaadin-date-picker-date-width` |
|
|
125
|
+
* | `--vaadin-date-picker-month-header-color` |
|
|
126
|
+
* | `--vaadin-date-picker-month-header-font-size` |
|
|
127
|
+
* | `--vaadin-date-picker-month-header-font-weight` |
|
|
128
|
+
* | `--vaadin-date-picker-month-padding` |
|
|
129
|
+
* | `--vaadin-date-picker-overlay-max-height` |
|
|
130
|
+
* | `--vaadin-date-picker-overlay-width` |
|
|
131
|
+
* | `--vaadin-date-picker-toolbar-padding` |
|
|
132
|
+
* | `--vaadin-date-picker-week-divider-color` |
|
|
133
|
+
* | `--vaadin-date-picker-week-number-color` |
|
|
134
|
+
* | `--vaadin-date-picker-week-number-font-size` |
|
|
135
|
+
* | `--vaadin-date-picker-weekday-color` |
|
|
136
|
+
* | `--vaadin-date-picker-weekday-font-size` |
|
|
137
|
+
* | `--vaadin-date-picker-weekday-font-weight` |
|
|
138
|
+
* | `--vaadin-date-picker-year-scroller-background` |
|
|
139
|
+
* | `--vaadin-date-picker-year-scroller-border-color` |
|
|
140
|
+
* | `--vaadin-date-picker-year-scroller-current-year-color` |
|
|
141
|
+
* | `--vaadin-date-picker-year-scroller-width` |
|
|
142
|
+
* | `--vaadin-field-default-width` |
|
|
143
|
+
* | `--vaadin-input-field-background` |
|
|
144
|
+
* | `--vaadin-input-field-border-color` |
|
|
145
|
+
* | `--vaadin-input-field-border-radius` |
|
|
146
|
+
* | `--vaadin-input-field-border-width` |
|
|
147
|
+
* | `--vaadin-input-field-bottom-end-radius` |
|
|
148
|
+
* | `--vaadin-input-field-bottom-start-radius` |
|
|
149
|
+
* | `--vaadin-input-field-button-text-color` |
|
|
150
|
+
* | `--vaadin-input-field-container-gap` |
|
|
151
|
+
* | `--vaadin-input-field-disabled-background` |
|
|
152
|
+
* | `--vaadin-input-field-disabled-text-color` |
|
|
153
|
+
* | `--vaadin-input-field-error-color` |
|
|
154
|
+
* | `--vaadin-input-field-error-font-size` |
|
|
155
|
+
* | `--vaadin-input-field-error-font-weight` |
|
|
156
|
+
* | `--vaadin-input-field-error-line-height` |
|
|
157
|
+
* | `--vaadin-input-field-gap` |
|
|
158
|
+
* | `--vaadin-input-field-helper-color` |
|
|
159
|
+
* | `--vaadin-input-field-helper-font-size` |
|
|
160
|
+
* | `--vaadin-input-field-helper-font-weight` |
|
|
161
|
+
* | `--vaadin-input-field-helper-line-height` |
|
|
162
|
+
* | `--vaadin-input-field-label-color` |
|
|
163
|
+
* | `--vaadin-input-field-label-font-size` |
|
|
164
|
+
* | `--vaadin-input-field-label-font-weight` |
|
|
165
|
+
* | `--vaadin-input-field-label-line-height` |
|
|
166
|
+
* | `--vaadin-input-field-padding` |
|
|
167
|
+
* | `--vaadin-input-field-placeholder-color` |
|
|
168
|
+
* | `--vaadin-input-field-required-indicator` |
|
|
169
|
+
* | `--vaadin-input-field-required-indicator-color` |
|
|
170
|
+
* | `--vaadin-input-field-top-end-radius` |
|
|
171
|
+
* | `--vaadin-input-field-top-start-radius` |
|
|
172
|
+
* | `--vaadin-input-field-value-color` |
|
|
173
|
+
* | `--vaadin-input-field-value-font-size` |
|
|
174
|
+
* | `--vaadin-input-field-value-font-weight` |
|
|
175
|
+
* | `--vaadin-input-field-value-line-height` |
|
|
176
|
+
*
|
|
114
177
|
* ### Internal components
|
|
115
178
|
*
|
|
116
179
|
* In addition to `<vaadin-date-picker>` itself, the following internal
|
|
@@ -128,6 +191,7 @@ export interface DatePickerEventMap extends HTMLElementEventMap, DatePickerCusto
|
|
|
128
191
|
* ----------------------|--------------------
|
|
129
192
|
* `years-toggle-button` | Fullscreen mode years scroller toggle
|
|
130
193
|
* `toolbar` | Toolbar with slotted buttons
|
|
194
|
+
* `loader` | Loading spinner shown while the date metadata provider is resolving
|
|
131
195
|
*
|
|
132
196
|
* The following state attributes are available on the `<vaadin-date-picker-overlay-content>` element:
|
|
133
197
|
*
|
|
@@ -136,6 +200,7 @@ export interface DatePickerEventMap extends HTMLElementEventMap, DatePickerCusto
|
|
|
136
200
|
* `desktop` | Set when the overlay content is in desktop mode
|
|
137
201
|
* `fullscreen` | Set when the overlay content is in fullscreen mode
|
|
138
202
|
* `years-visible` | Set when the year scroller is visible in fullscreen mode
|
|
203
|
+
* `loading` | Set while the date metadata provider is resolving
|
|
139
204
|
*
|
|
140
205
|
* In order to style the month calendar, use `<vaadin-month-calendar>` shadow DOM parts:
|
|
141
206
|
*
|
|
@@ -148,6 +213,7 @@ export interface DatePickerEventMap extends HTMLElementEventMap, DatePickerCusto
|
|
|
148
213
|
* `week-number` | Week number element
|
|
149
214
|
* `date` | Date element
|
|
150
215
|
* `disabled` | Disabled date element
|
|
216
|
+
* `loading` | Date element in a month whose metadata is currently being fetched
|
|
151
217
|
* `focused` | Focused date element
|
|
152
218
|
* `selected` | Selected date element
|
|
153
219
|
* `today` | Date element corresponding to the current day
|
|
@@ -36,12 +36,6 @@ import { DatePickerMixin } from './vaadin-date-picker-mixin.js';
|
|
|
36
36
|
*
|
|
37
37
|
* ### Styling
|
|
38
38
|
*
|
|
39
|
-
* The following custom properties are available for styling:
|
|
40
|
-
*
|
|
41
|
-
* Custom property | Description | Default
|
|
42
|
-
* -------------------------------|----------------------------|---------
|
|
43
|
-
* `--vaadin-field-default-width` | Default width of the field | `12em`
|
|
44
|
-
*
|
|
45
39
|
* The following shadow DOM parts are available for styling:
|
|
46
40
|
*
|
|
47
41
|
* Part name | Description
|
|
@@ -75,6 +69,69 @@ import { DatePickerMixin } from './vaadin-date-picker-mixin.js';
|
|
|
75
69
|
* `opened` | Set when the overlay is opened
|
|
76
70
|
* `week-numbers` | Set when week numbers are shown in the calendar
|
|
77
71
|
*
|
|
72
|
+
* The following custom CSS properties are available for styling:
|
|
73
|
+
*
|
|
74
|
+
* Custom CSS property |
|
|
75
|
+
* :----------------------------------------------------------|
|
|
76
|
+
* | `--vaadin-date-picker-date-border-radius` |
|
|
77
|
+
* | `--vaadin-date-picker-date-disabled-color` |
|
|
78
|
+
* | `--vaadin-date-picker-date-height` |
|
|
79
|
+
* | `--vaadin-date-picker-date-selected-background` |
|
|
80
|
+
* | `--vaadin-date-picker-date-selected-color` |
|
|
81
|
+
* | `--vaadin-date-picker-date-today-color` |
|
|
82
|
+
* | `--vaadin-date-picker-date-width` |
|
|
83
|
+
* | `--vaadin-date-picker-month-header-color` |
|
|
84
|
+
* | `--vaadin-date-picker-month-header-font-size` |
|
|
85
|
+
* | `--vaadin-date-picker-month-header-font-weight` |
|
|
86
|
+
* | `--vaadin-date-picker-month-padding` |
|
|
87
|
+
* | `--vaadin-date-picker-overlay-max-height` |
|
|
88
|
+
* | `--vaadin-date-picker-overlay-width` |
|
|
89
|
+
* | `--vaadin-date-picker-toolbar-padding` |
|
|
90
|
+
* | `--vaadin-date-picker-week-divider-color` |
|
|
91
|
+
* | `--vaadin-date-picker-week-number-color` |
|
|
92
|
+
* | `--vaadin-date-picker-week-number-font-size` |
|
|
93
|
+
* | `--vaadin-date-picker-weekday-color` |
|
|
94
|
+
* | `--vaadin-date-picker-weekday-font-size` |
|
|
95
|
+
* | `--vaadin-date-picker-weekday-font-weight` |
|
|
96
|
+
* | `--vaadin-date-picker-year-scroller-background` |
|
|
97
|
+
* | `--vaadin-date-picker-year-scroller-border-color` |
|
|
98
|
+
* | `--vaadin-date-picker-year-scroller-current-year-color` |
|
|
99
|
+
* | `--vaadin-date-picker-year-scroller-width` |
|
|
100
|
+
* | `--vaadin-field-default-width` |
|
|
101
|
+
* | `--vaadin-input-field-background` |
|
|
102
|
+
* | `--vaadin-input-field-border-color` |
|
|
103
|
+
* | `--vaadin-input-field-border-radius` |
|
|
104
|
+
* | `--vaadin-input-field-border-width` |
|
|
105
|
+
* | `--vaadin-input-field-bottom-end-radius` |
|
|
106
|
+
* | `--vaadin-input-field-bottom-start-radius` |
|
|
107
|
+
* | `--vaadin-input-field-button-text-color` |
|
|
108
|
+
* | `--vaadin-input-field-container-gap` |
|
|
109
|
+
* | `--vaadin-input-field-disabled-background` |
|
|
110
|
+
* | `--vaadin-input-field-disabled-text-color` |
|
|
111
|
+
* | `--vaadin-input-field-error-color` |
|
|
112
|
+
* | `--vaadin-input-field-error-font-size` |
|
|
113
|
+
* | `--vaadin-input-field-error-font-weight` |
|
|
114
|
+
* | `--vaadin-input-field-error-line-height` |
|
|
115
|
+
* | `--vaadin-input-field-gap` |
|
|
116
|
+
* | `--vaadin-input-field-helper-color` |
|
|
117
|
+
* | `--vaadin-input-field-helper-font-size` |
|
|
118
|
+
* | `--vaadin-input-field-helper-font-weight` |
|
|
119
|
+
* | `--vaadin-input-field-helper-line-height` |
|
|
120
|
+
* | `--vaadin-input-field-label-color` |
|
|
121
|
+
* | `--vaadin-input-field-label-font-size` |
|
|
122
|
+
* | `--vaadin-input-field-label-font-weight` |
|
|
123
|
+
* | `--vaadin-input-field-label-line-height` |
|
|
124
|
+
* | `--vaadin-input-field-padding` |
|
|
125
|
+
* | `--vaadin-input-field-placeholder-color` |
|
|
126
|
+
* | `--vaadin-input-field-required-indicator` |
|
|
127
|
+
* | `--vaadin-input-field-required-indicator-color` |
|
|
128
|
+
* | `--vaadin-input-field-top-end-radius` |
|
|
129
|
+
* | `--vaadin-input-field-top-start-radius` |
|
|
130
|
+
* | `--vaadin-input-field-value-color` |
|
|
131
|
+
* | `--vaadin-input-field-value-font-size` |
|
|
132
|
+
* | `--vaadin-input-field-value-font-weight` |
|
|
133
|
+
* | `--vaadin-input-field-value-line-height` |
|
|
134
|
+
*
|
|
78
135
|
* ### Internal components
|
|
79
136
|
*
|
|
80
137
|
* In addition to `<vaadin-date-picker>` itself, the following internal
|
|
@@ -92,6 +149,7 @@ import { DatePickerMixin } from './vaadin-date-picker-mixin.js';
|
|
|
92
149
|
* ----------------------|--------------------
|
|
93
150
|
* `years-toggle-button` | Fullscreen mode years scroller toggle
|
|
94
151
|
* `toolbar` | Toolbar with slotted buttons
|
|
152
|
+
* `loader` | Loading spinner shown while the date metadata provider is resolving
|
|
95
153
|
*
|
|
96
154
|
* The following state attributes are available on the `<vaadin-date-picker-overlay-content>` element:
|
|
97
155
|
*
|
|
@@ -100,6 +158,7 @@ import { DatePickerMixin } from './vaadin-date-picker-mixin.js';
|
|
|
100
158
|
* `desktop` | Set when the overlay content is in desktop mode
|
|
101
159
|
* `fullscreen` | Set when the overlay content is in fullscreen mode
|
|
102
160
|
* `years-visible` | Set when the year scroller is visible in fullscreen mode
|
|
161
|
+
* `loading` | Set while the date metadata provider is resolving
|
|
103
162
|
*
|
|
104
163
|
* In order to style the month calendar, use `<vaadin-month-calendar>` shadow DOM parts:
|
|
105
164
|
*
|
|
@@ -112,6 +171,7 @@ import { DatePickerMixin } from './vaadin-date-picker-mixin.js';
|
|
|
112
171
|
* `week-number` | Week number element
|
|
113
172
|
* `date` | Date element
|
|
114
173
|
* `disabled` | Disabled date element
|
|
174
|
+
* `loading` | Date element in a month whose metadata is currently being fetched
|
|
115
175
|
* `focused` | Focused date element
|
|
116
176
|
* `selected` | Selected date element
|
|
117
177
|
* `today` | Date element corresponding to the current day
|
|
@@ -37,6 +37,10 @@ template.innerHTML = `
|
|
|
37
37
|
box-sizing: border-box;
|
|
38
38
|
top: var(--vaadin-infinite-scroller-buffer-offset, 0);
|
|
39
39
|
}
|
|
40
|
+
|
|
41
|
+
::slotted(div) {
|
|
42
|
+
height: var(--vaadin-infinite-scroller-item-height);
|
|
43
|
+
}
|
|
40
44
|
</style>
|
|
41
45
|
|
|
42
46
|
<div id="scroller" tabindex="-1">
|
|
@@ -149,7 +153,7 @@ export class InfiniteScroller extends HTMLElement {
|
|
|
149
153
|
this.$.scroller.scrollTop = this.itemHeight * (index - this._firstIndex) + this._buffers[0].translateY;
|
|
150
154
|
} else {
|
|
151
155
|
this._initialIndex = ~~index;
|
|
152
|
-
this.
|
|
156
|
+
this.reset();
|
|
153
157
|
this._scrollDisabled = true;
|
|
154
158
|
this.$.scroller.scrollTop += (index % 1) * this.itemHeight;
|
|
155
159
|
this._scrollDisabled = false;
|
|
@@ -235,7 +239,7 @@ export class InfiniteScroller extends HTMLElement {
|
|
|
235
239
|
});
|
|
236
240
|
|
|
237
241
|
if (!this._buffers[0].translateY) {
|
|
238
|
-
this.
|
|
242
|
+
this.reset();
|
|
239
243
|
}
|
|
240
244
|
|
|
241
245
|
this._initDone = true;
|
|
@@ -262,7 +266,7 @@ export class InfiniteScroller extends HTMLElement {
|
|
|
262
266
|
if (scrollTop < this._bufferHeight || scrollTop > this._initialScroll * 2 - this._bufferHeight) {
|
|
263
267
|
// Scrolled near the end/beginning of the scrollable area -> reset.
|
|
264
268
|
this._initialIndex = ~~this.position;
|
|
265
|
-
this.
|
|
269
|
+
this.reset();
|
|
266
270
|
}
|
|
267
271
|
|
|
268
272
|
// Check if we scrolled enough to translate the buffer positions.
|
|
@@ -288,8 +292,18 @@ export class InfiniteScroller extends HTMLElement {
|
|
|
288
292
|
});
|
|
289
293
|
}
|
|
290
294
|
|
|
291
|
-
/**
|
|
292
|
-
|
|
295
|
+
/**
|
|
296
|
+
* Resets the scroller to the last starting index, and re-measures the
|
|
297
|
+
* item height in case the computed value of the CSS custom property
|
|
298
|
+
* has changed.
|
|
299
|
+
*/
|
|
300
|
+
reset() {
|
|
301
|
+
if (!this._activated || !this.isConnected) {
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
this._itemHeightVal = null;
|
|
306
|
+
|
|
293
307
|
this._scrollDisabled = true;
|
|
294
308
|
this.$.scroller.scrollTop = this._initialScroll;
|
|
295
309
|
this._buffers[0].translateY = this._initialScroll - this._bufferHeight;
|
|
@@ -314,7 +328,6 @@ export class InfiniteScroller extends HTMLElement {
|
|
|
314
328
|
this._buffers.forEach((buffer) => {
|
|
315
329
|
for (let i = 0; i < this.bufferSize; i++) {
|
|
316
330
|
const itemWrapper = document.createElement('div');
|
|
317
|
-
itemWrapper.style.height = `${this.itemHeight}px`;
|
|
318
331
|
itemWrapper.instance = {};
|
|
319
332
|
|
|
320
333
|
const slotName = `vaadin-infinite-scroller-item-content-${generateUniqueId()}`;
|