@webority/ui-elements 0.7.6 → 0.7.8

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.
@@ -76,7 +76,7 @@ var l = Symbol("wui.trustedHtml"), u = (e) => String(e ?? "").replace(/&/g, "&am
76
76
  ];
77
77
  }
78
78
  constructor() {
79
- super(), this._value = "", this._label = "", this._optionsProp = null, this._loading = !1, this._active = -1, this._timer = null, this._reqSeq = 0;
79
+ super(), this._value = "", this._label = "", this._optionsProp = null, this._loading = !1, this._active = -1, this._timer = null, this._reqSeq = 0, this._pendingSearch = null, this._typeahead = "", this._typeaheadTimer = null;
80
80
  try {
81
81
  this._internals = this.attachInternals();
82
82
  } catch {
@@ -84,7 +84,14 @@ var l = Symbol("wui.trustedHtml"), u = (e) => String(e ?? "").replace(/&/g, "&am
84
84
  }
85
85
  }
86
86
  connectedCallback() {
87
- this._rendered || (this._defaultCaptured ||= (this._defaultValue = this._value, !0), this.render());
87
+ if (!this._rendered) {
88
+ this._defaultCaptured ||= (this._defaultValue = this._value, !0), this.render();
89
+ return;
90
+ }
91
+ if (this._bindGlobal?.(), this._pendingSearch) {
92
+ let { query: e, seq: t } = this._pendingSearch;
93
+ clearTimeout(this._timer), this._timer = setTimeout(() => this._fireSearch(e, t), this._debounceMs);
94
+ }
88
95
  }
89
96
  formResetCallback() {
90
97
  this.value = this._defaultValue || "";
@@ -154,14 +161,16 @@ var l = Symbol("wui.trustedHtml"), u = (e) => String(e ?? "").replace(/&/g, "&am
154
161
  render() {
155
162
  this._snapshotDeclared();
156
163
  let e = this.getAttribute("placeholder") || "Search…", t = this.getAttribute("size"), n = t === "sm" ? " search-select-sm" : t === "lg" ? " search-select-lg" : "";
157
- this.innerHTML = `
164
+ this.id ||= `wui-autocomplete-${Math.random().toString(36).slice(2, 9)}`;
165
+ let r = `${this.id}-listbox`;
166
+ this._listboxId = r, this.innerHTML = `
158
167
  <div class="search-select${n}">
159
- <div class="input search-select-control search-select-ac" role="combobox" aria-haspopup="listbox" aria-expanded="false" aria-label="${m(this._accessibleName())}">
168
+ <div class="input search-select-control search-select-ac" role="combobox" aria-haspopup="listbox" aria-expanded="false" aria-controls="${m(r)}" aria-label="${m(this._accessibleName())}">
160
169
  <input class="search-select-input search-select-ac-input" placeholder="${m(e)}" aria-autocomplete="list" autocomplete="off"${this.hasAttribute("disabled") ? " disabled" : ""} />
161
170
  <span class="search-select-spinner spinner-border spinner-border-sm" role="status" aria-hidden="true" hidden></span>
162
171
  <button type="button" class="search-select-clear" aria-label="Clear" hidden><i class="bi bi-x" aria-hidden="true"></i></button>
163
172
  </div>
164
- <div class="search-select-menu search-select-menu-fixed" role="listbox" tabindex="-1" hidden>
173
+ <div class="search-select-menu search-select-menu-fixed" role="listbox" id="${m(r)}" tabindex="-1" hidden>
165
174
  <div class="search-select-options"></div>
166
175
  <div class="search-select-empty" hidden>No matches</div>
167
176
  <div class="search-select-hint" hidden>Type to search…</div>
@@ -199,31 +208,32 @@ var l = Symbol("wui.trustedHtml"), u = (e) => String(e ?? "").replace(/&/g, "&am
199
208
  let a = n.trim(), o = this._allowCustom && a && !this._matchesKnownOption(a) ? [...i, {
200
209
  value: a,
201
210
  custom: !0
202
- }] : i;
203
- t.optionsWrap.innerHTML = o.map((e) => {
211
+ }] : i, s = this._listboxId || `${this.id || "wui-autocomplete"}-listbox`;
212
+ t.optionsWrap.innerHTML = o.map((e, t) => {
213
+ let n = `${s}-opt-${t}`;
204
214
  if (e.custom) {
205
215
  let t = `Add “${u(e.value)}”`;
206
- return `<button type="button" role="option" class="search-select-option search-select-option-custom" data-value="${m(e.value)}" data-custom="true" aria-selected="false">${t}</button>`;
216
+ return `<button type="button" role="option" id="${m(n)}" class="search-select-option search-select-option-custom" data-value="${m(e.value)}" data-custom="true" aria-selected="false">${t}</button>`;
207
217
  }
208
- let t = String(e.value) === String(this._value);
209
- return `<button type="button" role="option" class="search-select-option${t ? " selected" : ""}" data-value="${m(e.value)}" aria-selected="${t}">${f(e)}</button>`;
210
- }).join(""), this._active = -1;
211
- let s = r.length < this._minChars;
212
- t.hint && (t.hint.hidden = !(this._remote && s && !i.length)), t.empty && (t.empty.hidden = this._loading || o.length > 0 || this._remote && s);
218
+ let r = String(e.value) === String(this._value);
219
+ return `<button type="button" role="option" id="${m(n)}" class="search-select-option${r ? " selected" : ""}" data-value="${m(e.value)}" aria-selected="${r}">${f(e)}</button>`;
220
+ }).join(""), this._active = -1, t.control?.removeAttribute("aria-activedescendant");
221
+ let c = r.length < this._minChars;
222
+ t.hint && (t.hint.hidden = !(this._remote && c && !i.length)), t.empty && (t.empty.hidden = this._loading || o.length > 0 || this._remote && c);
213
223
  }
214
224
  _wire() {
215
225
  this._teardown();
216
226
  let e = this._refs();
217
227
  if (!e.control || !e.input) return;
218
- let t = () => i(e.control, e.menu, { matchWidth: !0 }), n = () => this._optionEls().filter((e) => !e.hidden), r = (e) => {
219
- let t = n();
220
- this._active = e;
228
+ let t = () => i(e.control, e.menu, { matchWidth: !0 }), n = () => this._optionEls().filter((e) => !e.hidden), r = (t) => {
229
+ let r = n();
230
+ this._active = t;
221
231
  for (let e of this._optionEls()) e.classList.remove("is-active");
222
- e >= 0 && t[e] && (t[e].classList.add("is-active"), t[e].scrollIntoView({ block: "nearest" }));
232
+ t >= 0 && r[t] ? (r[t].classList.add("is-active"), r[t].scrollIntoView({ block: "nearest" }), e.control.setAttribute("aria-activedescendant", r[t].id)) : e.control.removeAttribute("aria-activedescendant");
223
233
  }, o = () => !e.menu.hidden, s = () => {
224
234
  e.menu.hidden = !1, e.control.setAttribute("aria-expanded", "true"), e.control.classList.add("open"), t(), this._renderOptions();
225
235
  }, l = () => {
226
- e.menu.hidden = !0, e.control.setAttribute("aria-expanded", "false"), e.control.classList.remove("open"), r(-1), this._syncInput();
236
+ e.menu.hidden = !0, e.control.setAttribute("aria-expanded", "false"), e.control.classList.remove("open"), r(-1), clearTimeout(this._typeaheadTimer), this._typeaheadTimer = null, this._typeahead = "", this._syncInput();
227
237
  }, u = (t) => {
228
238
  let n = t.dataset.custom === "true";
229
239
  this._value = t.dataset.value, this._label = n ? t.dataset.value : h(t.innerHTML), c(this, this._value), e.input.value = this._label, this.dispatchEvent(new CustomEvent("change", {
@@ -235,34 +245,49 @@ var l = Symbol("wui.trustedHtml"), u = (e) => String(e ?? "").replace(/&/g, "&am
235
245
  bubbles: !0,
236
246
  detail: { isCustom: !0 }
237
247
  })), l();
238
- };
239
- e.input.addEventListener("focus", () => s()), e.input.addEventListener("input", () => {
248
+ }, f = () => {
240
249
  let t = e.input.value;
241
250
  if (e.clear && (e.clear.hidden = !t), o() || s(), this._remote) {
242
- if (this._renderOptions(t), clearTimeout(this._timer), t.trim().length < this._minChars) return;
251
+ if (this._renderOptions(t), clearTimeout(this._timer), t.trim().length < this._minChars) {
252
+ this._pendingSearch = null;
253
+ return;
254
+ }
243
255
  let e = ++this._reqSeq;
244
- this._timer = setTimeout(() => {
245
- this.dispatchEvent(new CustomEvent("search", {
246
- bubbles: !0,
247
- detail: {
248
- query: t,
249
- seq: e
250
- }
251
- }));
252
- }, this._debounceMs);
256
+ this._pendingSearch = {
257
+ query: t,
258
+ seq: e
259
+ }, this._timer = setTimeout(() => this._fireSearch(t, e), this._debounceMs);
253
260
  } else this._renderOptions(t);
254
- }), e.input.addEventListener("keydown", (t) => {
255
- let i = n();
261
+ }, p = () => {
262
+ clearTimeout(this._typeaheadTimer), this._typeaheadTimer = null, this._typeahead = "";
263
+ }, m = (t) => {
264
+ let i = n(), a = t.target?.tagName === "INPUT" || t.target?.tagName === "TEXTAREA";
256
265
  if (t.key === "ArrowDown") t.preventDefault(), o() || s(), r(Math.min(this._active + 1, i.length - 1));
257
266
  else if (t.key === "ArrowUp") t.preventDefault(), r(Math.max(this._active - 1, 0));
258
- else if (t.key === "Enter") {
267
+ else if (t.key === "Home" && o() && !a) t.preventDefault(), i.length && r(0);
268
+ else if (t.key === "End" && o() && !a) t.preventDefault(), i.length && r(i.length - 1);
269
+ else if (t.key === "PageDown" && o() && !a) {
270
+ if (t.preventDefault(), !i.length) return;
271
+ let e = this._active < 0 ? 0 : this._active;
272
+ r(Math.min(e + 8, i.length - 1));
273
+ } else if (t.key === "PageUp" && o() && !a) {
274
+ if (t.preventDefault(), !i.length) return;
275
+ let e = this._active < 0 ? 0 : this._active;
276
+ r(Math.max(e - 8, 0));
277
+ } else if (t.key === "Enter") {
259
278
  if (i[this._active]) t.preventDefault(), u(i[this._active]);
260
279
  else if (this._allowCustom) {
261
280
  let n = e.input.value.trim();
262
281
  n && !this._matchesKnownOption(n) && (t.preventDefault(), d(n));
263
282
  }
264
- } else t.key === "Escape" && l();
265
- }), e.input.addEventListener("blur", (t) => {
283
+ } else if (t.key === "Escape") l();
284
+ else if (o() && t.key.length === 1 && !t.ctrlKey && !t.metaKey && !t.altKey && t.target?.tagName !== "INPUT" && t.target?.tagName !== "TEXTAREA") {
285
+ t.preventDefault(), clearTimeout(this._typeaheadTimer), this._typeahead += t.key.toLowerCase(), this._typeaheadTimer = setTimeout(p, 500);
286
+ let e = i.findIndex((e) => e.textContent.trim().toLowerCase().startsWith(this._typeahead));
287
+ e >= 0 && r(e);
288
+ }
289
+ };
290
+ e.input.addEventListener("focus", () => s()), e.input.addEventListener("input", f), e.input.addEventListener("keydown", m), e.menu.addEventListener("keydown", m), e.input.addEventListener("blur", (t) => {
266
291
  if (!this._allowCustom || t.relatedTarget && this.contains(t.relatedTarget)) return;
267
292
  let n = e.input.value.trim();
268
293
  !n || n === this._label || this._matchesKnownOption(n) || d(n);
@@ -274,14 +299,25 @@ var l = Symbol("wui.trustedHtml"), u = (e) => String(e ?? "").replace(/&/g, "&am
274
299
  t && r(this._optionEls().indexOf(t));
275
300
  }), e.optionsWrap.addEventListener("mouseleave", () => r(-1)), e.clear?.addEventListener("click", () => {
276
301
  this._value = "", this._label = "", c(this, ""), e.input.value = "", e.clear.hidden = !0, this._renderOptions(""), this.dispatchEvent(new Event("change", { bubbles: !0 })), e.input.focus();
277
- }), this._onDocClick = (e) => {
278
- o() && !this.contains(e.target) && l();
279
- }, document.addEventListener("click", this._onDocClick), a(this, () => {
280
- o() && t();
281
- });
302
+ }), this._bindGlobal = () => {
303
+ this._teardown(), this._onDocClick = (e) => {
304
+ o() && !this.contains(e.target) && l();
305
+ }, document.addEventListener("click", this._onDocClick), a(this, () => {
306
+ o() && t();
307
+ });
308
+ }, this._bindGlobal();
309
+ }
310
+ _fireSearch(e, t) {
311
+ this._pendingSearch = null, this.dispatchEvent(new CustomEvent("search", {
312
+ bubbles: !0,
313
+ detail: {
314
+ query: e,
315
+ seq: t
316
+ }
317
+ }));
282
318
  }
283
319
  _teardown() {
284
- this._onDocClick && document.removeEventListener("click", this._onDocClick), o(this), clearTimeout(this._timer);
320
+ this._onDocClick &&= (document.removeEventListener("click", this._onDocClick), null), o(this), clearTimeout(this._timer), clearTimeout(this._typeaheadTimer), this._typeaheadTimer = null, this._typeahead = "";
285
321
  }
286
322
  disconnectedCallback() {
287
323
  this._teardown();
@@ -314,17 +350,17 @@ var l = Symbol("wui.trustedHtml"), u = (e) => String(e ?? "").replace(/&/g, "&am
314
350
  m: t[2] - 1,
315
351
  d: +t[3]
316
352
  } : null;
317
- }, ee = (e) => {
353
+ }, x = (e) => {
318
354
  let t = b(e);
319
355
  return t ? `${v(t.d)} ${g[t.m].slice(0, 3)} ${t.y}` : "";
320
- }, x = (e, t) => new Date(e, t + 1, 0).getDate(), S = (e, t) => {
356
+ }, S = (e, t) => new Date(e, t + 1, 0).getDate(), C = (e, t) => {
321
357
  for (; t < 0;) t += 12, --e;
322
358
  for (; t > 11;) t -= 12, e += 1;
323
359
  return {
324
360
  y: e,
325
361
  m: t
326
362
  };
327
- }, te = class extends HTMLElement {
363
+ }, ee = class extends HTMLElement {
328
364
  static formAssociated = !0;
329
365
  static get observedAttributes() {
330
366
  return [
@@ -351,7 +387,11 @@ var l = Symbol("wui.trustedHtml"), u = (e) => String(e ?? "").replace(/&/g, "&am
351
387
  this._viewY = e.getFullYear(), this._viewM = e.getMonth(), this._mode = "days", this._focus = null, this._slide = "";
352
388
  }
353
389
  connectedCallback() {
354
- this._rendered || this.render();
390
+ if (!this._rendered) {
391
+ this.render();
392
+ return;
393
+ }
394
+ this._bindGlobal?.();
355
395
  }
356
396
  attributeChangedCallback(e, t, n) {
357
397
  this._rendered && (e === "value" ? (this._value = n || "", this._syncFormValue(), this._syncTrigger()) : e === "first-day" ? this.querySelector(".datepicker-pop")?.hidden || this._renderView() : this.render());
@@ -370,14 +410,14 @@ var l = Symbol("wui.trustedHtml"), u = (e) => String(e ?? "").replace(/&/g, "&am
370
410
  return Number.isInteger(e) && e >= 0 && e <= 6 ? e : 0;
371
411
  }
372
412
  render() {
373
- this._defaultValue === void 0 && (this._defaultValue = this.getAttribute("value") || ""), this._value = this.getAttribute("value") || this._value;
413
+ this._defaultValue === void 0 && (this._defaultValue = this.getAttribute("value") || "", this._value = this._defaultValue || this._value);
374
414
  let e = this.getAttribute("placeholder") || "Enter Date", t = b(this._value);
375
415
  t && (this._viewY = t.y, this._viewM = t.m);
376
416
  let n = this.getAttribute("size"), r = n === "sm" ? " input-sm" : n === "lg" ? " input-lg" : "", i = this.getAttribute("aria-label"), a = this.getAttribute("aria-describedby");
377
417
  this.innerHTML = `
378
418
  <div class="datepicker">
379
419
  <button type="button" class="input datepicker-trigger${r}${t ? " has-value" : ""}" aria-haspopup="dialog" aria-expanded="false"${this.hasAttribute("disabled") ? " disabled" : ""}${i ? ` aria-label="${u(i)}"` : ""}${a ? ` aria-describedby="${u(a)}"` : ""}>
380
- <span data-trigger-label class="${t ? "" : "search-select-placeholder"}">${t ? ee(this._value) : u(e)}</span>
420
+ <span data-trigger-label class="${t ? "" : "search-select-placeholder"}">${t ? x(this._value) : u(e)}</span>
381
421
  <i class="bi bi-calendar3" aria-hidden="true"></i>
382
422
  </button>
383
423
  <div class="datepicker-pop" role="dialog" aria-modal="false" hidden></div>
@@ -390,7 +430,7 @@ var l = Symbol("wui.trustedHtml"), u = (e) => String(e ?? "").replace(/&/g, "&am
390
430
  let e = this.querySelector(".datepicker-trigger"), t = this.querySelector("[data-trigger-label]");
391
431
  if (!t) return;
392
432
  let n = b(this._value);
393
- t.textContent = n ? ee(this._value) : this.getAttribute("placeholder") || "Enter Date", t.classList.toggle("search-select-placeholder", !n), e?.classList.toggle("has-value", !!n);
433
+ t.textContent = n ? x(this._value) : this.getAttribute("placeholder") || "Enter Date", t.classList.toggle("search-select-placeholder", !n), e?.classList.toggle("has-value", !!n);
394
434
  }
395
435
  _limits() {
396
436
  let e = b(this.getAttribute("min")), t = b(this.getAttribute("max")), n = e ? new Date(e.y, e.m, e.d).getTime() : -Infinity, r = t ? new Date(t.y, t.m, t.d).getTime() : Infinity;
@@ -401,7 +441,7 @@ var l = Symbol("wui.trustedHtml"), u = (e) => String(e ?? "").replace(/&/g, "&am
401
441
  },
402
442
  monthDisabled: (e, t) => {
403
443
  let i = new Date(e, t, 1).getTime();
404
- return new Date(e, t, x(e, t)).getTime() < n || i > r;
444
+ return new Date(e, t, S(e, t)).getTime() < n || i > r;
405
445
  },
406
446
  yearDisabled: (e) => {
407
447
  let t = new Date(e, 0, 1).getTime();
@@ -414,7 +454,7 @@ var l = Symbol("wui.trustedHtml"), u = (e) => String(e ?? "").replace(/&/g, "&am
414
454
  e && (this._mode === "months" ? e.innerHTML = this._monthsHtml() : this._mode === "years" ? e.innerHTML = this._yearsHtml() : e.innerHTML = this._daysHtml(), this._focusActive());
415
455
  }
416
456
  _daysHtml() {
417
- let e = this._firstDay(), t = (new Date(this._viewY, this._viewM, 1).getDay() - e + 7) % 7, n = x(this._viewY, this._viewM), r = b(this._value), i = /* @__PURE__ */ new Date(), { dayDisabled: a } = this._limits(), o = this._focus || r || {
457
+ let e = this._firstDay(), t = (new Date(this._viewY, this._viewM, 1).getDay() - e + 7) % 7, n = S(this._viewY, this._viewM), r = b(this._value), i = /* @__PURE__ */ new Date(), { dayDisabled: a } = this._limits(), o = this._focus || r || {
418
458
  y: this._viewY,
419
459
  m: this._viewM,
420
460
  d: 1
@@ -426,10 +466,10 @@ var l = Symbol("wui.trustedHtml"), u = (e) => String(e ?? "").replace(/&/g, "&am
426
466
  u ? "is-today" : "",
427
467
  l ? "is-selected" : ""
428
468
  ].filter(Boolean).join(" ")}" data-iso="${c}" role="gridcell" tabindex="${d && !f ? "0" : "-1"}"${l ? " aria-selected=\"true\"" : ""}${f ? " disabled aria-disabled=\"true\"" : ""}>${n}</button>`;
429
- }, c = "", l = S(this._viewY, this._viewM - 1), u = x(l.y, l.m);
469
+ }, c = "", l = C(this._viewY, this._viewM - 1), u = S(l.y, l.m);
430
470
  for (let e = t - 1; e >= 0; e--) c += s(l.y, l.m, u - e, !0);
431
471
  for (let e = 1; e <= n; e++) c += s(this._viewY, this._viewM, e, !1);
432
- let d = S(this._viewY, this._viewM + 1), f = (7 - (t + n) % 7) % 7;
472
+ let d = C(this._viewY, this._viewM + 1), f = (7 - (t + n) % 7) % 7;
433
473
  for (let e = 1; e <= f; e++) c += s(d.y, d.m, e, !0);
434
474
  let p = _.map((t, n) => _[(n + e) % 7]).map((e) => `<span>${e}</span>`).join("");
435
475
  return `
@@ -489,7 +529,7 @@ var l = Symbol("wui.trustedHtml"), u = (e) => String(e ?? "").replace(/&/g, "&am
489
529
  i(e, t);
490
530
  }
491
531
  _setFocus(e, t, n, r) {
492
- let { y: i, m: a } = S(e, t);
532
+ let { y: i, m: a } = C(e, t);
493
533
  this._focus = {
494
534
  y: i,
495
535
  m: a,
@@ -521,13 +561,13 @@ var l = Symbol("wui.trustedHtml"), u = (e) => String(e ?? "").replace(/&/g, "&am
521
561
  case "End": return n(6 - (new Date(t.y, t.m, t.d).getDay() - this._firstDay() + 7) % 7, "slide-next");
522
562
  case "PageUp": {
523
563
  e.preventDefault();
524
- let n = S(t.y, t.m - (e.shiftKey ? 12 : 1));
525
- return this._setFocus(n.y, n.m, Math.min(t.d, x(n.y, n.m)), "slide-prev");
564
+ let n = C(t.y, t.m - (e.shiftKey ? 12 : 1));
565
+ return this._setFocus(n.y, n.m, Math.min(t.d, S(n.y, n.m)), "slide-prev");
526
566
  }
527
567
  case "PageDown": {
528
568
  e.preventDefault();
529
- let n = S(t.y, t.m + (e.shiftKey ? 12 : 1));
530
- return this._setFocus(n.y, n.m, Math.min(t.d, x(n.y, n.m)), "slide-next");
569
+ let n = C(t.y, t.m + (e.shiftKey ? 12 : 1));
570
+ return this._setFocus(n.y, n.m, Math.min(t.d, S(n.y, n.m)), "slide-next");
531
571
  }
532
572
  case "Enter":
533
573
  case " ":
@@ -560,7 +600,7 @@ var l = Symbol("wui.trustedHtml"), u = (e) => String(e ?? "").replace(/&/g, "&am
560
600
  let t = e.target.closest("[data-nav]");
561
601
  if (t) {
562
602
  this._viewNavigated = !0, this._slide = Number(t.dataset.nav) < 0 ? "slide-prev" : "slide-next";
563
- let e = S(this._viewY, this._viewM + Number(t.dataset.nav));
603
+ let e = C(this._viewY, this._viewM + Number(t.dataset.nav));
564
604
  this._viewY = e.y, this._viewM = e.m, this._focus = {
565
605
  y: e.y,
566
606
  m: e.m,
@@ -610,22 +650,24 @@ var l = Symbol("wui.trustedHtml"), u = (e) => String(e ?? "").replace(/&/g, "&am
610
650
  s && !s.disabled && (this.value = s.dataset.iso, this.dispatchEvent(new Event("change", { bubbles: !0 })), this._close());
611
651
  }), this._onKeyBound = (e) => {
612
652
  r() && this._onKey(e);
613
- }, t.addEventListener("keydown", this._onKeyBound), this._onDocClick = (e) => {
614
- let t = this._popClick;
615
- this._popClick = !1, r() && !t && !this.contains(e.target) && this._close();
616
- }, document.addEventListener("click", this._onDocClick), this._onDocKey = (e) => {
617
- r() && e.key === "Escape" && this._close();
618
- }, document.addEventListener("keydown", this._onDocKey), a(this, () => {
619
- r() && this._position(e, t);
620
- }), this._syncFormValue();
653
+ }, t.addEventListener("keydown", this._onKeyBound), this._bindGlobal = () => {
654
+ this._teardown(), this._onDocClick = (e) => {
655
+ let t = this._popClick;
656
+ this._popClick = !1, r() && !t && !this.contains(e.target) && this._close();
657
+ }, document.addEventListener("click", this._onDocClick), this._onDocKey = (e) => {
658
+ r() && e.key === "Escape" && this._close();
659
+ }, document.addEventListener("keydown", this._onDocKey), a(this, () => {
660
+ r() && this._position(e, t);
661
+ });
662
+ }, this._bindGlobal(), this._syncFormValue();
621
663
  }
622
664
  _teardown() {
623
- this._onDocClick && document.removeEventListener("click", this._onDocClick), this._onDocKey && document.removeEventListener("keydown", this._onDocKey), o(this);
665
+ this._onDocClick &&= (document.removeEventListener("click", this._onDocClick), null), this._onDocKey &&= (document.removeEventListener("keydown", this._onDocKey), null), o(this);
624
666
  }
625
667
  disconnectedCallback() {
626
668
  this._teardown();
627
669
  }
628
- }, C = [
670
+ }, w = [
629
671
  "January",
630
672
  "February",
631
673
  "March",
@@ -638,7 +680,7 @@ var l = Symbol("wui.trustedHtml"), u = (e) => String(e ?? "").replace(/&/g, "&am
638
680
  "October",
639
681
  "November",
640
682
  "December"
641
- ], w = [
683
+ ], T = [
642
684
  "Su",
643
685
  "Mo",
644
686
  "Tu",
@@ -646,24 +688,24 @@ var l = Symbol("wui.trustedHtml"), u = (e) => String(e ?? "").replace(/&/g, "&am
646
688
  "Th",
647
689
  "Fr",
648
690
  "Sa"
649
- ], T = (e) => String(e).padStart(2, "0"), ne = (e, t, n) => `${e}-${T(t + 1)}-${T(n)}`, E = (e) => {
691
+ ], E = (e) => String(e).padStart(2, "0"), te = (e, t, n) => `${e}-${E(t + 1)}-${E(n)}`, D = (e) => {
650
692
  let t = /^(\d{4})-(\d{2})-(\d{2})$/.exec(e || "");
651
693
  return t ? {
652
694
  y: +t[1],
653
695
  m: t[2] - 1,
654
696
  d: +t[3]
655
697
  } : null;
656
- }, D = (e) => {
657
- let t = E(e);
658
- return t ? `${T(t.d)} ${C[t.m].slice(0, 3)} ${t.y}` : "";
659
- }, O = (e, t) => new Date(e, t + 1, 0).getDate(), k = (e, t) => {
698
+ }, O = (e) => {
699
+ let t = D(e);
700
+ return t ? `${E(t.d)} ${w[t.m].slice(0, 3)} ${t.y}` : "";
701
+ }, k = (e, t) => new Date(e, t + 1, 0).getDate(), A = (e, t) => {
660
702
  for (; t < 0;) t += 12, --e;
661
703
  for (; t > 11;) t -= 12, e += 1;
662
704
  return {
663
705
  y: e,
664
706
  m: t
665
707
  };
666
- }, A = class extends HTMLElement {
708
+ }, j = class extends HTMLElement {
667
709
  static formAssociated = !0;
668
710
  static get observedAttributes() {
669
711
  return [
@@ -694,7 +736,11 @@ var l = Symbol("wui.trustedHtml"), u = (e) => String(e ?? "").replace(/&/g, "&am
694
736
  this._viewY = e.getFullYear(), this._viewM = e.getMonth();
695
737
  }
696
738
  connectedCallback() {
697
- this._rendered || this.render();
739
+ if (!this._rendered) {
740
+ this.render();
741
+ return;
742
+ }
743
+ this._bindGlobal?.();
698
744
  }
699
745
  attributeChangedCallback(e, t, n) {
700
746
  this._rendered && (e === "start" || e === "end" ? (this._start = this.getAttribute("start") || "", this._end = this.getAttribute("end") || "", this._syncTrigger(), this._syncMirrors()) : this.render());
@@ -718,13 +764,13 @@ var l = Symbol("wui.trustedHtml"), u = (e) => String(e ?? "").replace(/&/g, "&am
718
764
  text: e,
719
765
  empty: !0
720
766
  } : {
721
- text: `${D(this._start) || "Start"} – ${D(this._end) || "End"}`,
767
+ text: `${O(this._start) || "Start"} – ${O(this._end) || "End"}`,
722
768
  empty: !1
723
769
  };
724
770
  }
725
771
  render() {
726
- this._defaultStart === void 0 && (this._defaultStart = this.getAttribute("start") || "", this._defaultEnd = this.getAttribute("end") || ""), this._start = this.getAttribute("start") || this._start, this._end = this.getAttribute("end") || this._end;
727
- let e = E(this._start);
772
+ this._defaultStart === void 0 && (this._defaultStart = this.getAttribute("start") || "", this._defaultEnd = this.getAttribute("end") || "", this._start = this._defaultStart || this._start, this._end = this._defaultEnd || this._end);
773
+ let e = D(this._start);
728
774
  e && (this._viewY = e.y, this._viewM = e.m);
729
775
  let t = this.getAttribute("size"), n = t === "sm" ? " input-sm" : t === "lg" ? " input-lg" : "", { text: r, empty: i } = this._label(), a = this.getAttribute("aria-label"), o = this.getAttribute("aria-describedby");
730
776
  this.innerHTML = `
@@ -758,24 +804,24 @@ var l = Symbol("wui.trustedHtml"), u = (e) => String(e ?? "").replace(/&/g, "&am
758
804
  r || (r = document.createElement("input"), r.type = "hidden", r.setAttribute("data-range-mirror", e), this.appendChild(r)), r.name = t, r.value = n || "", r.disabled = this.hasAttribute("disabled");
759
805
  }
760
806
  _limits() {
761
- let e = E(this.getAttribute("min")), t = E(this.getAttribute("max")), n = e ? new Date(e.y, e.m, e.d).getTime() : -Infinity, r = t ? new Date(t.y, t.m, t.d).getTime() : Infinity;
807
+ let e = D(this.getAttribute("min")), t = D(this.getAttribute("max")), n = e ? new Date(e.y, e.m, e.d).getTime() : -Infinity, r = t ? new Date(t.y, t.m, t.d).getTime() : Infinity;
762
808
  return (e, t, i) => {
763
809
  let a = new Date(e, t, i).getTime();
764
810
  return a < n || a > r;
765
811
  };
766
812
  }
767
813
  _monthHtml(e, t) {
768
- let n = this._firstDay(), r = (new Date(e, t, 1).getDay() - n + 7) % 7, i = O(e, t), a = this._limits(), o = w.map((e, t) => w[(t + n) % 7]).map((e) => `<span>${e}</span>`).join(""), s = (e, t, n, r) => {
769
- let i = ne(e, t, n), o = a(e, t, n);
814
+ let n = this._firstDay(), r = (new Date(e, t, 1).getDay() - n + 7) % 7, i = k(e, t), a = this._limits(), o = T.map((e, t) => T[(t + n) % 7]).map((e) => `<span>${e}</span>`).join(""), s = (e, t, n, r) => {
815
+ let i = te(e, t, n), o = a(e, t, n);
770
816
  return `<button type="button" class="${["datepicker-day", r ? "is-outside" : ""].filter(Boolean).join(" ")}" data-iso="${i}"${o ? " disabled" : ""}>${n}</button>`;
771
- }, c = "", l = k(e, t - 1), u = O(l.y, l.m);
817
+ }, c = "", l = A(e, t - 1), u = k(l.y, l.m);
772
818
  for (let e = r - 1; e >= 0; e--) c += s(l.y, l.m, u - e, !0);
773
819
  for (let n = 1; n <= i; n++) c += s(e, t, n, !1);
774
- let d = k(e, t + 1), f = (7 - (r + i) % 7) % 7;
820
+ let d = A(e, t + 1), f = (7 - (r + i) % 7) % 7;
775
821
  for (let e = 1; e <= f; e++) c += s(d.y, d.m, e, !0);
776
822
  return `
777
823
  <div class="daterange-cal">
778
- <div class="datepicker-month-label">${C[t]} ${e}</div>
824
+ <div class="datepicker-month-label">${w[t]} ${e}</div>
779
825
  <div class="datepicker-weekdays">${o}</div>
780
826
  <div class="datepicker-grid" role="grid">${c}</div>
781
827
  </div>`;
@@ -783,7 +829,7 @@ var l = Symbol("wui.trustedHtml"), u = (e) => String(e ?? "").replace(/&/g, "&am
783
829
  _renderView() {
784
830
  let e = this.querySelector(".daterange-pop");
785
831
  if (!e) return;
786
- let t = k(this._viewY, this._viewM + 1);
832
+ let t = A(this._viewY, this._viewM + 1);
787
833
  e.innerHTML = `
788
834
  <div class="daterange-head">
789
835
  <button type="button" class="datepicker-nav-btn" data-nav="-1" aria-label="Previous month"><i class="bi bi-chevron-left" aria-hidden="true"></i></button>
@@ -809,7 +855,7 @@ var l = Symbol("wui.trustedHtml"), u = (e) => String(e ?? "").replace(/&/g, "&am
809
855
  n.classList.toggle("is-range-start", i), n.classList.toggle("is-range-end", a), n.classList.toggle("in-range", o);
810
856
  }
811
857
  let i = e.querySelector("[data-range-hint]");
812
- i && (i.textContent = this._start ? this._end ? `${D(this._start)} – ${D(this._end)}` : "Pick an end date" : "Pick a start date");
858
+ i && (i.textContent = this._start ? this._end ? `${O(this._start)} – ${O(this._end)}` : "Pick an end date" : "Pick a start date");
813
859
  }
814
860
  _position(e, t) {
815
861
  i(e, t);
@@ -831,7 +877,7 @@ var l = Symbol("wui.trustedHtml"), u = (e) => String(e ?? "").replace(/&/g, "&am
831
877
  if (!e || !t) return;
832
878
  let r = () => !t.hidden;
833
879
  this._open = () => {
834
- let r = E(this._start);
880
+ let r = D(this._start);
835
881
  if (r) this._viewY = r.y, this._viewM = r.m;
836
882
  else {
837
883
  let e = /* @__PURE__ */ new Date();
@@ -844,7 +890,7 @@ var l = Symbol("wui.trustedHtml"), u = (e) => String(e ?? "").replace(/&/g, "&am
844
890
  this._popClick = !0;
845
891
  let t = e.target.closest("[data-nav]");
846
892
  if (t) {
847
- let e = k(this._viewY, this._viewM + Number(t.dataset.nav));
893
+ let e = A(this._viewY, this._viewM + Number(t.dataset.nav));
848
894
  this._viewY = e.y, this._viewM = e.m, this._renderView();
849
895
  return;
850
896
  }
@@ -857,22 +903,24 @@ var l = Symbol("wui.trustedHtml"), u = (e) => String(e ?? "").replace(/&/g, "&am
857
903
  }), t.addEventListener("mouseover", (e) => {
858
904
  let t = e.target.closest(".datepicker-day[data-iso]");
859
905
  t && this._start && !this._end && (this._hover = t.dataset.iso, this._paint());
860
- }), this._onDocClick = (e) => {
861
- let t = this._popClick;
862
- this._popClick = !1, r() && !t && !this.contains(e.target) && this._close();
863
- }, document.addEventListener("click", this._onDocClick), this._onDocKey = (e) => {
864
- r() && e.key === "Escape" && this._close();
865
- }, document.addEventListener("keydown", this._onDocKey), a(this, () => {
866
- r() && this._position(e, t);
867
- }), this._syncMirrors();
906
+ }), this._bindGlobal = () => {
907
+ this._teardown(), this._onDocClick = (e) => {
908
+ let t = this._popClick;
909
+ this._popClick = !1, r() && !t && !this.contains(e.target) && this._close();
910
+ }, document.addEventListener("click", this._onDocClick), this._onDocKey = (e) => {
911
+ r() && e.key === "Escape" && this._close();
912
+ }, document.addEventListener("keydown", this._onDocKey), a(this, () => {
913
+ r() && this._position(e, t);
914
+ });
915
+ }, this._bindGlobal(), this._syncMirrors();
868
916
  }
869
917
  _teardown() {
870
- this._onDocClick && document.removeEventListener("click", this._onDocClick), this._onDocKey && document.removeEventListener("keydown", this._onDocKey), o(this);
918
+ this._onDocClick &&= (document.removeEventListener("click", this._onDocClick), null), this._onDocKey &&= (document.removeEventListener("keydown", this._onDocKey), null), o(this);
871
919
  }
872
920
  disconnectedCallback() {
873
921
  this._teardown();
874
922
  }
875
- }, j = class extends HTMLElement {
923
+ }, ne = class extends HTMLElement {
876
924
  static formAssociated = !0;
877
925
  _accessibleName() {
878
926
  return this.getAttribute("aria-label") || this.getAttribute("placeholder") || "Select";
@@ -890,7 +938,7 @@ var l = Symbol("wui.trustedHtml"), u = (e) => String(e ?? "").replace(/&/g, "&am
890
938
  ];
891
939
  }
892
940
  constructor() {
893
- super(), this._values = [], this._optionsProp = null, this._active = -1;
941
+ super(), this._values = [], this._optionsProp = null, this._active = -1, this._typeahead = "", this._typeaheadTimer = null;
894
942
  try {
895
943
  this._internals = this.attachInternals();
896
944
  } catch {
@@ -900,11 +948,17 @@ var l = Symbol("wui.trustedHtml"), u = (e) => String(e ?? "").replace(/&/g, "&am
900
948
  connectedCallback() {
901
949
  if (!this._rendered) {
902
950
  if (!this._valuesInit && !this._optionsProp && !this._values.length) {
903
- let e = [...this.querySelectorAll(":scope > wui-option[selected]")].map((e) => e.getAttribute("value") ?? e.textContent.trim());
904
- e.length && (this._values = e.map(String));
951
+ let e = this.getAttribute("value");
952
+ if (e != null && e !== "") this._values = e.split(",").map((e) => e.trim()).filter(Boolean);
953
+ else {
954
+ let e = [...this.querySelectorAll(":scope > wui-option[selected]")].map((e) => e.getAttribute("value") ?? e.textContent.trim());
955
+ e.length && (this._values = e.map(String));
956
+ }
905
957
  }
906
958
  this._valuesInit = !0, this._defaultCaptured ||= (this._defaultValues = this._values.slice(), !0), this.render();
959
+ return;
907
960
  }
961
+ this._bindGlobal?.();
908
962
  }
909
963
  formResetCallback() {
910
964
  this.values = (this._defaultValues || []).slice();
@@ -916,7 +970,11 @@ var l = Symbol("wui.trustedHtml"), u = (e) => String(e ?? "").replace(/&/g, "&am
916
970
  return this._values.slice();
917
971
  }
918
972
  set values(e) {
919
- this._values = Array.isArray(e) ? e.map(String) : [], c(this, this._values.join(",")), this._rendered && this._renderControl();
973
+ if (this._values = Array.isArray(e) ? e.map(String) : [], c(this, this._values.join(",")), this._rendered) {
974
+ this._renderControl();
975
+ let e = this.querySelector(".search-select-input");
976
+ this._renderOptions(e ? e.value : "");
977
+ }
920
978
  }
921
979
  set options(e) {
922
980
  this._optionsProp = Array.isArray(e) ? e : null, this.isConnected && this.render();
@@ -949,14 +1007,16 @@ var l = Symbol("wui.trustedHtml"), u = (e) => String(e ?? "").replace(/&/g, "&am
949
1007
  render() {
950
1008
  this._snapshotDeclared();
951
1009
  let e = this.hasAttribute("searchable"), t = this.getAttribute("search-placeholder") || "Search…", n = this.getAttribute("icon"), r = this.getAttribute("size"), i = r === "sm" ? " search-select-sm" : r === "lg" ? " search-select-lg" : "";
952
- c(this, this._values.join(",")), this.innerHTML = `
1010
+ c(this, this._values.join(",")), this.id ||= `wui-multiselect-${Math.random().toString(36).slice(2, 9)}`;
1011
+ let a = `${this.id}-listbox`;
1012
+ this._listboxId = a, this.innerHTML = `
953
1013
  <div class="search-select${i}">
954
- <div class="input search-select-control search-select-multi" role="combobox" aria-haspopup="listbox" aria-expanded="false" aria-label="${M(this._accessibleName())}"${this.hasAttribute("disabled") ? " aria-disabled=\"true\"" : " tabindex=\"0\""}>
1014
+ <div class="input search-select-control search-select-multi" role="combobox" aria-haspopup="listbox" aria-expanded="false" aria-controls="${M(a)}" aria-label="${M(this._accessibleName())}"${this.hasAttribute("disabled") ? " aria-disabled=\"true\"" : " tabindex=\"0\""}>
955
1015
  ${n ? `<i class="bi bi-${M(n)} search-select-icon" aria-hidden="true"></i>` : ""}
956
1016
  <div class="ms-chips" data-chips></div>
957
1017
  <i class="bi bi-chevron-down search-select-caret" aria-hidden="true"></i>
958
1018
  </div>
959
- <div class="search-select-menu search-select-menu-fixed" role="listbox" aria-multiselectable="true" tabindex="-1" hidden>
1019
+ <div class="search-select-menu search-select-menu-fixed" role="listbox" id="${M(a)}" aria-multiselectable="true" tabindex="-1" hidden>
960
1020
  ${e ? `<div class="search-select-search"><i class="bi bi-search" aria-hidden="true"></i><input class="search-select-input" placeholder="${M(t)}" aria-autocomplete="list" /><button type="button" class="search-select-clear" aria-label="Clear search" hidden><i class="bi bi-x" aria-hidden="true"></i></button></div>` : ""}
961
1021
  <div class="search-select-options"></div>
962
1022
  <div class="search-select-empty" hidden>No matches</div>
@@ -971,7 +1031,7 @@ var l = Symbol("wui.trustedHtml"), u = (e) => String(e ?? "").replace(/&/g, "&am
971
1031
  e.innerHTML = `<span class="search-select-placeholder">${u(t)}</span>`;
972
1032
  return;
973
1033
  }
974
- e.innerHTML = this._values.map((e) => `<span class="chip chip-sm"><span class="chip-label">${this._labelHtmlFor(e)}</span><button type="button" class="chip-remove" data-remove="${M(e)}" aria-label="Remove ${re(this._labelFor(e))}"><i class="bi bi-x" aria-hidden="true"></i></button></span>`).join(""), this._collapseChips();
1034
+ e.innerHTML = this._values.map((e) => `<span class="chip chip-sm"><span class="chip-label">${this._labelHtmlFor(e)}</span><button type="button" class="chip-remove" data-remove="${M(e)}" aria-label="Remove ${M(re(this._labelFor(e)))}"><i class="bi bi-x" aria-hidden="true"></i></button></span>`).join(""), this._collapseChips();
975
1035
  }
976
1036
  _collapseChips() {
977
1037
  let e = this.querySelector("[data-chips]");
@@ -995,26 +1055,26 @@ var l = Symbol("wui.trustedHtml"), u = (e) => String(e ?? "").replace(/&/g, "&am
995
1055
  let t = this.querySelector(".search-select-options"), n = this.querySelector(".search-select-empty");
996
1056
  if (!t) return;
997
1057
  let r = (e || "").trim().toLowerCase(), i = this._readOptions();
998
- r && (i = i.filter((e) => re(e.label).toLowerCase().includes(r))), t.innerHTML = i.map((e) => {
999
- let t = this._values.includes(String(e.value));
1000
- return `<button type="button" role="option" class="search-select-option${t ? " selected" : ""}" data-value="${M(e.value)}" aria-selected="${t}"><span class="ms-opt-label">${f(e)}</span><span class="ms-check"><i class="bi bi-check" aria-hidden="true"></i></span></button>`;
1001
- }).join(""), n && (n.hidden = i.length > 0), this._active = -1;
1058
+ r && (i = i.filter((e) => re(e.label).toLowerCase().includes(r)));
1059
+ let a = this._listboxId || `${this.id || "wui-multiselect"}-listbox`;
1060
+ t.innerHTML = i.map((e, t) => {
1061
+ let n = this._values.includes(String(e.value));
1062
+ return `<button type="button" role="option" id="${M(`${a}-opt-${t}`)}" class="search-select-option${n ? " selected" : ""}" data-value="${M(e.value)}" aria-selected="${n}"><span class="ms-opt-label">${f(e)}</span><span class="ms-check"><i class="bi bi-check" aria-hidden="true"></i></span></button>`;
1063
+ }).join(""), n && (n.hidden = i.length > 0), this._active = -1, this.querySelector(".search-select-control")?.removeAttribute("aria-activedescendant");
1002
1064
  }
1003
1065
  _wire() {
1004
1066
  this._teardown();
1005
1067
  let e = this.querySelector(".search-select-control"), t = this.querySelector(".search-select-menu"), n = this.querySelector(".search-select-input"), r = this.querySelector(".search-select-clear"), o = this.querySelector(".search-select-options");
1006
1068
  if (!e || !t) return;
1007
- let s = () => this.hasAttribute("disabled");
1008
- !this._ro && typeof ResizeObserver < "u" && (this._ro = new ResizeObserver(() => this._collapseChips()), this._ro.observe(this));
1009
- let l = () => i(e, t, { matchWidth: !0 }), u = () => [...this.querySelectorAll(".search-select-option")], d = () => u().filter((e) => !e.hidden), f = (e) => {
1010
- let t = d();
1011
- this._active = e;
1069
+ let s = () => this.hasAttribute("disabled"), l = () => i(e, t, { matchWidth: !0 }), u = () => [...this.querySelectorAll(".search-select-option")], d = () => u().filter((e) => !e.hidden), f = (t) => {
1070
+ let n = d();
1071
+ this._active = t;
1012
1072
  for (let e of u()) e.classList.remove("is-active");
1013
- e >= 0 && t[e] && (t[e].classList.add("is-active"), t[e].scrollIntoView({ block: "nearest" }));
1073
+ t >= 0 && n[t] ? (n[t].classList.add("is-active"), n[t].scrollIntoView({ block: "nearest" }), e.setAttribute("aria-activedescendant", n[t].id)) : e.removeAttribute("aria-activedescendant");
1014
1074
  }, p = () => !t.hidden, m = () => {
1015
1075
  s() || (t.hidden = !1, e.setAttribute("aria-expanded", "true"), e.classList.add("open"), l(), n && (n.value = "", this._renderOptions(""), n.focus()));
1016
1076
  }, h = () => {
1017
- t.hidden = !0, e.setAttribute("aria-expanded", "false"), e.classList.remove("open"), f(-1);
1077
+ t.hidden = !0, e.setAttribute("aria-expanded", "false"), e.classList.remove("open"), f(-1), clearTimeout(this._typeaheadTimer), this._typeaheadTimer = null, this._typeahead = "";
1018
1078
  }, g = () => {
1019
1079
  c(this, this._values.join(",")), this.dispatchEvent(new Event("change", { bubbles: !0 }));
1020
1080
  }, _ = (e) => {
@@ -1040,31 +1100,54 @@ var l = Symbol("wui.trustedHtml"), u = (e) => String(e ?? "").replace(/&/g, "&am
1040
1100
  }), o.addEventListener("mouseleave", () => f(-1)), n?.addEventListener("input", () => {
1041
1101
  this._renderOptions(n.value), r && (r.hidden = !n.value), f(-1);
1042
1102
  });
1043
- let y = (t) => {
1044
- let r = d();
1045
- t.key === "ArrowDown" ? (t.preventDefault(), f(Math.min(this._active + 1, r.length - 1))) : t.key === "ArrowUp" ? (t.preventDefault(), f(Math.max(this._active - 1, 0))) : t.key === "Enter" ? (t.preventDefault(), r[this._active] && _(r[this._active].dataset.value)) : t.key === "Escape" ? (h(), e.focus()) : t.key === "Backspace" && !n?.value && this._values.length && v(this._values[this._values.length - 1]);
1103
+ let y = () => {
1104
+ clearTimeout(this._typeaheadTimer), this._typeaheadTimer = null, this._typeahead = "";
1105
+ }, b = (t) => {
1106
+ let r = d(), i = t.target?.tagName === "INPUT" || t.target?.tagName === "TEXTAREA";
1107
+ if (t.key === "ArrowDown") t.preventDefault(), f(Math.min(this._active + 1, r.length - 1));
1108
+ else if (t.key === "ArrowUp") t.preventDefault(), f(Math.max(this._active - 1, 0));
1109
+ else if (t.key === "Home" && !i) t.preventDefault(), r.length && f(0);
1110
+ else if (t.key === "End" && !i) t.preventDefault(), r.length && f(r.length - 1);
1111
+ else if (t.key === "PageDown" && !i) {
1112
+ if (t.preventDefault(), !r.length) return;
1113
+ let e = this._active < 0 ? 0 : this._active;
1114
+ f(Math.min(e + 8, r.length - 1));
1115
+ } else if (t.key === "PageUp" && !i) {
1116
+ if (t.preventDefault(), !r.length) return;
1117
+ let e = this._active < 0 ? 0 : this._active;
1118
+ f(Math.max(e - 8, 0));
1119
+ } else if (t.key === "Enter") t.preventDefault(), r[this._active] && _(r[this._active].dataset.value);
1120
+ else if (t.key === "Escape") h(), e.focus();
1121
+ else if (t.key === "Backspace" && !n?.value && this._values.length) v(this._values[this._values.length - 1]);
1122
+ else if (t.key.length === 1 && !t.ctrlKey && !t.metaKey && !t.altKey && t.target?.tagName !== "INPUT" && t.target?.tagName !== "TEXTAREA") {
1123
+ t.preventDefault(), clearTimeout(this._typeaheadTimer), this._typeahead += t.key.toLowerCase(), this._typeaheadTimer = setTimeout(y, 500);
1124
+ let e = r.findIndex((e) => e.textContent.trim().toLowerCase().startsWith(this._typeahead));
1125
+ e >= 0 && f(e);
1126
+ }
1046
1127
  };
1047
- n?.addEventListener("keydown", y), r?.addEventListener("click", () => {
1128
+ n?.addEventListener("keydown", b), r?.addEventListener("click", () => {
1048
1129
  n.value = "", this._renderOptions(""), r.hidden = !0, n.focus();
1049
1130
  }), e.addEventListener("keydown", (e) => {
1050
1131
  if (p()) {
1051
- y(e);
1132
+ b(e);
1052
1133
  return;
1053
1134
  }
1054
1135
  (e.key === "ArrowDown" || e.key === "Enter" || e.key === " ") && (e.preventDefault(), m());
1055
- }), this._onDocClick = (e) => {
1056
- p() && !this.contains(e.target) && h();
1057
- }, document.addEventListener("click", this._onDocClick), a(this, () => {
1058
- p() && l();
1059
- });
1136
+ }), this._bindGlobal = () => {
1137
+ this._teardown(), !this._ro && typeof ResizeObserver < "u" && (this._ro = new ResizeObserver(() => this._collapseChips()), this._ro.observe(this)), this._onDocClick = (e) => {
1138
+ p() && !this.contains(e.target) && h();
1139
+ }, document.addEventListener("click", this._onDocClick), a(this, () => {
1140
+ p() && l();
1141
+ });
1142
+ }, this._bindGlobal();
1060
1143
  }
1061
1144
  _teardown() {
1062
- this._onDocClick && document.removeEventListener("click", this._onDocClick), o(this);
1145
+ this._onDocClick &&= (document.removeEventListener("click", this._onDocClick), null), o(this), clearTimeout(this._typeaheadTimer), this._typeaheadTimer = null, this._typeahead = "";
1063
1146
  }
1064
1147
  disconnectedCallback() {
1065
1148
  this._teardown(), this._ro?.disconnect(), this._ro = null;
1066
1149
  }
1067
- }, M = (e) => String(e ?? "").replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;"), re = (e) => String(e ?? "").replace(/<[^>]*>/g, ""), ie = /[^0-9]/g, ae = /[^0-9a-zA-Z]/g, oe = class extends HTMLElement {
1150
+ }, M = (e) => String(e ?? "").replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;"), re = (e) => String(e ?? "").replace(/<[^>]*>/g, ""), ie = /[^0-9]/g, ae = /[^0-9a-zA-Z]/g, N = class extends HTMLElement {
1068
1151
  static formAssociated = !0;
1069
1152
  static get observedAttributes() {
1070
1153
  return [
@@ -1175,7 +1258,7 @@ var l = Symbol("wui.trustedHtml"), u = (e) => String(e ?? "").replace(/&/g, "&am
1175
1258
  disconnectedCallback() {
1176
1259
  this._onSelectionChange && document.removeEventListener("selectionchange", this._onSelectionChange);
1177
1260
  }
1178
- }, se = [
1261
+ }, oe = [
1179
1262
  [
1180
1263
  "AF",
1181
1264
  "Afghanistan",
@@ -2401,56 +2484,56 @@ var l = Symbol("wui.trustedHtml"), u = (e) => String(e ?? "").replace(/&/g, "&am
2401
2484
  "Zimbabwe",
2402
2485
  "263"
2403
2486
  ]
2404
- ], N = (e) => (se.find((t) => t[0] === e) || [
2487
+ ], P = (e) => (oe.find((t) => t[0] === e) || [
2405
2488
  "",
2406
2489
  "",
2407
2490
  ""
2408
- ])[2], P = (e) => `wui-flag wui-flag-${String(e).toLowerCase()}`, F = null, I = null;
2491
+ ])[2], F = (e) => `wui-flag wui-flag-${String(e).toLowerCase()}`, I = null, se = null;
2409
2492
  function ce() {
2410
- return F ? Promise.resolve(F) : (I ||= Promise.all([import("./libphonenumber-js-BcNT8oq0.js"), import("./examples.mobile.json-BMXTGiGC.js")]).then(([e, t]) => (F = {
2493
+ return I ? Promise.resolve(I) : (se ||= Promise.all([import("./libphonenumber-js-BcNT8oq0.js"), import("./examples.mobile.json-BMXTGiGC.js")]).then(([e, t]) => (I = {
2411
2494
  AsYouType: e.AsYouType,
2412
2495
  getExampleNumber: e.getExampleNumber,
2413
2496
  isValidPhoneNumber: e.isValidPhoneNumber,
2414
2497
  examples: t.default || t
2415
- }, F)).catch(() => null), I);
2498
+ }, I)).catch(() => null), se);
2416
2499
  }
2417
2500
  function L(e, t) {
2418
- if (!F || !t) return t;
2501
+ if (!I || !t) return t;
2419
2502
  try {
2420
- return new F.AsYouType(e).input(t);
2503
+ return new I.AsYouType(e).input(t);
2421
2504
  } catch {
2422
2505
  return t;
2423
2506
  }
2424
2507
  }
2425
2508
  function R(e) {
2426
- if (!F) return null;
2509
+ if (!I) return null;
2427
2510
  try {
2428
- return F.getExampleNumber(e, F.examples)?.formatNational() || null;
2511
+ return I.getExampleNumber(e, I.examples)?.formatNational() || null;
2429
2512
  } catch {
2430
2513
  return null;
2431
2514
  }
2432
2515
  }
2433
2516
  function z(e) {
2434
- if (!F || !e) return null;
2517
+ if (!I || !e) return null;
2435
2518
  try {
2436
- return F.isValidPhoneNumber(e);
2519
+ return I.isValidPhoneNumber(e);
2437
2520
  } catch {
2438
2521
  return null;
2439
2522
  }
2440
2523
  }
2441
2524
  function le(e) {
2442
- if (!F) return null;
2525
+ if (!I) return null;
2443
2526
  try {
2444
- let t = F.getExampleNumber(e, F.examples);
2527
+ let t = I.getExampleNumber(e, I.examples);
2445
2528
  return t?.nationalNumber ? t.nationalNumber.length : null;
2446
2529
  } catch {
2447
2530
  return null;
2448
2531
  }
2449
2532
  }
2450
2533
  function B(e) {
2451
- if (!F || !e?.trim().startsWith("+")) return null;
2534
+ if (!I || !e?.trim().startsWith("+")) return null;
2452
2535
  try {
2453
- let t = new F.AsYouType();
2536
+ let t = new I.AsYouType();
2454
2537
  t.input(e.trim());
2455
2538
  let n = t.getCountry();
2456
2539
  return n ? {
@@ -2481,119 +2564,170 @@ var V = class extends HTMLElement {
2481
2564
  } catch {
2482
2565
  this._internals = null;
2483
2566
  }
2484
- this._country = "IN", this._national = "";
2567
+ this._country = "IN", this._national = "", this._active = -1, this._committedValue = "";
2485
2568
  }
2486
2569
  connectedCallback() {
2487
- this._rendered || this.render();
2570
+ if (!this._rendered) {
2571
+ this.render();
2572
+ return;
2573
+ }
2574
+ this._bindGlobal?.();
2488
2575
  }
2489
2576
  attributeChangedCallback(e, t, n) {
2490
2577
  if (e === "value") {
2491
2578
  this.value = n;
2492
2579
  return;
2493
2580
  }
2494
- this._rendered && (e === "country" && (this._country = n || "IN"), this.render());
2581
+ this._rendered && (e === "country" && (this._country = n || "IN", this._suppressCountryRender) || this.render());
2495
2582
  }
2496
2583
  formResetCallback() {
2497
2584
  this.value = this._defaultValue || "";
2498
2585
  }
2499
2586
  get value() {
2500
- return this._national ? `+${N(this._country)}${this._national}` : "";
2587
+ return this._national ? `+${P(this._country)}${this._national}` : "";
2501
2588
  }
2502
2589
  set value(e) {
2503
2590
  let t = String(e ?? "").trim(), n = B(t);
2504
2591
  if (n) this._country = n.country, this._national = n.national.replace(/[^0-9]/g, "");
2505
2592
  else if (t.startsWith("+")) {
2506
- let e = t.replace(/[^0-9]/g, ""), n = String(N(this._country));
2593
+ let e = t.replace(/[^0-9]/g, ""), n = String(P(this._country));
2507
2594
  n && e.startsWith(n) && (e = e.slice(n.length)), this._national = e;
2508
2595
  } else this._national = t.replace(/[^0-9]/g, "");
2509
- n && this.getAttribute("country") !== this._country ? this.setAttribute("country", this._country) : this._rendered && this.render(), this._syncMirror();
2596
+ n && this.getAttribute("country") !== this._country ? this.setAttribute("country", this._country) : this._rendered && this.render(), this._committedValue = this.value, this._syncMirror();
2510
2597
  }
2511
2598
  _syncMirror() {
2512
2599
  c(this, this.value);
2513
2600
  }
2601
+ _emitInput() {
2602
+ this.dispatchEvent(new Event("input", { bubbles: !0 }));
2603
+ }
2604
+ _emitChange() {
2605
+ this._committedValue = this.value, this.dispatchEvent(new Event("change", { bubbles: !0 }));
2606
+ }
2514
2607
  render() {
2515
- this._defaultValue === void 0 && (this._defaultValue = this.getAttribute("value") || "");
2608
+ this._defaultValue === void 0 && (this._defaultValue = this.getAttribute("value") || ""), this._country = this.getAttribute("country") || this._country;
2516
2609
  let e = this.getAttribute("placeholder") || R(this._country) || "Enter phone number";
2517
- this._country = this.getAttribute("country") || this._country;
2518
- let t = se.map(([e, t, n]) => `<button type="button" role="option" class="country-dropdown-item${e === this._country ? " selected" : ""}" data-iso="${e}"><span class="${P(e)}" aria-hidden="true"></span><span class="country-name-text">${t}<span class="country-code-text">+${n}</span></span></button>`).join("");
2610
+ this.id ||= `wui-phone-${Math.random().toString(36).slice(2, 9)}`;
2611
+ let t = `${this.id}-listbox`;
2612
+ this._listboxId = t;
2613
+ let n = oe.map(([e, n, r], i) => `<button type="button" role="option" id="${H(`${t}-opt-${i}`)}" class="country-dropdown-item${e === this._country ? " selected" : ""}" data-iso="${e}" aria-selected="${e === this._country}"><span class="${F(e)}" aria-hidden="true"></span><span class="country-name-text">${n}<span class="country-code-text">+${r}</span></span></button>`).join("");
2519
2614
  this.innerHTML = `
2520
2615
  <div class="phone-input-wrap">
2521
2616
  <div class="phone-country-adornment">
2522
- <button type="button" class="country-toggle" aria-haspopup="listbox" aria-expanded="false"${this.hasAttribute("disabled") ? " disabled" : ""}>
2523
- <span class="${P(this._country)}" data-flag aria-hidden="true"></span>
2617
+ <button type="button" class="country-toggle" aria-haspopup="listbox" aria-expanded="false" aria-controls="${H(t)}"${this.hasAttribute("disabled") ? " disabled" : ""}>
2618
+ <span class="${F(this._country)}" data-flag aria-hidden="true"></span>
2524
2619
  <i class="bi bi-chevron-down phone-chevron" aria-hidden="true"></i>
2525
- <span class="phone-dial" data-dial>+${N(this._country)}</span>
2620
+ <span class="phone-dial" data-dial>+${P(this._country)}</span>
2526
2621
  </button>
2527
- <div class="country-dropdown-menu" role="listbox" hidden>
2528
- <div class="dropdown-search-wrapper"><span class="dropdown-search-icon"><i class="bi bi-search" aria-hidden="true"></i></span><input type="text" class="dropdown-search-input" placeholder="Search country or code" aria-label="Search countries" /></div>
2529
- <div class="country-list-scroll">${t}<div class="country-empty" hidden>No countries found</div></div>
2622
+ <div class="country-dropdown-menu" role="listbox" id="${H(t)}" tabindex="-1" hidden>
2623
+ <div class="dropdown-search-wrapper"><span class="dropdown-search-icon"><i class="bi bi-search" aria-hidden="true"></i></span><input type="text" class="dropdown-search-input" placeholder="Search country or code" aria-label="Search countries" aria-controls="${H(t)}" aria-autocomplete="list" /></div>
2624
+ <div class="country-list-scroll">${n}<div class="country-empty" hidden>No countries found</div></div>
2530
2625
  </div>
2531
2626
  </div>
2532
2627
  <input type="tel" class="input" placeholder="${H(e)}" value="${H(L(this._country, this._national))}"${this.getAttribute("aria-label") ? ` aria-label="${H(this.getAttribute("aria-label"))}"` : ""}${this.getAttribute("aria-describedby") ? ` aria-describedby="${H(this.getAttribute("aria-describedby"))}"` : ""}${this.hasAttribute("required") ? " required aria-required=\"true\"" : ""}${this.hasAttribute("disabled") ? " disabled" : ""} />
2533
2628
  </div>
2534
2629
  <div class="field-error" data-phone-error hidden></div>`, this._rendered = !0, c(this, this.value), this._wire();
2535
2630
  }
2631
+ _itemEls() {
2632
+ return [...this.querySelectorAll(".country-dropdown-item")];
2633
+ }
2634
+ _visibleItems() {
2635
+ return this._itemEls().filter((e) => !e.hidden);
2636
+ }
2536
2637
  _wire() {
2537
2638
  this._teardown();
2538
- let e = this.querySelector(".country-toggle"), t = this.querySelector(".phone-input-wrap"), n = this.querySelector(".country-dropdown-menu"), r = this.querySelector(".dropdown-search-input"), i = this.querySelector(".country-list-scroll"), a = this.querySelector(".country-empty"), o = this.querySelector("input[type=tel]"), s = this.querySelector("[data-flag]"), c = this.querySelector("[data-dial]");
2639
+ let e = this.querySelector(".country-toggle"), t = this.querySelector(".phone-input-wrap"), n = this.querySelector(".country-dropdown-menu"), r = this.querySelector(".dropdown-search-input"), s = this.querySelector(".country-list-scroll"), c = this.querySelector(".country-empty"), l = this.querySelector("input[type=tel]"), u = this.querySelector("[data-flag]"), d = this.querySelector("[data-dial]");
2539
2640
  if (!e || !n) return;
2540
- let l = () => !n.hidden, u = () => {
2541
- let r = (t || e).getBoundingClientRect(), i = n.offsetWidth || 320, a = n.offsetHeight || 320, o = window.innerHeight - r.bottom, s = o < a + 6 && r.top > o ? r.top - a - 6 : r.bottom + 6, c = Math.min(Math.max(8, r.left), Math.max(8, window.innerWidth - i - 8));
2542
- n.style.top = `${Math.max(8, s)}px`, n.style.left = `${c}px`;
2543
- }, d = () => {
2544
- n.hidden = !1, e.setAttribute("aria-expanded", "true"), r.value = "", p(""), u(), r.focus();
2545
- }, f = () => {
2546
- n.hidden = !0, e.setAttribute("aria-expanded", "false");
2547
- };
2548
- this._reposition = () => {
2549
- l() && u();
2550
- }, window.addEventListener("scroll", this._reposition, !0), window.addEventListener("resize", this._reposition);
2551
- let p = (e) => {
2641
+ let f = () => !n.hidden, p = () => i(t || e, n), m = (e) => {
2642
+ let t = this._visibleItems();
2643
+ this._active = e;
2644
+ for (let e of this._itemEls()) e.classList.remove("is-active");
2645
+ e >= 0 && t[e] ? (t[e].classList.add("is-active"), t[e].scrollIntoView({ block: "nearest" }), r?.setAttribute("aria-activedescendant", t[e].id)) : r?.removeAttribute("aria-activedescendant");
2646
+ }, h = () => {
2647
+ n.hidden = !1, e.setAttribute("aria-expanded", "true"), r.value = "", _(""), p(), r.focus(), m(this._visibleItems().findIndex((e) => e.classList.contains("selected")));
2648
+ }, g = () => {
2649
+ n.hidden = !0, e.setAttribute("aria-expanded", "false"), m(-1);
2650
+ }, _ = (e) => {
2552
2651
  let t = e.trim().toLowerCase(), n = 0;
2553
- for (let e of i.querySelectorAll(".country-dropdown-item")) {
2652
+ for (let e of this._itemEls()) {
2554
2653
  let r = !t || e.textContent.toLowerCase().includes(t);
2555
2654
  e.hidden = !r, r && (n += 1);
2556
2655
  }
2557
- a && (a.hidden = n > 0);
2558
- }, m = (e) => {
2559
- this._country = e, this.setAttribute("country", e), s && (s.className = P(e)), c && (c.textContent = `+${N(e)}`);
2560
- for (let t of i.querySelectorAll(".country-dropdown-item")) t.classList.toggle("selected", t.dataset.iso === e);
2561
- f(), this._syncMirror(), this.dispatchEvent(new Event("change", { bubbles: !0 }));
2656
+ c && (c.hidden = n > 0);
2657
+ }, v = (e) => {
2658
+ this._country = e, this.getAttribute("country") !== e && (this._suppressCountryRender = !0, this.setAttribute("country", e), this._suppressCountryRender = !1), u && (u.className = F(e)), d && (d.textContent = `+${P(e)}`);
2659
+ for (let t of this._itemEls()) {
2660
+ let n = t.dataset.iso === e;
2661
+ t.classList.toggle("selected", n), t.setAttribute("aria-selected", String(n));
2662
+ }
2663
+ !this.getAttribute("placeholder") && l && (l.placeholder = R(e) || "Enter phone number"), l && this._national && (l.value = L(e, this._national)), g(), this._syncMirror(), this._emitChange(), l?.focus();
2664
+ }, y = (t) => {
2665
+ let n = this._visibleItems();
2666
+ if (t.key === "ArrowDown") {
2667
+ if (t.preventDefault(), !f()) {
2668
+ h();
2669
+ return;
2670
+ }
2671
+ m(Math.min(this._active + 1, n.length - 1));
2672
+ } else if (t.key === "ArrowUp") {
2673
+ if (t.preventDefault(), !f()) return;
2674
+ m(Math.max(this._active - 1, 0));
2675
+ } else t.key === "Enter" ? (t.preventDefault(), f() && n[this._active] && v(n[this._active].dataset.iso)) : t.key === "Escape" && f() && (t.preventDefault(), g(), e.focus());
2562
2676
  };
2563
- e.addEventListener("click", () => l() ? f() : d()), r.addEventListener("input", () => p(r.value)), i.addEventListener("click", (e) => {
2677
+ e.addEventListener("click", () => f() ? g() : h()), e.addEventListener("keydown", (e) => {
2678
+ if (f()) {
2679
+ y(e);
2680
+ return;
2681
+ }
2682
+ (e.key === "ArrowDown" || e.key === "Enter" || e.key === " ") && (e.preventDefault(), h());
2683
+ }), r.addEventListener("input", () => {
2684
+ _(r.value);
2685
+ let e = this._visibleItems();
2686
+ m(e.length ? 0 : -1);
2687
+ }), s.addEventListener("click", (e) => {
2564
2688
  let t = e.target.closest(".country-dropdown-item");
2565
- t && m(t.dataset.iso);
2566
- });
2567
- let h = this.querySelector("[data-phone-error]"), g = (e) => {
2568
- if (o.classList.toggle("is-invalid", e), e ? o.setAttribute("aria-invalid", "true") : o.removeAttribute("aria-invalid"), h) {
2689
+ t && v(t.dataset.iso);
2690
+ }), s.addEventListener("mousemove", (e) => {
2691
+ let t = e.target.closest(".country-dropdown-item");
2692
+ t && m(this._visibleItems().indexOf(t));
2693
+ }), s.addEventListener("mouseleave", () => m(-1)), n.addEventListener("keydown", y);
2694
+ let b = this.querySelector("[data-phone-error]"), x = (e) => {
2695
+ if (l.classList.toggle("is-invalid", e), e ? l.setAttribute("aria-invalid", "true") : l.removeAttribute("aria-invalid"), b) {
2569
2696
  if (e) {
2570
2697
  let e = R(this._country);
2571
- h.textContent = e ? `Enter a valid phone number, e.g. ${e}` : "Enter a valid phone number";
2698
+ b.textContent = e ? `Enter a valid phone number, e.g. ${e}` : "Enter a valid phone number";
2572
2699
  }
2573
- h.hidden = !e;
2700
+ b.hidden = !e;
2574
2701
  }
2575
2702
  };
2576
- o.addEventListener("input", () => {
2577
- let e = o.value.replace(/[^0-9]/g, ""), t = le(this._country);
2578
- t && e.length > t && (e = e.slice(0, t)), this._national = e;
2579
- let n = L(this._country, this._national);
2580
- o.value !== n && (o.value = n), this._syncMirror(), this.dispatchEvent(new Event("change", { bubbles: !0 })), o.classList.contains("is-invalid") && (!this._national || z(this.value) === !0) && g(!1);
2581
- }), o.addEventListener("blur", () => {
2582
- g(this._national.length > 0 && z(this.value) === !1);
2583
- }), o.addEventListener("paste", (e) => {
2703
+ l.addEventListener("input", (e) => {
2704
+ e.stopPropagation();
2705
+ let t = l.value.replace(/[^0-9]/g, ""), n = le(this._country);
2706
+ n && t.length > n && (t = t.slice(0, n)), this._national = t;
2707
+ let r = L(this._country, this._national);
2708
+ l.value !== r && (l.value = r), this._syncMirror(), this._emitInput(), l.classList.contains("is-invalid") && (!this._national || z(this.value) === !0) && x(!1);
2709
+ }), l.addEventListener("change", (e) => e.stopPropagation()), l.addEventListener("blur", () => {
2710
+ x(this._national.length > 0 && z(this.value) === !1), this.value !== this._committedValue && this._emitChange();
2711
+ }), l.addEventListener("paste", (e) => {
2584
2712
  let t = B(e.clipboardData?.getData("text"));
2585
- t && (e.preventDefault(), this._national = t.national.replace(/[^0-9]/g, ""), t.country === this._country ? o.value = L(this._country, this._national) : this.setAttribute("country", t.country), this._syncMirror(), this.dispatchEvent(new Event("change", { bubbles: !0 })), this.querySelector("input[type=tel]")?.focus());
2586
- }), this._onDocClick = (e) => {
2587
- l() && !this.contains(e.target) && f();
2588
- }, document.addEventListener("click", this._onDocClick), ce().then((e) => {
2589
- if (!(!e || !o) && (this._national && (o.value = L(this._country, this._national)), !this.getAttribute("placeholder"))) {
2713
+ t && (e.preventDefault(), this._national = t.national.replace(/[^0-9]/g, ""), t.country === this._country ? l.value = L(this._country, this._national) : this.setAttribute("country", t.country), this._syncMirror(), this._emitInput(), this._emitChange(), this.querySelector("input[type=tel]")?.focus());
2714
+ }), this._bindGlobal = () => {
2715
+ this._teardownGlobals?.(), this._onDocClick = (e) => {
2716
+ f() && !this.contains(e.target) && g();
2717
+ }, document.addEventListener("click", this._onDocClick), a(this, () => {
2718
+ f() && p();
2719
+ });
2720
+ }, this._teardownGlobals = () => {
2721
+ this._onDocClick &&= (document.removeEventListener("click", this._onDocClick), null), o(this);
2722
+ }, this._bindGlobal(), ce().then((e) => {
2723
+ if (!(!e || !l.isConnected) && (this._national && (l.value = L(this._country, this._national)), !this.getAttribute("placeholder"))) {
2590
2724
  let e = R(this._country);
2591
- e && (o.placeholder = e);
2725
+ e && (l.placeholder = e);
2592
2726
  }
2593
2727
  }), this._syncMirror();
2594
2728
  }
2595
2729
  _teardown() {
2596
- this._reposition && (window.removeEventListener("scroll", this._reposition, !0), window.removeEventListener("resize", this._reposition)), this._onDocClick && document.removeEventListener("click", this._onDocClick);
2730
+ this._teardownGlobals?.();
2597
2731
  }
2598
2732
  disconnectedCallback() {
2599
2733
  this._teardown();
@@ -2625,10 +2759,14 @@ var V = class extends HTMLElement {
2625
2759
  } catch {
2626
2760
  this._internals = null;
2627
2761
  }
2628
- this._value = "", this._optionsProp = null, this._active = -1;
2762
+ this._value = "", this._optionsProp = null, this._active = -1, this._typeahead = "", this._typeaheadTimer = null;
2629
2763
  }
2630
2764
  connectedCallback() {
2631
- this._rendered || this.render();
2765
+ if (!this._rendered) {
2766
+ this.render();
2767
+ return;
2768
+ }
2769
+ this._bindGlobal?.();
2632
2770
  }
2633
2771
  attributeChangedCallback(e, t, n) {
2634
2772
  if (e === "value") {
@@ -2669,23 +2807,25 @@ var V = class extends HTMLElement {
2669
2807
  render() {
2670
2808
  this._defaultValue === void 0 && (this._defaultValue = this.getAttribute("value") || ""), this._snapshotDeclared();
2671
2809
  let e = this._readOptions(), t = this.hasAttribute("searchable"), n = this.hasAttribute("clearable"), r = this.getAttribute("size"), i = r === "sm" ? " search-select-sm" : r === "lg" ? " search-select-lg" : "", a = this.getAttribute("icon"), o = this.getAttribute("prefix"), s = this.getAttribute("placeholder") || "Select...", l = this.getAttribute("search-placeholder") || "Search...", d = e.find((e) => String(e.value) === String(this._value)) || e.find((e) => e.selected);
2672
- d && (this._value = String(d.value)), c(this, this._value);
2673
- let p = e.map((e) => {
2674
- let t = String(e.value) === String(this._value);
2675
- return `<button type="button" role="option" class="search-select-option${t ? " selected" : ""}" data-value="${W(e.value)}" aria-selected="${t}">${f(e)}</button>`;
2810
+ d && (this._value = String(d.value)), c(this, this._value), this.id ||= `wui-select-${Math.random().toString(36).slice(2, 9)}`;
2811
+ let p = `${this.id}-listbox`;
2812
+ this._listboxId = p;
2813
+ let m = e.map((e, t) => {
2814
+ let n = String(e.value) === String(this._value);
2815
+ return `<button type="button" role="option" id="${W(`${p}-opt-${t}`)}" class="search-select-option${n ? " selected" : ""}" data-value="${W(e.value)}" aria-selected="${n}">${f(e)}</button>`;
2676
2816
  }).join("");
2677
2817
  this.innerHTML = `
2678
2818
  <div class="search-select${this.hasAttribute("compact") ? " search-select-compact" : ""}${i}">
2679
- <button type="button" role="combobox" class="input search-select-control" aria-haspopup="listbox" aria-expanded="false" aria-label="${W(this._accessibleName())}"${this.hasAttribute("disabled") ? " disabled" : ""}>
2819
+ <button type="button" role="combobox" class="input search-select-control" aria-haspopup="listbox" aria-expanded="false" aria-controls="${W(p)}" aria-label="${W(this._accessibleName())}"${this.hasAttribute("disabled") ? " disabled" : ""}>
2680
2820
  ${a ? `<i class="bi bi-${W(a)} search-select-icon" aria-hidden="true"></i>` : ""}
2681
2821
  ${o ? `<span class="search-select-prefix">${u(o)}</span>` : ""}
2682
2822
  <span class="${d ? "" : "search-select-placeholder"}" data-label>${d ? f(d) : u(s)}</span>
2683
2823
  ${n ? "<span class=\"search-select-reset\" role=\"button\" aria-label=\"Clear selection\" hidden><i class=\"bi bi-x-lg\" aria-hidden=\"true\"></i></span>" : ""}
2684
2824
  <i class="bi bi-chevron-down search-select-caret" aria-hidden="true"></i>
2685
2825
  </button>
2686
- <div class="search-select-menu search-select-menu-fixed" role="listbox" tabindex="-1" hidden>
2826
+ <div class="search-select-menu search-select-menu-fixed" role="listbox" id="${W(p)}" tabindex="-1" hidden>
2687
2827
  ${t ? `<div class="search-select-search"><i class="bi bi-search" aria-hidden="true"></i><input class="search-select-input" placeholder="${W(l)}" aria-autocomplete="list" /><button type="button" class="search-select-clear" aria-label="Clear search" hidden><i class="bi bi-x" aria-hidden="true"></i></button></div>` : ""}
2688
- <div class="search-select-options">${p}<div class="search-select-empty" hidden>No matches</div></div>
2828
+ <div class="search-select-options">${m}<div class="search-select-empty" hidden>No matches</div></div>
2689
2829
  </div>
2690
2830
  </div>`, this._rendered = !0, c(this, this._value), this._wire(), this._syncReset();
2691
2831
  }
@@ -2728,11 +2868,11 @@ var V = class extends HTMLElement {
2728
2868
  let t = e.control.getBoundingClientRect();
2729
2869
  e.menu.style.width = "max-content", e.menu.style.minWidth = `${t.width}px`, e.menu.style.maxWidth = "280px", i(e.control, e.menu);
2730
2870
  } else i(e.control, e.menu, { matchWidth: !0 });
2731
- }, n = (e) => {
2732
- let t = this._visible();
2733
- this._active = e;
2871
+ }, n = (t) => {
2872
+ let n = this._visible();
2873
+ this._active = t;
2734
2874
  for (let e of this._optionEls()) e.classList.remove("is-active");
2735
- e >= 0 && t[e] && (t[e].classList.add("is-active"), t[e].scrollIntoView({ block: "nearest" }));
2875
+ t >= 0 && n[t] ? (n[t].classList.add("is-active"), n[t].scrollIntoView({ block: "nearest" }), e.control.setAttribute("aria-activedescendant", n[t].id)) : e.control.removeAttribute("aria-activedescendant");
2736
2876
  }, r = (t) => {
2737
2877
  let n = t.trim().toLowerCase(), r = 0;
2738
2878
  for (let e of this._optionEls()) {
@@ -2743,18 +2883,38 @@ var V = class extends HTMLElement {
2743
2883
  }, o = () => !e.menu.hidden, s = () => {
2744
2884
  e.menu.hidden = !1, e.control.setAttribute("aria-expanded", "true"), e.control.classList.add("open"), t(), e.search && (e.search.value = "", r(""), e.search.focus()), n(this._optionEls().findIndex((e) => e.classList.contains("selected")));
2745
2885
  }, c = () => {
2746
- e.menu.hidden = !0, e.control.setAttribute("aria-expanded", "false"), e.control.classList.remove("open"), n(-1);
2886
+ e.menu.hidden = !0, e.control.setAttribute("aria-expanded", "false"), e.control.classList.remove("open"), n(-1), clearTimeout(this._typeaheadTimer), this._typeaheadTimer = null, this._typeahead = "";
2747
2887
  }, l = (t) => {
2748
2888
  this.value = t.dataset.value, this.dispatchEvent(new Event("change", { bubbles: !0 })), c(), e.control.focus();
2749
- }, u = (t) => {
2750
- let r = this._visible();
2751
- t.key === "ArrowDown" ? (t.preventDefault(), n(Math.min(this._active + 1, r.length - 1))) : t.key === "ArrowUp" ? (t.preventDefault(), n(Math.max(this._active - 1, 0))) : t.key === "Enter" ? (t.preventDefault(), r[this._active] && l(r[this._active])) : t.key === "Escape" && (c(), e.control.focus());
2889
+ }, u = () => {
2890
+ clearTimeout(this._typeaheadTimer), this._typeaheadTimer = null, this._typeahead = "";
2891
+ }, d = (t) => {
2892
+ let r = this._visible(), i = t.target?.tagName === "INPUT" || t.target?.tagName === "TEXTAREA";
2893
+ if (t.key === "ArrowDown") t.preventDefault(), n(Math.min(this._active + 1, r.length - 1));
2894
+ else if (t.key === "ArrowUp") t.preventDefault(), n(Math.max(this._active - 1, 0));
2895
+ else if (t.key === "Home" && !i) t.preventDefault(), r.length && n(0);
2896
+ else if (t.key === "End" && !i) t.preventDefault(), r.length && n(r.length - 1);
2897
+ else if (t.key === "PageDown" && !i) {
2898
+ if (t.preventDefault(), !r.length) return;
2899
+ let e = this._active < 0 ? 0 : this._active;
2900
+ n(Math.min(e + 8, r.length - 1));
2901
+ } else if (t.key === "PageUp" && !i) {
2902
+ if (t.preventDefault(), !r.length) return;
2903
+ let e = this._active < 0 ? 0 : this._active;
2904
+ n(Math.max(e - 8, 0));
2905
+ } else if (t.key === "Enter") t.preventDefault(), r[this._active] && l(r[this._active]);
2906
+ else if (t.key === "Escape") c(), e.control.focus();
2907
+ else if (t.key.length === 1 && !t.ctrlKey && !t.metaKey && !t.altKey && t.target?.tagName !== "INPUT" && t.target?.tagName !== "TEXTAREA") {
2908
+ t.preventDefault(), clearTimeout(this._typeaheadTimer), this._typeahead += t.key.toLowerCase(), this._typeaheadTimer = setTimeout(u, 500);
2909
+ let e = r.findIndex((e) => e.textContent.trim().toLowerCase().startsWith(this._typeahead));
2910
+ e >= 0 && n(e);
2911
+ }
2752
2912
  };
2753
2913
  e.reset?.addEventListener("click", (t) => {
2754
2914
  t.stopPropagation(), this.value = "", this.dispatchEvent(new Event("change", { bubbles: !0 })), e.control.focus();
2755
2915
  }), e.control.addEventListener("click", () => o() ? c() : s()), e.control.addEventListener("keydown", (e) => {
2756
2916
  if (o()) {
2757
- u(e);
2917
+ d(e);
2758
2918
  return;
2759
2919
  }
2760
2920
  (e.key === "ArrowDown" || e.key === "Enter" || e.key === " ") && (e.preventDefault(), s());
@@ -2768,14 +2928,16 @@ var V = class extends HTMLElement {
2768
2928
  r(e.search.value), n(-1);
2769
2929
  }), e.clear?.addEventListener("click", () => {
2770
2930
  e.search.value = "", r(""), e.search.focus();
2771
- }), e.menu.addEventListener("keydown", u), this._onDocClick = (e) => {
2772
- o() && !this.contains(e.target) && c();
2773
- }, document.addEventListener("click", this._onDocClick), a(this, () => {
2774
- o() && t();
2775
- });
2931
+ }), e.menu.addEventListener("keydown", d), this._bindGlobal = () => {
2932
+ this._teardown(), this._onDocClick = (e) => {
2933
+ o() && !this.contains(e.target) && c();
2934
+ }, document.addEventListener("click", this._onDocClick), a(this, () => {
2935
+ o() && t();
2936
+ });
2937
+ }, this._bindGlobal();
2776
2938
  }
2777
2939
  _teardown() {
2778
- this._onDocClick && document.removeEventListener("click", this._onDocClick), o(this);
2940
+ this._onDocClick &&= (document.removeEventListener("click", this._onDocClick), null), o(this), clearTimeout(this._typeaheadTimer), this._typeaheadTimer = null, this._typeahead = "";
2779
2941
  }
2780
2942
  disconnectedCallback() {
2781
2943
  this._teardown();
@@ -2807,10 +2969,32 @@ var V = class extends HTMLElement {
2807
2969
  } catch {
2808
2970
  this._internals = null;
2809
2971
  }
2810
- this._value = 50, this._start = 25, this._end = 75, this._isDragging = !1, this._dragThumb = null, this._pointerDownListener = null, this._pointerMoveListener = null, this._pointerUpListener = null;
2972
+ this._value = 50, this._start = 25, this._end = 75, this._isDragging = !1, this._dragThumb = null, this._pointerDownListener = null, this._pointerMoveListener = null, this._pointerUpListener = null, this._thumbKeyListener = null, this._trackClickListener = null;
2811
2973
  }
2812
2974
  connectedCallback() {
2813
- this._rendered || this.render();
2975
+ if (!this._rendered) {
2976
+ this.render();
2977
+ return;
2978
+ }
2979
+ this._wire();
2980
+ }
2981
+ get value() {
2982
+ return this._value;
2983
+ }
2984
+ set value(e) {
2985
+ this._value = this._snapToStep(this._clamp(K(e, this._value))), this._syncValue(), this._syncMirrors();
2986
+ }
2987
+ get start() {
2988
+ return this._start;
2989
+ }
2990
+ set start(e) {
2991
+ this._start = Math.min(this._snapToStep(this._clamp(K(e, this._start))), this._end), this._syncValue(), this._syncMirrors();
2992
+ }
2993
+ get end() {
2994
+ return this._end;
2995
+ }
2996
+ set end(e) {
2997
+ this._end = Math.max(this._snapToStep(this._clamp(K(e, this._end))), this._start), this._syncValue(), this._syncMirrors();
2814
2998
  }
2815
2999
  attributeChangedCallback(e, t, n) {
2816
3000
  if (e === "value" || e === "start" || e === "end" || e === "min" || e === "max" || e === "step") {
@@ -2823,27 +3007,28 @@ var V = class extends HTMLElement {
2823
3007
  this._isRange() ? this._resetRange() : this._resetSingle();
2824
3008
  }
2825
3009
  _updateFromAttribute(e) {
2826
- let t = (e) => Number.parseFloat(e) || 0;
2827
- e === "value" ? this._value = this._snapToStep(this._clamp(t(this.getAttribute("value")))) : e === "start" ? this._start = this._snapToStep(this._clamp(t(this.getAttribute("start")))) : e === "end" && (this._end = this._snapToStep(this._clamp(t(this.getAttribute("end")))));
3010
+ e === "value" ? this._value = this._snapToStep(this._clamp(K(this.getAttribute("value"), this._value))) : e === "start" ? this._start = this._snapToStep(this._clamp(K(this.getAttribute("start"), this._start))) : e === "end" && (this._end = this._snapToStep(this._clamp(K(this.getAttribute("end"), this._end))));
2828
3011
  }
2829
3012
  _isRange() {
2830
3013
  return this.hasAttribute("range");
2831
3014
  }
2832
3015
  _min() {
2833
- return Number.parseFloat(this.getAttribute("min")) || 0;
3016
+ return K(this.getAttribute("min"), 0);
2834
3017
  }
2835
3018
  _max() {
2836
- return Number.parseFloat(this.getAttribute("max")) || 100;
3019
+ return K(this.getAttribute("max"), 100);
2837
3020
  }
2838
3021
  _step() {
2839
- return Number.parseFloat(this.getAttribute("step")) || 1;
3022
+ return K(this.getAttribute("step"), 1);
2840
3023
  }
2841
3024
  _clamp(e) {
2842
3025
  return Math.max(this._min(), Math.min(e, this._max()));
2843
3026
  }
2844
3027
  _snapToStep(e) {
2845
3028
  let t = this._step();
2846
- return t <= 0 ? e : Math.round(e / t) * t;
3029
+ if (t <= 0) return e;
3030
+ let n = this._min();
3031
+ return this._clamp(n + Math.round((e - n) / t) * t);
2847
3032
  }
2848
3033
  _captureDefaults() {
2849
3034
  this._defaultsCaptured ||= (this._isRange() ? (this._defaultStart = this._start, this._defaultEnd = this._end) : this._defaultValue = this._value, !0);
@@ -2858,7 +3043,7 @@ var V = class extends HTMLElement {
2858
3043
  this._captureDefaults();
2859
3044
  let e = this._min(), t = this._max(), n = this._isRange(), r = this.getAttribute("size"), i = r === "sm" ? " slider-sm" : r === "lg" ? " slider-lg" : "", a = this.hasAttribute("disabled");
2860
3045
  n ? (this._start = this._clamp(this._start), this._end = this._clamp(this._end), this._start > this._end && ([this._start, this._end] = [this._end, this._start])) : this._value = this._clamp(this._value);
2861
- let o = (n) => (n - e) / (t - e) * 100, s = n ? o(this._start) : 0, c = o(n ? this._end : this._value);
3046
+ let o = (n) => t === e ? 0 : (n - e) / (t - e) * 100, s = n ? o(this._start) : 0, c = o(n ? this._end : this._value);
2862
3047
  this.innerHTML = `
2863
3048
  <div class="slider${i}">
2864
3049
  <div class="slider-track" role="presentation"></div>
@@ -2911,7 +3096,7 @@ var V = class extends HTMLElement {
2911
3096
  }
2912
3097
  _syncValue() {
2913
3098
  if (!this._rendered) return;
2914
- let e = this._min(), t = this._max(), n = (n) => (n - e) / (t - e) * 100, r = this.querySelector(".slider-fill");
3099
+ let e = this._min(), t = this._max(), n = (n) => t === e ? 0 : (n - e) / (t - e) * 100, r = this.querySelector(".slider-fill");
2915
3100
  if (this._isRange()) {
2916
3101
  let e = n(this._start), t = n(this._end);
2917
3102
  r && (r.style.left = `${e}%`, r.style.right = `${100 - t}%`);
@@ -2946,8 +3131,8 @@ var V = class extends HTMLElement {
2946
3131
  _valueAtPosition(e) {
2947
3132
  let t = this.querySelector(".slider-track");
2948
3133
  if (!t) return this._min();
2949
- let n = t.getBoundingClientRect(), r = Math.max(0, Math.min(1, (e - n.left) / n.width)), i = this._min() + r * (this._max() - this._min()), a = this._step();
2950
- return Math.round(i / a) * a;
3134
+ let n = t.getBoundingClientRect(), r = Math.max(0, Math.min(1, (e - n.left) / n.width)), i = this._min() + r * (this._max() - this._min());
3135
+ return this._snapToStep(i);
2951
3136
  }
2952
3137
  _nearestThumb(e) {
2953
3138
  return Math.abs(e - this._start) <= Math.abs(e - this._end) ? "start" : "end";
@@ -2979,29 +3164,30 @@ var V = class extends HTMLElement {
2979
3164
  }
2980
3165
  }, this._pointerUpListener = () => {
2981
3166
  this._isDragging && (this._isDragging = !1, this._dragThumb = null, document.removeEventListener("pointermove", this._pointerMoveListener), document.removeEventListener("pointerup", this._pointerUpListener), this._syncMirrors(), this.dispatchEvent(new Event("change", { bubbles: !0 })));
2982
- }, e.forEach((e) => {
2983
- e.addEventListener("pointerdown", this._pointerDownListener), e.addEventListener("keydown", (t) => {
2984
- if (this.hasAttribute("disabled")) return;
2985
- let n = this._step(), r = n * 10, i = null, a = e.getAttribute("data-thumb");
2986
- t.key === "ArrowLeft" || t.key === "ArrowDown" ? (t.preventDefault(), i = (a === "end" ? this._end : a === "start" ? this._start : this._value) - n) : t.key === "ArrowRight" || t.key === "ArrowUp" ? (t.preventDefault(), i = (a === "end" ? this._end : a === "start" ? this._start : this._value) + n) : t.key === "PageDown" ? (t.preventDefault(), i = (a === "end" ? this._end : a === "start" ? this._start : this._value) - r) : t.key === "PageUp" ? (t.preventDefault(), i = (a === "end" ? this._end : a === "start" ? this._start : this._value) + r) : t.key === "Home" ? (t.preventDefault(), i = this._min()) : t.key === "End" && (t.preventDefault(), i = this._max()), i != null && (i = this._clamp(i), a === "single" ? this._value = i : a === "start" ? this._start = Math.min(i, this._end) : a === "end" && (this._end = Math.max(i, this._start)), this._syncValue(), this._syncMirrors(), this.dispatchEvent(new Event("change", { bubbles: !0 })));
2987
- });
2988
- }), t && t.addEventListener("click", (e) => {
3167
+ }, this._thumbKeyListener = (e) => {
3168
+ let t = e.currentTarget;
3169
+ if (this.hasAttribute("disabled")) return;
3170
+ let n = this._step(), r = n * 10, i = null, a = t.getAttribute("data-thumb"), o = a === "end" ? this._end : a === "start" ? this._start : this._value;
3171
+ e.key === "ArrowLeft" || e.key === "ArrowDown" ? (e.preventDefault(), i = o - n) : e.key === "ArrowRight" || e.key === "ArrowUp" ? (e.preventDefault(), i = o + n) : e.key === "PageDown" ? (e.preventDefault(), i = o - r) : e.key === "PageUp" ? (e.preventDefault(), i = o + r) : e.key === "Home" ? (e.preventDefault(), i = this._min()) : e.key === "End" && (e.preventDefault(), i = this._max()), i != null && (i = this._clamp(i), a === "single" ? this._value = i : a === "start" ? this._start = Math.min(i, this._end) : a === "end" && (this._end = Math.max(i, this._start)), this._syncValue(), this._syncMirrors(), this.dispatchEvent(new Event("change", { bubbles: !0 })));
3172
+ }, this._trackClickListener = (e) => {
2989
3173
  if (this.hasAttribute("disabled")) return;
2990
3174
  let t = this._valueAtPosition(e.clientX);
2991
- n ? this._nearestThumb(t) === "start" ? this._start = Math.min(t, this._end) : this._end = Math.max(t, this._start) : this._value = this._clamp(t), this._syncValue(), this._syncMirrors(), this.dispatchEvent(new Event("change", { bubbles: !0 }));
2992
- });
3175
+ n ? this._nearestThumb(t) === "start" ? this._start = Math.min(this._clamp(t), this._end) : this._end = Math.max(this._clamp(t), this._start) : this._value = this._clamp(t), this._syncValue(), this._syncMirrors(), this.dispatchEvent(new Event("change", { bubbles: !0 }));
3176
+ }, e.forEach((e) => {
3177
+ e.addEventListener("pointerdown", this._pointerDownListener), e.addEventListener("keydown", this._thumbKeyListener);
3178
+ }), t?.addEventListener("click", this._trackClickListener);
2993
3179
  }
2994
3180
  _teardown() {
2995
- this.querySelectorAll(".slider-thumb").forEach((e) => {
2996
- e.removeEventListener("pointerdown", this._pointerDownListener), e.removeEventListener("keydown", this._pointerMoveListener);
2997
- }), document.removeEventListener("pointermove", this._pointerMoveListener), document.removeEventListener("pointerup", this._pointerUpListener);
2998
- let e = this.querySelector(".slider-track");
2999
- e && e.removeEventListener("click", this._pointerUpListener);
3181
+ for (let e of this.querySelectorAll(".slider-thumb")) e.removeEventListener("pointerdown", this._pointerDownListener), e.removeEventListener("keydown", this._thumbKeyListener);
3182
+ document.removeEventListener("pointermove", this._pointerMoveListener), document.removeEventListener("pointerup", this._pointerUpListener), this._isDragging = !1, this._dragThumb = null, this.querySelector(".slider-track")?.removeEventListener("click", this._trackClickListener);
3000
3183
  }
3001
3184
  disconnectedCallback() {
3002
3185
  this._teardown();
3003
3186
  }
3004
- }, ue = (e) => String(e ?? "").replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;"), K = class extends HTMLElement {
3187
+ }, K = (e, t) => {
3188
+ let n = Number.parseFloat(e);
3189
+ return Number.isFinite(n) ? n : t;
3190
+ }, ue = (e) => String(e ?? "").replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;"), de = class extends HTMLElement {
3005
3191
  static formAssociated = !0;
3006
3192
  _accessibleName() {
3007
3193
  return this.getAttribute("aria-label") || this.getAttribute("placeholder") || "Add tags";
@@ -3012,7 +3198,9 @@ var V = class extends HTMLElement {
3012
3198
  "disabled",
3013
3199
  "size",
3014
3200
  "max-tags",
3015
- "aria-label"
3201
+ "aria-label",
3202
+ "separators",
3203
+ "allow-duplicates"
3016
3204
  ];
3017
3205
  }
3018
3206
  constructor() {
@@ -3026,19 +3214,31 @@ var V = class extends HTMLElement {
3026
3214
  connectedCallback() {
3027
3215
  if (!this._rendered) {
3028
3216
  if (!this._valuesInit && !this._values.length) {
3029
- let e = [...this.querySelectorAll(":scope > wui-tag")].map((e) => e.textContent.trim());
3030
- e.length && (this._values = e.map(String));
3217
+ let e = this.getAttribute("value");
3218
+ if (e != null && e !== "") this._values = e.split(",").map((e) => e.trim()).filter(Boolean);
3219
+ else {
3220
+ let e = [...this.querySelectorAll(":scope > wui-tag")].map((e) => e.textContent.trim());
3221
+ e.length && (this._values = e.map(String));
3222
+ }
3031
3223
  }
3032
3224
  this._valuesInit = !0, this._defaultCaptured ||= (this._defaultValues = this._values.slice(), !0), this.render();
3225
+ return;
3033
3226
  }
3227
+ this._wire();
3034
3228
  }
3035
3229
  formResetCallback() {
3036
3230
  this.values = (this._defaultValues || []).slice(), this._draftText = "";
3037
3231
  let e = this.querySelector("[data-input]");
3038
3232
  e && (e.value = "");
3039
3233
  }
3040
- attributeChangedCallback() {
3041
- this._rendered && this.render();
3234
+ attributeChangedCallback(e) {
3235
+ if (this._rendered) {
3236
+ if (e === "separators" || e === "allow-duplicates") {
3237
+ this._wire();
3238
+ return;
3239
+ }
3240
+ this.render();
3241
+ }
3042
3242
  }
3043
3243
  get values() {
3044
3244
  return this._values.slice();
@@ -3063,7 +3263,7 @@ var V = class extends HTMLElement {
3063
3263
  e.innerHTML = "";
3064
3264
  return;
3065
3265
  }
3066
- e.innerHTML = this._values.map((e) => `<span class="chip chip-sm"><span class="chip-label">${de(e)}</span><button type="button" class="chip-remove" data-remove="${q(e)}" aria-label="Remove ${q(e)}"><i class="bi bi-x" aria-hidden="true"></i></button></span>`).join("");
3266
+ e.innerHTML = this._values.map((e) => `<span class="chip chip-sm"><span class="chip-label">${fe(e)}</span><button type="button" class="chip-remove" data-remove="${q(e)}" aria-label="Remove ${q(e)}"><i class="bi bi-x" aria-hidden="true"></i></button></span>`).join("");
3067
3267
  }
3068
3268
  }
3069
3269
  _wire() {
@@ -3081,16 +3281,7 @@ var V = class extends HTMLElement {
3081
3281
  (!this._values.some((e) => a ? e === t : e.toLowerCase() === n) || a) && (this._values.push(t), this._renderControl(), s());
3082
3282
  }, u = (e) => {
3083
3283
  this._values = this._values.filter((t) => t !== e), this._renderControl(), s();
3084
- };
3085
- e.addEventListener("click", (e) => {
3086
- if (n()) return;
3087
- let r = e.target.closest("[data-remove]");
3088
- if (r) {
3089
- e.stopPropagation(), u(r.dataset.remove), t.focus();
3090
- return;
3091
- }
3092
- t.focus();
3093
- }), t.addEventListener("keydown", (e) => {
3284
+ }, d = (e) => {
3094
3285
  if (e.key === "Enter" && o.has("Enter")) {
3095
3286
  e.preventDefault(), l(t.value), t.value = "";
3096
3287
  return;
@@ -3109,7 +3300,7 @@ var V = class extends HTMLElement {
3109
3300
  return;
3110
3301
  }
3111
3302
  e.key === "Backspace" && !t.value && this._values.length && (e.preventDefault(), u(this._values[this._values.length - 1])), e.key === "Escape" && (t.value = "");
3112
- }), t.addEventListener("paste", (e) => {
3303
+ }, f = (e) => {
3113
3304
  e.preventDefault();
3114
3305
  let n = e.clipboardData.getData("text/plain"), a = [];
3115
3306
  for (let e of r) {
@@ -3122,22 +3313,28 @@ var V = class extends HTMLElement {
3122
3313
  a.length || a.push(n.trim());
3123
3314
  for (let e of a) if (l(e), i && this._values.length >= parseInt(i, 10)) break;
3124
3315
  t.value = "";
3125
- }), this._onDocClick = (e) => {
3316
+ };
3317
+ this._onControlClick = (e) => {
3318
+ if (n()) return;
3319
+ let r = e.target.closest("[data-remove]");
3320
+ if (r) {
3321
+ e.stopPropagation(), u(r.dataset.remove), t.focus();
3322
+ return;
3323
+ }
3324
+ t.focus();
3325
+ }, this._onInputKey = d, this._onInputPaste = f, e.addEventListener("click", this._onControlClick), t.addEventListener("keydown", this._onInputKey), t.addEventListener("paste", this._onInputPaste), this._onDocClick = (e) => {
3126
3326
  this.contains(e.target) || t.blur();
3127
3327
  }, document.addEventListener("click", this._onDocClick);
3128
3328
  }
3129
3329
  _teardown() {
3130
- this._onDocClick && document.removeEventListener("click", this._onDocClick);
3131
- let e = this.querySelector("[data-input]");
3132
- if (e) {
3133
- let t = e, n = t.cloneNode(!1);
3134
- t.replaceWith(n);
3135
- }
3330
+ this._onDocClick &&= (document.removeEventListener("click", this._onDocClick), null);
3331
+ let e = this.querySelector(".search-select-control"), t = this.querySelector("[data-input]");
3332
+ e && this._onControlClick && e.removeEventListener("click", this._onControlClick), t && this._onInputKey && (t.removeEventListener("keydown", this._onInputKey), t.removeEventListener("paste", this._onInputPaste));
3136
3333
  }
3137
3334
  disconnectedCallback() {
3138
3335
  this._teardown();
3139
3336
  }
3140
- }, de = (e) => String(e ?? "").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;"), q = (e) => String(e ?? "").replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;"), J = (e) => String(e).padStart(2, "0"), fe = (e, t) => `${J(e)}:${J(t)}`, Y = (e) => {
3337
+ }, fe = (e) => String(e ?? "").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;"), q = (e) => String(e ?? "").replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;"), J = (e) => String(e).padStart(2, "0"), pe = (e, t) => `${J(e)}:${J(t)}`, Y = (e) => {
3141
3338
  let t = /^(\d{2}):(\d{2})$/.exec(e || "");
3142
3339
  return t ? {
3143
3340
  h: +t[1],
@@ -3145,10 +3342,10 @@ var V = class extends HTMLElement {
3145
3342
  } : null;
3146
3343
  }, X = (e, t = "24") => {
3147
3344
  if (!e) return "";
3148
- if (t === "24") return fe(e.h, e.m);
3345
+ if (t === "24") return pe(e.h, e.m);
3149
3346
  let n = e.h % 12 || 12, r = e.h >= 12 ? "PM" : "AM";
3150
3347
  return `${n}:${J(e.m)} ${r}`;
3151
- }, pe = class extends HTMLElement {
3348
+ }, me = class extends HTMLElement {
3152
3349
  static formAssociated = !0;
3153
3350
  static get observedAttributes() {
3154
3351
  return [
@@ -3172,10 +3369,14 @@ var V = class extends HTMLElement {
3172
3369
  } catch {
3173
3370
  this._internals = null;
3174
3371
  }
3175
- this._value = "", this._focus = null;
3372
+ this._value = "", this._focus = null, this._typeahead = "", this._typeaheadTimer = null;
3176
3373
  }
3177
3374
  connectedCallback() {
3178
- this._rendered || this.render();
3375
+ if (!this._rendered) {
3376
+ this.render();
3377
+ return;
3378
+ }
3379
+ this._bindGlobal?.();
3179
3380
  }
3180
3381
  attributeChangedCallback(e, t, n) {
3181
3382
  this._rendered && (e === "value" ? (this._value = n || "", this._syncFormValue(), this._syncTrigger()) : this.render());
@@ -3190,7 +3391,7 @@ var V = class extends HTMLElement {
3190
3391
  this._value = e || "", c(this, this._value), this._syncTrigger();
3191
3392
  }
3192
3393
  render() {
3193
- this._defaultValue === void 0 && (this._defaultValue = this.getAttribute("value") || ""), this._value = this.getAttribute("value") || this._value;
3394
+ this._defaultValue === void 0 && (this._defaultValue = this.getAttribute("value") || "", this._value = this._defaultValue || this._value);
3194
3395
  let e = this.getAttribute("placeholder") || "Select time", t = Y(this._value), n = this.getAttribute("format") || "24", r = this.getAttribute("size"), i = r === "sm" ? " input-sm" : r === "lg" ? " input-lg" : "", a = this.getAttribute("aria-label"), o = this.getAttribute("aria-describedby");
3195
3396
  this.innerHTML = `
3196
3397
  <div class="timepicker">
@@ -3229,7 +3430,7 @@ var V = class extends HTMLElement {
3229
3430
  if (!e) return;
3230
3431
  let t = this.getAttribute("format") || "24", n = this._buildTimes(), r = Y(this._value), i = this._focus, a = "";
3231
3432
  for (let e = 0; e < n.length; e++) {
3232
- let o = n[e], s = fe(o.h, o.m), c = r && r.h === o.h && r.m === o.m;
3433
+ let o = n[e], s = pe(o.h, o.m), c = r && r.h === o.h && r.m === o.m;
3233
3434
  a += `<button type="button" class="timepicker-option${c ? " is-selected" : ""}" data-hm="${s}" role="option" tabindex="${i === e ? "0" : "-1"}"${c ? " aria-selected=\"true\"" : ""}>${X(o, t)}</button>`;
3234
3435
  }
3235
3436
  e.innerHTML = a, this._focusActive();
@@ -3256,6 +3457,26 @@ var V = class extends HTMLElement {
3256
3457
  this._focus = n, this._renderOptions();
3257
3458
  break;
3258
3459
  }
3460
+ case "Home":
3461
+ if (e.preventDefault(), !t.length) return;
3462
+ this._focus = 0, this._renderOptions();
3463
+ break;
3464
+ case "End":
3465
+ if (e.preventDefault(), !t.length) return;
3466
+ this._focus = t.length - 1, this._renderOptions();
3467
+ break;
3468
+ case "PageUp": {
3469
+ if (e.preventDefault(), !t.length) return;
3470
+ let n = this._focus == null || this._focus < 0 ? 0 : this._focus;
3471
+ this._focus = Math.max(n - 8, 0), this._renderOptions();
3472
+ break;
3473
+ }
3474
+ case "PageDown": {
3475
+ if (e.preventDefault(), !t.length) return;
3476
+ let n = this._focus == null || this._focus < 0 ? 0 : this._focus;
3477
+ this._focus = Math.min(n + 8, t.length - 1), this._renderOptions();
3478
+ break;
3479
+ }
3259
3480
  case "Enter":
3260
3481
  case " ":
3261
3482
  e.preventDefault(), t[this._focus] && (this.value = t[this._focus].dataset.hm, this.dispatchEvent(new Event("change", { bubbles: !0 })), this._close());
@@ -3263,7 +3484,13 @@ var V = class extends HTMLElement {
3263
3484
  case "Escape":
3264
3485
  this._close();
3265
3486
  break;
3266
- default:
3487
+ default: if (e.key.length === 1 && !e.ctrlKey && !e.metaKey && !e.altKey) {
3488
+ e.preventDefault(), clearTimeout(this._typeaheadTimer), this._typeahead += e.key.toLowerCase(), this._typeaheadTimer = setTimeout(() => {
3489
+ this._typeahead = "", this._typeaheadTimer = null;
3490
+ }, 500);
3491
+ let n = t.findIndex((e) => e.textContent.trim().toLowerCase().startsWith(this._typeahead));
3492
+ n >= 0 && (this._focus = n, this._renderOptions());
3493
+ }
3267
3494
  }
3268
3495
  }
3269
3496
  _wire() {
@@ -3276,7 +3503,7 @@ var V = class extends HTMLElement {
3276
3503
  let n = t.querySelector(".is-selected");
3277
3504
  n ? this._focus = [...t.querySelectorAll(".timepicker-option")].indexOf(n) : this._focus = 0, this._renderOptions(), t.querySelector("[tabindex=\"0\"]")?.focus();
3278
3505
  }, this._close = () => {
3279
- t.hidden = !0, e.setAttribute("aria-expanded", "false"), e.focus();
3506
+ t.hidden = !0, e.setAttribute("aria-expanded", "false"), clearTimeout(this._typeaheadTimer), this._typeaheadTimer = null, this._typeahead = "", e.focus();
3280
3507
  }, e.addEventListener("click", () => n() ? this._close() : this._open()), e.addEventListener("keydown", (e) => {
3281
3508
  (e.key === "Enter" || e.key === " " || e.key === "ArrowDown") && (e.preventDefault(), n() || this._open());
3282
3509
  }), t.addEventListener("click", (e) => {
@@ -3285,29 +3512,31 @@ var V = class extends HTMLElement {
3285
3512
  t && !t.disabled && (this.value = t.dataset.hm, this.dispatchEvent(new Event("change", { bubbles: !0 })), this._close());
3286
3513
  }), this._onKeyBound = (e) => {
3287
3514
  n() && this._onKey(e);
3288
- }, t.addEventListener("keydown", this._onKeyBound), this._onDocClick = (e) => {
3289
- let t = this._popClick;
3290
- this._popClick = !1, n() && !t && !this.contains(e.target) && this._close();
3291
- }, document.addEventListener("click", this._onDocClick), this._onDocKey = (e) => {
3292
- n() && e.key === "Escape" && this._close();
3293
- }, document.addEventListener("keydown", this._onDocKey), a(this, () => {
3294
- n() && this._position(e, t);
3295
- }), this._syncFormValue();
3515
+ }, t.addEventListener("keydown", this._onKeyBound), this._bindGlobal = () => {
3516
+ this._teardown(), this._onDocClick = (e) => {
3517
+ let t = this._popClick;
3518
+ this._popClick = !1, n() && !t && !this.contains(e.target) && this._close();
3519
+ }, document.addEventListener("click", this._onDocClick), this._onDocKey = (e) => {
3520
+ n() && e.key === "Escape" && this._close();
3521
+ }, document.addEventListener("keydown", this._onDocKey), a(this, () => {
3522
+ n() && this._position(e, t);
3523
+ });
3524
+ }, this._bindGlobal(), this._syncFormValue();
3296
3525
  }
3297
3526
  _teardown() {
3298
- this._onDocClick && document.removeEventListener("click", this._onDocClick), this._onDocKey && document.removeEventListener("keydown", this._onDocKey), o(this);
3527
+ this._onDocClick &&= (document.removeEventListener("click", this._onDocClick), null), this._onDocKey &&= (document.removeEventListener("keydown", this._onDocKey), null), o(this), clearTimeout(this._typeaheadTimer), this._typeaheadTimer = null, this._typeahead = "";
3299
3528
  }
3300
3529
  disconnectedCallback() {
3301
3530
  this._teardown();
3302
3531
  }
3303
- }, me = "image/png,image/jpeg,image/webp", he = 5, ge = {
3532
+ }, he = "image/png,image/jpeg,image/webp", ge = 5, _e = {
3304
3533
  "image/png": [".png"],
3305
3534
  "image/jpeg": [".jpg", ".jpeg"],
3306
3535
  "image/webp": [".webp"],
3307
3536
  "image/gif": [".gif"],
3308
3537
  "image/svg+xml": [".svg"],
3309
3538
  "application/pdf": [".pdf"]
3310
- }, _e = {
3539
+ }, ve = {
3311
3540
  "image/png": "PNG",
3312
3541
  "image/jpeg": "JPG",
3313
3542
  "image/webp": "WEBP",
@@ -3321,7 +3550,7 @@ var V = class extends HTMLElement {
3321
3550
  ".gif": "GIF",
3322
3551
  ".svg": "SVG",
3323
3552
  ".pdf": "PDF"
3324
- }, Z = (e) => String(e || "").split(",").map((e) => e.trim().toLowerCase()).filter(Boolean), Q = [
3553
+ }, Z = (e) => String(e || "").split(",").map((e) => e.trim().toLowerCase()).filter(Boolean), ye = [
3325
3554
  ".png",
3326
3555
  ".jpg",
3327
3556
  ".jpeg",
@@ -3332,44 +3561,44 @@ var V = class extends HTMLElement {
3332
3561
  ".avif",
3333
3562
  ".heic"
3334
3563
  ];
3335
- function ve(e) {
3564
+ function be(e) {
3336
3565
  if (!e) return !1;
3337
3566
  let t = typeof e == "object" && e.type ? String(e.type).toLowerCase() : "";
3338
3567
  if (t) return t.startsWith("image/");
3339
3568
  let n = typeof e == "string" ? e : e.name || e.url || "", r = String(n).toLowerCase();
3340
- return Q.some((e) => r.endsWith(e));
3569
+ return ye.some((e) => r.endsWith(e));
3341
3570
  }
3342
- function ye(e) {
3571
+ function xe(e) {
3343
3572
  let t = Z(e);
3344
- return t.length ? t.every((e) => e.startsWith(".") ? Q.includes(e) : e === "image/*" || e.startsWith("image/")) : !1;
3573
+ return t.length ? t.every((e) => e.startsWith(".") ? ye.includes(e) : e === "image/*" || e.startsWith("image/")) : !1;
3345
3574
  }
3346
- function be(e) {
3575
+ function Se(e) {
3347
3576
  let t = [];
3348
3577
  for (let n of Z(e)) {
3349
- let e = _e[n] || (n.startsWith(".") ? n.slice(1).toUpperCase() : n.toUpperCase());
3578
+ let e = ve[n] || (n.startsWith(".") ? n.slice(1).toUpperCase() : n.toUpperCase());
3350
3579
  t.includes(e) || t.push(e);
3351
3580
  }
3352
3581
  return t.length <= 1 ? t[0] || "supported" : `${t.slice(0, -1).join(", ")} or ${t[t.length - 1]}`;
3353
3582
  }
3354
- function xe(e, t) {
3583
+ function Ce(e, t) {
3355
3584
  let n = Z(t);
3356
3585
  if (!n.length) return !0;
3357
3586
  let r = (e.type || "").toLowerCase(), i = (e.name || "").toLowerCase();
3358
- return n.some((e) => e.startsWith(".") ? i.endsWith(e) : e.endsWith("/*") ? r.startsWith(e.slice(0, -1)) : r && r === e ? !0 : !r && (ge[e] || []).some((e) => i.endsWith(e)));
3587
+ return n.some((e) => e.startsWith(".") ? i.endsWith(e) : e.endsWith("/*") ? r.startsWith(e.slice(0, -1)) : r && r === e ? !0 : !r && (_e[e] || []).some((e) => i.endsWith(e)));
3359
3588
  }
3360
- function Se(e, t = {}) {
3589
+ function we(e, t = {}) {
3361
3590
  if (!e) return null;
3362
- let n = t.accept === void 0 ? me : t.accept, r = t.maxSizeMb || 5;
3363
- return xe(e, n) ? e.size > r * 1024 * 1024 ? `Keep the file under ${r} MB.` : null : `Choose a ${be(n)} file.`;
3591
+ let n = t.accept === void 0 ? he : t.accept, r = t.maxSizeMb || 5;
3592
+ return Ce(e, n) ? e.size > r * 1024 * 1024 ? `Keep the file under ${r} MB.` : null : `Choose a ${Se(n)} file.`;
3364
3593
  }
3365
3594
  //#endregion
3366
3595
  //#region src/index.js
3367
- var $ = (e, t) => {
3596
+ var Q = (e, t) => {
3368
3597
  typeof customElements < "u" && !customElements.get(e) && customElements.define(e, t);
3369
3598
  };
3370
- function Ce() {
3371
- $("wui-select", U), $("wui-phone", V), $("wui-datepicker", te), $("wui-date-range", A), $("wui-slider", G), $("wui-timepicker", pe), $("wui-autocomplete", p), $("wui-multiselect", j), $("wui-taginput", K), $("wui-otp", oe), $("wui-status-icon", n);
3599
+ function $() {
3600
+ Q("wui-select", U), Q("wui-phone", V), Q("wui-datepicker", ee), Q("wui-date-range", j), Q("wui-slider", G), Q("wui-timepicker", me), Q("wui-autocomplete", p), Q("wui-multiselect", ne), Q("wui-taginput", de), Q("wui-otp", N), Q("wui-status-icon", n);
3372
3601
  }
3373
- Ce();
3602
+ $();
3374
3603
  //#endregion
3375
- export { me as DEFAULT_IMAGE_ACCEPT, he as DEFAULT_MAX_SIZE_MB, t as STATUS_TONES, p as WuiAutocomplete, te as WuiDatePicker, A as WuiDateRange, j as WuiMultiSelect, oe as WuiOtp, V as WuiPhone, U as WuiSelect, G as WuiSlider, n as WuiStatusIcon, K as WuiTagInput, pe as WuiTimePicker, be as acceptLabel, Ce as defineWeborityElements, ve as isImageFile, ye as isImageOnlyAccept, xe as matchesAccept, Se as validateFile };
3604
+ export { he as DEFAULT_IMAGE_ACCEPT, ge as DEFAULT_MAX_SIZE_MB, t as STATUS_TONES, p as WuiAutocomplete, ee as WuiDatePicker, j as WuiDateRange, ne as WuiMultiSelect, N as WuiOtp, V as WuiPhone, U as WuiSelect, G as WuiSlider, n as WuiStatusIcon, de as WuiTagInput, me as WuiTimePicker, Se as acceptLabel, $ as defineWeborityElements, be as isImageFile, xe as isImageOnlyAccept, Ce as matchesAccept, we as validateFile };