@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.
@@ -1,363 +1,351 @@
1
- import { LitElement as p, unsafeCSS as b, css as _, html as x } from "lit";
2
- import { property as l } from "lit/decorators/property.js";
3
- import f, { generator as g } from "@cas-smartdesign/list-item";
4
- class C {
5
- getOffsetForIndexAndAlignment(t, e, i, n, s, r) {
6
- const m = Math.max(0, r * n), u = Math.min(m, t * n), c = Math.max(0, t * n - s + n);
7
- switch (e) {
8
- case "start":
9
- return u;
10
- case "end":
11
- return c;
12
- case "center": {
13
- const I = Math.round(c + (u - c) / 2);
14
- return I < Math.ceil(s / 2) ? 0 : I > m + Math.floor(s / 2) ? m : I;
15
- }
16
- default:
17
- return i >= c && i <= u ? i : i < c ? c : u;
18
- }
19
- }
20
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
21
- debounce(t) {
22
- let e;
23
- return (...i) => {
24
- e && window.cancelAnimationFrame(e), e = window.requestAnimationFrame(() => {
25
- t(...i), e = null;
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
- const w = new C();
31
- class T {
32
- constructor(t = 100, e = 5) {
33
- this.pageSize = t, this.preloadedItemsCount = e, this._finalSizeIsKnown = !1, this._itemCache = [], this._lastRequestedFirstIndex = 0, this._lastRequestedLastIndex = 0, this._lastLoadedIndex = 0, this.handleListDataRequest = (i) => {
34
- const { startIndex: n, stopIndex: s } = i.detail;
35
- this._lastRequestedFirstIndex = n, this._lastRequestedLastIndex = s, this._list.items = this._itemCache.slice(n, s + 1), !this.finalSizeIsKnown && this._lastLoadedIndex < s + this.preloadedItemsCount && this.requestData();
36
- }, this.itemCount = t;
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
- const v = ":host{display:block;position:relative;contain:layout;--sd-virtual-list-focus-highlight-color: #1467ba;--sd-virtual-list-item-separator-color: #d9d9d9}: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(*){width:100%;position:absolute;box-sizing:border-box}.container>::slotted(:not([last])){border-bottom:1px solid var(--sd-virtual-list-item-separator-color)}";
79
- var S = Object.defineProperty, A = Object.getOwnPropertyDescriptor, d = (h, t, e, i) => {
80
- for (var n = i > 1 ? void 0 : i ? A(t, e) : t, s = h.length - 1, r; s >= 0; s--)
81
- (r = h[s]) && (n = (i ? r(t, e, n) : r(n)) || n);
82
- return i && n && S(t, e, n), n;
83
- }, y = /* @__PURE__ */ ((h) => (h.TriggerOnly = "trigger-only", h.Single = "single", h.Multi = "multi", h))(y || {});
84
- let L = 0;
85
- var a;
86
- const o = (a = class extends p {
87
- constructor() {
88
- super(), this.items = [], this.selectionType = "trigger-only", this.id = a.ID + "_" + L++, this.role = "listbox", this.itemGenerator = g, this._lastKnownScrollTop = 0, this._lastRenderedScrollTop = 0, this._itemsRenderData = [], this._elementCache = /* @__PURE__ */ new Map(), this._visibleItemsNum = 0, this._selectedIndices = [], this._focusIndex = -1, this._lastKnownHeight = 0, this.onScroll = () => {
89
- this._lastKnownScrollTop = this.scrollTop;
90
- const t = this._lastRenderedScrollTop - this._lastKnownScrollTop;
91
- Math.abs(t) >= this.itemHeight && (this._lastRenderedScrollTop = this._lastKnownScrollTop, this.requestUpdate());
92
- }, this.handleKeyDown = (t) => {
93
- let e = !0;
94
- switch (t.key) {
95
- case "Down":
96
- case "ArrowDown":
97
- this.focusIndex = (this.focusIndex + 1) % this.itemCount;
98
- break;
99
- case "Up":
100
- case "ArrowUp":
101
- this.focusIndex > 0 ? this.focusIndex-- : this.finalSizeIsKnown && (this.focusIndex = this.itemCount - 1);
102
- break;
103
- case "Enter":
104
- this.handleSelection(this.focusIndex, t);
105
- break;
106
- case "End":
107
- this.focusIndex = this.itemCount - 1;
108
- break;
109
- case "PageDown":
110
- this.focusIndex = this.normalizeIndex(this.focusIndex + this._visibleItemsNum - 1);
111
- break;
112
- case "Home":
113
- this.focusIndex = 0;
114
- break;
115
- case "PageUp":
116
- this.focusIndex = this.normalizeIndex(this.focusIndex - this._visibleItemsNum + 1);
117
- break;
118
- default:
119
- e = !1;
120
- break;
121
- }
122
- e && (t.preventDefault(), t.stopPropagation());
123
- }, this._resizeObserver = new ResizeObserver(() => {
124
- this._lastKnownHeight !== this.offsetHeight && (this._lastKnownHeight = this.offsetHeight, this.requestUpdate());
125
- });
126
- }
127
- get focusTarget() {
128
- return this.hasAttribute("focus-target");
129
- }
130
- set focusTarget(t) {
131
- this.toggleAttribute("focus-target", t);
132
- }
133
- get focusIndex() {
134
- return this._focusIndex;
135
- }
136
- set focusIndex(t) {
137
- if (t >= -1 && t < this.itemCount) {
138
- const e = this._focusIndex;
139
- this._focusIndex = t, (t <= this._firstVisibleIndex || this._lastVisibleIndex <= t) && this.scrollToItem(t), e != t && (t == -1 && this.removeAttribute("aria-activedescendant"), this.requestUpdate("focusIndex", e));
140
- }
141
- }
142
- get selectedIndices() {
143
- return this._selectedIndices;
144
- }
145
- set selectedIndices(t) {
146
- t ? this._selectedIndices = t.map((e) => Number(e)) : this._selectedIndices = [], this.requestUpdate("selectedIndices");
147
- }
148
- scrollToItem(t, e = "auto") {
149
- this.scrollTop = w.getOffsetForIndexAndAlignment(
150
- this.normalizeIndex(t),
151
- e,
152
- this.scrollTop,
153
- this.itemHeight,
154
- this.height,
155
- this.itemCount
156
- ), this._lastKnownScrollTop = this.scrollTop;
157
- }
158
- getListItem(t) {
159
- return !this.shadowRoot || t < this._firstVisibleIndex || this._lastVisibleIndex < t ? null : this.querySelector(`[item-index="${t}"]`);
160
- }
161
- connectedCallback() {
162
- super.connectedCallback(), this._resizeObserver.observe(this), this.scrollTop !== this._lastKnownScrollTop && (this.scrollTop = this._lastKnownScrollTop, this.requestUpdate());
163
- }
164
- disconnectedCallback() {
165
- super.disconnectedCallback(), this._resizeObserver.disconnect();
166
- }
167
- firstUpdated(t) {
168
- super.firstUpdated(t), this.addEventListener("scroll", this.onScroll), this.addEventListener("keydown", this.handleKeyDown), this.addEventListener("click", this.handleClick), this.addEventListener("mousedown", (e) => {
169
- e.button == 1 && e.preventDefault();
170
- }), this.addEventListener("auxclick", this.handleClick), this.addEventListener("focus", () => {
171
- this.matches(":focus-visible") && (this.focusIndex == -1 ? (this.selectedIndices && (this.focusIndex = this.selectedIndices[0]), this.focusIndex == -1 && this.itemCount > 0 && (this.focusIndex = 0)) : this.updateFocusedItemAttributes());
172
- }), this.addEventListener("blur", () => {
173
- this.focusIndex != -1 && this.updateFocusedItemAttributes();
174
- }), this.selectedIndices.length > 0 && this.scrollToItem(this.selectedIndices[0], "center");
175
- }
176
- updateFocusedItemAttributes() {
177
- const t = this.getListItem(this.focusIndex);
178
- t && (this.focusTarget || document.activeElement == this ? (t.setAttribute("focused", ""), this.setAttribute("aria-activedescendant", t.id)) : (t.removeAttribute("focused"), this.removeAttribute("aria-activedescendant")));
179
- }
180
- static get styles() {
181
- return [
182
- _`
183
- ${b(v)}
184
- `
185
- ];
186
- }
187
- render() {
188
- return this.updateItemsRenderData(), x`
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
- updated(t) {
195
- if (super.updated(t), this._lastRenderedScrollTop = this._lastKnownScrollTop, this.updateItems(), (this._increaseWidthOnNextRenderIfNeeded || this._reachedMaxWidth) && //
196
- this._firstVisibleIndex < this._lastVisibleIndex)
197
- if (this.querySelector("[item-index]"))
198
- this.adjustWidthIfNeeded();
199
- else {
200
- const e = new MutationObserver(() => {
201
- this.adjustWidthIfNeeded(), e.disconnect();
202
- });
203
- e.observe(this);
204
- }
205
- }
206
- adjustWidthIfNeeded() {
207
- this._increaseWidthOnNextRenderIfNeeded ? (this._increaseWidthOnNextRenderIfNeeded = !1, window.requestAnimationFrame(() => {
208
- const t = Number.parseInt(getComputedStyle(this).maxWidth) - this.offsetWidth;
209
- if (t == 0)
210
- this._reachedMaxWidth = !0, this.enableLineClampOnItemsIfNeeded();
211
- else {
212
- this._reachedMaxWidth = !1;
213
- const e = [...this.querySelectorAll("[item-index]")].map((n) => {
214
- if (n instanceof f) {
215
- n.enableLineClamp = !1;
216
- const s = n.missingWidthForTexts;
217
- return s > t && (n.enableLineClamp = !0), s;
218
- }
219
- }), i = Math.max(...e);
220
- i > 0 && (this.style.width = `${this.offsetWidth + i}px`);
221
- }
222
- })) : this._reachedMaxWidth && this.enableLineClampOnItemsIfNeeded();
223
- }
224
- enableLineClampOnItemsIfNeeded() {
225
- this.querySelectorAll("[item-index]").forEach((t) => {
226
- t instanceof f && (t.enableLineClamp = t.enableLineClamp || t.missingWidthForTexts > 0);
227
- });
228
- }
229
- /**
230
- * Searches for list-items where there is a need for an additional width (ellipsis maybe shown) and increases the width of the list,
231
- * therefore all the content is visible without tooltips. As it can be an expensive task to retrieve the required details, calling
232
- * 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.
233
- * If the maximum width is reached, line clamp is enabled on list items as a last resort approach to show the content if possible.
234
- */
235
- increaseWidthOnNextRenderIfNeeded() {
236
- this._increaseWidthOnNextRenderIfNeeded = !0;
237
- }
238
- updateItems() {
239
- const t = [...this.querySelectorAll("[item-index]")], e = /* @__PURE__ */ new Map(), i = document.createDocumentFragment();
240
- for (const n of this._itemsRenderData) {
241
- const s = this.renderItem(n);
242
- s.parentElement || i.appendChild(s), e.set(n.dataHash, s);
243
- const r = t.indexOf(s);
244
- r !== -1 && t.splice(r, 1);
245
- }
246
- this.appendChild(i);
247
- for (const n of t)
248
- n instanceof f && (n.enableLineClamp = !1), this.removeChild(n);
249
- e.forEach((n, s) => {
250
- this._elementCache.set(s, n);
251
- });
252
- }
253
- renderItem({ index: t, top: e, dataHash: i, data: n }) {
254
- let s;
255
- return n ? this._elementCache.has(i) ? (s = this._elementCache.get(i), this._elementCache.delete(i)) : (s = this.itemGenerator(n, t), s.setAttribute("slot", "items")) : (s = document.createElement("div"), s.setAttribute("placeholder-item", ""), s.setAttribute("slot", "items")), Object.assign(s.style, {
256
- transform: `translateY(${e}px)`,
257
- height: `${this.itemHeight}px`
258
- }), s.setAttribute("item-index", t.toString()), s.setAttribute("aria-setsize", String(this.finalSizeIsKnown ? this.itemCount : -1)), s.setAttribute("aria-posinset", String(t + 1)), (!s.id || s.id.startsWith(this.id + "_item_")) && (s.id = this.id + "_item_" + t), this.itemCount - 1 == t ? s.setAttribute("last", "") : s.removeAttribute("last"), this.updateSelectedAttribute(t, s), this.updateFocusedAttribute(t, s), s;
259
- }
260
- updateFocusedAttribute(t, e) {
261
- this.focusIndex == t && (this.focusTarget || document.activeElement == this) ? (e.setAttribute("focused", ""), this.setAttribute("aria-activedescendant", e.id)) : e.removeAttribute("focused");
262
- }
263
- updateSelectedAttribute(t, e) {
264
- const i = this.selectedIndices.indexOf(t) !== -1;
265
- i ? e.setAttribute("selected", "") : e.removeAttribute("selected"), e.setAttribute("aria-selected", String(i));
266
- }
267
- updateItemsRenderData() {
268
- if (this._itemsRenderData = [], this._visibleItemsNum = Math.min(Math.ceil(this.height / this.itemHeight), this.itemCount), this._visibleItemsNum > 0) {
269
- this._firstVisibleIndex = this.normalizeIndex(Math.floor(this._lastKnownScrollTop / this.itemHeight)), this._lastVisibleIndex = this.normalizeIndex(this._firstVisibleIndex + this._visibleItemsNum);
270
- const t = this.normalizeIndex(this._firstVisibleIndex - 2), e = this.normalizeIndex(this._lastVisibleIndex + 2);
271
- this.requestData(t, e);
272
- for (let i = t; i <= e; i++) {
273
- const n = i - t, s = this.items[n];
274
- let r;
275
- s ? r = JSON.stringify(s) : r = `placeholder-${n}`, this._itemsRenderData.push({
276
- index: i,
277
- top: this.itemHeight * i,
278
- physicalIndex: n,
279
- dataHash: r,
280
- data: s
281
- });
282
- }
283
- } else
284
- this._firstVisibleIndex = 0, this._lastVisibleIndex = 0;
285
- }
286
- normalizeIndex(t) {
287
- return Math.max(0, Math.min(t, this.itemCount - 1));
288
- }
289
- get height() {
290
- return this.offsetHeight;
291
- }
292
- requestData(t, e) {
293
- !Number.isNaN(t) && !Number.isNaN(e) && this.dispatchEvent(
294
- new CustomEvent("data-request", {
295
- detail: {
296
- startIndex: t,
297
- stopIndex: e
298
- }
299
- })
300
- );
301
- }
302
- handleSelection(t, e) {
303
- if (t < 0 || this.itemCount <= t)
304
- return;
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
- //# sourceMappingURL=virtual-list.mjs.map
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