@vaadin/component-base 24.0.0-alpha7 → 24.0.0-alpha8

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.
Files changed (58) hide show
  1. package/package.json +2 -2
  2. package/src/a11y-announcer.d.ts +1 -1
  3. package/src/a11y-announcer.js +1 -1
  4. package/src/active-mixin.d.ts +1 -1
  5. package/src/active-mixin.js +1 -1
  6. package/src/browser-utils.js +7 -7
  7. package/src/controller-mixin.d.ts +1 -1
  8. package/src/controller-mixin.js +1 -1
  9. package/src/delegate-focus-mixin.d.ts +48 -0
  10. package/src/delegate-focus-mixin.js +228 -0
  11. package/src/delegate-state-mixin.d.ts +20 -0
  12. package/src/delegate-state-mixin.js +125 -0
  13. package/src/dir-mixin.d.ts +1 -5
  14. package/src/dir-mixin.js +1 -31
  15. package/src/dir-utils.d.ts +19 -0
  16. package/src/dir-utils.js +36 -0
  17. package/src/disabled-mixin.d.ts +1 -1
  18. package/src/disabled-mixin.js +1 -1
  19. package/src/dom-utils.d.ts +1 -1
  20. package/src/dom-utils.js +1 -1
  21. package/src/element-mixin.d.ts +1 -1
  22. package/src/element-mixin.js +11 -5
  23. package/src/focus-mixin.d.ts +1 -1
  24. package/src/focus-mixin.js +1 -1
  25. package/src/focus-trap-controller.d.ts +1 -1
  26. package/src/focus-trap-controller.js +1 -1
  27. package/src/focus-utils.d.ts +1 -1
  28. package/src/focus-utils.js +1 -1
  29. package/src/gestures.js +1 -1
  30. package/src/iron-list-core.js +32 -12
  31. package/src/keyboard-direction-mixin.d.ts +1 -1
  32. package/src/keyboard-direction-mixin.js +1 -1
  33. package/src/keyboard-mixin.d.ts +1 -1
  34. package/src/keyboard-mixin.js +1 -1
  35. package/src/list-mixin.d.ts +1 -1
  36. package/src/list-mixin.js +5 -6
  37. package/src/media-query-controller.d.ts +1 -1
  38. package/src/media-query-controller.js +1 -1
  39. package/src/overflow-controller.d.ts +1 -1
  40. package/src/overflow-controller.js +1 -1
  41. package/src/polylit-mixin.d.ts +1 -1
  42. package/src/polylit-mixin.js +9 -4
  43. package/src/resize-mixin.d.ts +1 -1
  44. package/src/resize-mixin.js +1 -1
  45. package/src/{slot-observe-controller.d.ts → slot-child-observe-controller.d.ts} +2 -2
  46. package/src/{slot-observe-controller.js → slot-child-observe-controller.js} +2 -2
  47. package/src/slot-controller.d.ts +1 -1
  48. package/src/slot-controller.js +1 -1
  49. package/src/tabindex-mixin.d.ts +1 -1
  50. package/src/tabindex-mixin.js +1 -1
  51. package/src/templates.js +1 -1
  52. package/src/tooltip-controller.d.ts +1 -1
  53. package/src/tooltip-controller.js +1 -1
  54. package/src/unique-id-utils.d.ts +1 -1
  55. package/src/unique-id-utils.js +1 -1
  56. package/src/virtualizer-iron-list-adapter.js +65 -9
  57. package/src/dir-helper.d.ts +0 -42
  58. package/src/dir-helper.js +0 -93
package/src/dom-utils.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2021 - 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
 
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2021 - 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 '../custom_typings/vaadin-usage-statistics.js';
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2021 - 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 { setCancelSyntheticClickEvents } from '@polymer/polymer/lib/utils/settings.js';
@@ -15,14 +15,20 @@ import { DirMixin } from './dir-mixin.js';
15
15
  // for buttons that are based on `[role=button]` e.g vaadin-button.
16
16
  setCancelSyntheticClickEvents(false);
17
17
 
18
- window.Vaadin ||= {};
18
+ if (!window.Vaadin) {
19
+ window.Vaadin = {};
20
+ }
19
21
 
20
22
  /**
21
23
  * Array of Vaadin custom element classes that have been finalized.
22
24
  */
23
- window.Vaadin.registrations ||= [];
25
+ if (!window.Vaadin.registrations) {
26
+ window.Vaadin.registrations = [];
27
+ }
24
28
 
25
- window.Vaadin.developmentModeCallback ||= {};
29
+ if (!window.Vaadin.developmentModeCallback) {
30
+ window.Vaadin.developmentModeCallback = {};
31
+ }
26
32
 
27
33
  window.Vaadin.developmentModeCallback['vaadin-usage-statistics'] = function () {
28
34
  usageStatistics();
@@ -39,7 +45,7 @@ const registered = new Set();
39
45
  export const ElementMixin = (superClass) =>
40
46
  class VaadinElementMixin extends DirMixin(superClass) {
41
47
  static get version() {
42
- return '24.0.0-alpha7';
48
+ return '24.0.0-alpha8';
43
49
  }
44
50
 
45
51
  /** @protected */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2021 - 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 type { Constructor } from '@open-wc/dedupe-mixin';
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2021 - 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 { dedupingMixin } from '@polymer/polymer/lib/utils/mixin.js';
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2021 - 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 type { ReactiveController } from 'lit';
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2021 - 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 { getFocusableElements, isElementFocused } from './focus-utils.js';
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2021 - 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
 
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2021 - 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
 
package/src/gestures.js CHANGED
@@ -90,7 +90,7 @@ function PASSIVE_TOUCH(eventName) {
90
90
  }
91
91
 
92
92
  // Check for touch-only devices
93
- const IS_TOUCH_ONLY = navigator.userAgent.match(/iP(?:[oa]d|hone)|Android/);
93
+ const IS_TOUCH_ONLY = navigator.userAgent.match(/iP(?:[oa]d|hone)|Android/u);
94
94
 
95
95
  // Defined at https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#enabling-and-disabling-form-controls:-the-disabled-attribute
96
96
  /** @type {!Object<boolean>} */
@@ -10,12 +10,22 @@
10
10
  import { animationFrame, idlePeriod, microTask } from './async.js';
11
11
  import { Debouncer, enqueueDebouncer, flush } from './debounce.js';
12
12
 
13
- const IOS = navigator.userAgent.match(/iP(?:hone|ad;(?: U;)? CPU) OS (\d+)/);
13
+ const IOS = navigator.userAgent.match(/iP(?:hone|ad;(?: U;)? CPU) OS (\d+)/u);
14
14
  const IOS_TOUCH_SCROLLING = IOS && IOS[1] >= 8;
15
15
  const DEFAULT_PHYSICAL_COUNT = 3;
16
16
 
17
17
  /**
18
- * @private
18
+ * DO NOT EDIT THIS FILE!
19
+ *
20
+ * This file includes the iron-list scrolling engine copied from
21
+ * https://github.com/PolymerElements/iron-list/blob/master/iron-list.js
22
+ *
23
+ * If something in the scrolling engine needs to be changed
24
+ * for the virtualizer's purposes, override a function
25
+ * in virtualizer-iron-list-adapter.js instead of changing it here.
26
+ *
27
+ * This will allow us to keep the iron-list code here as close to
28
+ * the original as possible.
19
29
  */
20
30
  export const ironList = {
21
31
  /**
@@ -491,9 +501,12 @@ export const ironList = {
491
501
  this._physicalIndexForKey = {};
492
502
  this._firstVisibleIndexVal = null;
493
503
  this._lastVisibleIndexVal = null;
494
- this._physicalCount ||= 0;
495
- this._physicalItems ||= [];
496
- this._physicalSizes ||= [];
504
+ if (!this._physicalItems) {
505
+ this._physicalItems = [];
506
+ }
507
+ if (!this._physicalSizes) {
508
+ this._physicalSizes = [];
509
+ }
497
510
  this._physicalStart = 0;
498
511
  if (this._scrollTop > this._scrollOffset) {
499
512
  this._resetScrollPosition(0);
@@ -635,16 +648,21 @@ export const ironList = {
635
648
  * @param {boolean=} forceUpdate If true, updates the height no matter what.
636
649
  */
637
650
  _updateScrollerSize(forceUpdate) {
638
- this._estScrollHeight =
651
+ const estScrollHeight =
639
652
  this._physicalBottom +
640
653
  Math.max(this._virtualCount - this._physicalCount - this._virtualStart, 0) * this._physicalAverage;
641
654
 
642
- forceUpdate ||= this._scrollHeight === 0;
643
- forceUpdate ||= this._scrollPosition >= this._estScrollHeight - this._physicalSize;
655
+ this._estScrollHeight = estScrollHeight;
656
+
644
657
  // Amortize height adjustment, so it won't trigger large repaints too often.
645
- if (forceUpdate || Math.abs(this._estScrollHeight - this._scrollHeight) >= this._viewportHeight) {
646
- this.$.items.style.height = `${this._estScrollHeight}px`;
647
- this._scrollHeight = this._estScrollHeight;
658
+ if (
659
+ forceUpdate ||
660
+ this._scrollHeight === 0 ||
661
+ this._scrollPosition >= estScrollHeight - this._physicalSize ||
662
+ Math.abs(estScrollHeight - this._scrollHeight) >= this._viewportHeight
663
+ ) {
664
+ this.$.items.style.height = `${estScrollHeight}px`;
665
+ this._scrollHeight = estScrollHeight;
648
666
  }
649
667
  },
650
668
 
@@ -740,7 +758,9 @@ export const ironList = {
740
758
  },
741
759
 
742
760
  _debounce(name, cb, asyncModule) {
743
- this._debouncers ||= {};
761
+ if (!this._debouncers) {
762
+ this._debouncers = {};
763
+ }
744
764
  this._debouncers[name] = Debouncer.debounce(this._debouncers[name], asyncModule, cb.bind(this));
745
765
  enqueueDebouncer(this._debouncers[name]);
746
766
  },
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2022 Vaadin Ltd.
3
+ * Copyright (c) 2022 - 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 type { Constructor } from '@open-wc/dedupe-mixin';
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2022 Vaadin Ltd.
3
+ * Copyright (c) 2022 - 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 { isElementFocused, isElementHidden } from './focus-utils.js';
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2021 - 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 type { Constructor } from '@open-wc/dedupe-mixin';
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2021 - 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 { dedupingMixin } from '@polymer/polymer/lib/utils/mixin.js';
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2017 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2017 - 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 type { Constructor } from '@open-wc/dedupe-mixin';
package/src/list-mixin.js CHANGED
@@ -1,12 +1,12 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2017 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2017 - 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 { FlattenedNodesObserver } from '@polymer/polymer/lib/utils/flattened-nodes-observer.js';
7
7
  import { timeOut } from './async.js';
8
8
  import { Debouncer } from './debounce.js';
9
- import { DirHelper } from './dir-helper.js';
9
+ import { getNormalizedScrollLeft, setNormalizedScrollLeft } from './dir-utils.js';
10
10
  import { KeyboardDirectionMixin } from './keyboard-direction-mixin.js';
11
11
 
12
12
  /**
@@ -213,7 +213,7 @@ export const ListMixin = (superClass) =>
213
213
  const key = event.key;
214
214
 
215
215
  const currentIdx = this.items.indexOf(this.focused);
216
- if (/[a-zA-Z0-9]/.test(key) && key.length === 1) {
216
+ if (/[a-zA-Z0-9]/u.test(key) && key.length === 1) {
217
217
  const idx = this._searchKey(currentIdx, key);
218
218
  if (idx >= 0) {
219
219
  this._focus(idx);
@@ -327,9 +327,8 @@ export const ListMixin = (superClass) =>
327
327
  this._scrollerElement.scrollTop += pixels;
328
328
  } else {
329
329
  const dir = this.getAttribute('dir') || 'ltr';
330
- const scrollType = DirHelper.detectScrollType();
331
- const scrollLeft = DirHelper.getNormalizedScrollLeft(scrollType, dir, this._scrollerElement) + pixels;
332
- DirHelper.setNormalizedScrollLeft(scrollType, dir, this._scrollerElement, scrollLeft);
330
+ const scrollLeft = getNormalizedScrollLeft(this._scrollerElement, dir) + pixels;
331
+ setNormalizedScrollLeft(this._scrollerElement, dir, scrollLeft);
333
332
  }
334
333
  }
335
334
 
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2021 - 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 type { ReactiveController } from 'lit';
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2021 - 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
 
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2021 - 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 type { ReactiveController } from 'lit';
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2021 - 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 { FlattenedNodesObserver } from '@polymer/polymer/lib/utils/flattened-nodes-observer.js';
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2021 - 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 type { Constructor } from '@open-wc/dedupe-mixin';
@@ -1,16 +1,18 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2021 - 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 { dedupeMixin } from '@open-wc/dedupe-mixin';
7
7
 
8
8
  const caseMap = {};
9
9
 
10
- const CAMEL_TO_DASH = /([A-Z])/g;
10
+ const CAMEL_TO_DASH = /([A-Z])/gu;
11
11
 
12
12
  function camelToDash(camel) {
13
- caseMap[camel] ||= camel.replace(CAMEL_TO_DASH, '-$1').toLowerCase();
13
+ if (!caseMap[camel]) {
14
+ caseMap[camel] = camel.replace(CAMEL_TO_DASH, '-$1').toLowerCase();
15
+ }
14
16
  return caseMap[camel];
15
17
  }
16
18
 
@@ -169,7 +171,10 @@ const PolylitMixinImplementation = (superclass) => {
169
171
  firstUpdated() {
170
172
  super.firstUpdated();
171
173
 
172
- this.$ ||= {};
174
+ if (!this.$) {
175
+ this.$ = {};
176
+ }
177
+
173
178
  this.shadowRoot.querySelectorAll('[id]').forEach((node) => {
174
179
  this.$[node.id] = node;
175
180
  });
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2021 - 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 type { Constructor } from '@open-wc/dedupe-mixin';
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2021 - 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 { dedupingMixin } from '@polymer/polymer/lib/utils/mixin.js';
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2022 Vaadin Ltd.
3
+ * Copyright (c) 2022 - 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 { SlotController } from './slot-controller.js';
@@ -9,7 +9,7 @@ import { SlotController } from './slot-controller.js';
9
9
  * A controller that observes slotted element mutations, especially ID attribute
10
10
  * and the text content, and fires an event to notify host element about those.
11
11
  */
12
- export class SlotObserveController extends SlotController {
12
+ export class SlotChildObserveController extends SlotController {
13
13
  /**
14
14
  * Setup the mutation observer on the node to update ID and notify host.
15
15
  * Node doesn't get observed automatically until this method is called.
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2022 Vaadin Ltd.
3
+ * Copyright (c) 2022 - 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 { SlotController } from './slot-controller.js';
@@ -9,7 +9,7 @@ import { SlotController } from './slot-controller.js';
9
9
  * A controller that observes slotted element mutations, especially ID attribute
10
10
  * and the text content, and fires an event to notify host element about those.
11
11
  */
12
- export class SlotObserveController extends SlotController {
12
+ export class SlotChildObserveController extends SlotController {
13
13
  constructor(host, slot, tagName, config = {}) {
14
14
  super(host, slot, tagName, { ...config, useUniqueId: true });
15
15
  }
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2021 - 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 type { ReactiveController } from 'lit';
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2021 - 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 { FlattenedNodesObserver } from '@polymer/polymer/lib/utils/flattened-nodes-observer.js';
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2021 - 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 type { Constructor } from '@open-wc/dedupe-mixin';
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2021 - 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 { DisabledMixin } from './disabled-mixin.js';
package/src/templates.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2021 - 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
 
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2022 Vaadin Ltd.
3
+ * Copyright (c) 2022 - 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 { SlotController } from './slot-controller.js';
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2022 Vaadin Ltd.
3
+ * Copyright (c) 2022 - 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 { SlotController } from './slot-controller.js';
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2021 - 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
 
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2021 - 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
 
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
3
+ * Copyright (c) 2021 - 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 { animationFrame, timeOut } from './async.js';
@@ -34,6 +34,7 @@ export class IronListAdapter {
34
34
  this.timeouts = {
35
35
  SCROLL_REORDER: 500,
36
36
  IGNORE_WHEEL: 500,
37
+ FIX_INVALID_ITEM_POSITIONING: 100,
37
38
  };
38
39
 
39
40
  this.__resizeObserver = new ResizeObserver(() => this._resizeHandler());
@@ -121,6 +122,9 @@ export class IronListAdapter {
121
122
  this._resizeHandler();
122
123
  flush();
123
124
  this._scrollHandler();
125
+ if (this.__fixInvalidItemPositioningDebouncer) {
126
+ this.__fixInvalidItemPositioningDebouncer.flush();
127
+ }
124
128
  if (this.__scrollReorderDebouncer) {
125
129
  this.__scrollReorderDebouncer.flush();
126
130
  }
@@ -184,6 +188,14 @@ export class IronListAdapter {
184
188
  if (size === this.size) {
185
189
  return;
186
190
  }
191
+ // Cancel active debouncers
192
+ if (this.__fixInvalidItemPositioningDebouncer) {
193
+ this.__fixInvalidItemPositioningDebouncer.cancel();
194
+ }
195
+ if (this._debouncers && this._debouncers._increasePoolIfNeeded) {
196
+ // Avoid creating unnecessary elements on the following flush()
197
+ this._debouncers._increasePoolIfNeeded.cancel();
198
+ }
187
199
 
188
200
  // Prevent element update while the scroll position is being restored
189
201
  this.__preventElementUpdates = true;
@@ -199,10 +211,6 @@ export class IronListAdapter {
199
211
  // Change the size
200
212
  this.__size = size;
201
213
 
202
- // Flush before invoking items change to avoid
203
- // creating excess elements on the following flush()
204
- flush();
205
-
206
214
  this._itemsChanged({
207
215
  path: 'items',
208
216
  });
@@ -344,6 +352,15 @@ export class IronListAdapter {
344
352
  }
345
353
  }
346
354
 
355
+ if (delta) {
356
+ // There was a change in scroll top. Schedule a check for invalid item positioning.
357
+ this.__fixInvalidItemPositioningDebouncer = Debouncer.debounce(
358
+ this.__fixInvalidItemPositioningDebouncer,
359
+ timeOut.after(this.timeouts.FIX_INVALID_ITEM_POSITIONING),
360
+ () => this.__fixInvalidItemPositioning(),
361
+ );
362
+ }
363
+
347
364
  if (this.reorderElements) {
348
365
  this.__scrollReorderDebouncer = Debouncer.debounce(
349
366
  this.__scrollReorderDebouncer,
@@ -355,9 +372,46 @@ export class IronListAdapter {
355
372
  this.__previousScrollTop = this._scrollTop;
356
373
 
357
374
  // If the first visible index is not 0 when scrolled to the top,
358
- // add some scroll offset to enable the user to continue scrolling.
359
- if (this._scrollTop === 0 && this.firstVisibleIndex !== 0) {
360
- this._scrollTop = 1;
375
+ // scroll to index 0 to fix the issue.
376
+ if (this._scrollTop === 0 && this.firstVisibleIndex !== 0 && Math.abs(delta) > 0) {
377
+ this.scrollToIndex(0);
378
+ }
379
+ }
380
+
381
+ /**
382
+ * Work around an iron-list issue with invalid item positioning.
383
+ * See https://github.com/vaadin/flow-components/issues/4306
384
+ * @private
385
+ */
386
+ __fixInvalidItemPositioning() {
387
+ if (!this.scrollTarget.isConnected) {
388
+ return;
389
+ }
390
+
391
+ // Check if the first physical item element is below the top of the viewport
392
+ const physicalTopBelowTop = this._physicalTop > this._scrollTop;
393
+ // Check if the last physical item element is above the bottom of the viewport
394
+ const physicalBottomAboveBottom = this._physicalBottom < this._scrollBottom;
395
+
396
+ // Check if the first index is visible
397
+ const firstIndexVisible = this.adjustedFirstVisibleIndex === 0;
398
+ // Check if the last index is visible
399
+ const lastIndexVisible = this.adjustedLastVisibleIndex === this.size - 1;
400
+
401
+ if ((physicalTopBelowTop && !firstIndexVisible) || (physicalBottomAboveBottom && !lastIndexVisible)) {
402
+ // Invalid state! Try to recover.
403
+
404
+ const isScrollingDown = physicalBottomAboveBottom;
405
+ // Set the "_ratio" property temporarily to 0 to make iron-list's _getReusables
406
+ // place all the free physical items on one side of the viewport.
407
+ const originalRatio = this._ratio;
408
+ this._ratio = 0;
409
+ // Fake a scroll change to make _scrollHandler place the physical items
410
+ // on the desired side.
411
+ this._scrollPosition = this._scrollTop + (isScrollingDown ? -1 : 1);
412
+ this._scrollHandler();
413
+ // Restore the original "_ratio" value.
414
+ this._ratio = originalRatio;
361
415
  }
362
416
  }
363
417
 
@@ -376,7 +430,9 @@ export class IronListAdapter {
376
430
  deltaY *= this._scrollPageHeight;
377
431
  }
378
432
 
379
- this._deltaYAcc ||= 0;
433
+ if (!this._deltaYAcc) {
434
+ this._deltaYAcc = 0;
435
+ }
380
436
 
381
437
  if (this._wheelAnimationFrame) {
382
438
  // Accumulate wheel delta while a frame is being processed