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