@vaadin/date-picker 24.0.0-alpha1 → 24.0.0-alpha10

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.
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2016 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2016 - 2023 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import '@vaadin/button/src/vaadin-button.js';
@@ -231,10 +231,6 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
231
231
  ];
232
232
  }
233
233
 
234
- get __isRTL() {
235
- return this.getAttribute('dir') === 'rtl';
236
- }
237
-
238
234
  /**
239
235
  * Whether to scroll to a sub-month position when scrolling to a date.
240
236
  * This is active if the month scroller is not large enough to fit a
@@ -272,31 +268,27 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
272
268
  );
273
269
 
274
270
  this.addController(
275
- new SlotController(
276
- this,
277
- 'today-button',
278
- () => document.createElement('vaadin-button'),
279
- (_, btn) => {
271
+ new SlotController(this, 'today-button', 'vaadin-button', {
272
+ observe: false,
273
+ initializer: (btn) => {
280
274
  btn.setAttribute('theme', 'tertiary');
281
275
  btn.addEventListener('keydown', (e) => this.__onTodayButtonKeyDown(e));
282
276
  addListener(btn, 'tap', this._onTodayTap.bind(this));
283
277
  this._todayButton = btn;
284
278
  },
285
- ),
279
+ }),
286
280
  );
287
281
 
288
282
  this.addController(
289
- new SlotController(
290
- this,
291
- 'cancel-button',
292
- () => document.createElement('vaadin-button'),
293
- (_, btn) => {
283
+ new SlotController(this, 'cancel-button', 'vaadin-button', {
284
+ observe: false,
285
+ initializer: (btn) => {
294
286
  btn.setAttribute('theme', 'tertiary');
295
287
  btn.addEventListener('keydown', (e) => this.__onCancelButtonKeyDown(e));
296
288
  addListener(btn, 'tap', this._cancel.bind(this));
297
289
  this._cancelButton = btn;
298
290
  },
299
- ),
291
+ }),
300
292
  );
301
293
 
302
294
  this.__initMonthScroller();
@@ -335,11 +327,9 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
335
327
 
336
328
  __initMonthScroller() {
337
329
  this.addController(
338
- new SlotController(
339
- this,
340
- 'months',
341
- () => document.createElement('vaadin-date-picker-month-scroller'),
342
- (_, scroller) => {
330
+ new SlotController(this, 'months', 'vaadin-date-picker-month-scroller', {
331
+ observe: false,
332
+ initializer: (scroller) => {
343
333
  scroller.addEventListener('custom-scroll', () => {
344
334
  this._onMonthScroll();
345
335
  });
@@ -367,17 +357,15 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
367
357
 
368
358
  this._monthScroller = scroller;
369
359
  },
370
- ),
360
+ }),
371
361
  );
372
362
  }
373
363
 
374
364
  __initYearScroller() {
375
365
  this.addController(
376
- new SlotController(
377
- this,
378
- 'years',
379
- () => document.createElement('vaadin-date-picker-year-scroller'),
380
- (_, scroller) => {
366
+ new SlotController(this, 'years', 'vaadin-date-picker-year-scroller', {
367
+ observe: false,
368
+ initializer: (scroller) => {
381
369
  scroller.setAttribute('aria-hidden', 'true');
382
370
 
383
371
  addListener(scroller, 'tap', (e) => {
@@ -398,7 +386,7 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
398
386
 
399
387
  this._yearScroller = scroller;
400
388
  },
401
- ),
389
+ }),
402
390
  );
403
391
  }
404
392
 
@@ -656,7 +644,10 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
656
644
  const initialPosition = this._monthScroller.position;
657
645
 
658
646
  const smoothScroll = (timestamp) => {
659
- start = start || timestamp;
647
+ if (!start) {
648
+ start = timestamp;
649
+ }
650
+
660
651
  const currentTime = timestamp - start;
661
652
 
662
653
  if (currentTime < this.scrollDuration) {
@@ -984,58 +975,55 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
984
975
  this.focusDate(getClosestDate(focus, [this.minDate, this.maxDate]));
985
976
  }
986
977
 
987
- _moveFocusByDays(days) {
988
- const focus = this.focusedDate;
989
- const dateToFocus = new Date(0, 0);
990
- dateToFocus.setFullYear(focus.getFullYear());
991
- dateToFocus.setMonth(focus.getMonth());
992
- dateToFocus.setDate(focus.getDate() + days);
993
-
994
- if (this._dateAllowed(dateToFocus, this.minDate, this.maxDate)) {
995
- this.focusDate(dateToFocus);
996
- } else if (this._dateAllowed(focus, this.minDate, this.maxDate)) {
978
+ _focusAllowedDate(dateToFocus, diff, keepMonth) {
979
+ if (this._dateAllowed(dateToFocus)) {
980
+ this.focusDate(dateToFocus, keepMonth);
981
+ } else if (this._dateAllowed(this.focusedDate)) {
997
982
  // Move to min or max date
998
- if (days > 0) {
999
- // Down or right
983
+ if (diff > 0) {
984
+ // Down, Right or Page Down key
1000
985
  this.focusDate(this.maxDate);
1001
986
  } else {
1002
- // Up or left
987
+ // Up, Left or Page Up key
1003
988
  this.focusDate(this.minDate);
1004
989
  }
1005
990
  } else {
1006
991
  // Move to closest allowed date
1007
- this._focusClosestDate(focus);
992
+ this._focusClosestDate(this.focusedDate);
1008
993
  }
1009
994
  }
1010
995
 
1011
- _moveFocusByMonths(months) {
1012
- const focus = this.focusedDate;
1013
- const dateToFocus = new Date(0, 0);
1014
- dateToFocus.setFullYear(focus.getFullYear());
1015
- dateToFocus.setMonth(focus.getMonth() + months);
996
+ _getDateDiff(months, days) {
997
+ const date = new Date(0, 0);
998
+ date.setFullYear(this.focusedDate.getFullYear());
999
+ date.setMonth(this.focusedDate.getMonth() + months);
1000
+ if (days) {
1001
+ date.setDate(this.focusedDate.getDate() + days);
1002
+ }
1003
+ return date;
1004
+ }
1016
1005
 
1006
+ _moveFocusByDays(days) {
1007
+ const dateToFocus = this._getDateDiff(0, days);
1008
+
1009
+ this._focusAllowedDate(dateToFocus, days, false);
1010
+ }
1011
+
1012
+ _moveFocusByMonths(months) {
1013
+ const dateToFocus = this._getDateDiff(months);
1017
1014
  const targetMonth = dateToFocus.getMonth();
1018
1015
 
1019
- dateToFocus.setDate(this._focusedMonthDate || (this._focusedMonthDate = focus.getDate()));
1016
+ if (!this._focusedMonthDate) {
1017
+ this._focusedMonthDate = this.focusedDate.getDate();
1018
+ }
1019
+
1020
+ dateToFocus.setDate(this._focusedMonthDate);
1021
+
1020
1022
  if (dateToFocus.getMonth() !== targetMonth) {
1021
1023
  dateToFocus.setDate(0);
1022
1024
  }
1023
1025
 
1024
- if (this._dateAllowed(dateToFocus, this.minDate, this.maxDate)) {
1025
- this.focusDate(dateToFocus, true);
1026
- } else if (this._dateAllowed(focus, this.minDate, this.maxDate)) {
1027
- // Move to min or max date
1028
- if (months > 0) {
1029
- // Pagedown
1030
- this.focusDate(this.maxDate);
1031
- } else {
1032
- // Pageup
1033
- this.focusDate(this.minDate);
1034
- }
1035
- } else {
1036
- // Move to closest allowed date
1037
- this._focusClosestDate(focus);
1038
- }
1026
+ this._focusAllowedDate(dateToFocus, months, true);
1039
1027
  }
1040
1028
 
1041
1029
  _moveFocusInsideMonth(focusedDate, property) {
@@ -1050,9 +1038,9 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
1050
1038
  dateToFocus.setDate(0);
1051
1039
  }
1052
1040
 
1053
- if (this._dateAllowed(dateToFocus, this.minDate, this.maxDate)) {
1041
+ if (this._dateAllowed(dateToFocus)) {
1054
1042
  this.focusDate(dateToFocus);
1055
- } else if (this._dateAllowed(focusedDate, this.minDate, this.maxDate)) {
1043
+ } else if (this._dateAllowed(focusedDate)) {
1056
1044
  // Move to minDate or maxDate
1057
1045
  this.focusDate(this[property]);
1058
1046
  } else {
@@ -1061,7 +1049,7 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
1061
1049
  }
1062
1050
  }
1063
1051
 
1064
- _dateAllowed(date, min, max) {
1052
+ _dateAllowed(date, min = this.minDate, max = this.maxDate) {
1065
1053
  return (!min || date >= min) && (!max || date <= max);
1066
1054
  }
1067
1055
 
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2016 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2016 - 2023 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import { Overlay } from '@vaadin/overlay/src/vaadin-overlay.js';
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2016 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2016 - 2023 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import { html } from '@polymer/polymer/lib/utils/html-tag.js';
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2016 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2016 - 2023 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2016 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2016 - 2023 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
@@ -85,8 +85,6 @@ export interface DatePickerEventMap extends HTMLElementEventMap, DatePickerCusto
85
85
  * Attribute | Description | Part name
86
86
  * -----------|--------------------------------------------------|-----------
87
87
  * `opened` | Set when the date selector overlay is opened | :host
88
- * `today` | Set on the date corresponding to the current day | date
89
- * `selected` | Set on the selected date | date
90
88
  *
91
89
  * If you want to replace the default `<input>` and its container with a custom implementation to get full control
92
90
  * over the input field, consider using the [`<vaadin-date-picker-light>`](#/elements/vaadin-date-picker-light) element.
@@ -133,6 +131,10 @@ export interface DatePickerEventMap extends HTMLElementEventMap, DatePickerCusto
133
131
  * `week-numbers` | Week numbers container
134
132
  * `week-number` | Week number element
135
133
  * `date` | Date element
134
+ * `disabled` | Disabled date element
135
+ * `focused` | Focused date element
136
+ * `selected` | Selected date element
137
+ * `today` | Date element corresponding to the current day
136
138
  *
137
139
  * In order to style year scroller elements, use `<vaadin-date-picker-year>` shadow DOM parts:
138
140
  *
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2016 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2016 - 2023 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import '@vaadin/input-container/src/vaadin-input-container.js';
@@ -53,8 +53,6 @@ registerStyles('vaadin-date-picker', inputFieldShared, { moduleId: 'vaadin-date-
53
53
  * Attribute | Description | Part name
54
54
  * -----------|--------------------------------------------------|-----------
55
55
  * `opened` | Set when the date selector overlay is opened | :host
56
- * `today` | Set on the date corresponding to the current day | date
57
- * `selected` | Set on the selected date | date
58
56
  *
59
57
  * If you want to replace the default `<input>` and its container with a custom implementation to get full control
60
58
  * over the input field, consider using the [`<vaadin-date-picker-light>`](#/elements/vaadin-date-picker-light) element.
@@ -101,6 +99,10 @@ registerStyles('vaadin-date-picker', inputFieldShared, { moduleId: 'vaadin-date-
101
99
  * `week-numbers` | Week numbers container
102
100
  * `week-number` | Week number element
103
101
  * `date` | Date element
102
+ * `disabled` | Disabled date element
103
+ * `focused` | Focused date element
104
+ * `selected` | Selected date element
105
+ * `today` | Date element corresponding to the current day
104
106
  *
105
107
  * In order to style year scroller elements, use `<vaadin-date-picker-year>` shadow DOM parts:
106
108
  *
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2016 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2016 - 2023 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import { afterNextRender } from '@polymer/polymer/lib/utils/render-status.js';
@@ -8,6 +8,7 @@ import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
8
8
  import { timeOut } from '@vaadin/component-base/src/async.js';
9
9
  import { isFirefox } from '@vaadin/component-base/src/browser-utils.js';
10
10
  import { Debouncer } from '@vaadin/component-base/src/debounce.js';
11
+ import { generateUniqueId } from '@vaadin/component-base/src/unique-id-utils.js';
11
12
 
12
13
  /**
13
14
  * @extends HTMLElement
@@ -117,6 +118,71 @@ export class InfiniteScroller extends PolymerElement {
117
118
  };
118
119
  }
119
120
 
121
+ /**
122
+ * @return {number}
123
+ */
124
+ get bufferOffset() {
125
+ return this._buffers[0].offsetTop;
126
+ }
127
+
128
+ /**
129
+ * @return {number}
130
+ */
131
+ get itemHeight() {
132
+ if (!this._itemHeightVal) {
133
+ const itemHeight = getComputedStyle(this).getPropertyValue('--vaadin-infinite-scroller-item-height');
134
+ // Use background-position temp inline style for unit conversion
135
+ const tmpStyleProp = 'background-position';
136
+ this.$.fullHeight.style.setProperty(tmpStyleProp, itemHeight);
137
+ const itemHeightPx = getComputedStyle(this.$.fullHeight).getPropertyValue(tmpStyleProp);
138
+ this.$.fullHeight.style.removeProperty(tmpStyleProp);
139
+ this._itemHeightVal = parseFloat(itemHeightPx);
140
+ }
141
+
142
+ return this._itemHeightVal;
143
+ }
144
+
145
+ /** @private */
146
+ get _bufferHeight() {
147
+ return this.itemHeight * this.bufferSize;
148
+ }
149
+
150
+ /**
151
+ * @return {number}
152
+ */
153
+ get position() {
154
+ return (this.$.scroller.scrollTop - this._buffers[0].translateY) / this.itemHeight + this._firstIndex;
155
+ }
156
+
157
+ /**
158
+ * Current scroller position as index. Can be a fractional number.
159
+ *
160
+ * @type {number}
161
+ */
162
+ set position(index) {
163
+ this._preventScrollEvent = true;
164
+ if (index > this._firstIndex && index < this._firstIndex + this.bufferSize * 2) {
165
+ this.$.scroller.scrollTop = this.itemHeight * (index - this._firstIndex) + this._buffers[0].translateY;
166
+ } else {
167
+ this._initialIndex = ~~index;
168
+ this._reset();
169
+ this._scrollDisabled = true;
170
+ this.$.scroller.scrollTop += (index % 1) * this.itemHeight;
171
+ this._scrollDisabled = false;
172
+ }
173
+
174
+ if (this._mayHaveMomentum) {
175
+ // Stop the possible iOS Safari momentum with -webkit-overflow-scrolling: auto;
176
+ this.$.scroller.classList.add('notouchscroll');
177
+ this._mayHaveMomentum = false;
178
+
179
+ setTimeout(() => {
180
+ // Restore -webkit-overflow-scrolling: touch; after a small delay.
181
+ this.$.scroller.classList.remove('notouchscroll');
182
+ }, 10);
183
+ }
184
+ }
185
+
120
186
  /** @protected */
121
187
  ready() {
122
188
  super.ready();
@@ -235,71 +301,6 @@ export class InfiniteScroller extends PolymerElement {
235
301
  });
236
302
  }
237
303
 
238
- /**
239
- * @return {number}
240
- */
241
- get bufferOffset() {
242
- return this._buffers[0].offsetTop;
243
- }
244
-
245
- /**
246
- * @return {number}
247
- */
248
- get position() {
249
- return (this.$.scroller.scrollTop - this._buffers[0].translateY) / this.itemHeight + this._firstIndex;
250
- }
251
-
252
- /**
253
- * Current scroller position as index. Can be a fractional number.
254
- *
255
- * @type {number}
256
- */
257
- set position(index) {
258
- this._preventScrollEvent = true;
259
- if (index > this._firstIndex && index < this._firstIndex + this.bufferSize * 2) {
260
- this.$.scroller.scrollTop = this.itemHeight * (index - this._firstIndex) + this._buffers[0].translateY;
261
- } else {
262
- this._initialIndex = ~~index;
263
- this._reset();
264
- this._scrollDisabled = true;
265
- this.$.scroller.scrollTop += (index % 1) * this.itemHeight;
266
- this._scrollDisabled = false;
267
- }
268
-
269
- if (this._mayHaveMomentum) {
270
- // Stop the possible iOS Safari momentum with -webkit-overflow-scrolling: auto;
271
- this.$.scroller.classList.add('notouchscroll');
272
- this._mayHaveMomentum = false;
273
-
274
- setTimeout(() => {
275
- // Restore -webkit-overflow-scrolling: touch; after a small delay.
276
- this.$.scroller.classList.remove('notouchscroll');
277
- }, 10);
278
- }
279
- }
280
-
281
- /**
282
- * @return {number}
283
- */
284
- get itemHeight() {
285
- if (!this._itemHeightVal) {
286
- const itemHeight = getComputedStyle(this).getPropertyValue('--vaadin-infinite-scroller-item-height');
287
- // Use background-position temp inline style for unit conversion
288
- const tmpStyleProp = 'background-position';
289
- this.$.fullHeight.style.setProperty(tmpStyleProp, itemHeight);
290
- const itemHeightPx = getComputedStyle(this.$.fullHeight).getPropertyValue(tmpStyleProp);
291
- this.$.fullHeight.style.removeProperty(tmpStyleProp);
292
- this._itemHeightVal = parseFloat(itemHeightPx);
293
- }
294
-
295
- return this._itemHeightVal;
296
- }
297
-
298
- /** @private */
299
- get _bufferHeight() {
300
- return this.itemHeight * this.bufferSize;
301
- }
302
-
303
304
  /** @private */
304
305
  _reset() {
305
306
  this._scrollDisabled = true;
@@ -329,8 +330,7 @@ export class InfiniteScroller extends PolymerElement {
329
330
  itemWrapper.style.height = `${this.itemHeight}px`;
330
331
  itemWrapper.instance = {};
331
332
 
332
- const contentId = (InfiniteScroller._contentIndex = InfiniteScroller._contentIndex + 1 || 0);
333
- const slotName = `vaadin-infinite-scroller-item-content-${contentId}`;
333
+ const slotName = `vaadin-infinite-scroller-item-content-${generateUniqueId()}`;
334
334
 
335
335
  const slot = document.createElement('slot');
336
336
  slot.setAttribute('name', slotName);
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2016 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2016 - 2023 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import '@polymer/polymer/lib/elements/dom-repeat.js';
@@ -32,17 +32,21 @@ class MonthCalendar extends FocusMixin(ThemableMixin(PolymerElement)) {
32
32
  display: flex;
33
33
  }
34
34
 
35
- [part='date'] {
35
+ [part~='date'] {
36
36
  outline: none;
37
37
  }
38
38
 
39
+ [part~='disabled'] {
40
+ pointer-events: none;
41
+ }
42
+
39
43
  [part='week-number'][hidden],
40
44
  [part='weekday'][hidden] {
41
45
  display: none;
42
46
  }
43
47
 
44
48
  [part='weekday'],
45
- [part='date'] {
49
+ [part~='date'] {
46
50
  width: calc(100% / 7);
47
51
  padding: 0;
48
52
  font-weight: normal;
@@ -56,7 +60,7 @@ class MonthCalendar extends FocusMixin(ThemableMixin(PolymerElement)) {
56
60
  }
57
61
 
58
62
  :host([week-numbers]) [part='weekday']:not(:empty),
59
- :host([week-numbers]) [part='date'] {
63
+ :host([week-numbers]) [part~='date'] {
60
64
  width: 12.5%;
61
65
  }
62
66
  </style>
@@ -99,12 +103,9 @@ class MonthCalendar extends FocusMixin(ThemableMixin(PolymerElement)) {
99
103
  <template is="dom-repeat" items="[[week]]">
100
104
  <td
101
105
  role="gridcell"
102
- part="date"
106
+ part$="[[__getDatePart(item, focusedDate, selectedDate, minDate, maxDate)]]"
103
107
  date="[[item]]"
104
- today$="[[_isToday(item)]]"
105
- focused$="[[__isDayFocused(item, focusedDate)]]"
106
108
  tabindex$="[[__getDayTabindex(item, focusedDate)]]"
107
- selected$="[[__isDaySelected(item, selectedDate)]]"
108
109
  disabled$="[[__isDayDisabled(item, minDate, maxDate)]]"
109
110
  aria-selected$="[[__getDayAriaSelected(item, selectedDate)]]"
110
111
  aria-disabled$="[[__getDayAriaDisabled(item, minDate, maxDate)]]"
@@ -204,18 +205,18 @@ class MonthCalendar extends FocusMixin(ThemableMixin(PolymerElement)) {
204
205
  ];
205
206
  }
206
207
 
208
+ get focusableDateElement() {
209
+ return [...this.shadowRoot.querySelectorAll('[part~=date]')].find((datePart) => {
210
+ return dateEquals(datePart.date, this.focusedDate);
211
+ });
212
+ }
213
+
207
214
  /** @protected */
208
215
  ready() {
209
216
  super.ready();
210
217
  addListener(this.$.monthGrid, 'tap', this._handleTap.bind(this));
211
218
  }
212
219
 
213
- get focusableDateElement() {
214
- return [...this.shadowRoot.querySelectorAll('[part=date]')].find((datePart) => {
215
- return dateEquals(datePart.date, this.focusedDate);
216
- });
217
- }
218
-
219
220
  /* Returns true if all the dates in the month are out of the allowed range */
220
221
  _isDisabled(month, minDate, maxDate) {
221
222
  // First day of the month
@@ -369,6 +370,28 @@ class MonthCalendar extends FocusMixin(ThemableMixin(PolymerElement)) {
369
370
  e.preventDefault();
370
371
  }
371
372
 
373
+ __getDatePart(date, focusedDate, selectedDate, minDate, maxDate) {
374
+ const result = ['date'];
375
+
376
+ if (this.__isDayDisabled(date, minDate, maxDate)) {
377
+ result.push('disabled');
378
+ }
379
+
380
+ if (this.__isDayFocused(date, focusedDate)) {
381
+ result.push('focused');
382
+ }
383
+
384
+ if (this.__isDaySelected(date, selectedDate)) {
385
+ result.push('selected');
386
+ }
387
+
388
+ if (this._isToday(date)) {
389
+ result.push('today');
390
+ }
391
+
392
+ return result.join(' ');
393
+ }
394
+
372
395
  __getWeekNumber(days) {
373
396
  const date = days.reduce((acc, d) => {
374
397
  return !acc && d ? d : acc;
@@ -50,7 +50,7 @@ registerStyles(
50
50
 
51
51
  /* Date and week number cells */
52
52
 
53
- [part='date'],
53
+ [part~='date'],
54
54
  [part='week-number'] {
55
55
  box-sizing: border-box;
56
56
  display: inline-flex;
@@ -60,28 +60,28 @@ registerStyles(
60
60
  position: relative;
61
61
  }
62
62
 
63
- [part='date'] {
63
+ [part~='date'] {
64
64
  transition: color 0.1s;
65
65
  }
66
66
 
67
- [part='date']:not(:empty) {
67
+ [part~='date']:not(:empty) {
68
68
  cursor: var(--lumo-clickable-cursor);
69
69
  }
70
70
 
71
71
  :host([week-numbers]) [part='weekday']:not(:empty),
72
- :host([week-numbers]) [part='date'] {
72
+ :host([week-numbers]) [part~='date'] {
73
73
  width: calc((100% - var(--lumo-size-xs)) / 7);
74
74
  }
75
75
 
76
76
  /* Today date */
77
77
 
78
- [part='date'][today] {
78
+ [part~='date'][part~='today'] {
79
79
  color: var(--lumo-primary-text-color);
80
80
  }
81
81
 
82
82
  /* Focused date */
83
83
 
84
- [part='date']::before {
84
+ [part~='date']::before {
85
85
  content: '';
86
86
  position: absolute;
87
87
  z-index: -1;
@@ -97,11 +97,11 @@ registerStyles(
97
97
  border-radius: var(--lumo-border-radius-m);
98
98
  }
99
99
 
100
- [part='date'][focused]::before {
100
+ [part~='date'][part~='focused']::before {
101
101
  box-shadow: 0 0 0 1px var(--lumo-base-color), 0 0 0 3px var(--lumo-primary-color-50pct);
102
102
  }
103
103
 
104
- :host(:not([focused])) [part='date'][focused]::before {
104
+ :host(:not([focused])) [part~='date'][part~='focused']::before {
105
105
  animation: vaadin-date-picker-month-calendar-focus-date 1.4s infinite;
106
106
  }
107
107
 
@@ -111,33 +111,33 @@ registerStyles(
111
111
  }
112
112
  }
113
113
 
114
- [part='date']:not(:empty):not([disabled]):not([selected]):hover::before {
114
+ [part~='date']:not(:empty):not([part~='disabled']):not([part~='selected']):hover::before {
115
115
  background-color: var(--lumo-primary-color-10pct);
116
116
  }
117
117
 
118
- [part='date'][selected] {
118
+ [part~='date'][part~='selected'] {
119
119
  color: var(--lumo-primary-contrast-color);
120
120
  }
121
121
 
122
- [part='date'][selected]::before {
122
+ [part~='date'][part~='selected']::before {
123
123
  background-color: var(--lumo-primary-color);
124
124
  }
125
125
 
126
- [part='date'][disabled] {
126
+ [part~='date'][part~='disabled'] {
127
127
  color: var(--lumo-disabled-text-color);
128
128
  }
129
129
 
130
130
  @media (pointer: coarse) {
131
- [part='date']:hover:not([selected])::before,
132
- [part='date'][focused]:not([selected])::before {
131
+ [part~='date']:hover:not([part~='selected'])::before,
132
+ [part~='focused']:not([part~='selected'])::before {
133
133
  display: none;
134
134
  }
135
135
 
136
- [part='date']:not(:empty):not([disabled]):active::before {
136
+ [part~='date']:not(:empty):not([part~='disabled']):active::before {
137
137
  display: block;
138
138
  }
139
139
 
140
- [part='date'][selected]::before {
140
+ [part~='date'][part~='selected']::before {
141
141
  box-shadow: none;
142
142
  }
143
143
  }