@vaadin/date-picker 23.3.0-alpha5 → 24.0.0-alpha2
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/package.json +10 -10
- package/src/vaadin-date-picker-helper.d.ts +7 -0
- package/src/vaadin-date-picker-helper.js +14 -0
- package/src/vaadin-date-picker-light.d.ts +0 -6
- package/src/vaadin-date-picker-light.js +4 -42
- package/src/vaadin-date-picker-mixin.d.ts +0 -9
- package/src/vaadin-date-picker-mixin.js +72 -51
- package/src/vaadin-date-picker-month-scroller.js +74 -0
- package/src/vaadin-date-picker-overlay-content.js +238 -166
- package/src/vaadin-date-picker-overlay.js +18 -7
- package/src/vaadin-date-picker-year-scroller.js +104 -0
- package/src/vaadin-date-picker-year.js +57 -0
- package/src/vaadin-date-picker.d.ts +23 -11
- package/src/vaadin-date-picker.js +42 -38
- package/src/vaadin-infinite-scroller.js +30 -33
- package/src/vaadin-month-calendar.js +31 -8
- package/theme/lumo/vaadin-date-picker-overlay-content-styles.js +13 -50
- package/theme/lumo/vaadin-date-picker-year-styles.js +32 -0
- package/theme/lumo/vaadin-month-calendar-styles.js +16 -16
- package/theme/material/vaadin-date-picker-overlay-content-styles.js +10 -31
- package/theme/material/vaadin-date-picker-year-styles.js +28 -0
- package/theme/material/vaadin-month-calendar-styles.js +14 -14
- package/web-types.json +5 -5
- package/web-types.lit.json +5 -5
- package/src/vaadin-date-picker-styles.js +0 -28
|
@@ -5,7 +5,11 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import '@vaadin/button/src/vaadin-button.js';
|
|
7
7
|
import './vaadin-month-calendar.js';
|
|
8
|
-
import './vaadin-
|
|
8
|
+
import './vaadin-date-picker-month-scroller.js';
|
|
9
|
+
import './vaadin-date-picker-year-scroller.js';
|
|
10
|
+
import './vaadin-date-picker-year.js';
|
|
11
|
+
import { flush } from '@polymer/polymer/lib/utils/flush.js';
|
|
12
|
+
import { afterNextRender } from '@polymer/polymer/lib/utils/render-status.js';
|
|
9
13
|
import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
|
|
10
14
|
import { timeOut } from '@vaadin/component-base/src/async.js';
|
|
11
15
|
import { ControllerMixin } from '@vaadin/component-base/src/controller-mixin.js';
|
|
@@ -13,8 +17,9 @@ import { Debouncer } from '@vaadin/component-base/src/debounce.js';
|
|
|
13
17
|
import { DirMixin } from '@vaadin/component-base/src/dir-mixin.js';
|
|
14
18
|
import { addListener, setTouchAction } from '@vaadin/component-base/src/gestures.js';
|
|
15
19
|
import { MediaQueryController } from '@vaadin/component-base/src/media-query-controller.js';
|
|
20
|
+
import { SlotController } from '@vaadin/component-base/src/slot-controller.js';
|
|
16
21
|
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
17
|
-
import { dateEquals, extractDateParts, getClosestDate } from './vaadin-date-picker-helper.js';
|
|
22
|
+
import { dateAfterXMonths, dateEquals, extractDateParts, getClosestDate } from './vaadin-date-picker-helper.js';
|
|
18
23
|
|
|
19
24
|
/**
|
|
20
25
|
* @extends HTMLElement
|
|
@@ -63,62 +68,17 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
63
68
|
overflow: hidden;
|
|
64
69
|
}
|
|
65
70
|
|
|
66
|
-
[
|
|
67
|
-
[part='years'] {
|
|
68
|
-
height: 100%;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
[part='months'] {
|
|
72
|
-
--vaadin-infinite-scroller-item-height: 270px;
|
|
73
|
-
position: absolute;
|
|
74
|
-
top: 0;
|
|
75
|
-
left: 0;
|
|
76
|
-
right: 0;
|
|
77
|
-
bottom: 0;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
#scrollers[desktop] [part='months'] {
|
|
71
|
+
:host([desktop]) ::slotted([slot='months']) {
|
|
81
72
|
right: 50px;
|
|
82
73
|
transform: none !important;
|
|
83
74
|
}
|
|
84
75
|
|
|
85
|
-
[
|
|
86
|
-
--vaadin-infinite-scroller-item-height: 80px;
|
|
87
|
-
width: 50px;
|
|
88
|
-
position: absolute;
|
|
89
|
-
right: 0;
|
|
90
|
-
transform: translateX(100%);
|
|
91
|
-
-webkit-tap-highlight-color: transparent;
|
|
92
|
-
-webkit-user-select: none;
|
|
93
|
-
-moz-user-select: none;
|
|
94
|
-
user-select: none;
|
|
95
|
-
/* Center the year scroller position. */
|
|
96
|
-
--vaadin-infinite-scroller-buffer-offset: 50%;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
#scrollers[desktop] [part='years'] {
|
|
100
|
-
position: absolute;
|
|
76
|
+
:host([desktop]) ::slotted([slot='years']) {
|
|
101
77
|
transform: none !important;
|
|
102
78
|
}
|
|
103
79
|
|
|
104
|
-
[
|
|
105
|
-
|
|
106
|
-
display: block;
|
|
107
|
-
background: transparent;
|
|
108
|
-
width: 0;
|
|
109
|
-
height: 0;
|
|
110
|
-
position: absolute;
|
|
111
|
-
left: 0;
|
|
112
|
-
top: 50%;
|
|
113
|
-
transform: translateY(-50%);
|
|
114
|
-
border-width: 6px;
|
|
115
|
-
border-style: solid;
|
|
116
|
-
border-color: transparent;
|
|
117
|
-
border-left-color: #000;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
:host(.animate) [part='months'],
|
|
121
|
-
:host(.animate) [part='years'] {
|
|
80
|
+
:host(.animate) ::slotted([slot='months']),
|
|
81
|
+
:host(.animate) ::slotted([slot='years']) {
|
|
122
82
|
transition: all 200ms;
|
|
123
83
|
}
|
|
124
84
|
|
|
@@ -130,7 +90,7 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
130
90
|
}
|
|
131
91
|
</style>
|
|
132
92
|
|
|
133
|
-
<div part="overlay-header" on-touchend="_preventDefault"
|
|
93
|
+
<div part="overlay-header" on-touchend="_preventDefault" aria-hidden="true">
|
|
134
94
|
<div part="label">[[_formatDisplayed(selectedDate, i18n.formatDate, label)]]</div>
|
|
135
95
|
<div part="clear-button" hidden$="[[!selectedDate]]"></div>
|
|
136
96
|
<div part="toggle-button"></div>
|
|
@@ -140,67 +100,14 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
140
100
|
</div>
|
|
141
101
|
</div>
|
|
142
102
|
|
|
143
|
-
<div id="scrollers"
|
|
144
|
-
<
|
|
145
|
-
|
|
146
|
-
on-custom-scroll="_onMonthScroll"
|
|
147
|
-
on-touchstart="_onMonthScrollTouchStart"
|
|
148
|
-
buffer-size="3"
|
|
149
|
-
active="[[initialPosition]]"
|
|
150
|
-
part="months"
|
|
151
|
-
>
|
|
152
|
-
<template>
|
|
153
|
-
<vaadin-month-calendar
|
|
154
|
-
i18n="[[i18n]]"
|
|
155
|
-
month="[[_dateAfterXMonths(index)]]"
|
|
156
|
-
selected-date="{{selectedDate}}"
|
|
157
|
-
focused-date="[[focusedDate]]"
|
|
158
|
-
ignore-taps="[[_ignoreTaps]]"
|
|
159
|
-
show-week-numbers="[[showWeekNumbers]]"
|
|
160
|
-
min-date="[[minDate]]"
|
|
161
|
-
max-date="[[maxDate]]"
|
|
162
|
-
part="month"
|
|
163
|
-
theme$="[[_theme]]"
|
|
164
|
-
on-keydown="__onMonthCalendarKeyDown"
|
|
165
|
-
>
|
|
166
|
-
</vaadin-month-calendar>
|
|
167
|
-
</template>
|
|
168
|
-
</vaadin-infinite-scroller>
|
|
169
|
-
<vaadin-infinite-scroller
|
|
170
|
-
id="yearScroller"
|
|
171
|
-
on-custom-scroll="_onYearScroll"
|
|
172
|
-
on-touchstart="_onYearScrollTouchStart"
|
|
173
|
-
buffer-size="12"
|
|
174
|
-
active="[[initialPosition]]"
|
|
175
|
-
part="years"
|
|
176
|
-
aria-hidden="true"
|
|
177
|
-
>
|
|
178
|
-
<template>
|
|
179
|
-
<div
|
|
180
|
-
part="year-number"
|
|
181
|
-
current$="[[_isCurrentYear(index)]]"
|
|
182
|
-
selected$="[[_isSelectedYear(index, selectedDate)]]"
|
|
183
|
-
>
|
|
184
|
-
[[_yearAfterXYears(index)]]
|
|
185
|
-
</div>
|
|
186
|
-
<div part="year-separator" aria-hidden="true"></div>
|
|
187
|
-
</template>
|
|
188
|
-
</vaadin-infinite-scroller>
|
|
103
|
+
<div id="scrollers">
|
|
104
|
+
<slot name="months"></slot>
|
|
105
|
+
<slot name="years"></slot>
|
|
189
106
|
</div>
|
|
190
107
|
|
|
191
108
|
<div on-touchend="_preventDefault" role="toolbar" part="toolbar">
|
|
192
|
-
<
|
|
193
|
-
|
|
194
|
-
part="today-button"
|
|
195
|
-
theme="tertiary"
|
|
196
|
-
disabled="[[!_isTodayAllowed(minDate, maxDate)]]"
|
|
197
|
-
on-keydown="__onTodayButtonKeyDown"
|
|
198
|
-
>
|
|
199
|
-
[[i18n.today]]
|
|
200
|
-
</vaadin-button>
|
|
201
|
-
<vaadin-button id="cancelButton" part="cancel-button" theme="tertiary" on-keydown="__onCancelButtonKeyDown">
|
|
202
|
-
[[i18n.cancel]]
|
|
203
|
-
</vaadin-button>
|
|
109
|
+
<slot name="today-button"></slot>
|
|
110
|
+
<slot name="cancel-button"></slot>
|
|
204
111
|
</div>
|
|
205
112
|
`;
|
|
206
113
|
}
|
|
@@ -249,7 +156,10 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
249
156
|
|
|
250
157
|
_visibleMonthIndex: Number,
|
|
251
158
|
|
|
252
|
-
_desktopMode:
|
|
159
|
+
_desktopMode: {
|
|
160
|
+
type: Boolean,
|
|
161
|
+
observer: '_desktopModeChanged',
|
|
162
|
+
},
|
|
253
163
|
|
|
254
164
|
_desktopMediaQuery: {
|
|
255
165
|
type: String,
|
|
@@ -270,6 +180,7 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
270
180
|
|
|
271
181
|
showWeekNumbers: {
|
|
272
182
|
type: Boolean,
|
|
183
|
+
value: false,
|
|
273
184
|
},
|
|
274
185
|
|
|
275
186
|
_ignoreTaps: Boolean,
|
|
@@ -290,9 +201,36 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
290
201
|
* Input label
|
|
291
202
|
*/
|
|
292
203
|
label: String,
|
|
204
|
+
|
|
205
|
+
_cancelButton: {
|
|
206
|
+
type: Object,
|
|
207
|
+
},
|
|
208
|
+
|
|
209
|
+
_todayButton: {
|
|
210
|
+
type: Object,
|
|
211
|
+
},
|
|
212
|
+
|
|
213
|
+
calendars: {
|
|
214
|
+
type: Array,
|
|
215
|
+
value: () => [],
|
|
216
|
+
},
|
|
217
|
+
|
|
218
|
+
years: {
|
|
219
|
+
type: Array,
|
|
220
|
+
value: () => [],
|
|
221
|
+
},
|
|
293
222
|
};
|
|
294
223
|
}
|
|
295
224
|
|
|
225
|
+
static get observers() {
|
|
226
|
+
return [
|
|
227
|
+
'__updateCalendars(calendars, i18n, minDate, maxDate, selectedDate, focusedDate, showWeekNumbers, _ignoreTaps, _theme)',
|
|
228
|
+
'__updateCancelButton(_cancelButton, i18n)',
|
|
229
|
+
'__updateTodayButton(_todayButton, i18n, minDate, maxDate)',
|
|
230
|
+
'__updateYears(years, selectedDate, _theme)',
|
|
231
|
+
];
|
|
232
|
+
}
|
|
233
|
+
|
|
296
234
|
get __isRTL() {
|
|
297
235
|
return this.getAttribute('dir') === 'rtl';
|
|
298
236
|
}
|
|
@@ -306,11 +244,7 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
306
244
|
* @private
|
|
307
245
|
*/
|
|
308
246
|
get __useSubMonthScrolling() {
|
|
309
|
-
return this
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
get calendars() {
|
|
313
|
-
return [...this.shadowRoot.querySelectorAll('vaadin-month-calendar')];
|
|
247
|
+
return this._monthScroller.clientHeight < this._monthScroller.itemHeight + this._monthScroller.bufferOffset;
|
|
314
248
|
}
|
|
315
249
|
|
|
316
250
|
get focusableDateElement() {
|
|
@@ -324,10 +258,7 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
324
258
|
|
|
325
259
|
addListener(this.$.scrollers, 'track', this._track.bind(this));
|
|
326
260
|
addListener(this.shadowRoot.querySelector('[part="clear-button"]'), 'tap', this._clear.bind(this));
|
|
327
|
-
addListener(this.shadowRoot.querySelector('[part="today-button"]'), 'tap', this._onTodayTap.bind(this));
|
|
328
|
-
addListener(this.shadowRoot.querySelector('[part="cancel-button"]'), 'tap', this._cancel.bind(this));
|
|
329
261
|
addListener(this.shadowRoot.querySelector('[part="toggle-button"]'), 'tap', this._cancel.bind(this));
|
|
330
|
-
addListener(this.shadowRoot.querySelector('[part="years"]'), 'tap', this._onYearTap.bind(this));
|
|
331
262
|
addListener(
|
|
332
263
|
this.shadowRoot.querySelector('[part="years-toggle-button"]'),
|
|
333
264
|
'tap',
|
|
@@ -339,6 +270,37 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
339
270
|
this._desktopMode = matches;
|
|
340
271
|
}),
|
|
341
272
|
);
|
|
273
|
+
|
|
274
|
+
this.addController(
|
|
275
|
+
new SlotController(
|
|
276
|
+
this,
|
|
277
|
+
'today-button',
|
|
278
|
+
() => document.createElement('vaadin-button'),
|
|
279
|
+
(_, btn) => {
|
|
280
|
+
btn.setAttribute('theme', 'tertiary');
|
|
281
|
+
btn.addEventListener('keydown', (e) => this.__onTodayButtonKeyDown(e));
|
|
282
|
+
addListener(btn, 'tap', this._onTodayTap.bind(this));
|
|
283
|
+
this._todayButton = btn;
|
|
284
|
+
},
|
|
285
|
+
),
|
|
286
|
+
);
|
|
287
|
+
|
|
288
|
+
this.addController(
|
|
289
|
+
new SlotController(
|
|
290
|
+
this,
|
|
291
|
+
'cancel-button',
|
|
292
|
+
() => document.createElement('vaadin-button'),
|
|
293
|
+
(_, btn) => {
|
|
294
|
+
btn.setAttribute('theme', 'tertiary');
|
|
295
|
+
btn.addEventListener('keydown', (e) => this.__onCancelButtonKeyDown(e));
|
|
296
|
+
addListener(btn, 'tap', this._cancel.bind(this));
|
|
297
|
+
this._cancelButton = btn;
|
|
298
|
+
},
|
|
299
|
+
),
|
|
300
|
+
);
|
|
301
|
+
|
|
302
|
+
this.__initMonthScroller();
|
|
303
|
+
this.__initYearScroller();
|
|
342
304
|
}
|
|
343
305
|
|
|
344
306
|
/**
|
|
@@ -359,7 +321,7 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
359
321
|
* Focuses the cancel button
|
|
360
322
|
*/
|
|
361
323
|
focusCancel() {
|
|
362
|
-
this
|
|
324
|
+
this._cancelButton.focus();
|
|
363
325
|
}
|
|
364
326
|
|
|
365
327
|
/**
|
|
@@ -368,7 +330,126 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
368
330
|
scrollToDate(date, animate) {
|
|
369
331
|
const offset = this.__useSubMonthScrolling ? this._calculateWeekScrollOffset(date) : 0;
|
|
370
332
|
this._scrollToPosition(this._differenceInMonths(date, this._originDate) + offset, animate);
|
|
371
|
-
this
|
|
333
|
+
this._monthScroller.forceUpdate();
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
__initMonthScroller() {
|
|
337
|
+
this.addController(
|
|
338
|
+
new SlotController(
|
|
339
|
+
this,
|
|
340
|
+
'months',
|
|
341
|
+
() => document.createElement('vaadin-date-picker-month-scroller'),
|
|
342
|
+
(_, scroller) => {
|
|
343
|
+
scroller.addEventListener('custom-scroll', () => {
|
|
344
|
+
this._onMonthScroll();
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
scroller.addEventListener('touchstart', () => {
|
|
348
|
+
this._onMonthScrollTouchStart();
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
scroller.addEventListener('keydown', (e) => {
|
|
352
|
+
this.__onMonthCalendarKeyDown(e);
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
scroller.addEventListener('init-done', () => {
|
|
356
|
+
const calendars = [...this.querySelectorAll('vaadin-month-calendar')];
|
|
357
|
+
|
|
358
|
+
// Two-way binding for selectedDate property
|
|
359
|
+
calendars.forEach((calendar) => {
|
|
360
|
+
calendar.addEventListener('selected-date-changed', (e) => {
|
|
361
|
+
this.selectedDate = e.detail.value;
|
|
362
|
+
});
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
this.calendars = calendars;
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
this._monthScroller = scroller;
|
|
369
|
+
},
|
|
370
|
+
),
|
|
371
|
+
);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
__initYearScroller() {
|
|
375
|
+
this.addController(
|
|
376
|
+
new SlotController(
|
|
377
|
+
this,
|
|
378
|
+
'years',
|
|
379
|
+
() => document.createElement('vaadin-date-picker-year-scroller'),
|
|
380
|
+
(_, scroller) => {
|
|
381
|
+
scroller.setAttribute('aria-hidden', 'true');
|
|
382
|
+
|
|
383
|
+
addListener(scroller, 'tap', (e) => {
|
|
384
|
+
this._onYearTap(e);
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
scroller.addEventListener('custom-scroll', () => {
|
|
388
|
+
this._onYearScroll();
|
|
389
|
+
});
|
|
390
|
+
|
|
391
|
+
scroller.addEventListener('touchstart', () => {
|
|
392
|
+
this._onYearScrollTouchStart();
|
|
393
|
+
});
|
|
394
|
+
|
|
395
|
+
scroller.addEventListener('init-done', () => {
|
|
396
|
+
this.years = [...this.querySelectorAll('vaadin-date-picker-year')];
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
this._yearScroller = scroller;
|
|
400
|
+
},
|
|
401
|
+
),
|
|
402
|
+
);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
__updateCancelButton(cancelButton, i18n) {
|
|
406
|
+
if (cancelButton) {
|
|
407
|
+
cancelButton.textContent = i18n && i18n.cancel;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
__updateTodayButton(todayButton, i18n, minDate, maxDate) {
|
|
412
|
+
if (todayButton) {
|
|
413
|
+
todayButton.textContent = i18n && i18n.today;
|
|
414
|
+
todayButton.disabled = !this._isTodayAllowed(minDate, maxDate);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
// eslint-disable-next-line max-params
|
|
419
|
+
__updateCalendars(calendars, i18n, minDate, maxDate, selectedDate, focusedDate, showWeekNumbers, ignoreTaps, theme) {
|
|
420
|
+
if (calendars && calendars.length) {
|
|
421
|
+
calendars.forEach((calendar) => {
|
|
422
|
+
calendar.setProperties({
|
|
423
|
+
i18n,
|
|
424
|
+
minDate,
|
|
425
|
+
maxDate,
|
|
426
|
+
focusedDate,
|
|
427
|
+
selectedDate,
|
|
428
|
+
showWeekNumbers,
|
|
429
|
+
ignoreTaps,
|
|
430
|
+
});
|
|
431
|
+
|
|
432
|
+
if (theme) {
|
|
433
|
+
calendar.setAttribute('theme', theme);
|
|
434
|
+
} else {
|
|
435
|
+
calendar.removeAttribute('theme');
|
|
436
|
+
}
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
__updateYears(years, selectedDate, theme) {
|
|
442
|
+
if (years && years.length) {
|
|
443
|
+
years.forEach((year) => {
|
|
444
|
+
year.selectedDate = selectedDate;
|
|
445
|
+
|
|
446
|
+
if (theme) {
|
|
447
|
+
year.setAttribute('theme', theme);
|
|
448
|
+
} else {
|
|
449
|
+
year.removeAttribute('theme');
|
|
450
|
+
}
|
|
451
|
+
});
|
|
452
|
+
}
|
|
372
453
|
}
|
|
373
454
|
|
|
374
455
|
/**
|
|
@@ -382,18 +463,12 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
382
463
|
);
|
|
383
464
|
}
|
|
384
465
|
|
|
385
|
-
|
|
386
|
-
this.
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
_isCurrentYear(yearsFromNow) {
|
|
390
|
-
return yearsFromNow === 0;
|
|
466
|
+
_desktopModeChanged(desktopMode) {
|
|
467
|
+
this.toggleAttribute('desktop', desktopMode);
|
|
391
468
|
}
|
|
392
469
|
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
return selectedDate.getFullYear() === this._originDate.getFullYear() + yearsFromNow;
|
|
396
|
-
}
|
|
470
|
+
_focusedDateChanged(focusedDate) {
|
|
471
|
+
this.revealDate(focusedDate);
|
|
397
472
|
}
|
|
398
473
|
|
|
399
474
|
/**
|
|
@@ -413,14 +488,14 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
413
488
|
}
|
|
414
489
|
|
|
415
490
|
// Otherwise determine if we need to scroll to make the month of the date visible
|
|
416
|
-
const scrolledAboveViewport = this
|
|
491
|
+
const scrolledAboveViewport = this._monthScroller.position > diff;
|
|
417
492
|
|
|
418
493
|
const visibleArea = Math.max(
|
|
419
|
-
this
|
|
420
|
-
this
|
|
494
|
+
this._monthScroller.itemHeight,
|
|
495
|
+
this._monthScroller.clientHeight - this._monthScroller.bufferOffset * 2,
|
|
421
496
|
);
|
|
422
|
-
const visibleItems = visibleArea / this
|
|
423
|
-
const scrolledBelowViewport = this
|
|
497
|
+
const visibleItems = visibleArea / this._monthScroller.itemHeight;
|
|
498
|
+
const scrolledBelowViewport = this._monthScroller.position + visibleItems - 1 < diff;
|
|
424
499
|
|
|
425
500
|
if (scrolledAboveViewport) {
|
|
426
501
|
this._scrollToPosition(diff, animate);
|
|
@@ -460,17 +535,23 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
460
535
|
}
|
|
461
536
|
|
|
462
537
|
_initialPositionChanged(initialPosition) {
|
|
538
|
+
if (this._monthScroller && this._yearScroller) {
|
|
539
|
+
this._monthScroller.active = true;
|
|
540
|
+
this._yearScroller.active = true;
|
|
541
|
+
}
|
|
542
|
+
|
|
463
543
|
this.scrollToDate(initialPosition);
|
|
464
544
|
}
|
|
465
545
|
|
|
466
546
|
_repositionYearScroller() {
|
|
467
|
-
|
|
468
|
-
this
|
|
547
|
+
const monthPosition = this._monthScroller.position;
|
|
548
|
+
this._visibleMonthIndex = Math.floor(monthPosition);
|
|
549
|
+
this._yearScroller.position = (monthPosition + this._originDate.getMonth()) / 12;
|
|
469
550
|
}
|
|
470
551
|
|
|
471
552
|
_repositionMonthScroller() {
|
|
472
|
-
this
|
|
473
|
-
this._visibleMonthIndex = Math.floor(this
|
|
553
|
+
this._monthScroller.position = this._yearScroller.position * 12 - this._originDate.getMonth();
|
|
554
|
+
this._visibleMonthIndex = Math.floor(this._monthScroller.position);
|
|
474
555
|
}
|
|
475
556
|
|
|
476
557
|
_onMonthScroll() {
|
|
@@ -513,7 +594,7 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
513
594
|
_onTodayTap() {
|
|
514
595
|
const today = new Date();
|
|
515
596
|
|
|
516
|
-
if (Math.abs(this
|
|
597
|
+
if (Math.abs(this._monthScroller.position - this._differenceInMonths(today, this._originDate)) < 0.001) {
|
|
517
598
|
// Select today only if the month scroller is positioned approximately
|
|
518
599
|
// at the beginning of the current month
|
|
519
600
|
this._selectDate(today);
|
|
@@ -534,9 +615,9 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
534
615
|
_onYearTap(e) {
|
|
535
616
|
if (!this._ignoreTaps && !this._notTapping) {
|
|
536
617
|
const scrollDelta =
|
|
537
|
-
e.detail.y - (this
|
|
538
|
-
const yearDelta = scrollDelta / this
|
|
539
|
-
this._scrollToPosition(this
|
|
618
|
+
e.detail.y - (this._yearScroller.getBoundingClientRect().top + this._yearScroller.clientHeight / 2);
|
|
619
|
+
const yearDelta = scrollDelta / this._yearScroller.itemHeight;
|
|
620
|
+
this._scrollToPosition(this._monthScroller.position + yearDelta * 12, true);
|
|
540
621
|
}
|
|
541
622
|
}
|
|
542
623
|
|
|
@@ -547,7 +628,7 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
547
628
|
}
|
|
548
629
|
|
|
549
630
|
if (!animate) {
|
|
550
|
-
this
|
|
631
|
+
this._monthScroller.position = targetPosition;
|
|
551
632
|
this._targetPosition = undefined;
|
|
552
633
|
this._repositionYearScroller();
|
|
553
634
|
this.__tryFocusDate();
|
|
@@ -572,7 +653,7 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
572
653
|
};
|
|
573
654
|
|
|
574
655
|
let start = 0;
|
|
575
|
-
const initialPosition = this
|
|
656
|
+
const initialPosition = this._monthScroller.position;
|
|
576
657
|
|
|
577
658
|
const smoothScroll = (timestamp) => {
|
|
578
659
|
start = start || timestamp;
|
|
@@ -585,7 +666,7 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
585
666
|
this._targetPosition - initialPosition,
|
|
586
667
|
this.scrollDuration,
|
|
587
668
|
);
|
|
588
|
-
this
|
|
669
|
+
this._monthScroller.position = currentPos;
|
|
589
670
|
window.requestAnimationFrame(smoothScroll);
|
|
590
671
|
} else {
|
|
591
672
|
this.dispatchEvent(
|
|
@@ -599,7 +680,7 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
599
680
|
}),
|
|
600
681
|
);
|
|
601
682
|
|
|
602
|
-
this
|
|
683
|
+
this._monthScroller.position = this._targetPosition;
|
|
603
684
|
this._targetPosition = undefined;
|
|
604
685
|
|
|
605
686
|
revealResolve();
|
|
@@ -694,26 +775,13 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
694
775
|
|
|
695
776
|
_translateXChanged(x) {
|
|
696
777
|
if (!this._desktopMode) {
|
|
697
|
-
this
|
|
698
|
-
this
|
|
778
|
+
this._monthScroller.style.transform = `translateX(${x - this._yearScrollerWidth}px)`;
|
|
779
|
+
this._yearScroller.style.transform = `translateX(${x}px)`;
|
|
699
780
|
}
|
|
700
781
|
}
|
|
701
782
|
|
|
702
|
-
_yearAfterXYears(index) {
|
|
703
|
-
const result = new Date(this._originDate);
|
|
704
|
-
result.setFullYear(parseInt(index) + this._originDate.getFullYear());
|
|
705
|
-
return result.getFullYear();
|
|
706
|
-
}
|
|
707
|
-
|
|
708
783
|
_yearAfterXMonths(months) {
|
|
709
|
-
return
|
|
710
|
-
}
|
|
711
|
-
|
|
712
|
-
_dateAfterXMonths(months) {
|
|
713
|
-
const result = new Date(this._originDate);
|
|
714
|
-
result.setDate(1);
|
|
715
|
-
result.setMonth(parseInt(months) + this._originDate.getMonth());
|
|
716
|
-
return result;
|
|
784
|
+
return dateAfterXMonths(months).getFullYear();
|
|
717
785
|
}
|
|
718
786
|
|
|
719
787
|
_differenceInMonths(date1, date2) {
|
|
@@ -817,7 +885,7 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
817
885
|
|
|
818
886
|
if (this.hasAttribute('fullscreen')) {
|
|
819
887
|
// Trap focus in the overlay
|
|
820
|
-
this
|
|
888
|
+
this.focusCancel();
|
|
821
889
|
} else {
|
|
822
890
|
this.__focusInput();
|
|
823
891
|
}
|
|
@@ -890,7 +958,11 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
|
|
|
890
958
|
// Wait for `vaadin-month-calendar` elements to be rendered
|
|
891
959
|
if (!this.calendars.length) {
|
|
892
960
|
await new Promise((resolve) => {
|
|
893
|
-
|
|
961
|
+
afterNextRender(this, () => {
|
|
962
|
+
// Force dom-repeat elements to render
|
|
963
|
+
flush();
|
|
964
|
+
resolve();
|
|
965
|
+
});
|
|
894
966
|
});
|
|
895
967
|
}
|
|
896
968
|
|
|
@@ -3,15 +3,26 @@
|
|
|
3
3
|
* Copyright (c) 2016 - 2022 Vaadin Ltd.
|
|
4
4
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
5
|
*/
|
|
6
|
-
import { DisableUpgradeMixin } from '@polymer/polymer/lib/mixins/disable-upgrade-mixin.js';
|
|
7
6
|
import { Overlay } from '@vaadin/overlay/src/vaadin-overlay.js';
|
|
8
7
|
import { PositionMixin } from '@vaadin/overlay/src/vaadin-overlay-position-mixin.js';
|
|
9
|
-
import { registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
10
|
-
import { datePickerOverlayStyles } from './vaadin-date-picker-styles.js';
|
|
8
|
+
import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
11
9
|
|
|
12
|
-
registerStyles(
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
registerStyles(
|
|
11
|
+
'vaadin-date-picker-overlay',
|
|
12
|
+
css`
|
|
13
|
+
[part='overlay'] {
|
|
14
|
+
display: flex;
|
|
15
|
+
flex: auto;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
[part~='content'] {
|
|
19
|
+
flex: auto;
|
|
20
|
+
}
|
|
21
|
+
`,
|
|
22
|
+
{
|
|
23
|
+
moduleId: 'vaadin-date-picker-overlay-styles',
|
|
24
|
+
},
|
|
25
|
+
);
|
|
15
26
|
|
|
16
27
|
let memoizedTemplate;
|
|
17
28
|
|
|
@@ -21,7 +32,7 @@ let memoizedTemplate;
|
|
|
21
32
|
* @extends Overlay
|
|
22
33
|
* @private
|
|
23
34
|
*/
|
|
24
|
-
class DatePickerOverlay extends
|
|
35
|
+
class DatePickerOverlay extends PositionMixin(Overlay) {
|
|
25
36
|
static get is() {
|
|
26
37
|
return 'vaadin-date-picker-overlay';
|
|
27
38
|
}
|