@cas-smartdesign/virtual-list 7.2.0 → 8.0.0
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/dist/data-provider.d.ts +3 -2
- package/dist/data-provider.d.ts.map +1 -0
- package/dist/docs/1_selection_types.js +1 -1
- package/dist/docs/2_lazy_load_with_search.js +1 -1
- package/dist/docs/3_duplicate_items.js +1 -1
- package/dist/docs/doc.css +1 -1
- package/dist/docs/doc.mjs +153 -148
- package/dist/docs/item-provider.mjs +1 -1
- package/dist/list-util.d.ts +1 -0
- package/dist/list-util.d.ts.map +1 -0
- package/dist/virtual-list.d.ts +13 -18
- package/dist/virtual-list.d.ts.map +1 -0
- package/dist/virtual-list.mjs +344 -356
- package/dist/virtual-list.mjs.map +1 -1
- package/npm-third-party-licenses.json +58 -108
- package/package.json +16 -15
- package/readme.md +2 -2
- package/dist/virtual-list-with-externals.js +0 -84
- package/dist/virtual-list-with-externals.js.map +0 -7
package/dist/virtual-list.mjs
CHANGED
|
@@ -1,363 +1,351 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
class
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
1
|
+
import e, { generator as t } from "@cas-smartdesign/list-item";
|
|
2
|
+
import { LitElement as n, css as r, html as i, unsafeCSS as a } from "lit";
|
|
3
|
+
import { property as o } from "lit/decorators/property.js";
|
|
4
|
+
var s = new class {
|
|
5
|
+
getOffsetForIndexAndAlignment(e, t, n, r, i, a) {
|
|
6
|
+
let o = Math.max(0, a * r), s = Math.min(o, e * r), c = Math.max(0, e * r - i + r);
|
|
7
|
+
switch (t) {
|
|
8
|
+
case "start": return s;
|
|
9
|
+
case "end": return c;
|
|
10
|
+
case "center": {
|
|
11
|
+
let e = Math.round(c + (s - c) / 2);
|
|
12
|
+
return e < Math.ceil(i / 2) ? 0 : e > o + Math.floor(i / 2) ? o : e;
|
|
13
|
+
}
|
|
14
|
+
default: return n >= c && n <= s ? n : n < c ? c : s;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
debounce(e) {
|
|
18
|
+
let t;
|
|
19
|
+
return (...n) => {
|
|
20
|
+
t && window.cancelAnimationFrame(t), t = window.requestAnimationFrame(() => {
|
|
21
|
+
e(...n), t = null;
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
}();
|
|
26
|
+
//#endregion
|
|
27
|
+
//#region \0@oxc-project+runtime@0.122.0/helpers/decorateMetadata.js
|
|
28
|
+
function c(e, t) {
|
|
29
|
+
if (typeof Reflect == "object" && typeof Reflect.metadata == "function") return Reflect.metadata(e, t);
|
|
29
30
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
get currentPage() {
|
|
39
|
-
return this.items.length == 0 && this.finalSizeIsKnown ? 0 : Math.floor((this.items.length - 1) / this.pageSize);
|
|
40
|
-
}
|
|
41
|
-
get finalSizeIsKnown() {
|
|
42
|
-
return this._finalSizeIsKnown;
|
|
43
|
-
}
|
|
44
|
-
set finalSizeIsKnown(t) {
|
|
45
|
-
this._finalSizeIsKnown = t, t && (this.itemCount = this._itemCache.length), this._list && (this._list.finalSizeIsKnown = t);
|
|
46
|
-
}
|
|
47
|
-
get itemCount() {
|
|
48
|
-
return this._itemCount;
|
|
49
|
-
}
|
|
50
|
-
set itemCount(t) {
|
|
51
|
-
this._itemCount = t, this._list && (this._list.itemCount = t);
|
|
52
|
-
}
|
|
53
|
-
get items() {
|
|
54
|
-
return this._itemCache;
|
|
55
|
-
}
|
|
56
|
-
set items(t) {
|
|
57
|
-
this._itemCache = t, this.onItemsChange();
|
|
58
|
-
}
|
|
59
|
-
addItems(t) {
|
|
60
|
-
this._itemCache = this._itemCache.concat(t), this.onItemsChange();
|
|
61
|
-
}
|
|
62
|
-
connectList(t) {
|
|
63
|
-
this._list && this._list.removeEventListener("data-request", this.handleListDataRequest), this._list = t, t.itemCount = this.itemCount, t.addEventListener("data-request", this.handleListDataRequest), t.finalSizeIsKnown = this._finalSizeIsKnown;
|
|
64
|
-
}
|
|
65
|
-
onItemsChange() {
|
|
66
|
-
this._pendingDataRequest = !1, this._lastLoadedIndex = this._itemCache.length - 1, this.finalSizeIsKnown ? this.itemCount = this._itemCache.length : this._lastLoadedIndex > this.itemCount && (this.itemCount = this._lastLoadedIndex), this._list && (this._list.items = this._itemCache.slice(this._lastRequestedFirstIndex, this._lastRequestedLastIndex + 1));
|
|
67
|
-
}
|
|
68
|
-
requestData() {
|
|
69
|
-
if (!this._pendingDataRequest)
|
|
70
|
-
if (this.onDataRequest)
|
|
71
|
-
this._pendingDataRequest = !0, this.onDataRequest(this.currentPage + 1), this._lastLoadedIndex += this.pageSize - 1, this._lastLoadedIndex > this.itemCount && (this.itemCount = this._lastLoadedIndex);
|
|
72
|
-
else
|
|
73
|
-
throw Error(
|
|
74
|
-
"The final size is not yet known and the list would require item data from index " + this._lastRequestedFirstIndex + ". to " + this._lastRequestedLastIndex + ". which is not possible to load without a configured onDataRequest"
|
|
75
|
-
);
|
|
76
|
-
}
|
|
31
|
+
//#endregion
|
|
32
|
+
//#region \0@oxc-project+runtime@0.122.0/helpers/decorate.js
|
|
33
|
+
function l(e, t, n, r) {
|
|
34
|
+
var i = arguments.length, a = i < 3 ? t : r === null ? r = Object.getOwnPropertyDescriptor(t, n) : r, o;
|
|
35
|
+
if (typeof Reflect == "object" && typeof Reflect.decorate == "function") a = Reflect.decorate(e, t, n, r);
|
|
36
|
+
else for (var s = e.length - 1; s >= 0; s--) (o = e[s]) && (a = (i < 3 ? o(a) : i > 3 ? o(t, n, a) : o(t, n)) || a);
|
|
37
|
+
return i > 3 && a && Object.defineProperty(t, n, a), a;
|
|
77
38
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
let
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
39
|
+
//#endregion
|
|
40
|
+
//#region data-provider.ts
|
|
41
|
+
var u = class {
|
|
42
|
+
constructor(e = 100, t = 5) {
|
|
43
|
+
this.pageSize = e, this.preloadedItemsCount = t, this._finalSizeIsKnown = !1, this._itemCache = [], this._lastRequestedFirstIndex = 0, this._lastRequestedLastIndex = 0, this._lastLoadedIndex = 0, this._pendingDataRequest = !1, this.handleListDataRequest = (e) => {
|
|
44
|
+
if (this._list == null) return;
|
|
45
|
+
let { startIndex: t, stopIndex: n } = e.detail;
|
|
46
|
+
this._lastRequestedFirstIndex = t, this._lastRequestedLastIndex = n, this._list.items = this._itemCache.slice(t, n + 1), !this.finalSizeIsKnown && this._lastLoadedIndex < n + this.preloadedItemsCount && this.requestData();
|
|
47
|
+
}, this._itemCount = e;
|
|
48
|
+
}
|
|
49
|
+
get currentPage() {
|
|
50
|
+
return this.items.length == 0 && this.finalSizeIsKnown ? 0 : Math.floor((this.items.length - 1) / this.pageSize);
|
|
51
|
+
}
|
|
52
|
+
get finalSizeIsKnown() {
|
|
53
|
+
return this._finalSizeIsKnown;
|
|
54
|
+
}
|
|
55
|
+
set finalSizeIsKnown(e) {
|
|
56
|
+
this._finalSizeIsKnown = e, e && (this.itemCount = this._itemCache.length), this._list && (this._list.finalSizeIsKnown = e);
|
|
57
|
+
}
|
|
58
|
+
get itemCount() {
|
|
59
|
+
return this._itemCount;
|
|
60
|
+
}
|
|
61
|
+
set itemCount(e) {
|
|
62
|
+
this._itemCount = e, this._list && (this._list.itemCount = e);
|
|
63
|
+
}
|
|
64
|
+
get items() {
|
|
65
|
+
return this._itemCache;
|
|
66
|
+
}
|
|
67
|
+
set items(e) {
|
|
68
|
+
this._itemCache = e, this.onItemsChange();
|
|
69
|
+
}
|
|
70
|
+
addItems(e) {
|
|
71
|
+
this._itemCache = this._itemCache.concat(e), this.onItemsChange();
|
|
72
|
+
}
|
|
73
|
+
connectList(e) {
|
|
74
|
+
this._list && this._list.removeEventListener("sd-virtual-list-data-request", this.handleListDataRequest), this._list = e, e.itemCount = this.itemCount, e.addEventListener("sd-virtual-list-data-request", this.handleListDataRequest), e.finalSizeIsKnown = this._finalSizeIsKnown;
|
|
75
|
+
}
|
|
76
|
+
onItemsChange() {
|
|
77
|
+
this._pendingDataRequest = !1, this._lastLoadedIndex = this._itemCache.length - 1, this.finalSizeIsKnown ? this.itemCount = this._itemCache.length : this._lastLoadedIndex > this.itemCount && (this.itemCount = this._lastLoadedIndex), this._list && (this._list.items = this._itemCache.slice(this._lastRequestedFirstIndex, this._lastRequestedLastIndex + 1));
|
|
78
|
+
}
|
|
79
|
+
requestData() {
|
|
80
|
+
if (!this._pendingDataRequest) if (this.onDataRequest) this._pendingDataRequest = !0, this.onDataRequest(this.currentPage + 1), this._lastLoadedIndex += this.pageSize - 1, this._lastLoadedIndex > this.itemCount && (this.itemCount = this._lastLoadedIndex);
|
|
81
|
+
else throw Error("The final size is not yet known and the list would require item data from index " + this._lastRequestedFirstIndex + ". to " + this._lastRequestedLastIndex + ". which is not possible to load without a configured onDataRequest");
|
|
82
|
+
}
|
|
83
|
+
}, d = ":host{contain:layout;--sd-virtual-list-focus-highlight-color:#1467ba;--sd-virtual-list-item-separator-color:#d9d9d9;display:block;position:relative}:host(:focus){outline:none}:host(:focus-visible) ::slotted([focused]){box-shadow:0 0 0 1px var(--sd-virtual-list-focus-highlight-color) inset}.container{width:100%}.container>::slotted(*){box-sizing:border-box;width:100%;position:absolute}.container>::slotted(:not([last])){border-bottom:1px solid var(--sd-virtual-list-item-separator-color)}", f, p = /* @__PURE__ */ function(e) {
|
|
84
|
+
return e.TriggerOnly = "trigger-only", e.Single = "single", e.Multi = "multi", e;
|
|
85
|
+
}({}), m = 0, h = class o extends n {
|
|
86
|
+
static {
|
|
87
|
+
this.ID = "sd-virtual-list";
|
|
88
|
+
}
|
|
89
|
+
static {
|
|
90
|
+
this.ensureDefined = () => {
|
|
91
|
+
e.ensureDefined(), customElements.get(o.ID) || customElements.define(o.ID, o);
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
get focusTarget() {
|
|
95
|
+
return this.hasAttribute("focus-target");
|
|
96
|
+
}
|
|
97
|
+
set focusTarget(e) {
|
|
98
|
+
this.toggleAttribute("focus-target", e);
|
|
99
|
+
}
|
|
100
|
+
get focusIndex() {
|
|
101
|
+
return this._focusIndex;
|
|
102
|
+
}
|
|
103
|
+
set focusIndex(e) {
|
|
104
|
+
if (e >= -1 && e < this.itemCount) {
|
|
105
|
+
let t = this._focusIndex;
|
|
106
|
+
this._focusIndex = e, (e <= this._firstVisibleIndex || this._lastVisibleIndex <= e) && this.scrollToItem(e), t != e && (e == -1 && this.removeAttribute("aria-activedescendant"), this.requestUpdate("focusIndex", t));
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
get selectedIndices() {
|
|
110
|
+
return this._selectedIndices;
|
|
111
|
+
}
|
|
112
|
+
set selectedIndices(e) {
|
|
113
|
+
e ? this._selectedIndices = e.map((e) => Number(e)) : this._selectedIndices = [], this.requestUpdate("selectedIndices");
|
|
114
|
+
}
|
|
115
|
+
scrollToItem(e, t = "auto") {
|
|
116
|
+
this.scrollTop = s.getOffsetForIndexAndAlignment(this.normalizeIndex(e), t, this.scrollTop, this.itemHeight, this.height, this.itemCount), this._lastKnownScrollTop = this.scrollTop;
|
|
117
|
+
}
|
|
118
|
+
getListItem(e) {
|
|
119
|
+
return !this.shadowRoot || e < this._firstVisibleIndex || this._lastVisibleIndex < e ? null : this.querySelector(`[item-index="${e}"]`);
|
|
120
|
+
}
|
|
121
|
+
constructor() {
|
|
122
|
+
super(), this.itemHeight = 50, this.itemCount = 0, this.items = [], this.selectionType = p.TriggerOnly, this.id = o.ID + "_" + m++, this.role = "listbox", this.itemGenerator = t, this._lastKnownScrollTop = 0, this._lastRenderedScrollTop = 0, this._itemsRenderData = [], this._elementCache = /* @__PURE__ */ new Map(), this._firstVisibleIndex = -1, this._lastVisibleIndex = -1, this._visibleItemsNum = 0, this._selectedIndices = [], this._focusIndex = -1, this._lastKnownHeight = 0, this.onScroll = () => {
|
|
123
|
+
this._lastKnownScrollTop = this.scrollTop;
|
|
124
|
+
let e = this._lastRenderedScrollTop - this._lastKnownScrollTop;
|
|
125
|
+
Math.abs(e) >= this.itemHeight && (this._lastRenderedScrollTop = this._lastKnownScrollTop, this.requestUpdate());
|
|
126
|
+
}, this.handleKeyDown = (e) => {
|
|
127
|
+
let t = !0;
|
|
128
|
+
switch (e.key) {
|
|
129
|
+
case "Down":
|
|
130
|
+
case "ArrowDown":
|
|
131
|
+
this.focusIndex = (this.focusIndex + 1) % this.itemCount;
|
|
132
|
+
break;
|
|
133
|
+
case "Up":
|
|
134
|
+
case "ArrowUp":
|
|
135
|
+
this.focusIndex > 0 ? this.focusIndex-- : this.finalSizeIsKnown && (this.focusIndex = this.itemCount - 1);
|
|
136
|
+
break;
|
|
137
|
+
case "Enter":
|
|
138
|
+
this.handleSelection(this.focusIndex, e);
|
|
139
|
+
break;
|
|
140
|
+
case "End":
|
|
141
|
+
this.focusIndex = this.itemCount - 1;
|
|
142
|
+
break;
|
|
143
|
+
case "PageDown":
|
|
144
|
+
this.focusIndex = this.normalizeIndex(this.focusIndex + this._visibleItemsNum - 1);
|
|
145
|
+
break;
|
|
146
|
+
case "Home":
|
|
147
|
+
this.focusIndex = 0;
|
|
148
|
+
break;
|
|
149
|
+
case "PageUp":
|
|
150
|
+
this.focusIndex = this.normalizeIndex(this.focusIndex - this._visibleItemsNum + 1);
|
|
151
|
+
break;
|
|
152
|
+
default:
|
|
153
|
+
t = !1;
|
|
154
|
+
break;
|
|
155
|
+
}
|
|
156
|
+
t && (e.preventDefault(), e.stopPropagation());
|
|
157
|
+
}, this.handleClick = (e) => {
|
|
158
|
+
let t = e.composedPath().find((e) => e instanceof HTMLElement && e.hasAttribute && e.hasAttribute("item-index"));
|
|
159
|
+
if (t) {
|
|
160
|
+
let n = t.getAttribute("item-index");
|
|
161
|
+
if (n != null) {
|
|
162
|
+
let t = parseInt(n);
|
|
163
|
+
Number.isInteger(t) && ((e.button == 0 || e.button == 1) && this.handleSelection(t, e), this.focusIndex = t);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}, this._resizeObserver = new ResizeObserver(() => {
|
|
167
|
+
this._lastKnownHeight !== this.offsetHeight && (this._lastKnownHeight = this.offsetHeight, this.requestUpdate());
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
connectedCallback() {
|
|
171
|
+
super.connectedCallback(), this._resizeObserver.observe(this), this.scrollTop !== this._lastKnownScrollTop && (this.scrollTop = this._lastKnownScrollTop, this.requestUpdate());
|
|
172
|
+
}
|
|
173
|
+
disconnectedCallback() {
|
|
174
|
+
super.disconnectedCallback(), this._resizeObserver.disconnect();
|
|
175
|
+
}
|
|
176
|
+
firstUpdated(e) {
|
|
177
|
+
super.firstUpdated(e), this.addEventListener("scroll", this.onScroll), this.addEventListener("keydown", this.handleKeyDown), this.addEventListener("click", this.handleClick), this.addEventListener("mousedown", (e) => {
|
|
178
|
+
e.button == 1 && e.preventDefault();
|
|
179
|
+
}), this.addEventListener("auxclick", this.handleClick), this.addEventListener("focus", () => {
|
|
180
|
+
this.matches(":focus-visible") && (this.focusIndex == -1 ? (this.selectedIndices && (this.focusIndex = this.selectedIndices[0] ?? -1), this.focusIndex == -1 && this.itemCount > 0 && (this.focusIndex = 0)) : this.updateFocusedItemAttributes());
|
|
181
|
+
}), this.addEventListener("blur", () => {
|
|
182
|
+
this.focusIndex != -1 && this.updateFocusedItemAttributes();
|
|
183
|
+
}), this.selectedIndices.length > 0 && this.scrollToItem(this.selectedIndices[0] ?? -1, "center");
|
|
184
|
+
}
|
|
185
|
+
updateFocusedItemAttributes() {
|
|
186
|
+
let e = this.getListItem(this.focusIndex);
|
|
187
|
+
e && (this.focusTarget || document.activeElement == this ? (e.setAttribute("focused", ""), this.setAttribute("aria-activedescendant", e.id)) : (e.removeAttribute("focused"), this.removeAttribute("aria-activedescendant")));
|
|
188
|
+
}
|
|
189
|
+
static get styles() {
|
|
190
|
+
return [r`
|
|
191
|
+
${a(d)}
|
|
192
|
+
`];
|
|
193
|
+
}
|
|
194
|
+
render() {
|
|
195
|
+
return this.updateItemsRenderData(), i`
|
|
189
196
|
<div class="container" style="height: ${this.itemCount * this.itemHeight}px">
|
|
190
197
|
<slot name="items"></slot>
|
|
191
198
|
</div>
|
|
192
199
|
`;
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
const i = this.getListItem(t);
|
|
306
|
-
if (i.getAttribute("aria-disabled") == "true" || i.hasAttribute("disabled"))
|
|
307
|
-
return;
|
|
308
|
-
let n = !0;
|
|
309
|
-
if (this.selectionType !== "trigger-only") {
|
|
310
|
-
const s = this.selectedIndices.indexOf(t);
|
|
311
|
-
n = s == -1, n ? this.selectionType === "single" ? this.selectedIndices = [t] : this.selectedIndices.push(t) : this.selectedIndices.splice(s, 1), this.requestUpdate("selectedIndices");
|
|
312
|
-
}
|
|
313
|
-
this.focusIndex = t, this.dispatchSelectionEvent(t, n, e);
|
|
314
|
-
}
|
|
315
|
-
dispatchSelectionEvent(t, e, i) {
|
|
316
|
-
this.dispatchEvent(
|
|
317
|
-
new CustomEvent("selection", {
|
|
318
|
-
detail: { index: t, selected: e, originalEvent: i }
|
|
319
|
-
})
|
|
320
|
-
);
|
|
321
|
-
}
|
|
322
|
-
handleClick(t) {
|
|
323
|
-
const e = t.composedPath().find((i) => i.hasAttribute && i.hasAttribute("item-index"));
|
|
324
|
-
if (e) {
|
|
325
|
-
const i = parseInt(e.getAttribute("item-index"));
|
|
326
|
-
Number.isInteger(i) && ((t.button == 0 || t.button == 1) && this.handleSelection(i, t), this.focusIndex = i);
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
}, a.ID = "sd-virtual-list", a.ensureDefined = () => {
|
|
330
|
-
f.ensureDefined(), customElements.get(a.ID) || customElements.define(a.ID, a);
|
|
331
|
-
}, a);
|
|
332
|
-
d([
|
|
333
|
-
l({ type: Number, attribute: "item-height", reflect: !0 })
|
|
334
|
-
], o.prototype, "itemHeight", 2);
|
|
335
|
-
d([
|
|
336
|
-
l({ type: Number })
|
|
337
|
-
], o.prototype, "itemCount", 2);
|
|
338
|
-
d([
|
|
339
|
-
l({ type: Array, attribute: !1 })
|
|
340
|
-
], o.prototype, "items", 2);
|
|
341
|
-
d([
|
|
342
|
-
l({ type: String, attribute: "selection-type", reflect: !0, noAccessor: !0 })
|
|
343
|
-
], o.prototype, "selectionType", 2);
|
|
344
|
-
d([
|
|
345
|
-
l({ type: String, attribute: !0, reflect: !0 })
|
|
346
|
-
], o.prototype, "id", 2);
|
|
347
|
-
d([
|
|
348
|
-
l({ type: String, reflect: !0 })
|
|
349
|
-
], o.prototype, "role", 2);
|
|
350
|
-
d([
|
|
351
|
-
l({ type: Number, attribute: "focus-index", reflect: !0 })
|
|
352
|
-
], o.prototype, "focusIndex", 1);
|
|
353
|
-
d([
|
|
354
|
-
l({ type: Array, attribute: !1 })
|
|
355
|
-
], o.prototype, "selectedIndices", 1);
|
|
356
|
-
let D = o;
|
|
357
|
-
D.ensureDefined();
|
|
358
|
-
export {
|
|
359
|
-
T as ListDataProvider,
|
|
360
|
-
y as SelectionType,
|
|
361
|
-
D as default
|
|
200
|
+
}
|
|
201
|
+
updated(e) {
|
|
202
|
+
super.updated(e), this._lastRenderedScrollTop = this._lastKnownScrollTop, this.updateItems(), (this._increaseWidthOnNextRenderIfNeeded || this._reachedMaxWidth) && this._firstVisibleIndex < this._lastVisibleIndex && this.adjustWidthIfNeeded();
|
|
203
|
+
}
|
|
204
|
+
adjustWidthIfNeeded() {
|
|
205
|
+
this._increaseWidthOnNextRenderIfNeeded ? (this._increaseWidthOnNextRenderIfNeeded = !1, window.requestAnimationFrame(() => {
|
|
206
|
+
let t = Number.parseInt(getComputedStyle(this).maxWidth) - this.offsetWidth;
|
|
207
|
+
if (t == 0) this._reachedMaxWidth = !0, this.enableLineClampOnItemsIfNeeded();
|
|
208
|
+
else {
|
|
209
|
+
this._reachedMaxWidth = !1;
|
|
210
|
+
let n = [...this.querySelectorAll("[item-index]")].map((n) => {
|
|
211
|
+
if (n instanceof e) {
|
|
212
|
+
n.enableLineClamp = !1;
|
|
213
|
+
let e = n.missingWidthForTexts;
|
|
214
|
+
return e > t && (n.enableLineClamp = !0), e;
|
|
215
|
+
}
|
|
216
|
+
let r = n.scrollWidth - n.clientWidth;
|
|
217
|
+
return r > 0 ? r + 1 : 0;
|
|
218
|
+
}), r = Math.max(...n);
|
|
219
|
+
r > 0 && (this.style.width = `${this.offsetWidth + r}px`);
|
|
220
|
+
}
|
|
221
|
+
})) : this._reachedMaxWidth && this.enableLineClampOnItemsIfNeeded();
|
|
222
|
+
}
|
|
223
|
+
enableLineClampOnItemsIfNeeded() {
|
|
224
|
+
this.querySelectorAll("[item-index]").forEach((t) => {
|
|
225
|
+
t instanceof e && (t.enableLineClamp = t.enableLineClamp || t.missingWidthForTexts > 0);
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Searches for list-items where there is a need for an additional width (ellipsis maybe shown) and increases the width of the list,
|
|
230
|
+
* therefore all the content is visible without tooltips. As it can be an expensive task to retrieve the required details, calling
|
|
231
|
+
* this function has an effect only on the very next render. Note that it only works if the virtual-list works with sd-list-item elements.
|
|
232
|
+
* If the maximum width is reached, line clamp is enabled on list items as a last resort approach to show the content if possible.
|
|
233
|
+
*/
|
|
234
|
+
increaseWidthOnNextRenderIfNeeded() {
|
|
235
|
+
this._increaseWidthOnNextRenderIfNeeded = !0;
|
|
236
|
+
}
|
|
237
|
+
updateItems() {
|
|
238
|
+
let t = [...this.querySelectorAll("[item-index]")], n = /* @__PURE__ */ new Map(), r = document.createDocumentFragment();
|
|
239
|
+
for (let e of this._itemsRenderData) {
|
|
240
|
+
let i = this.renderItem(e);
|
|
241
|
+
i.parentElement || r.appendChild(i), n.set(e.dataHash, i);
|
|
242
|
+
let a = t.indexOf(i);
|
|
243
|
+
a !== -1 && t.splice(a, 1);
|
|
244
|
+
}
|
|
245
|
+
this.appendChild(r);
|
|
246
|
+
for (let n of t) n instanceof e && (n.enableLineClamp = !1), this.removeChild(n);
|
|
247
|
+
n.forEach((e, t) => {
|
|
248
|
+
this._elementCache.set(t, e);
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
renderItem({ index: e, top: t, dataHash: n, data: r }) {
|
|
252
|
+
let i;
|
|
253
|
+
return r ? this._elementCache.has(n) ? (i = this._elementCache.get(n), this._elementCache.delete(n)) : (i = this.itemGenerator(r, e), i.setAttribute("slot", "items")) : (i = document.createElement("div"), i.setAttribute("placeholder-item", ""), i.setAttribute("slot", "items")), Object.assign(i.style, {
|
|
254
|
+
transform: `translateY(${t}px)`,
|
|
255
|
+
height: `${this.itemHeight}px`
|
|
256
|
+
}), i.setAttribute("item-index", e.toString()), i.setAttribute("aria-setsize", String(this.finalSizeIsKnown ? this.itemCount : -1)), i.setAttribute("aria-posinset", String(e + 1)), (!i.id || i.id.startsWith(this.id + "_item_")) && (i.id = this.id + "_item_" + e), this.itemCount - 1 == e ? i.setAttribute("last", "") : i.removeAttribute("last"), this.updateSelectedAttribute(e, i), this.updateFocusedAttribute(e, i), i;
|
|
257
|
+
}
|
|
258
|
+
updateFocusedAttribute(e, t) {
|
|
259
|
+
this.focusIndex == e && (this.focusTarget || document.activeElement == this) ? (t.setAttribute("focused", ""), this.setAttribute("aria-activedescendant", t.id)) : t.removeAttribute("focused");
|
|
260
|
+
}
|
|
261
|
+
updateSelectedAttribute(e, t) {
|
|
262
|
+
let n = this.selectedIndices.indexOf(e) !== -1;
|
|
263
|
+
n ? t.setAttribute("selected", "") : t.removeAttribute("selected"), t.setAttribute("aria-selected", String(n));
|
|
264
|
+
}
|
|
265
|
+
updateItemsRenderData() {
|
|
266
|
+
if (this._itemsRenderData = [], this._visibleItemsNum = Math.min(Math.ceil(this.height / this.itemHeight), this.itemCount), this._visibleItemsNum > 0) {
|
|
267
|
+
this._firstVisibleIndex = this.normalizeIndex(Math.floor(this._lastKnownScrollTop / this.itemHeight)), this._lastVisibleIndex = this.normalizeIndex(this._firstVisibleIndex + this._visibleItemsNum);
|
|
268
|
+
let e = this.normalizeIndex(this._firstVisibleIndex - 2), t = this.normalizeIndex(this._lastVisibleIndex + 2);
|
|
269
|
+
this.requestData(e, t);
|
|
270
|
+
for (let n = e; n <= t; n++) {
|
|
271
|
+
let t = n - e, r = this.items[t], i;
|
|
272
|
+
i = r ? JSON.stringify(r) : `placeholder-${t}`, this._itemsRenderData.push({
|
|
273
|
+
index: n,
|
|
274
|
+
top: this.itemHeight * n,
|
|
275
|
+
physicalIndex: t,
|
|
276
|
+
dataHash: i,
|
|
277
|
+
data: r
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
} else this._firstVisibleIndex = 0, this._lastVisibleIndex = 0;
|
|
281
|
+
}
|
|
282
|
+
normalizeIndex(e) {
|
|
283
|
+
return Math.max(0, Math.min(e, this.itemCount - 1));
|
|
284
|
+
}
|
|
285
|
+
get height() {
|
|
286
|
+
return this.offsetHeight;
|
|
287
|
+
}
|
|
288
|
+
requestData(e, t) {
|
|
289
|
+
!Number.isNaN(e) && !Number.isNaN(t) && this.dispatchEvent(new CustomEvent("sd-virtual-list-data-request", { detail: {
|
|
290
|
+
startIndex: e,
|
|
291
|
+
stopIndex: t
|
|
292
|
+
} }));
|
|
293
|
+
}
|
|
294
|
+
handleSelection(e, t) {
|
|
295
|
+
if (e < 0 || this.itemCount <= e) return;
|
|
296
|
+
let n = this.getListItem(e);
|
|
297
|
+
if (n == null || n.getAttribute("aria-disabled") == "true" || n.hasAttribute("disabled")) return;
|
|
298
|
+
let r = !0;
|
|
299
|
+
if (this.selectionType !== p.TriggerOnly) {
|
|
300
|
+
let t = this.selectedIndices.indexOf(e);
|
|
301
|
+
r = t == -1, r ? this.selectionType === p.Single ? this.selectedIndices = [e] : this.selectedIndices.push(e) : this.selectedIndices.splice(t, 1), this.requestUpdate("selectedIndices");
|
|
302
|
+
}
|
|
303
|
+
this.focusIndex = e, this.dispatchSelectionEvent(e, r, t);
|
|
304
|
+
}
|
|
305
|
+
dispatchSelectionEvent(e, t, n) {
|
|
306
|
+
this.dispatchEvent(new CustomEvent("sd-virtual-list-selection", { detail: {
|
|
307
|
+
index: e,
|
|
308
|
+
selected: t,
|
|
309
|
+
originalEvent: n
|
|
310
|
+
} }));
|
|
311
|
+
}
|
|
362
312
|
};
|
|
363
|
-
|
|
313
|
+
l([o({
|
|
314
|
+
type: Number,
|
|
315
|
+
attribute: "item-height",
|
|
316
|
+
reflect: !0
|
|
317
|
+
}), c("design:type", Number)], h.prototype, "itemHeight", void 0), l([o({ type: Number }), c("design:type", Number)], h.prototype, "itemCount", void 0), l([o({
|
|
318
|
+
type: Array,
|
|
319
|
+
attribute: !1
|
|
320
|
+
}), c("design:type", Array)], h.prototype, "items", void 0), l([o({
|
|
321
|
+
type: String,
|
|
322
|
+
attribute: "selection-type",
|
|
323
|
+
reflect: !0,
|
|
324
|
+
noAccessor: !0
|
|
325
|
+
}), c("design:type", typeof (f = p !== void 0 && p) == "function" ? f : Object)], h.prototype, "selectionType", void 0), l([o({
|
|
326
|
+
type: String,
|
|
327
|
+
attribute: !0,
|
|
328
|
+
reflect: !0
|
|
329
|
+
}), c("design:type", String)], h.prototype, "id", void 0), l([o({
|
|
330
|
+
type: String,
|
|
331
|
+
reflect: !0
|
|
332
|
+
}), c("design:type", Object)], h.prototype, "role", void 0), l([
|
|
333
|
+
o({
|
|
334
|
+
type: Number,
|
|
335
|
+
attribute: "focus-index",
|
|
336
|
+
reflect: !0
|
|
337
|
+
}),
|
|
338
|
+
c("design:type", Number),
|
|
339
|
+
c("design:paramtypes", [])
|
|
340
|
+
], h.prototype, "focusIndex", null), l([
|
|
341
|
+
o({
|
|
342
|
+
type: Array,
|
|
343
|
+
attribute: !1
|
|
344
|
+
}),
|
|
345
|
+
c("design:type", Array),
|
|
346
|
+
c("design:paramtypes", [])
|
|
347
|
+
], h.prototype, "selectedIndices", null), h.ensureDefined();
|
|
348
|
+
//#endregion
|
|
349
|
+
export { u as ListDataProvider, p as SelectionType, h as default };
|
|
350
|
+
|
|
351
|
+
//# sourceMappingURL=virtual-list.mjs.map
|