@oslokommune/punkt-elements 15.4.5 → 16.0.2

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.
Files changed (73) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/dist/{card-CnPjrdre.js → card-CmfUyl_s.js} +1 -1
  3. package/dist/{card-5S2r9UD1.cjs → card-Db9QSEqh.cjs} +1 -1
  4. package/dist/{checkbox-D98_NjcU.cjs → checkbox-Cpyay9_l.cjs} +1 -1
  5. package/dist/{checkbox-BSz71IeT.js → checkbox-D6nltMuc.js} +1 -1
  6. package/dist/combobox-Bv37b6cI.cjs +135 -0
  7. package/dist/combobox-CoO8T-F-.js +818 -0
  8. package/dist/{datepicker-SEKblnRR.cjs → datepicker-CrvQ5Y5w.cjs} +1 -1
  9. package/dist/{datepicker-nnyTW0vf.js → datepicker-DbsIuC5Z.js} +2 -2
  10. package/dist/index.d.ts +157 -90
  11. package/dist/{input-element-Bkv6Yxld.js → input-element-BGNbdzy2.js} +1 -1
  12. package/dist/{input-element-DM0tY799.cjs → input-element-CSDVA3Y6.cjs} +1 -1
  13. package/dist/listbox-Dm2mKp6_.cjs +101 -0
  14. package/dist/listbox-OdkIn9_A.js +431 -0
  15. package/dist/pkt-card.cjs +1 -1
  16. package/dist/pkt-card.js +1 -1
  17. package/dist/pkt-checkbox.cjs +1 -1
  18. package/dist/pkt-checkbox.js +1 -1
  19. package/dist/pkt-combobox.cjs +1 -1
  20. package/dist/pkt-combobox.js +1 -1
  21. package/dist/pkt-datepicker.cjs +1 -1
  22. package/dist/pkt-datepicker.js +2 -2
  23. package/dist/pkt-header.cjs +1 -1
  24. package/dist/pkt-header.js +1 -1
  25. package/dist/pkt-index.cjs +1 -1
  26. package/dist/pkt-index.js +9 -9
  27. package/dist/pkt-listbox.cjs +1 -1
  28. package/dist/pkt-listbox.js +1 -1
  29. package/dist/pkt-options-controller-BogGk-6J.cjs +1 -0
  30. package/dist/{pkt-options-controller-BcGywCmf.js → pkt-options-controller-Z-bPox7n.js} +2 -2
  31. package/dist/pkt-radiobutton.cjs +1 -1
  32. package/dist/pkt-radiobutton.js +1 -1
  33. package/dist/pkt-select.cjs +1 -1
  34. package/dist/pkt-select.js +1 -1
  35. package/dist/pkt-tag.cjs +1 -1
  36. package/dist/pkt-tag.js +1 -1
  37. package/dist/pkt-textarea.cjs +1 -1
  38. package/dist/pkt-textarea.js +1 -1
  39. package/dist/pkt-textinput.cjs +1 -1
  40. package/dist/pkt-textinput.js +1 -1
  41. package/dist/{radiobutton-95wp024h.cjs → radiobutton-CNHCpKn0.cjs} +1 -1
  42. package/dist/{radiobutton-CTFAV5GU.js → radiobutton-DgC27mb0.js} +1 -1
  43. package/dist/{select-YLvYAQX6.js → select-7VuYtPZv.js} +2 -2
  44. package/dist/{select-CZ_Lx5W6.cjs → select-PWPy5gTB.cjs} +1 -1
  45. package/dist/{tag-68q0_Sn0.js → tag-DZPqFiem.js} +37 -33
  46. package/dist/tag-DmbgBCKu.cjs +27 -0
  47. package/dist/{textarea-CuTsE1WX.cjs → textarea-CO7Ikug5.cjs} +1 -1
  48. package/dist/{textarea-DhWH99qN.js → textarea-VpCEjVFx.js} +1 -1
  49. package/dist/{textinput-BCi9p0Du.js → textinput-C2AZ9ss2.js} +1 -1
  50. package/dist/{textinput-st4Vml5J.cjs → textinput-DRFZU3dA.cjs} +1 -1
  51. package/package.json +4 -4
  52. package/src/components/card/card.ts +1 -0
  53. package/src/components/combobox/combobox-base.ts +158 -0
  54. package/src/components/combobox/combobox-handlers.ts +419 -0
  55. package/src/components/combobox/combobox-types.ts +10 -0
  56. package/src/components/combobox/combobox-utils.ts +135 -0
  57. package/src/components/combobox/combobox-value.ts +248 -0
  58. package/src/components/combobox/combobox.accessibility.test.ts +243 -0
  59. package/src/components/combobox/{combobox.test.ts → combobox.core.test.ts} +104 -46
  60. package/src/components/combobox/combobox.interaction.test.ts +436 -0
  61. package/src/components/combobox/combobox.selection.test.ts +543 -0
  62. package/src/components/combobox/combobox.ts +260 -734
  63. package/src/components/listbox/index.ts +2 -0
  64. package/src/components/listbox/listbox.interaction.test.ts +580 -0
  65. package/src/components/listbox/listbox.test.ts +32 -6
  66. package/src/components/listbox/listbox.ts +109 -126
  67. package/src/components/tag/tag.ts +3 -0
  68. package/dist/combobox-C5YcNVSZ.cjs +0 -128
  69. package/dist/combobox-cer7PLSE.js +0 -533
  70. package/dist/listbox-C7NEa9SU.cjs +0 -96
  71. package/dist/listbox-Cykec1bj.js +0 -361
  72. package/dist/pkt-options-controller-BnTmkl3g.cjs +0 -1
  73. package/dist/tag-BnT5onW2.cjs +0 -26
@@ -0,0 +1,818 @@
1
+ import { n as r, A as m, b as c, t as M } from "./element-CV9utnHJ.js";
2
+ import { o as u } from "./if-defined-rXcLNTzN.js";
3
+ import { e as y, n as b } from "./ref-Dma3n3i8.js";
4
+ import { e as w } from "./class-map-3ADKve8g.js";
5
+ import { c as P } from "./repeat-DnlRNf63.js";
6
+ import { f, g as B, b as U, i as k, a as E, c as R } from "./listbox-OdkIn9_A.js";
7
+ import { r as v } from "./state-l4hGZdFJ.js";
8
+ import { P as q } from "./input-element-BGNbdzy2.js";
9
+ import { P as N } from "./pkt-options-controller-Z-bPox7n.js";
10
+ import { P as L } from "./pkt-slot-controller-D7CrjM52.js";
11
+ import "./input-wrapper-CaUY90qz.js";
12
+ import "./icon-D0IQAVwS.js";
13
+ import "./tag-DZPqFiem.js";
14
+ const j = (i, t, e) => {
15
+ switch (i) {
16
+ case ",":
17
+ return e ? "addValue" : null;
18
+ case "Enter":
19
+ return "addValue";
20
+ case "Tab":
21
+ case "ArrowDown":
22
+ return t ? null : "focusListbox";
23
+ case "Escape":
24
+ return "closeOptions";
25
+ default:
26
+ return null;
27
+ }
28
+ }, K = (i, t, e, s, l) => {
29
+ if (!i) return { action: "none", value: null };
30
+ const a = f(e, i);
31
+ return !t.includes(i) && !a ? s ? { action: "addUserValue", value: i } : l ? { action: "none", value: null } : { action: "removeValue", value: t[0] } : a && !t.includes(a.value) ? { action: "selectOption", value: a.value } : { action: "none", value: null };
32
+ }, W = (i, t, e, s, l) => i.trim().toLowerCase() ? {
33
+ ...B(i, t, e, s),
34
+ shouldRemoveValue: !1,
35
+ shouldResetInput: !1
36
+ } : {
37
+ addValueText: null,
38
+ userInfoMessage: "",
39
+ shouldRemoveValue: !l && !!t[0],
40
+ shouldResetInput: !0
41
+ }, $ = (i, t, e) => {
42
+ const s = f(t, i);
43
+ return e === "label" && (s != null && s.label) ? s.label : i;
44
+ }, x = {
45
+ markOptionSelected(i, t) {
46
+ if (t) {
47
+ for (const e of i)
48
+ if (e.value === t) {
49
+ e.selected = !0;
50
+ break;
51
+ }
52
+ }
53
+ },
54
+ markOptionDeselected(i, t) {
55
+ if (t) {
56
+ for (const e of i)
57
+ if (e.value === t) {
58
+ e.selected = !1;
59
+ break;
60
+ }
61
+ }
62
+ },
63
+ markAllSelected(i) {
64
+ for (const t of i)
65
+ t.selected = !0;
66
+ },
67
+ markAllDeselected(i) {
68
+ for (const t of i)
69
+ t.selected = !1;
70
+ },
71
+ removeUserAddedOptions(i) {
72
+ return i.filter((t) => !t.userAdded);
73
+ }
74
+ }, C = {
75
+ parseOptionsFromSlot(i) {
76
+ const t = [];
77
+ return i.forEach((e) => {
78
+ if (!e.textContent && !e.getAttribute("value")) return;
79
+ const s = {
80
+ value: e.getAttribute("value") || e.textContent || "",
81
+ label: e.textContent || e.getAttribute("value") || ""
82
+ };
83
+ e.getAttribute("data-prefix") && (s.prefix = e.getAttribute("data-prefix") || void 0), e.getAttribute("tagskincolor") && (s.tagSkinColor = e.getAttribute("tagskincolor")), e.getAttribute("description") && (s.description = e.getAttribute("description") || void 0), s.fulltext = U(s), t.push(s);
84
+ }), t;
85
+ }
86
+ }, A = {
87
+ /**
88
+ * Ensures options have labels and fulltext set.
89
+ * Also syncs selected state with current values.
90
+ *
91
+ * IMPORTANT: Mutates options in place to preserve referential identity
92
+ * between this._options and this.options in the Lit component.
93
+ */
94
+ syncOptionsWithValues(i, t) {
95
+ const e = [...t];
96
+ return i.forEach((s) => {
97
+ s.value && !s.label && (s.label = s.value), s.selected && !e.includes(s.value) && e.push(s.value), s.fulltext = U(s), s.selected = s.selected || e.includes(s.value);
98
+ }), { options: i, newValues: e };
99
+ },
100
+ /**
101
+ * Merges user-added options with new options, preserving user additions.
102
+ */
103
+ mergeWithUserAdded(i, t) {
104
+ return [...t.filter((l) => (l == null ? void 0 : l.userAdded) && l.selected).filter(
105
+ (l) => !(Array.isArray(i) ? i : []).some((a) => a.value === l.value)
106
+ ), ...i];
107
+ }
108
+ }, G = { displayValueAs: { default: "label" } }, J = {
109
+ props: G
110
+ };
111
+ var H = Object.defineProperty, h = (i, t, e, s) => {
112
+ for (var l = void 0, a = i.length - 1, o; a >= 0; a--)
113
+ (o = i[a]) && (l = o(t, e, l) || l);
114
+ return l && H(t, e, l), l;
115
+ };
116
+ class n extends q {
117
+ constructor() {
118
+ super(), this.helptextSlot = y(), this.value = "", this.options = [], this.defaultOptions = [], this.allowUserInput = !1, this.typeahead = !1, this.includeSearch = !1, this.searchPlaceholder = "", this.multiple = !1, this.maxlength = null, this.displayValueAs = J.props.displayValueAs.default, this.tagPlacement = null, this.isOpen = !1, this._options = [], this._value = [], this._isOptionsOpen = !1, this._userInfoMessage = "", this._addValueText = null, this._maxIsReached = !1, this._search = "", this._inputFocus = !1, this._internalValueSync = !1, this._optionsFromSlot = !1, this._lastSlotGeneration = 0, this._suppressNextOpen = !1, this.inputRef = y(), this.triggerRef = y(), this.listboxRef = y(), this.optionsController = new N(this), this.slotController = new L(this, this.helptextSlot), this.slotController.skipOptions = !0;
119
+ }
120
+ get _hasTextInput() {
121
+ return this.typeahead || this.allowUserInput;
122
+ }
123
+ get _selectionDescription() {
124
+ if (!(!this.multiple || this._value.length === 0))
125
+ return `${this._value.length} valgt`;
126
+ }
127
+ /**
128
+ * Focuses the appropriate trigger element after closing the listbox.
129
+ * Select-only: the combobox input div. Editable: the text input.
130
+ */
131
+ focusTrigger() {
132
+ var t, e;
133
+ this._hasTextInput ? (t = this.inputRef.value) == null || t.focus() : (e = this.triggerRef.value) == null || e.focus();
134
+ }
135
+ /**
136
+ * Parses the value prop into an internal string array.
137
+ */
138
+ parseValue() {
139
+ return Array.isArray(this.value) ? this.multiple ? this.value : this.value.length > 0 ? [this.value[0]] : [] : this.value && this.multiple ? this.value.split(",") : this.value ? [this.value] : [];
140
+ }
141
+ /**
142
+ * Updates the _maxIsReached state flag.
143
+ */
144
+ updateMaxReached() {
145
+ this._maxIsReached = k(this._value.length, this.maxlength);
146
+ }
147
+ /**
148
+ * Syncs the public value property from internal _value state and dispatches
149
+ * events if the value content changed. Always sets this.value as a string
150
+ * to prevent array→string reflect cascades.
151
+ */
152
+ syncValueAndDispatch(t) {
153
+ const e = this._value, s = this.multiple ? e.join(",") : e[0] || "", l = Array.isArray(this.value) ? this.value.join(",") : String(this.value || "");
154
+ if (s !== l && (this._internalValueSync = !0, this.value = s), (t == null ? void 0 : t.join(",")) !== e.join(",")) {
155
+ const a = this.multiple ? [...e] : e[0] || "";
156
+ this.onChange(a);
157
+ } else e.length === 0 && t && t.length > 0 && this.clearInputValue();
158
+ }
159
+ /**
160
+ * Override onChange to skip the base class touched guard.
161
+ * The base class returns early on the first call (setting touched = true but not
162
+ * dispatching events). Combobox needs consistent event dispatch regardless of
163
+ * touched state.
164
+ */
165
+ onChange(t) {
166
+ this.touched = !0, super.onChange(t);
167
+ }
168
+ /**
169
+ * No-op override of the base class valueChanged.
170
+ * The base class version sets both this.value AND this._value, which creates
171
+ * an infinite _value → valueChanged → value → parseValue → _value loop.
172
+ * Combobox handles value sync and event dispatch in syncValueAndDispatch() instead.
173
+ */
174
+ valueChanged() {
175
+ }
176
+ }
177
+ h([
178
+ r({ type: String, reflect: !0 })
179
+ ], n.prototype, "value");
180
+ h([
181
+ r({ type: Array })
182
+ ], n.prototype, "options");
183
+ h([
184
+ r({ type: Array, attribute: "default-options" })
185
+ ], n.prototype, "defaultOptions");
186
+ h([
187
+ r({ type: Boolean, attribute: "allow-user-input" })
188
+ ], n.prototype, "allowUserInput");
189
+ h([
190
+ r({ type: Boolean })
191
+ ], n.prototype, "typeahead");
192
+ h([
193
+ r({ type: Boolean, attribute: "include-search" })
194
+ ], n.prototype, "includeSearch");
195
+ h([
196
+ r({ type: String, attribute: "search-placeholder" })
197
+ ], n.prototype, "searchPlaceholder");
198
+ h([
199
+ r({ type: Boolean })
200
+ ], n.prototype, "multiple");
201
+ h([
202
+ r({ type: Number })
203
+ ], n.prototype, "maxlength");
204
+ h([
205
+ r({ type: String, attribute: "display-value-as" })
206
+ ], n.prototype, "displayValueAs");
207
+ h([
208
+ r({ type: String, attribute: "tag-placement" })
209
+ ], n.prototype, "tagPlacement");
210
+ h([
211
+ r({ type: Boolean, attribute: "open" })
212
+ ], n.prototype, "isOpen");
213
+ h([
214
+ v()
215
+ ], n.prototype, "_options");
216
+ h([
217
+ v()
218
+ ], n.prototype, "_value");
219
+ h([
220
+ v()
221
+ ], n.prototype, "_isOptionsOpen");
222
+ h([
223
+ v()
224
+ ], n.prototype, "_userInfoMessage");
225
+ h([
226
+ v()
227
+ ], n.prototype, "_addValueText");
228
+ h([
229
+ v()
230
+ ], n.prototype, "_maxIsReached");
231
+ h([
232
+ v()
233
+ ], n.prototype, "_search");
234
+ h([
235
+ v()
236
+ ], n.prototype, "_inputFocus");
237
+ class z extends n {
238
+ toggleValue(t) {
239
+ var T, S;
240
+ if (this.disabled) return;
241
+ this.touched = !0, this._userInfoMessage = "", this._addValueText = null;
242
+ const e = ((T = f(this.options, t)) == null ? void 0 : T.value) || null, s = this._value.includes(t || e || ""), l = !!e, a = ((S = this._options.find((D) => D.value === t)) == null ? void 0 : S.disabled) || !1, o = !(t != null && t.trim()), p = !this.multiple, d = this.multiple, V = k(this._value.length, this.maxlength);
243
+ let _ = !1, O = !0, g = "", I = "";
244
+ a || (!l && this.allowUserInput && !o ? (this.addNewUserValue(t), g = "Ny verdi lagt til", _ = d) : !l && !this.allowUserInput ? (p && this._value[0] && this.removeValue(this._value[0]), O = !1, _ = !0, g = "Ingen treff i søket") : s ? (this.removeValue(e), _ = !0, p && this._hasTextInput && this.inputRef.value && this.inputRef.value.type !== "hidden" && (this.inputRef.value.value = "")) : o && p ? (this.removeAllSelected(), _ = !0) : p ? (this._value[0] && this.removeSelected(this._value[0]), this.setSelected(e), _ = !1) : d && !V ? (this.setSelected(e), _ = !0) : d && V ? (g = "Maks antall valg nådd", O = !1, I = t) : (p && this.removeAllSelected(), g = "Ingen gyldig verdi valgt", O = !1, _ = !0, I = t), this._isOptionsOpen = _, _ || (p && this._hasTextInput && (this._suppressNextOpen = !0), window.setTimeout(() => {
245
+ this.focusTrigger();
246
+ }, 0)), this._userInfoMessage = g, this._search = I || "", this.resetComboboxInput(O), d && this.updateMaxReached());
247
+ }
248
+ setSelected(t) {
249
+ if (!this._value.includes(t)) {
250
+ if (this.multiple && k(this._value.length, this.maxlength)) {
251
+ this._userInfoMessage = "Maks antall valg nådd";
252
+ return;
253
+ }
254
+ !this.multiple && this.removeAllSelected(), this._value = t ? [...this._value, t] : this._value, x.markOptionSelected(this._options, t), this.resetComboboxInput(!0);
255
+ }
256
+ }
257
+ removeSelected(t) {
258
+ if (!t) return;
259
+ this._value = this._value.filter((s) => s !== t);
260
+ const e = f(this.options, t);
261
+ e && (x.markOptionDeselected(this.options, t), e.userAdded ? (this._options = [...this._options.filter((s) => s.value !== t)], this.options = [...this.options.filter((s) => s.value !== t)]) : this._options.some((s) => s.value === t) || (this._options = [...this._options, e]));
262
+ }
263
+ addAllOptions() {
264
+ if (this.multiple) {
265
+ if (this.maxlength && this._options.length > this.maxlength) {
266
+ this._userInfoMessage = "For mange valgt";
267
+ return;
268
+ }
269
+ this._value = this._options.map((t) => t.value), x.markAllSelected(this._options), this.requestUpdate();
270
+ }
271
+ }
272
+ removeAllSelected() {
273
+ this._value = [], x.markAllDeselected(this._options), this._options = x.removeUserAddedOptions(this._options), this.requestUpdate();
274
+ }
275
+ addValue() {
276
+ var e;
277
+ const t = ((e = this.inputRef.value) == null ? void 0 : e.value.trim()) || "";
278
+ if (this._search = t, t && this._value.includes(t)) {
279
+ this.resetComboboxInput(!0), this._userInfoMessage = "Verdien er allerede valgt";
280
+ return;
281
+ }
282
+ this.toggleValue(t);
283
+ }
284
+ removeValue(t) {
285
+ this._value = this.multiple ? this._value.filter((e) => e !== t) : [], this.removeSelected(t);
286
+ }
287
+ addNewUserValue(t) {
288
+ if (!t || t.trim() === "") return;
289
+ if (!this.multiple)
290
+ this._value[0] && this.removeSelected(this._value[0]), this._value = [t];
291
+ else if (!f(this.options, t)) {
292
+ if (k(this._value.length, this.maxlength)) return;
293
+ this._value = [...this._value, t];
294
+ }
295
+ const e = { value: t, label: t, userAdded: !0, selected: !0 };
296
+ this.options = [e, ...this.options], this._options = [e, ...this._options], this.resetComboboxInput(!0), this.multiple || (this._isOptionsOpen = !1, this._hasTextInput && (this._suppressNextOpen = !0), window.setTimeout(() => {
297
+ this.focusTrigger();
298
+ }, 0)), this.requestUpdate();
299
+ }
300
+ resetComboboxInput(t = !0) {
301
+ this._addValueText = null, this.inputRef.value && this.inputRef.value.type !== "hidden" && t && (this._search = "", this.multiple ? this.inputRef.value.value = "" : (this.inputRef.value.value = this._value[0] ? $(this._value[0], this.options, this.displayValueAs) : "", this._userInfoMessage = "")), this._options = [...this.options];
302
+ }
303
+ removeLastValue(t) {
304
+ if (this._value.length === 0) return;
305
+ t.preventDefault();
306
+ const e = this._value[this._value.length - 1];
307
+ e && this.removeSelected(e), this.updateMaxReached();
308
+ }
309
+ }
310
+ class Q extends z {
311
+ handleInput(t) {
312
+ if (t.stopPropagation(), t.stopImmediatePropagation(), this.disabled) return;
313
+ this.touched = !0;
314
+ const e = t.target;
315
+ if (this._search = e.value, this.checkForMatches(), this.typeahead)
316
+ if (this._search) {
317
+ const { filtered: s, suggestion: l } = E(this.options, this._search);
318
+ this._options = s, t.inputType !== "deleteContentBackward" && (l != null && l.label) && this.inputRef.value && this.inputRef.value.type !== "hidden" && (e.value = l.label, window.setTimeout(
319
+ () => e.setSelectionRange(this._search.length, e.value.length),
320
+ 0
321
+ ), e.selectionDirection = "backward");
322
+ } else
323
+ this._options = [...this.options];
324
+ }
325
+ handleFocus() {
326
+ if (!this.disabled) {
327
+ if (this._suppressNextOpen) {
328
+ this._suppressNextOpen = !1, this._inputFocus = !0, this.requestUpdate();
329
+ return;
330
+ }
331
+ !this.multiple && this._value[0] && this.inputRef.value && this.inputRef.value.type !== "hidden" && (this.inputRef.value.value = $(
332
+ this._value[0],
333
+ this.options,
334
+ this.displayValueAs
335
+ )), this._inputFocus = !0, this._search = "", this._options = [...this.options], this._isOptionsOpen = !0, this.onFocus(), this.requestUpdate();
336
+ }
337
+ }
338
+ handleFocusOut(t) {
339
+ var l, a;
340
+ if (this.disabled || !this._isOptionsOpen) return;
341
+ const e = t.relatedTarget;
342
+ ((l = e == null ? void 0 : e.closest("pkt-combobox")) == null ? void 0 : l.id) === this.id || ((a = t.target) == null ? void 0 : a.getAttribute("data-focusfix")) === this.id || e === this.inputRef.value || e === this.triggerRef.value || this.closeAndProcessInput();
343
+ }
344
+ /**
345
+ * Shared close logic used by both focusout and outside-click handlers.
346
+ * Processes any pending input value, then closes the dropdown.
347
+ */
348
+ closeAndProcessInput() {
349
+ if (this._inputFocus = !1, this._addValueText = null, this._userInfoMessage = "", this._search = "", this.inputRef.value && this.inputRef.value.type !== "hidden") {
350
+ const t = this.inputRef.value.value;
351
+ if (this.multiple) {
352
+ if (t !== "") {
353
+ const { action: e, value: s } = K(
354
+ t,
355
+ this._value,
356
+ this.options,
357
+ this.allowUserInput,
358
+ this.multiple
359
+ );
360
+ switch (e) {
361
+ case "addUserValue":
362
+ this.addNewUserValue(s);
363
+ break;
364
+ case "selectOption":
365
+ this.setSelected(s);
366
+ break;
367
+ case "removeValue":
368
+ this.removeValue(s);
369
+ break;
370
+ }
371
+ }
372
+ } else if (!t)
373
+ this._value[0] && this.removeSelected(this._value[0]);
374
+ else {
375
+ const e = f(this.options, t);
376
+ e && e.value !== this._value[0] ? (this._value[0] && this.removeSelected(this._value[0]), this.setSelected(e.value)) : !e && this.allowUserInput && (this._value[0] && this.removeSelected(this._value[0]), this.addNewUserValue(t));
377
+ }
378
+ !this.multiple && this._value[0] ? this.inputRef.value.value = $(
379
+ this._value[0],
380
+ this.options,
381
+ this.displayValueAs
382
+ ) : this.inputRef.value.value = "";
383
+ }
384
+ this._isOptionsOpen = !1, this.onBlur();
385
+ }
386
+ handleBlur() {
387
+ this._inputFocus = !1, this.onBlur();
388
+ }
389
+ handleInputClick(t) {
390
+ var e, s;
391
+ if (this.disabled) {
392
+ t.preventDefault(), t.stopImmediatePropagation();
393
+ return;
394
+ }
395
+ this._hasTextInput ? ((e = this.inputRef.value) == null || e.focus(), this.requestUpdate()) : (t.stopImmediatePropagation(), t.preventDefault(), this._isOptionsOpen = !this._isOptionsOpen, this._isOptionsOpen && ((s = this.listboxRef.value) == null || s.focusFirstOrSelectedOption()));
396
+ }
397
+ handlePlaceholderClick(t) {
398
+ this.disabled || (t.stopPropagation(), this._hasTextInput && this.inputRef.value ? (this.inputRef.value.focus(), this._inputFocus = !0, this.requestUpdate()) : (this._isOptionsOpen = !this._isOptionsOpen, this.requestUpdate()));
399
+ }
400
+ handleSelectOnlyKeydown(t) {
401
+ var e, s;
402
+ if (!this.disabled)
403
+ switch (t.key) {
404
+ case "Enter":
405
+ case " ":
406
+ case "ArrowDown":
407
+ case "ArrowUp":
408
+ t.preventDefault(), this._isOptionsOpen ? this._isOptionsOpen = !1 : (this._isOptionsOpen = !0, (e = this.listboxRef.value) == null || e.focusFirstOrSelectedOption());
409
+ break;
410
+ case "Escape":
411
+ this._isOptionsOpen && (t.preventDefault(), this._isOptionsOpen = !1);
412
+ break;
413
+ case "Home":
414
+ case "End":
415
+ t.preventDefault(), this._isOptionsOpen || (this._isOptionsOpen = !0), (s = this.listboxRef.value) == null || s.focusFirstOrSelectedOption();
416
+ break;
417
+ case "ArrowLeft":
418
+ this.multiple && this._value.length > 0 && (t.preventDefault(), this.focusTag(this._value.length - 1));
419
+ break;
420
+ case "Backspace":
421
+ case "Delete":
422
+ this.multiple && this._value.length > 0 && (t.preventDefault(), this.removeSelected(this._value[this._value.length - 1]));
423
+ break;
424
+ }
425
+ }
426
+ handleOptionToggled(t) {
427
+ this.toggleValue(t.detail);
428
+ }
429
+ handleSearch(t) {
430
+ t.stopPropagation(), this._search = t.detail.toLowerCase(), this.checkForMatches();
431
+ }
432
+ handleInputKeydown(t) {
433
+ var s, l, a;
434
+ if (t.key === "Backspace") {
435
+ const o = !((s = this.inputRef.value) != null && s.value);
436
+ !this._search && o && this.multiple && this._value.length > 0 && this.removeLastValue(t);
437
+ return;
438
+ }
439
+ if (t.key === "ArrowLeft" && this.multiple && this._value.length > 0) {
440
+ const o = this.inputRef.value;
441
+ if (o && o.selectionStart === 0 && !o.value) {
442
+ t.preventDefault(), this.focusTag(this._value.length - 1);
443
+ return;
444
+ }
445
+ }
446
+ const e = j(t.key, t.shiftKey, this.multiple);
447
+ if (e && !(t.key === "Tab" && !this._isOptionsOpen)) {
448
+ if (e === "focusListbox" && t.key === "Tab" && !((l = this.listboxRef.value) == null ? void 0 : l.querySelector(
449
+ '[role="option"]:not([data-disabled]), [data-type="new-option"]'
450
+ ))) {
451
+ this.closeAndProcessInput();
452
+ return;
453
+ }
454
+ switch (t.preventDefault(), e) {
455
+ case "addValue":
456
+ this.addValue();
457
+ break;
458
+ case "focusListbox":
459
+ (a = this.listboxRef.value) == null || a.focusFirstOrSelectedOption();
460
+ break;
461
+ case "closeOptions":
462
+ this._isOptionsOpen = !1;
463
+ break;
464
+ }
465
+ }
466
+ }
467
+ handleTagRemove(t) {
468
+ this.removeSelected(t), this._hasTextInput && this.inputRef.value && (this._inputFocus = !0, this.inputRef.value.focus(), this.requestUpdate());
469
+ }
470
+ getInsideTags() {
471
+ return Array.from(
472
+ this.querySelectorAll(".pkt-combobox__input .pkt-combobox__tag-list pkt-tag")
473
+ );
474
+ }
475
+ focusTag(t) {
476
+ var l;
477
+ const e = this.getInsideTags();
478
+ e.forEach((a, o) => {
479
+ a.buttonTabindex = o === t ? 0 : -1;
480
+ });
481
+ const s = (l = e[t]) == null ? void 0 : l.querySelector("button");
482
+ s == null || s.focus();
483
+ }
484
+ resetTagTabindices() {
485
+ this.getInsideTags().forEach((e) => {
486
+ e.buttonTabindex = -1;
487
+ });
488
+ }
489
+ handleTagKeydown(t, e) {
490
+ t.stopPropagation();
491
+ const s = () => {
492
+ var l;
493
+ this.resetTagTabindices(), this._hasTextInput && this.inputRef.value ? this.inputRef.value.focus() : (l = this.triggerRef.value) == null || l.focus();
494
+ };
495
+ switch (t.key) {
496
+ case "ArrowLeft":
497
+ t.preventDefault(), e > 0 && this.focusTag(e - 1);
498
+ break;
499
+ case "ArrowRight":
500
+ t.preventDefault(), e < this._value.length - 1 ? this.focusTag(e + 1) : s();
501
+ break;
502
+ case "Backspace":
503
+ case "Delete":
504
+ t.preventDefault();
505
+ {
506
+ const l = this._value[e], a = e >= this._value.length - 1 ? e - 1 : e;
507
+ this.removeSelected(l), a >= 0 ? (this.requestUpdate(), this.updateComplete.then(() => this.focusTag(a))) : s();
508
+ }
509
+ break;
510
+ case "Tab":
511
+ this.resetTagTabindices();
512
+ break;
513
+ case "Escape":
514
+ t.preventDefault(), s();
515
+ break;
516
+ }
517
+ }
518
+ checkForMatches() {
519
+ var s;
520
+ const t = ((s = this.inputRef.value) == null ? void 0 : s.value) || this._search || "", e = W(
521
+ t,
522
+ this._value,
523
+ this.options,
524
+ this.allowUserInput,
525
+ this.multiple
526
+ );
527
+ if (e.shouldRemoveValue && this.removeValue(this._value[0]), e.shouldResetInput) {
528
+ this.resetComboboxInput(!1);
529
+ return;
530
+ }
531
+ this._addValueText = e.addValueText, this._userInfoMessage = e.userInfoMessage;
532
+ }
533
+ }
534
+ var X = Object.getOwnPropertyDescriptor, Y = (i, t, e, s) => {
535
+ for (var l = s > 1 ? void 0 : s ? X(t, e) : t, a = i.length - 1, o; a >= 0; a--)
536
+ (o = i[a]) && (l = o(l) || l);
537
+ return l;
538
+ };
539
+ let F = class extends Q {
540
+ constructor() {
541
+ super(...arguments), this.handleBodyClick = (i) => {
542
+ this._isOptionsOpen && !this.contains(i.target) && this.closeAndProcessInput();
543
+ };
544
+ }
545
+ // Lifecycle methods
546
+ connectedCallback() {
547
+ var i, t;
548
+ if (super.connectedCallback(), document == null || document.body.addEventListener("click", this.handleBodyClick), this._options = [], this.defaultOptions && this.defaultOptions.length) {
549
+ const e = ((i = this.options) == null ? void 0 : i.filter((s) => s.userAdded)) || [];
550
+ this.options = [...e, ...JSON.parse(JSON.stringify(this.defaultOptions))], this._options = Array.isArray(this.options) ? [...this.options] : [];
551
+ }
552
+ if ((t = this.optionsController) != null && t.nodes && this.optionsController.nodes.length) {
553
+ const e = C.parseOptionsFromSlot(this.optionsController.nodes);
554
+ e.length && (this.options = [...e], this._options = [...e], this._optionsFromSlot = !0, this._lastSlotGeneration = this.optionsController.generation);
555
+ }
556
+ }
557
+ willUpdate(i) {
558
+ if (this._optionsFromSlot && this.optionsController) {
559
+ const t = this.optionsController.generation;
560
+ if (t !== this._lastSlotGeneration) {
561
+ this._lastSlotGeneration = t;
562
+ const e = C.parseOptionsFromSlot(this.optionsController.nodes), s = this._options.filter((l) => l.userAdded);
563
+ this.options = [...s, ...e];
564
+ }
565
+ }
566
+ super.willUpdate(i);
567
+ }
568
+ disconnectedCallback() {
569
+ super.disconnectedCallback(), document == null || document.body.removeEventListener("click", this.handleBodyClick);
570
+ }
571
+ firstUpdated(i) {
572
+ this.defaultValue !== null && !this.value && (this.value = this.defaultValue), super.firstUpdated(i);
573
+ }
574
+ updated(i) {
575
+ i.has("isOpen") && (this._isOptionsOpen = this.isOpen);
576
+ const t = i.has("value"), e = i.has("_value");
577
+ if (t && this._internalValueSync)
578
+ this._internalValueSync = !1, e && this.syncValueAndDispatch(i.get("_value"));
579
+ else if (t) {
580
+ const l = [...this._value], a = this.parseValue();
581
+ a.join(",") !== this._value.join(",") && (this._value = a), this.updateMaxReached(), this.syncValueAndDispatch(l);
582
+ } else e && this.syncValueAndDispatch(i.get("_value"));
583
+ if (i.has("defaultOptions") && this.defaultOptions.length) {
584
+ const l = (Array.isArray(this.options) ? this.options : []).filter((a) => a.userAdded) || [];
585
+ this.options = [...l, ...JSON.parse(JSON.stringify(this.defaultOptions))], this._options = Array.isArray(this.options) ? [...this.options] : [];
586
+ }
587
+ if (i.has("options")) {
588
+ const l = i.get("options") || this._options || [], a = A.mergeWithUserAdded(this.options, l);
589
+ this._options = a, a.length > this.options.length && (this.options = a);
590
+ const o = A.syncOptionsWithValues(this._options, this._value);
591
+ if (this._options = o.options, o.newValues.length > this._value.length) {
592
+ const p = [...this._value];
593
+ this._value = o.newValues, this.syncValueAndDispatch(p);
594
+ }
595
+ }
596
+ if (i.has("_search") && this.dispatchEvent(
597
+ new CustomEvent("search", {
598
+ detail: this._search,
599
+ bubbles: !1
600
+ })
601
+ ), !this._isOptionsOpen && !this.multiple && this._hasTextInput && this.inputRef.value && this.inputRef.value.type !== "hidden") {
602
+ const l = this._value[0] ? $(this._value[0], this.options, this.displayValueAs) : "";
603
+ this.inputRef.value.value !== l && (this.inputRef.value.value = l);
604
+ }
605
+ super.updated(i);
606
+ }
607
+ /**
608
+ * Override form reset to properly restore combobox state.
609
+ * The base class deselects all options and sets value/defaultValue, but
610
+ * combobox needs to re-sync _options with the restored values and clean up
611
+ * user-added options and UI state.
612
+ */
613
+ formResetCallback() {
614
+ this.touched = !1;
615
+ const i = this.defaultValue || (this.multiple, "");
616
+ this.value = i, this._value = this.parseValue(), this._options = this._options.filter((t) => !t.userAdded).map((t) => ({ ...t, selected: this._value.includes(t.value) })), this.options = this.options.filter((t) => !t.userAdded).map((t) => ({ ...t, selected: this._value.includes(t.value) })), this._search = "", this._isOptionsOpen = !1, this._userInfoMessage = "", this._addValueText = null, this._inputFocus = !1, this.updateMaxReached(), this.inputRef.value && this.inputRef.value.type !== "hidden" && (this.inputRef.value.value = ""), this.internals.setFormValue(""), this.internals.ariaInvalid = "false", this.requestUpdate();
617
+ }
618
+ attributeChangedCallback(i, t, e) {
619
+ if (i === "options") {
620
+ this._options = Array.isArray(this.options) ? [...this.options] : [];
621
+ const s = A.syncOptionsWithValues(this._options, this._value);
622
+ this._options = s.options, s.newValues.length > this._value.length && (this._value = s.newValues), this._search = "";
623
+ }
624
+ super.attributeChangedCallback(i, t, e);
625
+ }
626
+ // Render methods
627
+ render() {
628
+ return c`
629
+ <pkt-input-wrapper
630
+ .label=${this.label}
631
+ .helptext=${this.helptext}
632
+ .helptextDropdown=${u(this.helptextDropdown)}
633
+ .helptextDropdownButton=${u(this.helptextDropdownButton)}
634
+ ?fullwidth=${this.fullwidth}
635
+ ?hasError=${this.hasError}
636
+ ?inline=${this.inline}
637
+ ?disabled=${this.disabled}
638
+ .errorMessage=${this.errorMessage}
639
+ ?optionalTag=${this.optionalTag}
640
+ .optionalText=${this.optionalText}
641
+ ?requiredTag=${this.requiredTag}
642
+ .requiredText=${this.requiredText}
643
+ .tagText=${this.tagText}
644
+ useWrapper=${this.useWrapper}
645
+ .forId=${this._hasTextInput ? this.id + "-input" : this.id + "-combobox"}
646
+ ?hasFieldset=${!this._hasTextInput}
647
+ class="pkt-combobox__wrapper"
648
+ @labelClick=${this.handleInputClick}
649
+ >
650
+ <div class="pkt-contents" ${b(this.helptextSlot)} name="helptext" slot="helptext"></div>
651
+ <div class="pkt-combobox" @focusout=${this.handleFocusOut}>
652
+ <div
653
+ class=${w({
654
+ "pkt-combobox__input": !0,
655
+ "pkt-combobox__input--fullwidth": this.fullwidth,
656
+ "pkt-combobox__input--open": this._isOptionsOpen,
657
+ "pkt-combobox__input--error": this.hasError,
658
+ "pkt-combobox__input--disabled": this.disabled
659
+ })}
660
+ id=${u(this._hasTextInput ? void 0 : `${this.id}-combobox`)}
661
+ role=${u(this._hasTextInput ? void 0 : "combobox")}
662
+ aria-expanded=${u(
663
+ this._hasTextInput ? void 0 : this._isOptionsOpen ? "true" : "false"
664
+ )}
665
+ aria-controls=${u(this._hasTextInput ? void 0 : `${this.id}-listbox`)}
666
+ aria-haspopup=${u(this._hasTextInput ? void 0 : "listbox")}
667
+ aria-labelledby=${u(
668
+ this._hasTextInput ? void 0 : `${this.id}-combobox-label`
669
+ )}
670
+ aria-activedescendant=${u(
671
+ !this._hasTextInput && this._value[0] && f(this.options, this._value[0]) ? `${this.id}-listbox-${R(this._options, this._value[0])}` : void 0
672
+ )}
673
+ aria-description=${u(this._selectionDescription || void 0)}
674
+ tabindex=${this._hasTextInput || this.disabled ? "-1" : "0"}
675
+ @click=${this.handleInputClick}
676
+ @keydown=${this._hasTextInput ? m : this.handleSelectOnlyKeydown}
677
+ ${b(this.triggerRef)}
678
+ >
679
+ ${!this._hasTextInput && this.placeholder && (!this._value.length || this.multiple && this.tagPlacement == "outside") && !this._inputFocus ? c`<span class="pkt-combobox__placeholder" @click=${this.handlePlaceholderClick}
680
+ >${this.placeholder}</span
681
+ >` : this.tagPlacement !== "outside" ? this.renderSingleOrMultipleValues() : m}
682
+ ${this.renderInputField()}
683
+ <pkt-icon
684
+ class=${w({
685
+ "pkt-combobox__arrow-icon": !0,
686
+ "pkt-combobox__arrow-icon--open": this._isOptionsOpen
687
+ })}
688
+ name="chevron-thin-down"
689
+ aria-hidden="true"
690
+ ></pkt-icon>
691
+ </div>
692
+
693
+ <pkt-listbox
694
+ id="${this.id}-listbox"
695
+ .options=${this._options}
696
+ .isOpen=${this._isOptionsOpen}
697
+ .searchPlaceholder=${this.searchPlaceholder}
698
+ .label="Liste: ${this.label || ""}"
699
+ ?include-search=${this.includeSearch}
700
+ ?is-multi-select=${this.multiple}
701
+ ?allow-user-input=${this.allowUserInput && !this._maxIsReached}
702
+ ?max-is-reached=${this._maxIsReached}
703
+ .customUserInput=${u(this._addValueText)}
704
+ .userMessage=${this._userInfoMessage}
705
+ @search=${this.handleSearch}
706
+ @option-toggle=${this.handleOptionToggled}
707
+ @select-all=${this.addAllOptions}
708
+ @close-options=${() => this._isOptionsOpen = !1}
709
+ @tab-close=${() => this.closeAndProcessInput()}
710
+ .searchValue=${this._search || null}
711
+ .maxLength=${this.maxlength || 0}
712
+ ${b(this.listboxRef)}
713
+ ></pkt-listbox>
714
+ </div>
715
+
716
+ ${this.tagPlacement === "outside" && this.multiple ? c`<div class="pkt-combobox__tags-outside">
717
+ ${this.renderSingleOrMultipleValues()}
718
+ </div>` : m}
719
+ </pkt-input-wrapper>
720
+ `;
721
+ }
722
+ renderInputField() {
723
+ return this.typeahead || this.allowUserInput ? c`
724
+ <div class="pkt-combobox__input-div combobox__input">
725
+ <input
726
+ type="text"
727
+ id="${this.id}-input"
728
+ name=${(this.name || this.id) + "-input"}
729
+ placeholder=${u(
730
+ !this._value.length || this.multiple && this.tagPlacement === "outside" ? this.placeholder : void 0
731
+ )}
732
+ @input=${this.handleInput}
733
+ @change=${(i) => {
734
+ i.stopPropagation(), i.stopImmediatePropagation();
735
+ }}
736
+ @keydown=${this.handleInputKeydown}
737
+ @focus=${this.handleFocus}
738
+ @blur=${this.handleBlur}
739
+ autocomplete="off"
740
+ role="combobox"
741
+ aria-expanded=${this._isOptionsOpen ? "true" : "false"}
742
+ aria-label=${u(this.label)}
743
+ aria-autocomplete=${this.typeahead ? "both" : this.allowUserInput ? "list" : "none"}
744
+ aria-controls="${this.id}-listbox"
745
+ aria-activedescendant=${u(
746
+ this._value[0] && f(this.options, this._value[0]) ? `${this.id}-listbox-${R(this._options, this._value[0])}` : void 0
747
+ )}
748
+ aria-description=${u(this._selectionDescription || void 0)}
749
+ ${b(this.inputRef)}
750
+ />
751
+ </div>
752
+ ` : c`
753
+ <input
754
+ type="hidden"
755
+ id="${this.id}-input"
756
+ name=${(this.name || this.id) + "-input"}
757
+ .value=${this._value.join(",")}
758
+ ${b(this.inputRef)}
759
+ />
760
+ `;
761
+ }
762
+ renderSingleOrMultipleValues() {
763
+ if (!this.multiple && this._hasTextInput) return m;
764
+ const i = !this.multiple, t = this.renderValueTag(f(this.options, this._value[0])), e = this.tagPlacement === "outside", s = c`
765
+ <ul role="list" class="pkt-combobox__tag-list">
766
+ ${P(
767
+ this._value,
768
+ (l) => l,
769
+ (l, a) => {
770
+ const o = f(this.options, l), p = o == null ? void 0 : o.tagSkinColor;
771
+ return c`
772
+ <li
773
+ role="listitem"
774
+ @click=${e ? m : (d) => d.stopPropagation()}
775
+ @mousedown=${e ? m : (d) => d.preventDefault()}
776
+ >
777
+ <pkt-tag
778
+ skin=${p || "blue-dark"}
779
+ ?closeTag=${!this.disabled}
780
+ .buttonTabindex=${e ? void 0 : -1}
781
+ @close=${() => this.handleTagRemove(l)}
782
+ @keydown=${e ? m : (d) => this.handleTagKeydown(d, a)}
783
+ >
784
+ ${this.renderValueTag(o)}
785
+ </pkt-tag>
786
+ </li>
787
+ `;
788
+ }
789
+ )}
790
+ </ul>
791
+ `;
792
+ return i ? t : s;
793
+ }
794
+ renderValueTag(i) {
795
+ if (!i) return "";
796
+ switch (this.displayValueAs) {
797
+ case "prefixAndValue":
798
+ return c`<span class="pkt-combobox__value" data-focusfix=${this.id}
799
+ >${i.prefix || ""} ${i.value}</span
800
+ >`;
801
+ case "value":
802
+ return c`<span class="pkt-combobox__value" data-focusfix=${this.id}
803
+ >${i.value}</span
804
+ >`;
805
+ case "label":
806
+ default:
807
+ return c`<span class="pkt-combobox__value" data-focusfix=${this.id}
808
+ >${i.label || i.value}</span
809
+ >`;
810
+ }
811
+ }
812
+ };
813
+ F = Y([
814
+ M("pkt-combobox")
815
+ ], F);
816
+ export {
817
+ F as P
818
+ };