@cas-smartdesign/token-selector 0.15.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.
@@ -0,0 +1,637 @@
1
+ import { LitElement as b, unsafeCSS as T, html as v, nothing as w } from "lit";
2
+ import { property as a } from "lit/decorators/property.js";
3
+ import "@cas-smartdesign/lit-input";
4
+ import E from "@cas-smartdesign/field-validation-message";
5
+ import { generator as S } from "@cas-smartdesign/list-item";
6
+ import _ from "@cas-smartdesign/popover";
7
+ import I from "@cas-smartdesign/list";
8
+ import { KeyDownDelegator as C } from "@cas-smartdesign/element-utils";
9
+ import { ifDefined as A } from "lit/directives/if-defined.js";
10
+ import { unsafeSVG as P } from "lit/directives/unsafe-svg.js";
11
+ import L from "@cas-smartdesign/image-tools";
12
+ class D {
13
+ constructor(e, t, i, s) {
14
+ this.inputElement = e, this.notSelectedTokensProvider = t, this.initializeCallback = s, this.filter = (n, o) => {
15
+ if (!n)
16
+ return !0;
17
+ if (o.disabled || o.deactivated)
18
+ return !1;
19
+ if (o.caption && o.caption.toLowerCase().includes(n))
20
+ return !0;
21
+ }, I.ensureDefined(), this._tokenList = new I(), this._tokenList.style.minWidth = "250px", this._tokenList.addEventListener("selection", (n) => {
22
+ const o = n.detail.index, c = this._suggestItems[o];
23
+ i(c), this.hide();
24
+ }), new C(this._tokenList, (n, o, c) => {
25
+ this._tokenList.dispatchEvent(new KeyboardEvent(n.type, n)), !c && !this.isOpened && this.show();
26
+ }).connect(e);
27
+ }
28
+ show() {
29
+ this.inputElement.effectiveDisabled || (this.popover, this._suggestItems = this.filterItems((this.inputElement.value || "").toLowerCase()), this._suggestItems.length == 0 ? this.hide() : (this._tokenList.items = this._suggestItems.map((e) => ({ ...e, contentMode: "text" })), this._tokenList.focusIndex = -1, Object.assign(this._tokenList.style, {
30
+ minWidth: `${Math.max(this.popover.targetElement.offsetWidth, 250)}px`
31
+ }), this.popover.show()));
32
+ }
33
+ refreshItems() {
34
+ this.isOpened && (this._suggestItems = this.filterItems((this.inputElement.value || "").toLowerCase()), this._suggestItems.length == 0 ? this.hide() : this._tokenList.items = this._suggestItems.map((e) => ({ ...e, contentMode: "text" })));
35
+ }
36
+ filterItems(e) {
37
+ const t = this.notSelectedTokensProvider();
38
+ return e ? t.filter((i) => this.filter(e, i)) : t;
39
+ }
40
+ hide() {
41
+ var e;
42
+ this._suggestItems = [], this._tokenList.items = [], (e = this._popover) == null || e.hide();
43
+ }
44
+ get list() {
45
+ return this._tokenList;
46
+ }
47
+ get popover() {
48
+ return this._popover || (this._popover = this.createPopover(), this.initializeCallback(this)), this._popover;
49
+ }
50
+ createPopover() {
51
+ const e = new _();
52
+ return e.setAttribute("trigger-type", "manual"), e.setAttribute("placement", "bottom-start"), e.setAttribute("modal", ""), e.setAttribute("popover-for", "token-autosuggest-popover"), e.setAttribute("offset", "-2"), e.targetElement = this.inputElement, e.appendChild(this._tokenList), e;
53
+ }
54
+ get isOpened() {
55
+ return this._popover && this._popover.hasAttribute("open");
56
+ }
57
+ get focusedSuggestToken() {
58
+ return this._suggestItems[this._tokenList.focusIndex];
59
+ }
60
+ }
61
+ const O = ":host{flex-shrink:0;max-width:100%}.container{display:flex;height:28px;background-color:var(--token-background-color, #f3f3f3);border:var(--token-border);box-sizing:border-box}.container .icon-wrapper{display:flex;flex-shrink:0;justify-content:center;align-items:center;width:28px;height:100%;overflow:hidden;background-color:var(--token-icon-background-color, transparent)}.container .icon-wrapper .icon{height:100%;width:100%;object-fit:contain;background-size:cover;background-repeat:no-repeat;background-position:center}.container .value{display:inline-block;align-self:center;padding:0 8px;font-family:Segoe UI,Lucida Sans,Arial,sans-serif;font-size:16px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.container .delete-button-wrapper{display:flex;align-self:center;height:16px;width:16px;padding-right:8px;opacity:.5}.container .delete-button-wrapper:hover{cursor:pointer;filter:brightness(10%);opacity:1}", M = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">\r
62
+ <path d="m3.5 12.5 9-9m-9 0 9 9" style="fill:none;stroke:#333;stroke-linecap:square;stroke-width:1.1px"/>\r
63
+ </svg>`;
64
+ var $ = Object.defineProperty, q = Object.getOwnPropertyDescriptor, g = (r, e, t, i) => {
65
+ for (var s = i > 1 ? void 0 : i ? q(e, t) : e, n = r.length - 1, o; n >= 0; n--)
66
+ (o = r[n]) && (s = (i ? o(e, t, s) : o(s)) || s);
67
+ return i && s && $(e, t, s), s;
68
+ };
69
+ const x = {
70
+ fromAttribute: (r) => r == "true",
71
+ toAttribute: (r) => r
72
+ };
73
+ var u;
74
+ const p = (u = class extends b {
75
+ constructor() {
76
+ super(...arguments), this.value = "", this.type = "", this.icon = "", this.iconPlaceholder = "", this.iconBackgroundColor = "", this._checked = !1;
77
+ }
78
+ static get styles() {
79
+ return T(O);
80
+ }
81
+ set checked(e) {
82
+ const t = this._checked;
83
+ this._checked = !this.disabled && e, this.requestUpdate("checked", t);
84
+ }
85
+ get checked() {
86
+ return this._checked;
87
+ }
88
+ firstUpdated(e) {
89
+ super.firstUpdated(e), this.tabIndex = -1, this.setAttribute("role", "option"), this.setAttribute("aria-selected", "true"), this.addEventListener("click", (i) => {
90
+ i.stopPropagation(), i.getModifierState("Control") ? this.checked = !this.checked : (this.checked = !0, this._tokenClickHandler && this._tokenClickHandler(this.index));
91
+ });
92
+ const t = this.shadowRoot.querySelector(".delete-button-wrapper");
93
+ t && t.addEventListener("click", (i) => {
94
+ i.stopPropagation(), this._tokenDeleteHandler && this._tokenDeleteHandler(this.index);
95
+ });
96
+ }
97
+ render() {
98
+ return v`
99
+ <div class="container">
100
+ <slot name="before-icon"></slot>
101
+ ${this.renderIcon()}
102
+ <slot name="after-icon"></slot>
103
+ <div class="value">${this.value}</div>
104
+ ${this.disabled ? w : v` <div class="delete-button-wrapper">${P(M)}</div> `}
105
+ </div>
106
+ `;
107
+ }
108
+ renderIcon() {
109
+ if (this.icon || this.iconPlaceholder) {
110
+ const e = this.iconBackgroundColor != null ? `--token-icon-background-color: ${this.iconBackgroundColor}` : void 0;
111
+ return v`
112
+ <div class="icon-wrapper" style="${A(e)}" role="img">
113
+ <div class="icon"></div>
114
+ </div>
115
+ `;
116
+ }
117
+ return w;
118
+ }
119
+ updated(e) {
120
+ super.updated(e), (e.has("icon") || e.has("iconPlaceholder")) && (this.icon || this.iconPlaceholder) && L.showImage(this.shadowRoot.querySelector(".icon"), this.icon, this.iconPlaceholder), e.has("disabled") && !this.disabled && this.checked && (this.checked = !1);
121
+ }
122
+ setClickHandler(e) {
123
+ this._tokenClickHandler = e;
124
+ }
125
+ setDeleteHandler(e) {
126
+ this._tokenDeleteHandler = e;
127
+ }
128
+ }, u.ID = "sd-token", u.ensureDefined = () => {
129
+ customElements.get(u.ID) || customElements.define(u.ID, u);
130
+ }, u);
131
+ g([
132
+ a({ type: String, attribute: !0, reflect: !0 })
133
+ ], p.prototype, "value", 2);
134
+ g([
135
+ a({ type: String, attribute: !0, reflect: !0 })
136
+ ], p.prototype, "type", 2);
137
+ g([
138
+ a({ type: String })
139
+ ], p.prototype, "icon", 2);
140
+ g([
141
+ a({ type: String })
142
+ ], p.prototype, "iconPlaceholder", 2);
143
+ g([
144
+ a({ type: String })
145
+ ], p.prototype, "iconBackgroundColor", 2);
146
+ g([
147
+ a({ converter: x, reflect: !0, attribute: "aria-disabled" })
148
+ ], p.prototype, "disabled", 2);
149
+ g([
150
+ a({ converter: x, reflect: !0, attribute: "aria-current" })
151
+ ], p.prototype, "current", 2);
152
+ g([
153
+ a({ converter: x, reflect: !0, attribute: "aria-checked" })
154
+ ], p.prototype, "checked", 1);
155
+ let k = p;
156
+ const G = (r, e) => {
157
+ const t = document.createElement(k.ID);
158
+ return r && (t.value = r.caption, t.type = r.type, t.icon = r.icon, t.iconPlaceholder = r.iconPlaceholder, t.iconBackgroundColor = r.iconBackgroundColor, t.disabled = r.disabled, t.index = e), t;
159
+ };
160
+ k.ensureDefined();
161
+ const m = "web application/json";
162
+ class B {
163
+ constructor(e, t, i) {
164
+ navigator.clipboard && (e.addEventListener("copy", () => {
165
+ t() || this.writeToClipboard(e);
166
+ }), e.addEventListener("cut", () => {
167
+ t() || (e.removeSelectionOrActiveToken(), this.writeToClipboard(e));
168
+ }), e.addEventListener("paste", () => {
169
+ e.disabled || this.readFromClipboard(i);
170
+ }));
171
+ }
172
+ writeToClipboard(e) {
173
+ const t = e.querySelectorAll("[slot='items'][aria-checked='true']"), i = [];
174
+ if (t.length > 0)
175
+ t.forEach((s) => i.push(s.index));
176
+ else if (e.activeTokenIndex != -1) {
177
+ const s = e.activeTokenElement;
178
+ s && i.push(s.index);
179
+ }
180
+ if (i.length > 0) {
181
+ const s = JSON.stringify(i.map((o) => e.items[o])), n = new Blob([s], { type: m });
182
+ navigator.clipboard.write([
183
+ new ClipboardItem({
184
+ [m]: n
185
+ })
186
+ ]);
187
+ }
188
+ }
189
+ async readFromClipboard(e) {
190
+ const t = await navigator.clipboard.read();
191
+ for (const i of t)
192
+ if (i.types.includes(m)) {
193
+ const n = await (await i.getType(m)).text(), o = JSON.parse(n);
194
+ Array.isArray(o) && e(o);
195
+ }
196
+ }
197
+ }
198
+ const F = ":host{display:flex;align-items:flex-end}:host .additonal-content::slotted(*){align-self:end;flex-shrink:0}:host([drop]) ::slotted(*){pointer-events:none}:host(:not([readonly])) ::slotted(sd-token:last-of-type){margin-right:24px;margin-bottom:4px}.container{display:flex;flex-wrap:wrap;gap:8px;flex-grow:1;min-width:0}.container .placeholder{color:#767676;line-height:24px;align-self:flex-end}.input{flex-grow:1;min-width:0;width:100%}.input .token-wrapper{display:flex;flex-wrap:wrap;flex:1 0 auto;width:100%;gap:8px}";
199
+ class H {
200
+ constructor(e, t) {
201
+ this.tokenSelector = e;
202
+ let i = [];
203
+ const s = (n) => {
204
+ const o = n.target;
205
+ e.contains(o) || e.removeTokens(i), i = [];
206
+ };
207
+ e.addEventListener("dragstart", (n) => {
208
+ const o = n.target;
209
+ if (o instanceof k) {
210
+ if (o.disabled) {
211
+ n.preventDefault();
212
+ return;
213
+ }
214
+ o.setAttribute("aria-checked", "true");
215
+ const c = e.querySelectorAll("[slot='items'][aria-checked='true']");
216
+ if (c.length > 0) {
217
+ const y = Array.from(c).filter((f) => !f.disabled).map((f) => (i.push(f.index), e.items[f.index]));
218
+ if (n.dataTransfer.setData("text/plain", JSON.stringify(y)), n.dataTransfer.dropEffect = "move", n.dataTransfer.effectAllowed = "move", c.length > 1) {
219
+ const f = this.createCustomDragImage(o, y.length);
220
+ n.dataTransfer.setDragImage(f, -14, -14);
221
+ }
222
+ window.addEventListener("drop", s, { capture: !0, once: !0 });
223
+ }
224
+ }
225
+ }), e.addEventListener("dragenter", (n) => {
226
+ e.setAttribute("drop", ""), n.preventDefault();
227
+ }), e.addEventListener("dragover", (n) => n.preventDefault()), e.addEventListener("dragleave", (n) => {
228
+ n.target == e && e.removeAttribute("drop");
229
+ }), e.addEventListener("drop", (n) => {
230
+ e.removeAttribute("drop");
231
+ const o = n.dataTransfer.getData("text/plain");
232
+ if (o)
233
+ try {
234
+ const c = JSON.parse(o);
235
+ Array.isArray(c) && (t(c), n.preventDefault());
236
+ } catch {
237
+ }
238
+ }), e.addEventListener("dragend", () => {
239
+ window.removeEventListener("drop", s), i = [];
240
+ });
241
+ }
242
+ createCustomDragImage(e, t) {
243
+ let i = e.cloneNode(!0);
244
+ if (i.setAttribute("aria-disabled", "true"), this.tokenSelector.tokenType)
245
+ i.value = t + " " + this.tokenSelector.tokenType;
246
+ else {
247
+ const s = document.createElement("div");
248
+ s.innerText = "+" + (t - 1), Object.assign(s.style, {
249
+ position: "absolute",
250
+ left: "90%",
251
+ top: "75%"
252
+ });
253
+ const n = document.createElement("div");
254
+ n.appendChild(i), n.appendChild(s), i = n;
255
+ }
256
+ return Object.assign(i.style, {
257
+ height: e.offsetHeight,
258
+ outline: "none",
259
+ maxWidth: "500px",
260
+ position: "absolute",
261
+ display: "block",
262
+ left: "-99999px",
263
+ overflow: "visible",
264
+ margin: "1px"
265
+ }), i.slot = "items", this.tokenSelector.appendChild(i), requestAnimationFrame(() => i.remove()), i;
266
+ }
267
+ }
268
+ var N = Object.defineProperty, j = Object.getOwnPropertyDescriptor, d = (r, e, t, i) => {
269
+ for (var s = i > 1 ? void 0 : i ? j(e, t) : e, n = r.length - 1, o; n >= 0; n--)
270
+ (o = r[n]) && (s = (i ? o(e, t, s) : o(s)) || s);
271
+ return i && s && N(e, t, s), s;
272
+ };
273
+ function K(r, e) {
274
+ let t;
275
+ return function(...i) {
276
+ t != null && clearTimeout(t), t = window.setTimeout(() => r(...i), e);
277
+ };
278
+ }
279
+ var R = /* @__PURE__ */ ((r) => (r.RemoveOnly = "remove-only", r.Multi = "multi", r))(R || {}), h;
280
+ const l = (h = class extends b {
281
+ constructor() {
282
+ super(...arguments), this.selectionMode = "multi", this.items = [], this.selectedIndexes = [], this._tokenGenerator = G, this._autoSuggestItemGenerator = S, this.additionalTokenCommittingKeys = [], this._activeTokenIndex = -1, this.handleInputKeyDown = (e, t) => {
283
+ if ((e.key === "Enter" || this.additionalTokenCommittingKeys.includes(e.key)) && t.value) {
284
+ e.preventDefault(), e.stopPropagation(), this.commitTokenValue(t.value);
285
+ return;
286
+ }
287
+ switch (e.key) {
288
+ case "Escape": {
289
+ e.preventDefault(), e.stopPropagation(), this.tokenSuggestPopover.hide();
290
+ break;
291
+ }
292
+ case "Tab": {
293
+ this.commitTokenValue(t.value), this.tokenSuggestPopover.hide();
294
+ break;
295
+ }
296
+ default:
297
+ this.handleKeyDown(e);
298
+ }
299
+ }, this.handleKeyDown = (e) => {
300
+ switch (e.key) {
301
+ case "ArrowLeft": {
302
+ this.hasInputValue || this.updateActiveToken(-1);
303
+ break;
304
+ }
305
+ case "ArrowRight": {
306
+ this.hasInputValue || this.updateActiveToken(1);
307
+ break;
308
+ }
309
+ case "Enter": {
310
+ if (!this.hasInputValue && this.activeTokenIndex != -1) {
311
+ const t = this.activeTokenElement;
312
+ e.getModifierState("Control") ? t.checked = !t.checked : (t.checked = !0, this.onTokenClick(t, !1)), document.activeElement != this && this.focus();
313
+ }
314
+ break;
315
+ }
316
+ case "Backspace": {
317
+ this.hasInputValue || (this.activeTokenIndex == -1 ? this.updateActiveToken(-1) : this.removeSelectionOrActiveToken());
318
+ break;
319
+ }
320
+ case "Clear":
321
+ case "Delete": {
322
+ this.removeSelectionOrActiveToken();
323
+ break;
324
+ }
325
+ case "a": {
326
+ !this.hasInputValue && e.getModifierState("Control") && (this.querySelectorAll("[slot='items']").forEach((t) => t.checked = !0), e.preventDefault(), e.stopPropagation());
327
+ break;
328
+ }
329
+ }
330
+ }, this.handleWindowPointerDown = (e) => {
331
+ const t = this.inputElement;
332
+ if (!t || !t.value)
333
+ return;
334
+ e.composedPath().some((s) => {
335
+ if (s instanceof HTMLElement && (e.composedPath().indexOf(t) > -1 || s.getAttribute("popover-for") === "token-autosuggest-popover"))
336
+ return !0;
337
+ }) || this.commitTokenValue(t.value);
338
+ }, this.debouncedShowTokenSuggestPopover = K(this.showFilteredTokenSuggestions.bind(this), 200);
339
+ }
340
+ static get styles() {
341
+ return T(F);
342
+ }
343
+ get tokenGenerator() {
344
+ return this._tokenGenerator;
345
+ }
346
+ set tokenGenerator(e) {
347
+ this._tokenGenerator = e, this.render();
348
+ }
349
+ get autoSuggestItemGenerator() {
350
+ return this._autoSuggestItemGenerator;
351
+ }
352
+ set autoSuggestItemGenerator(e) {
353
+ this._autoSuggestItemGenerator = e, this._tokenSuggestPopover && (this._tokenSuggestPopover.list.itemGenerator = e);
354
+ }
355
+ setAdditionalTokenCommittingKeys(e) {
356
+ this.additionalTokenCommittingKeys = e;
357
+ }
358
+ openSuggestions() {
359
+ this.inputElement && (this.focus(), this.tokenSuggestPopover.show());
360
+ }
361
+ focus() {
362
+ this.inputElement ? this.inputElement.focus() : this.shadowRoot.querySelector(".container").focus();
363
+ }
364
+ render() {
365
+ return this.selectionMode == "remove-only" ? v`<div class="container" tabindex="0">
366
+ <slot name="items"
367
+ >${this.placeholder ? v`<span part="remove-only-placeholder" class="placeholder"
368
+ >${this.placeholder}</span
369
+ >` : w}</slot
370
+ >
371
+ </div>
372
+ <slot class="additonal-content" name="additional-content"></slot>` : v`
373
+ <sd-lit-input
374
+ class="input"
375
+ .extendedPrefix=${!0}
376
+ .label=${this.inputLabel}
377
+ .validationLevel=${this.validationLevel}
378
+ .validationIconSrc=${this.validationIconSrc}
379
+ .validationMessage=${this.validationMessage}
380
+ .alwaysFloatLabel=${this.selectedIndexes.length > 0}
381
+ .placeholder=${this.selectedIndexes.length == 0 ? this.placeholder : ""}
382
+ .disabled=${this.disabled}
383
+ tabindex="0"
384
+ ><div class="token-wrapper" slot="prefix"><slot name="items"></slot></div>
385
+ </sd-lit-input>
386
+ <slot class="additonal-content" name="additional-content"></slot>
387
+ `;
388
+ }
389
+ firstUpdated(e) {
390
+ super.firstUpdated(e), this.setAttribute("role", "listbox"), this.setAttribute("aria-multiselectable", "true"), this.hasAttribute("tabIndex") || (this.tabIndex = 0), this.addEventListener("focusout", (t) => {
391
+ const i = t.relatedTarget;
392
+ !this.contains(i) && !this.shadowRoot.contains(i) && this.querySelectorAll("[slot='items'][aria-checked='true']").forEach(
393
+ (s) => s.checked = !1
394
+ );
395
+ }), new B(
396
+ this,
397
+ () => {
398
+ var t;
399
+ return (t = this.inputElement) == null ? void 0 : t.value;
400
+ },
401
+ (t) => this.addMatchingItems(t)
402
+ ), new H(this, (t) => this.addMatchingItems(t));
403
+ }
404
+ addMatchingItems(e) {
405
+ const t = e.map((i) => {
406
+ const s = i.caption == null ? -1 : this.findIndex(i);
407
+ return s != -1 && !this.items[s].disabled && !this.selectedIndexes.includes(s) ? s : -1;
408
+ }).filter((i) => i != -1);
409
+ t.length > 0 && this.handleTokenSelection(t);
410
+ }
411
+ removeSelectionOrActiveToken() {
412
+ if (!this.disabled) {
413
+ const e = this.querySelectorAll("[slot='items'][aria-checked='true']");
414
+ if (e.length > 0) {
415
+ const t = Array.from(e);
416
+ this.removeTokens(t.filter((i) => !i.disabled).map((i) => i.index));
417
+ } else if (this.activeTokenIndex != -1) {
418
+ const t = this.activeTokenElement;
419
+ t && !t.disabled && this.removeTokens([t.index]);
420
+ }
421
+ }
422
+ }
423
+ updateActiveToken(e) {
424
+ const t = this.querySelectorAll("[slot='items']").length - 1;
425
+ this.activeTokenIndex == -1 ? e < 0 && (this.activeTokenIndex = t) : this.activeTokenIndex == t && e > 0 ? (this.activeTokenIndex = -1, this.focus()) : this.activeTokenIndex = Math.max(0, Math.min(t, this.activeTokenIndex + e));
426
+ }
427
+ commitTokenValue(e) {
428
+ if (this.disabled)
429
+ return;
430
+ if (this.tokenSuggestPopover.isOpened) {
431
+ const i = this.tokenSuggestPopover.focusedSuggestToken;
432
+ if (i) {
433
+ if (!i.disabled) {
434
+ const s = this.findIndex(i);
435
+ this.handleTokenSelection([s]), this.tokenSuggestPopover.hide();
436
+ }
437
+ return;
438
+ }
439
+ }
440
+ if (!(e != null && e.trim()))
441
+ return;
442
+ const t = this.items.findIndex(
443
+ (i) => this.caseSensitive ? i.caption == e : i.caption.toLowerCase() == e.toLowerCase()
444
+ );
445
+ this.selectedIndexes.includes(t) || (t >= 0 ? this.handleTokenSelection([t]) : this.handleTokenCreation(e)), this.requestUpdate("selectedIndexes"), this.tokenSuggestPopover.hide(), window.removeEventListener("pointerdown", this.handleWindowPointerDown);
446
+ }
447
+ updated(e) {
448
+ if (super.updated(e), this._tokenSuggestPopover && (this.tokenSuggestPopover.list.className = this.suggestListClass || "", this.suggestionFilter && (this.tokenSuggestPopover.filter = this.suggestionFilter)), e.has("selectionMode"))
449
+ if (this.selectionMode == "multi") {
450
+ this.setAttribute("aria-haspopup", "listbox");
451
+ const t = this.inputElement;
452
+ t.addEventListener("immediate-value-change", (i) => this.handleInputValueChange(i)), t.addEventListener("keydown", (i) => this.handleInputKeyDown(i, t)), window.queueMicrotask(() => this.tokenSuggestPopover);
453
+ } else
454
+ this.removeAttribute("aria-haspopup"), this.addEventListener("keydown", this.handleKeyDown), this._tokenSuggestPopover && (this._tokenSuggestPopover.popover.remove(), this._tokenSuggestPopover = null);
455
+ (e.size == 0 || e.has("selectionMode") || e.has("items") || e.has("selectedIndexes") || e.has("disabled")) && this.updateItems();
456
+ }
457
+ handleInputValueChange(e) {
458
+ e.detail.value ? (this.activeTokenIndex = -1, this.cancelSearch = !1, this.debouncedShowTokenSuggestPopover(), window.addEventListener("pointerdown", this.handleWindowPointerDown)) : (this.tokenSuggestPopover.hide(), this.cancelSearch = !0);
459
+ }
460
+ showFilteredTokenSuggestions() {
461
+ !this.cancelSearch && this.inputElement.value && this.tokenSuggestPopover.show();
462
+ }
463
+ isTokenNotSelected(e) {
464
+ return !this.selectedIndexes.includes(e);
465
+ }
466
+ get tokenSuggestPopover() {
467
+ return !this._tokenSuggestPopover && this.inputElement && (this._tokenSuggestPopover = new D(
468
+ this.inputElement,
469
+ () => this.items.filter((e, t) => !e.disabled && this.isTokenNotSelected(t)),
470
+ (e) => {
471
+ const t = this.findIndex(e);
472
+ this.handleTokenSelection([t]), window.removeEventListener("pointerdown", this.handleWindowPointerDown);
473
+ },
474
+ (e) => {
475
+ this.appendChild(e.popover), this.dispatchEvent(new CustomEvent("auto-suggest-initialized")), e.popover.addEventListener("close", () => {
476
+ this.inputElement.value && !this.contains(document.activeElement) && (this.inputElement.value = "");
477
+ });
478
+ }
479
+ ), this._tokenSuggestPopover.list.itemGenerator = this._autoSuggestItemGenerator, this._tokenSuggestPopover.list.className = this.suggestListClass, this.suggestionFilter && (this._tokenSuggestPopover.filter = this.suggestionFilter)), this._tokenSuggestPopover;
480
+ }
481
+ updateItems() {
482
+ if (!this.isConnected || !this.items)
483
+ return;
484
+ const e = this.inputElement;
485
+ e && (!this._tokenSuggestPopover || !this._tokenSuggestPopover.isOpened) && (e.value = ""), this.querySelectorAll("[slot='items']").forEach((s) => {
486
+ this.removeChild(s);
487
+ });
488
+ const t = document.createDocumentFragment();
489
+ let i = [];
490
+ this.selectionMode == "remove-only" ? i = this.items.map((s) => this.disableIfNeeded(s)) : this.selectedIndexes.forEach((s) => {
491
+ i.push(this.disableIfNeeded(this.items[s]));
492
+ }), i.forEach((s) => {
493
+ const n = this.tokenGenerator(s, this.findIndex(s));
494
+ n.slot = "items", t.appendChild(n), n.id || (n.id = window.crypto.getRandomValues(new Uint32Array(1))[0].toString(16)), n.setClickHandler(() => this.onTokenClick(n, !0)), n.addEventListener("click", () => {
495
+ document.activeElement != this && this.focus();
496
+ }), n.setDeleteHandler((o) => this.removeTokens([o]));
497
+ }), this.appendChild(t), this._tokenSuggestPopover && this._tokenSuggestPopover.refreshItems();
498
+ }
499
+ removeTokens(e) {
500
+ this.disabled || (this.activeTokenIndex != -1 && e.includes(this.activeTokenElement.index) && (this.activeTokenIndex = -1), this.selectionMode == "remove-only" ? this.dispatchEvent(
501
+ new CustomEvent("tokens-removed", {
502
+ detail: {
503
+ removedIndices: e
504
+ }
505
+ })
506
+ ) : (this.selectedIndexes = this.selectedIndexes.filter((t) => !e.includes(t)), this.dispatchEvent(
507
+ new CustomEvent("tokens-removed", {
508
+ detail: {
509
+ removedIndices: e,
510
+ selectedIndices: [...this.selectedIndexes]
511
+ }
512
+ })
513
+ )));
514
+ }
515
+ onTokenClick(e, t) {
516
+ let i;
517
+ this.querySelectorAll("[slot='items']").forEach((s, n) => {
518
+ e == s ? i = n : s.setAttribute("aria-checked", "false");
519
+ }), this.activeTokenIndex = i, this.setAttribute("aria-activedescendant", this.activeTokenElement.id), this._tokenSuggestPopover && this._tokenSuggestPopover.isOpened && this._tokenSuggestPopover.hide(), this.dispatchEvent(
520
+ new CustomEvent("token-clicked", {
521
+ detail: {
522
+ index: e.index,
523
+ tokenElement: e,
524
+ byPointerDevice: t
525
+ }
526
+ })
527
+ );
528
+ }
529
+ disableIfNeeded(e) {
530
+ return this.disabled ? { ...e, disabled: !0 } : e;
531
+ }
532
+ handleTokenSelection(e) {
533
+ this.selectedIndexes = this.selectedIndexes.concat(e), this.dispatchEvent(
534
+ new CustomEvent("tokens-selected", {
535
+ detail: {
536
+ newIndices: e,
537
+ selectedIndices: [...this.selectedIndexes]
538
+ }
539
+ })
540
+ );
541
+ }
542
+ handleTokenCreation(e) {
543
+ this.dispatchEvent(
544
+ new CustomEvent("token-created", {
545
+ detail: {
546
+ value: e
547
+ }
548
+ })
549
+ );
550
+ }
551
+ get inputElement() {
552
+ return this.shadowRoot.querySelector(".input");
553
+ }
554
+ get activeTokenElement() {
555
+ return this.getTokenElement(this.activeTokenIndex);
556
+ }
557
+ getTokenElement(e) {
558
+ return this.querySelector("[slot='items']:nth-of-type(" + (e + 1) + ")");
559
+ }
560
+ findIndex(e) {
561
+ return this.items.findIndex((t) => t.caption === e.caption);
562
+ }
563
+ get activeTokenIndex() {
564
+ return this._activeTokenIndex;
565
+ }
566
+ set activeTokenIndex(e) {
567
+ if (this._activeTokenIndex != -1) {
568
+ const t = this.activeTokenElement;
569
+ t && (t.current = !1);
570
+ }
571
+ if (this._activeTokenIndex = e, e == -1)
572
+ this.removeAttribute("aria-activedescendant");
573
+ else {
574
+ const t = this.activeTokenElement;
575
+ t.current = !0, this.setAttribute("aria-activedescendant", t.id);
576
+ }
577
+ }
578
+ get hasInputValue() {
579
+ var e;
580
+ return !!((e = this.inputElement) != null && e.value);
581
+ }
582
+ }, h.ID = "sd-token-selector", h.ensureDefined = () => {
583
+ k.ensureDefined(), customElements.get(h.ID) || customElements.define(h.ID, h);
584
+ }, h.shadowRootOptions = {
585
+ ...b.shadowRootOptions,
586
+ delegatesFocus: !0
587
+ }, h);
588
+ d([
589
+ a({ type: String, attribute: "selection-mode", reflect: !0 })
590
+ ], l.prototype, "selectionMode", 2);
591
+ d([
592
+ a({ type: Array, attribute: !1 })
593
+ ], l.prototype, "items", 2);
594
+ d([
595
+ a({ type: Array, attribute: !1 })
596
+ ], l.prototype, "selectedIndexes", 2);
597
+ d([
598
+ a({ type: String, reflect: !0 })
599
+ ], l.prototype, "placeholder", 2);
600
+ d([
601
+ a({ type: String, reflect: !0, attribute: "suggest-list-class" })
602
+ ], l.prototype, "suggestListClass", 2);
603
+ d([
604
+ a({ type: String, reflect: !0, attribute: "input-label" })
605
+ ], l.prototype, "inputLabel", 2);
606
+ d([
607
+ a({
608
+ converter: {
609
+ fromAttribute: (r) => r == "true",
610
+ toAttribute: (r) => r
611
+ },
612
+ reflect: !0,
613
+ attribute: "aria-disabled"
614
+ })
615
+ ], l.prototype, "disabled", 2);
616
+ d([
617
+ a({ type: String, attribute: !0 })
618
+ ], l.prototype, "validationMessage", 2);
619
+ d([
620
+ a({ type: String, attribute: !0 })
621
+ ], l.prototype, "validationIconSrc", 2);
622
+ d([
623
+ a({ converter: E.levelConverter, attribute: !0, reflect: !0 })
624
+ ], l.prototype, "validationLevel", 2);
625
+ d([
626
+ a({ type: String, reflect: !0, attribute: "token-type" })
627
+ ], l.prototype, "tokenType", 2);
628
+ d([
629
+ a({ type: Boolean, reflect: !0, attribute: "case-sensitive" })
630
+ ], l.prototype, "caseSensitive", 2);
631
+ let ie = l;
632
+ export {
633
+ R as SelectionMode,
634
+ ie as default,
635
+ G as generator
636
+ };
637
+ //# sourceMappingURL=token-selector.mjs.map