@vaadin/vaadin-date-picker 4.4.3 → 4.4.4

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 CHANGED
@@ -10,7 +10,7 @@
10
10
  "repository": "vaadin/vaadin-date-picker",
11
11
  "homepage": "https://vaadin.com/components",
12
12
  "name": "@vaadin/vaadin-date-picker",
13
- "version": "4.4.3",
13
+ "version": "4.4.4",
14
14
  "main": "vaadin-date-picker.js",
15
15
  "author": "Vaadin Ltd",
16
16
  "license": "Apache-2.0",
@@ -295,6 +295,18 @@ class DatePickerOverlayContentElement extends
295
295
  return this.getAttribute('dir') === 'rtl';
296
296
  }
297
297
 
298
+ /**
299
+ * Whether to scroll to a sub-month position when scrolling to a date.
300
+ * This is active if the month scroller is not large enough to fit a
301
+ * full month. In that case we want to scroll to a position between
302
+ * two months in order to have the focused date in the visible area.
303
+ * @returns {boolean} whether to use sub-month scrolling
304
+ * @private
305
+ */
306
+ get __useSubMonthScrolling() {
307
+ return this.$.monthScroller.clientHeight < this.$.monthScroller.itemHeight + this.$.monthScroller.bufferOffset;
308
+ }
309
+
298
310
  ready() {
299
311
  super.ready();
300
312
  this.setAttribute('tabindex', 0);
@@ -356,7 +368,9 @@ class DatePickerOverlayContentElement extends
356
368
  * Scrolls the list to the given Date.
357
369
  */
358
370
  scrollToDate(date, animate) {
359
- this._scrollToPosition(this._differenceInMonths(date, this._originDate), animate);
371
+ const offset = this.__useSubMonthScrolling ? this._calculateWeekScrollOffset(date) : 0;
372
+ this._scrollToPosition(this._differenceInMonths(date, this._originDate) + offset, animate);
373
+ this.$.monthScroller.forceUpdate();
360
374
  }
361
375
 
362
376
  _focusedDateChanged(focusedDate) {
@@ -377,23 +391,63 @@ class DatePickerOverlayContentElement extends
377
391
  * Scrolls the month and year scrollers enough to reveal the given date.
378
392
  */
379
393
  revealDate(date, animate = true) {
380
- if (date) {
381
- const diff = this._differenceInMonths(date, this._originDate);
382
- const scrolledAboveViewport = this.$.monthScroller.position > diff;
383
-
384
- const visibleArea = Math.max(
385
- this.$.monthScroller.itemHeight,
386
- this.$.monthScroller.clientHeight - this.$.monthScroller.bufferOffset * 2
387
- );
388
- const visibleItems = visibleArea / this.$.monthScroller.itemHeight;
389
- const scrolledBelowViewport = this.$.monthScroller.position + visibleItems - 1 < diff;
390
-
391
- if (scrolledAboveViewport) {
392
- this._scrollToPosition(diff, animate);
393
- } else if (scrolledBelowViewport) {
394
- this._scrollToPosition(diff - visibleItems + 1, animate);
394
+ if (!date) {
395
+ return;
396
+ }
397
+ const diff = this._differenceInMonths(date, this._originDate);
398
+ // If scroll area does not fit the full month, then always scroll with an offset to
399
+ // approximately display the week of the date
400
+ if (this.__useSubMonthScrolling) {
401
+ const offset = this._calculateWeekScrollOffset(date);
402
+ this._scrollToPosition(diff + offset, animate);
403
+ return;
404
+ }
405
+
406
+ // Otherwise determine if we need to scroll to make the month of the date visible
407
+ const scrolledAboveViewport = this.$.monthScroller.position > diff;
408
+
409
+ const visibleArea = Math.max(
410
+ this.$.monthScroller.itemHeight,
411
+ this.$.monthScroller.clientHeight - this.$.monthScroller.bufferOffset * 2
412
+ );
413
+ const visibleItems = visibleArea / this.$.monthScroller.itemHeight;
414
+ const scrolledBelowViewport = this.$.monthScroller.position + visibleItems - 1 < diff;
415
+
416
+ if (scrolledAboveViewport) {
417
+ this._scrollToPosition(diff, animate);
418
+ } else if (scrolledBelowViewport) {
419
+ this._scrollToPosition(diff - visibleItems + 1, animate);
420
+ }
421
+ }
422
+
423
+ /**
424
+ * Calculates an offset to be added to the month scroll position
425
+ * when using sub-month scrolling, in order ensure that the week
426
+ * that the date is in is visible even for small scroll areas.
427
+ * As the month scroller uses a month as minimal scroll unit
428
+ * (a value of `1` equals one month), we can not exactly identify
429
+ * the position of a specific week. This is a best effort
430
+ * implementation based on manual testing.
431
+ * @param date the date for which to calculate the offset
432
+ * @returns {number} the offset
433
+ * @private
434
+ */
435
+ _calculateWeekScrollOffset(date) {
436
+ // Get first day of month
437
+ const temp = new Date(0, 0);
438
+ temp.setFullYear(date.getFullYear());
439
+ temp.setMonth(date.getMonth());
440
+ temp.setDate(1);
441
+ // Determine week (=row index) of date within the month
442
+ let week = 0;
443
+ while (temp.getDate() < date.getDate()) {
444
+ temp.setDate(temp.getDate() + 1);
445
+ if (temp.getDay() === this.i18n.firstDayOfWeek) {
446
+ week += 1;
395
447
  }
396
448
  }
449
+ // Calculate magic number that approximately keeps the week visible
450
+ return week / 6;
397
451
  }
398
452
 
399
453
  _onOverlayFocus() {
@@ -147,7 +147,7 @@ class DatePickerElement extends
147
147
  }
148
148
 
149
149
  static get version() {
150
- return '4.4.3';
150
+ return '4.4.4';
151
151
  }
152
152
 
153
153
  static get properties() {
@@ -143,6 +143,18 @@ class InfiniteScrollerElement extends PolymerElement {
143
143
  }
144
144
  }
145
145
 
146
+ /**
147
+ * Force the scroller to update clones after a reset, without
148
+ * waiting for the debouncer to resolve.
149
+ */
150
+ forceUpdate() {
151
+ if (this._debouncerUpdateClones) {
152
+ this._buffers[0].updated = this._buffers[1].updated = false;
153
+ this._updateClones();
154
+ this._debouncerUpdateClones.cancel();
155
+ }
156
+ }
157
+
146
158
  _activated(active) {
147
159
  if (active && !this._initialized) {
148
160
  this._createPool();
@@ -36,7 +36,7 @@ const $_documentContainer = html`<dom-module id="lumo-date-picker-overlay-conten
36
36
  + var(--lumo-size-m) * 6
37
37
  + var(--lumo-space-s)
38
38
  );
39
- --vaadin-infinite-scroller-buffer-offset: 20%;
39
+ --vaadin-infinite-scroller-buffer-offset: 10%;
40
40
  -webkit-mask-image: linear-gradient(transparent, #000 10%, #000 85%, transparent);
41
41
  mask-image: linear-gradient(transparent, #000 10%, #000 85%, transparent);
42
42
  position: relative;