@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.
- package/package.json +2 -2
- package/src/a11y-announcer.d.ts +1 -1
- package/src/a11y-announcer.js +1 -1
- package/src/active-mixin.d.ts +1 -1
- package/src/active-mixin.js +1 -1
- package/src/browser-utils.js +7 -7
- package/src/controller-mixin.d.ts +1 -1
- package/src/controller-mixin.js +1 -1
- package/src/delegate-focus-mixin.d.ts +48 -0
- package/src/delegate-focus-mixin.js +228 -0
- package/src/delegate-state-mixin.d.ts +20 -0
- package/src/delegate-state-mixin.js +125 -0
- package/src/dir-mixin.d.ts +1 -5
- package/src/dir-mixin.js +1 -31
- package/src/dir-utils.d.ts +19 -0
- package/src/dir-utils.js +36 -0
- package/src/disabled-mixin.d.ts +1 -1
- package/src/disabled-mixin.js +1 -1
- package/src/dom-utils.d.ts +1 -1
- package/src/dom-utils.js +1 -1
- package/src/element-mixin.d.ts +1 -1
- package/src/element-mixin.js +11 -5
- package/src/focus-mixin.d.ts +1 -1
- package/src/focus-mixin.js +1 -1
- package/src/focus-trap-controller.d.ts +1 -1
- package/src/focus-trap-controller.js +1 -1
- package/src/focus-utils.d.ts +1 -1
- package/src/focus-utils.js +1 -1
- package/src/gestures.js +1 -1
- package/src/iron-list-core.js +32 -12
- package/src/keyboard-direction-mixin.d.ts +1 -1
- package/src/keyboard-direction-mixin.js +1 -1
- package/src/keyboard-mixin.d.ts +1 -1
- package/src/keyboard-mixin.js +1 -1
- package/src/list-mixin.d.ts +1 -1
- package/src/list-mixin.js +5 -6
- package/src/media-query-controller.d.ts +1 -1
- package/src/media-query-controller.js +1 -1
- package/src/overflow-controller.d.ts +1 -1
- package/src/overflow-controller.js +1 -1
- package/src/polylit-mixin.d.ts +1 -1
- package/src/polylit-mixin.js +9 -4
- package/src/resize-mixin.d.ts +1 -1
- package/src/resize-mixin.js +1 -1
- package/src/{slot-observe-controller.d.ts → slot-child-observe-controller.d.ts} +2 -2
- package/src/{slot-observe-controller.js → slot-child-observe-controller.js} +2 -2
- package/src/slot-controller.d.ts +1 -1
- package/src/slot-controller.js +1 -1
- package/src/tabindex-mixin.d.ts +1 -1
- package/src/tabindex-mixin.js +1 -1
- package/src/templates.js +1 -1
- package/src/tooltip-controller.d.ts +1 -1
- package/src/tooltip-controller.js +1 -1
- package/src/unique-id-utils.d.ts +1 -1
- package/src/unique-id-utils.js +1 -1
- package/src/virtualizer-iron-list-adapter.js +65 -9
- package/src/dir-helper.d.ts +0 -42
- package/src/dir-helper.js +0 -93
package/src/dom-utils.js
CHANGED
package/src/element-mixin.d.ts
CHANGED
package/src/element-mixin.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* Copyright (c) 2021 -
|
|
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-
|
|
48
|
+
return '24.0.0-alpha8';
|
|
43
49
|
}
|
|
44
50
|
|
|
45
51
|
/** @protected */
|
package/src/focus-mixin.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* Copyright (c) 2021 -
|
|
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';
|
package/src/focus-mixin.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* Copyright (c) 2021 -
|
|
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 -
|
|
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';
|
package/src/focus-utils.d.ts
CHANGED
package/src/focus-utils.js
CHANGED
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>} */
|
package/src/iron-list-core.js
CHANGED
|
@@ -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
|
-
*
|
|
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.
|
|
495
|
-
|
|
496
|
-
|
|
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
|
-
|
|
651
|
+
const estScrollHeight =
|
|
639
652
|
this._physicalBottom +
|
|
640
653
|
Math.max(this._virtualCount - this._physicalCount - this._virtualStart, 0) * this._physicalAverage;
|
|
641
654
|
|
|
642
|
-
|
|
643
|
-
|
|
655
|
+
this._estScrollHeight = estScrollHeight;
|
|
656
|
+
|
|
644
657
|
// Amortize height adjustment, so it won't trigger large repaints too often.
|
|
645
|
-
if (
|
|
646
|
-
|
|
647
|
-
this._scrollHeight
|
|
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 { isElementFocused, isElementHidden } from './focus-utils.js';
|
package/src/keyboard-mixin.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* Copyright (c) 2021 -
|
|
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';
|
package/src/keyboard-mixin.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* Copyright (c) 2021 -
|
|
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';
|
package/src/list-mixin.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* Copyright (c) 2017 -
|
|
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 -
|
|
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 {
|
|
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]
|
|
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
|
|
331
|
-
|
|
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 -
|
|
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';
|
package/src/polylit-mixin.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* Copyright (c) 2021 -
|
|
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';
|
package/src/polylit-mixin.js
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* Copyright (c) 2021 -
|
|
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])/
|
|
10
|
+
const CAMEL_TO_DASH = /([A-Z])/gu;
|
|
11
11
|
|
|
12
12
|
function camelToDash(camel) {
|
|
13
|
-
caseMap[camel]
|
|
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
|
});
|
package/src/resize-mixin.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* Copyright (c) 2021 -
|
|
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';
|
package/src/resize-mixin.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* Copyright (c) 2021 -
|
|
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
|
|
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
|
|
12
|
+
export class SlotChildObserveController extends SlotController {
|
|
13
13
|
constructor(host, slot, tagName, config = {}) {
|
|
14
14
|
super(host, slot, tagName, { ...config, useUniqueId: true });
|
|
15
15
|
}
|
package/src/slot-controller.d.ts
CHANGED
package/src/slot-controller.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* Copyright (c) 2021 -
|
|
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';
|
package/src/tabindex-mixin.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* Copyright (c) 2021 -
|
|
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';
|
package/src/tabindex-mixin.js
CHANGED
package/src/templates.js
CHANGED
package/src/unique-id-utils.d.ts
CHANGED
package/src/unique-id-utils.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* Copyright (c) 2021 -
|
|
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
|
-
//
|
|
359
|
-
if (this._scrollTop === 0 && this.firstVisibleIndex !== 0) {
|
|
360
|
-
this.
|
|
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
|
|
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
|