@helixui/library 3.2.0-next.98 → 3.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (146) hide show
  1. package/custom-elements.json +30 -18
  2. package/dist/components/hx-alert/hx-alert.styles.d.ts.map +1 -1
  3. package/dist/components/hx-alert/index.js +1 -1
  4. package/dist/components/hx-banner/hx-banner.styles.d.ts.map +1 -1
  5. package/dist/components/hx-banner/index.js +1 -1
  6. package/dist/components/hx-button/hx-button.d.ts +8 -6
  7. package/dist/components/hx-button/hx-button.d.ts.map +1 -1
  8. package/dist/components/hx-button/hx-button.styles.d.ts.map +1 -1
  9. package/dist/components/hx-button/index.js +1 -1
  10. package/dist/components/hx-checkbox/hx-checkbox.styles.d.ts.map +1 -1
  11. package/dist/components/hx-checkbox/index.js +1 -1
  12. package/dist/components/hx-code-snippet/hx-code-snippet.styles.d.ts.map +1 -1
  13. package/dist/components/hx-code-snippet/index.js +1 -1
  14. package/dist/components/hx-combobox/hx-combobox.styles.d.ts.map +1 -1
  15. package/dist/components/hx-combobox/index.js +1 -1
  16. package/dist/components/hx-date-picker/hx-date-picker.styles.d.ts.map +1 -1
  17. package/dist/components/hx-date-picker/index.js +1 -1
  18. package/dist/components/hx-link/hx-link.styles.d.ts.map +1 -1
  19. package/dist/components/hx-link/index.js +1 -1
  20. package/dist/components/hx-list/hx-list-item.styles.d.ts.map +1 -1
  21. package/dist/components/hx-list/index.js +1 -1
  22. package/dist/components/hx-radio-group/hx-radio.styles.d.ts.map +1 -1
  23. package/dist/components/hx-radio-group/index.js +1 -1
  24. package/dist/components/hx-rating/hx-rating.styles.d.ts.map +1 -1
  25. package/dist/components/hx-rating/index.js +1 -1
  26. package/dist/components/hx-select/hx-select.styles.d.ts.map +1 -1
  27. package/dist/components/hx-select/index.js +1 -1
  28. package/dist/components/hx-side-nav/hx-side-nav.d.ts +4 -3
  29. package/dist/components/hx-side-nav/hx-side-nav.d.ts.map +1 -1
  30. package/dist/components/hx-side-nav/hx-side-nav.styles.d.ts.map +1 -1
  31. package/dist/components/hx-side-nav/index.js +1 -1
  32. package/dist/components/hx-slider/hx-slider.styles.d.ts.map +1 -1
  33. package/dist/components/hx-slider/index.js +1 -1
  34. package/dist/components/hx-split-button/hx-split-button.styles.d.ts.map +1 -1
  35. package/dist/components/hx-split-button/index.js +1 -1
  36. package/dist/components/hx-switch/hx-switch.styles.d.ts.map +1 -1
  37. package/dist/components/hx-switch/index.js +1 -1
  38. package/dist/components/hx-tabs/hx-tab-panel.styles.d.ts.map +1 -1
  39. package/dist/components/hx-tabs/hx-tab.styles.d.ts.map +1 -1
  40. package/dist/components/hx-tabs/index.js +1 -1
  41. package/dist/components/hx-text-input/hx-text-input.styles.d.ts.map +1 -1
  42. package/dist/components/hx-text-input/index.js +1 -1
  43. package/dist/components/hx-textarea/hx-textarea.styles.d.ts.map +1 -1
  44. package/dist/components/hx-textarea/index.js +1 -1
  45. package/dist/components/hx-theme/hx-theme.d.ts +14 -2
  46. package/dist/components/hx-theme/hx-theme.d.ts.map +1 -1
  47. package/dist/components/hx-theme/index.js +1 -1
  48. package/dist/components/hx-toggle-button/hx-toggle-button.styles.d.ts.map +1 -1
  49. package/dist/components/hx-toggle-button/index.js +1 -1
  50. package/dist/components/hx-tree-view/hx-tree-view.styles.d.ts.map +1 -1
  51. package/dist/components/hx-tree-view/index.js +1 -1
  52. package/dist/css/helix-all.css +122 -120
  53. package/dist/css/helix-core.css +53 -23
  54. package/dist/css/helix-data.css +20 -6
  55. package/dist/css/helix-feedback.css +3 -12
  56. package/dist/css/helix-forms.css +16 -63
  57. package/dist/css/helix-navigation.css +28 -8
  58. package/dist/css/helix-tokens.css +8 -8
  59. package/dist/css/helix-utility.css +2 -8
  60. package/dist/css/hx-alert.css +1 -4
  61. package/dist/css/hx-banner.css +2 -8
  62. package/dist/css/hx-button.css +52 -19
  63. package/dist/css/hx-checkbox.css +1 -4
  64. package/dist/css/hx-code-snippet.css +20 -6
  65. package/dist/css/hx-combobox.css +2 -8
  66. package/dist/css/hx-date-picker.css +5 -21
  67. package/dist/css/hx-link.css +1 -4
  68. package/dist/css/hx-rating.css +1 -2
  69. package/dist/css/hx-select.css +1 -4
  70. package/dist/css/hx-side-nav.css +27 -6
  71. package/dist/css/hx-slider.css +1 -4
  72. package/dist/css/hx-split-button.css +2 -8
  73. package/dist/css/hx-switch.css +1 -4
  74. package/dist/css/hx-text-input.css +2 -8
  75. package/dist/css/hx-textarea.css +1 -4
  76. package/dist/css/hx-toggle-button.css +1 -4
  77. package/dist/css/hx-tree-view.css +1 -2
  78. package/dist/css/index.css +1 -1
  79. package/dist/css/manifest.json +20 -18
  80. package/dist/index.js +22 -22
  81. package/dist/shared/{hx-alert-C597yHpD.js → hx-alert-CLn7CstP.js} +2 -5
  82. package/dist/shared/hx-alert-CLn7CstP.js.map +1 -0
  83. package/dist/shared/{hx-banner-Cxd7eFUP.js → hx-banner-D3DzpfcP.js} +7 -13
  84. package/dist/shared/hx-banner-D3DzpfcP.js.map +1 -0
  85. package/dist/shared/{hx-button-9OUjJnk7.js → hx-button-DPY6SPVT.js} +58 -25
  86. package/dist/shared/hx-button-DPY6SPVT.js.map +1 -0
  87. package/dist/shared/{hx-checkbox-DBD-gMoz.js → hx-checkbox-D7xma9YH.js} +6 -9
  88. package/dist/shared/hx-checkbox-D7xma9YH.js.map +1 -0
  89. package/dist/shared/{hx-code-snippet-CJrFeyz0.js → hx-code-snippet-fVV3Z2DZ.js} +55 -41
  90. package/dist/shared/hx-code-snippet-fVV3Z2DZ.js.map +1 -0
  91. package/dist/shared/{hx-combobox-ClhNRAS5.js → hx-combobox-DDzqNKEW.js} +6 -12
  92. package/dist/shared/hx-combobox-DDzqNKEW.js.map +1 -0
  93. package/dist/shared/{hx-date-picker-BJm7Yrda.js → hx-date-picker-2iRG1p74.js} +12 -28
  94. package/dist/shared/hx-date-picker-2iRG1p74.js.map +1 -0
  95. package/dist/shared/{hx-link-9Ig2DW6L.js → hx-link-C-O6vq0Q.js} +2 -5
  96. package/dist/shared/hx-link-C-O6vq0Q.js.map +1 -0
  97. package/dist/shared/{hx-list-CkphGi9T.js → hx-list-MyEhh8c7.js} +3 -5
  98. package/dist/shared/hx-list-MyEhh8c7.js.map +1 -0
  99. package/dist/shared/{hx-nav-item-DH2tXcj1.js → hx-nav-item-xqRPOCWX.js} +58 -37
  100. package/dist/shared/hx-nav-item-xqRPOCWX.js.map +1 -0
  101. package/dist/shared/{hx-radio-dFjUAost.js → hx-radio-CJvNU2yP.js} +2 -5
  102. package/dist/shared/{hx-radio-dFjUAost.js.map → hx-radio-CJvNU2yP.js.map} +1 -1
  103. package/dist/shared/{hx-rating-CGtsejNf.js → hx-rating-C3QP53k9.js} +2 -3
  104. package/dist/shared/hx-rating-C3QP53k9.js.map +1 -0
  105. package/dist/shared/{hx-select-Bf4usFts.js → hx-select-C8fEHQhC.js} +2 -5
  106. package/dist/shared/hx-select-C8fEHQhC.js.map +1 -0
  107. package/dist/shared/{hx-slider-m0aEClH1.js → hx-slider-Blmv_rwS.js} +23 -26
  108. package/dist/shared/hx-slider-Blmv_rwS.js.map +1 -0
  109. package/dist/shared/{hx-split-button-BxDFfx4D.js → hx-split-button-Djnc5Aeg.js} +3 -9
  110. package/dist/shared/hx-split-button-Djnc5Aeg.js.map +1 -0
  111. package/dist/shared/{hx-switch-DvAW4YY-.js → hx-switch-BrZFaRue.js} +6 -9
  112. package/dist/shared/hx-switch-BrZFaRue.js.map +1 -0
  113. package/dist/shared/{hx-tab-panel-SWOEHuJc.js → hx-tab-panel-DspCrKqo.js} +3 -9
  114. package/dist/shared/{hx-tab-panel-SWOEHuJc.js.map → hx-tab-panel-DspCrKqo.js.map} +1 -1
  115. package/dist/shared/{hx-text-input-Bn7Gn8CI.js → hx-text-input-D6FlOZM-.js} +3 -9
  116. package/dist/shared/hx-text-input-D6FlOZM-.js.map +1 -0
  117. package/dist/shared/{hx-textarea-Jx1xnhgv.js → hx-textarea-CNG590KY.js} +6 -9
  118. package/dist/shared/hx-textarea-CNG590KY.js.map +1 -0
  119. package/dist/shared/{hx-theme-BiyQ7UUK.js → hx-theme-BsefFWTO.js} +83 -113
  120. package/dist/shared/hx-theme-BsefFWTO.js.map +1 -0
  121. package/dist/shared/{hx-toggle-button-DPAIh_Xo.js → hx-toggle-button-iLiYrMbD.js} +2 -5
  122. package/dist/shared/hx-toggle-button-iLiYrMbD.js.map +1 -0
  123. package/dist/shared/{hx-tree-item-Dt0Ozqyr.js → hx-tree-item-C2CiWuDE.js} +2 -3
  124. package/dist/shared/hx-tree-item-C2CiWuDE.js.map +1 -0
  125. package/figma-inventory.json +34 -19
  126. package/package.json +2 -2
  127. package/dist/shared/hx-alert-C597yHpD.js.map +0 -1
  128. package/dist/shared/hx-banner-Cxd7eFUP.js.map +0 -1
  129. package/dist/shared/hx-button-9OUjJnk7.js.map +0 -1
  130. package/dist/shared/hx-checkbox-DBD-gMoz.js.map +0 -1
  131. package/dist/shared/hx-code-snippet-CJrFeyz0.js.map +0 -1
  132. package/dist/shared/hx-combobox-ClhNRAS5.js.map +0 -1
  133. package/dist/shared/hx-date-picker-BJm7Yrda.js.map +0 -1
  134. package/dist/shared/hx-link-9Ig2DW6L.js.map +0 -1
  135. package/dist/shared/hx-list-CkphGi9T.js.map +0 -1
  136. package/dist/shared/hx-nav-item-DH2tXcj1.js.map +0 -1
  137. package/dist/shared/hx-rating-CGtsejNf.js.map +0 -1
  138. package/dist/shared/hx-select-Bf4usFts.js.map +0 -1
  139. package/dist/shared/hx-slider-m0aEClH1.js.map +0 -1
  140. package/dist/shared/hx-split-button-BxDFfx4D.js.map +0 -1
  141. package/dist/shared/hx-switch-DvAW4YY-.js.map +0 -1
  142. package/dist/shared/hx-text-input-Bn7Gn8CI.js.map +0 -1
  143. package/dist/shared/hx-textarea-Jx1xnhgv.js.map +0 -1
  144. package/dist/shared/hx-theme-BiyQ7UUK.js.map +0 -1
  145. package/dist/shared/hx-toggle-button-DPAIh_Xo.js.map +0 -1
  146. package/dist/shared/hx-tree-item-Dt0Ozqyr.js.map +0 -1
@@ -1,9 +1,9 @@
1
- import { css as u, html as p, nothing as h } from "lit";
2
- import { property as r, state as c, customElement as f } from "lit/decorators.js";
3
- import { classMap as x } from "lit/directives/class-map.js";
4
- import { a as m } from "./forced-colors-CTEDFRGa.js";
1
+ import { css as f, html as p, nothing as h } from "lit";
2
+ import { property as i, state as c, customElement as m } from "lit/decorators.js";
3
+ import { classMap as u } from "lit/directives/class-map.js";
4
+ import { a as x } from "./forced-colors-CTEDFRGa.js";
5
5
  import { H as b } from "./helix-element-BNEYeiys.js";
6
- const v = u`
6
+ const v = f`
7
7
  :host {
8
8
  display: block;
9
9
  }
@@ -83,7 +83,8 @@ const v = u`
83
83
  min-width: var(--hx-touch-target-min, 2.75rem);
84
84
  min-height: var(--hx-touch-target-min, 2.75rem);
85
85
  padding: var(--hx-space-1, 0.25rem) var(--hx-space-2, 0.5rem);
86
- border: var(--hx-border-width-thin, 1px) solid var(--hx-color-border-strong, #66787b);
86
+ border: var(--hx-border-width-thin, 1px) solid
87
+ var(--hx-color-border-on-dark-strong, rgba(255, 255, 255, 0.7));
87
88
  border-radius: var(--hx-border-radius-sm, 0.25rem);
88
89
  /* Copy button sits on the always-dark block snippet surface; uses inverse family for contrast on the terminal background. */
89
90
  background-color: var(--hx-color-surface-inverse, #0d1825);
@@ -108,8 +109,14 @@ const v = u`
108
109
  }
109
110
 
110
111
  .code-snippet__copy-button:focus-visible {
111
- outline: var(--hx-focus-ring-width, 2px) solid
112
- var(--hx-focus-ring-color, var(--hx-color-primary-600, #0f7078));
112
+ /* Always-dark terminal surface — uses primary-400 (#6AB1B1, 7.27:1 on #0d1825)
113
+ instead of the light-mode --hx-focus-ring-color (primary-600, 3.07:1 — razor
114
+ above the 3:1 UI floor with no headroom). Deliberate primitive-tier consumption:
115
+ there is no semantic focus-ring-on-dark alias today — the dark.color.focus-ring
116
+ override at tokens.json only fires under theme=dark, but this surface is dark in
117
+ every theme. Tracked for promotion to a semantic alias in a future token-cascade
118
+ follow-up. */
119
+ outline: var(--hx-focus-ring-width, 2px) solid var(--hx-color-primary-400, #6ab1b1);
113
120
  outline-offset: var(--hx-focus-ring-offset, 2px);
114
121
  }
115
122
 
@@ -128,7 +135,8 @@ const v = u`
128
135
  min-height: var(--hx-touch-target-min, 2.75rem);
129
136
  padding: var(--hx-space-2, 0.5rem) var(--hx-space-4, 1rem);
130
137
  border: none;
131
- border-top: var(--hx-border-width-thin, 1px) solid var(--hx-color-border-strong, #66787b);
138
+ border-top: var(--hx-border-width-thin, 1px) solid
139
+ var(--hx-color-border-on-dark-strong, rgba(255, 255, 255, 0.7));
132
140
  /* Expand button is attached to the always-dark block snippet — inverse family maintains the terminal aesthetic. */
133
141
  background-color: var(--hx-color-surface-inverse, #0d1825);
134
142
  color: var(--hx-color-text-inverse, #ffffff);
@@ -149,8 +157,14 @@ const v = u`
149
157
  }
150
158
 
151
159
  .code-snippet__expand-button:focus-visible {
152
- outline: var(--hx-focus-ring-width, 2px) solid
153
- var(--hx-focus-ring-color, var(--hx-color-primary-600, #0f7078));
160
+ /* Always-dark terminal surface — uses primary-400 (#6AB1B1, 7.27:1 on #0d1825)
161
+ instead of the light-mode --hx-focus-ring-color (primary-600, 3.07:1 — razor
162
+ above the 3:1 UI floor with no headroom). Deliberate primitive-tier consumption:
163
+ there is no semantic focus-ring-on-dark alias today — the dark.color.focus-ring
164
+ override at tokens.json only fires under theme=dark, but this surface is dark in
165
+ every theme. Tracked for promotion to a semantic alias in a future token-cascade
166
+ follow-up. */
167
+ outline: var(--hx-focus-ring-width, 2px) solid var(--hx-color-primary-400, #6ab1b1);
154
168
  outline-offset: var(--hx-focus-ring-offset, 2px);
155
169
  }
156
170
 
@@ -211,7 +225,7 @@ const v = u`
211
225
  border: 0;
212
226
  }
213
227
  `;
214
- var y = Object.defineProperty, g = Object.getOwnPropertyDescriptor, i = (e, t, n, a) => {
228
+ var y = Object.defineProperty, g = Object.getOwnPropertyDescriptor, r = (e, t, n, a) => {
215
229
  for (var s = a > 1 ? void 0 : a ? g(t, n) : t, l = e.length - 1, d; l >= 0; l--)
216
230
  (d = e[l]) && (s = (a ? d(t, n, s) : d(s)) || s);
217
231
  return a && s && y(t, n, s), s;
@@ -286,7 +300,7 @@ let o = class extends b {
286
300
  <slot @slotchange=${this._handleSlotChange}></slot>
287
301
  </code>
288
302
  `;
289
- const e = this._getDisplayLines(), t = this._isTruncated(), n = this.language ? `Code snippet: ${this.language}` : "Code snippet", a = x({
303
+ const e = this._getDisplayLines(), t = this._isTruncated(), n = this.language ? `Code snippet: ${this.language}` : "Code snippet", a = u({
290
304
  "code-snippet__code": !0,
291
305
  [`language-${this.language}`]: !!this.language
292
306
  });
@@ -316,7 +330,7 @@ let o = class extends b {
316
330
  <pre
317
331
  role="region"
318
332
  aria-label=${n}
319
- class=${x({
333
+ class=${u({
320
334
  "code-snippet__pre": !0,
321
335
  "code-snippet__pre--wrap": this.wrap
322
336
  })}
@@ -340,50 +354,50 @@ let o = class extends b {
340
354
  `;
341
355
  }
342
356
  };
343
- o.styles = [v, m];
344
- i([
345
- r({ type: String, reflect: !0 })
357
+ o.styles = [v, x];
358
+ r([
359
+ i({ type: String, reflect: !0 })
346
360
  ], o.prototype, "language", 2);
347
- i([
348
- r({ type: Boolean, reflect: !0 })
361
+ r([
362
+ i({ type: Boolean, reflect: !0 })
349
363
  ], o.prototype, "inline", 2);
350
- i([
351
- r({ type: Boolean, reflect: !0 })
364
+ r([
365
+ i({ type: Boolean, reflect: !0 })
352
366
  ], o.prototype, "wrap", 2);
353
- i([
354
- r({ type: Boolean, reflect: !0 })
367
+ r([
368
+ i({ type: Boolean, reflect: !0 })
355
369
  ], o.prototype, "copyable", 2);
356
- i([
357
- r({ type: Number, attribute: "max-lines", reflect: !0 })
370
+ r([
371
+ i({ type: Number, attribute: "max-lines", reflect: !0 })
358
372
  ], o.prototype, "maxLines", 2);
359
- i([
360
- r({ type: Boolean, attribute: "line-numbers", reflect: !0 })
373
+ r([
374
+ i({ type: Boolean, attribute: "line-numbers", reflect: !0 })
361
375
  ], o.prototype, "lineNumbers", 2);
362
- i([
363
- r({ type: String, attribute: "label-copy" })
376
+ r([
377
+ i({ type: String, attribute: "label-copy" })
364
378
  ], o.prototype, "labelCopy", 2);
365
- i([
366
- r({ type: String, attribute: "label-copied" })
379
+ r([
380
+ i({ type: String, attribute: "label-copied" })
367
381
  ], o.prototype, "labelCopied", 2);
368
- i([
369
- r({ type: String, attribute: "label-show-more" })
382
+ r([
383
+ i({ type: String, attribute: "label-show-more" })
370
384
  ], o.prototype, "labelShowMore", 2);
371
- i([
372
- r({ type: String, attribute: "label-show-less" })
385
+ r([
386
+ i({ type: String, attribute: "label-show-less" })
373
387
  ], o.prototype, "labelShowLess", 2);
374
- i([
388
+ r([
375
389
  c()
376
390
  ], o.prototype, "_copied", 2);
377
- i([
391
+ r([
378
392
  c()
379
393
  ], o.prototype, "_expanded", 2);
380
- i([
394
+ r([
381
395
  c()
382
396
  ], o.prototype, "_codeText", 2);
383
- o = i([
384
- f("hx-code-snippet")
397
+ o = r([
398
+ m("hx-code-snippet")
385
399
  ], o);
386
400
  export {
387
401
  o as H
388
402
  };
389
- //# sourceMappingURL=hx-code-snippet-CJrFeyz0.js.map
403
+ //# sourceMappingURL=hx-code-snippet-fVV3Z2DZ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hx-code-snippet-fVV3Z2DZ.js","sources":["../../src/components/hx-code-snippet/hx-code-snippet.styles.ts","../../src/components/hx-code-snippet/hx-code-snippet.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixCodeSnippetStyles = css`\n :host {\n display: block;\n }\n\n :host([inline]) {\n display: inline;\n }\n\n /* ─── Inline Mode ─── */\n\n .code-snippet--inline {\n display: inline;\n font-family: var(--hx-code-snippet-font-family, var(--hx-font-family-mono, monospace));\n font-size: var(--hx-code-snippet-font-size, var(--hx-font-size-sm, 0.875em));\n background-color: var(--hx-code-snippet-inline-bg, var(--hx-color-surface-sunken, #ebeee9));\n color: var(--hx-code-snippet-inline-color, var(--hx-color-text-primary, #0d1825));\n padding: var(--hx-code-snippet-inline-padding-y, 0.125em)\n var(--hx-code-snippet-inline-padding-x, 0.375em);\n border-radius: var(--hx-code-snippet-border-radius, var(--hx-border-radius-sm, 0.25rem));\n }\n\n /* ─── Block Mode Container ─── */\n\n .code-snippet {\n position: relative;\n background-color: var(--hx-code-snippet-bg, var(--hx-color-surface-inverse, #0d1825));\n border-radius: var(--hx-code-snippet-border-radius, var(--hx-border-radius-md, 0.375rem));\n overflow: hidden;\n }\n\n /* ─── Hidden Slot ─── */\n\n .code-snippet__slot {\n display: none;\n }\n\n /* ─── Header ─── */\n\n .code-snippet__header {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n padding: var(--hx-space-2, 0.5rem) var(--hx-space-2, 0.5rem) 0;\n min-height: var(--hx-space-8, 2rem);\n }\n\n /* ─── Pre / Code ─── */\n\n .code-snippet__pre {\n margin: 0;\n padding: var(--hx-code-snippet-padding, var(--hx-space-4, 1rem));\n overflow-x: auto;\n white-space: pre;\n }\n\n .code-snippet__pre--wrap {\n white-space: pre-wrap;\n word-break: break-word;\n }\n\n .code-snippet__code {\n display: block;\n font-family: var(--hx-code-snippet-font-family, var(--hx-font-family-mono, monospace));\n font-size: var(--hx-code-snippet-font-size, var(--hx-font-size-sm, 0.875rem));\n line-height: var(--hx-line-height-relaxed, 1.75);\n color: var(--hx-code-snippet-color, var(--hx-color-text-inverse, #ffffff));\n tab-size: var(--hx-code-snippet-tab-size, 2);\n }\n\n /* ─── Copy Button ─── */\n\n .code-snippet__copy-button {\n display: inline-flex;\n align-items: center;\n gap: var(--hx-space-1, 0.25rem);\n /* WCAG 2.5.5: minimum 44×44px touch target */\n min-width: var(--hx-touch-target-min, 2.75rem);\n min-height: var(--hx-touch-target-min, 2.75rem);\n padding: var(--hx-space-1, 0.25rem) var(--hx-space-2, 0.5rem);\n border: var(--hx-border-width-thin, 1px) solid\n var(--hx-color-border-on-dark-strong, rgba(255, 255, 255, 0.7));\n border-radius: var(--hx-border-radius-sm, 0.25rem);\n /* Copy button sits on the always-dark block snippet surface; uses inverse family for contrast on the terminal background. */\n background-color: var(--hx-color-surface-inverse, #0d1825);\n color: var(--hx-color-text-inverse, #ffffff);\n font-family: var(--hx-code-snippet-font-family, var(--hx-font-family-sans, sans-serif));\n font-size: var(--hx-font-size-xs, 0.75rem);\n font-weight: var(--hx-font-weight-medium, 500);\n line-height: 1; /* intentional literal: icon/action button needs line-height 1; no token maps to exactly 1 */\n cursor: pointer;\n transition:\n background-color var(--hx-transition-fast, 150ms ease),\n color var(--hx-transition-fast, 150ms ease),\n border-color var(--hx-transition-fast, 150ms ease);\n white-space: nowrap;\n z-index: 1; /* @audit-exception: local stacking context within shadow root */\n }\n\n .code-snippet__copy-button:hover {\n /* Hover on inverse terminal surface — keep semantic inverse family; border lifts via border-default in inverse context. */\n background-color: var(--hx-color-surface-inverse, #0d1825);\n border-color: var(--hx-color-border-default, #d6dbd5);\n }\n\n .code-snippet__copy-button:focus-visible {\n /* Always-dark terminal surface — uses primary-400 (#6AB1B1, 7.27:1 on #0d1825)\n instead of the light-mode --hx-focus-ring-color (primary-600, 3.07:1 — razor\n above the 3:1 UI floor with no headroom). Deliberate primitive-tier consumption:\n there is no semantic focus-ring-on-dark alias today — the dark.color.focus-ring\n override at tokens.json only fires under theme=dark, but this surface is dark in\n every theme. Tracked for promotion to a semantic alias in a future token-cascade\n follow-up. */\n outline: var(--hx-focus-ring-width, 2px) solid var(--hx-color-primary-400, #6ab1b1);\n outline-offset: var(--hx-focus-ring-offset, 2px);\n }\n\n .code-snippet__copy-button:active {\n /* Non-standard token — fallback 0.8 applies if token is absent */\n filter: brightness(var(--hx-filter-brightness-active, 0.8));\n }\n\n /* ─── Expand Button ─── */\n\n .code-snippet__expand-button {\n display: block;\n width: 100%;\n /* WCAG 2.5.5: minimum 44×44px touch target */\n min-width: var(--hx-touch-target-min, 2.75rem);\n min-height: var(--hx-touch-target-min, 2.75rem);\n padding: var(--hx-space-2, 0.5rem) var(--hx-space-4, 1rem);\n border: none;\n border-top: var(--hx-border-width-thin, 1px) solid\n var(--hx-color-border-on-dark-strong, rgba(255, 255, 255, 0.7));\n /* Expand button is attached to the always-dark block snippet — inverse family maintains the terminal aesthetic. */\n background-color: var(--hx-color-surface-inverse, #0d1825);\n color: var(--hx-color-text-inverse, #ffffff);\n font-family: var(--hx-code-snippet-font-family, var(--hx-font-family-sans, sans-serif));\n font-size: var(--hx-font-size-sm, 0.875rem);\n font-weight: var(--hx-font-weight-medium, 500);\n text-align: center;\n cursor: pointer;\n transition:\n border-color var(--hx-transition-fast, 150ms ease),\n filter var(--hx-transition-fast, 150ms ease);\n }\n\n .code-snippet__expand-button:hover {\n /* Hover on inverse terminal surface — lift the top border to border-default and brighten the background; matches the copy-button hover affordance pattern. */\n border-top-color: var(--hx-color-border-default, #e2e8f0);\n filter: brightness(var(--hx-filter-brightness-hover, 1.15));\n }\n\n .code-snippet__expand-button:focus-visible {\n /* Always-dark terminal surface — uses primary-400 (#6AB1B1, 7.27:1 on #0d1825)\n instead of the light-mode --hx-focus-ring-color (primary-600, 3.07:1 — razor\n above the 3:1 UI floor with no headroom). Deliberate primitive-tier consumption:\n there is no semantic focus-ring-on-dark alias today — the dark.color.focus-ring\n override at tokens.json only fires under theme=dark, but this surface is dark in\n every theme. Tracked for promotion to a semantic alias in a future token-cascade\n follow-up. */\n outline: var(--hx-focus-ring-width, 2px) solid var(--hx-color-primary-400, #6ab1b1);\n outline-offset: var(--hx-focus-ring-offset, 2px);\n }\n\n /* ─── Line Numbers ─── */\n\n .code-snippet__line-number {\n display: inline-block;\n min-width: var(--hx-space-8, 2rem);\n padding-inline-end: var(--hx-space-3, 0.75rem);\n color: var(--hx-code-snippet-line-number-color, var(--hx-color-text-muted, #4a5362));\n user-select: none;\n text-align: end;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .code-snippet__copy-button {\n transition: none;\n }\n\n .code-snippet__expand-button {\n transition: none;\n }\n }\n\n /* ─── Forced Colors (Windows High Contrast) ─── */\n\n @media (forced-colors: active) {\n .code-snippet {\n border: 1px solid CanvasText;\n }\n\n .code-snippet--inline {\n border: 1px solid CanvasText;\n }\n\n .code-snippet__copy-button {\n border-color: ButtonText;\n color: ButtonText;\n }\n\n .code-snippet__expand-button {\n border-top-color: CanvasText;\n color: ButtonText;\n }\n }\n\n /* ─── Screen-reader only ─── */\n\n .sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n }\n`;\n","import { html, nothing, TemplateResult } from 'lit';\nimport '../../utilities/document-token-adoption.js';\nimport { HelixElement } from '../../base/index.js';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { helixCodeSnippetStyles } from './hx-code-snippet.styles.js';\nimport { forcedColorsSurface } from '../../styles/forced-colors.js';\n\n/**\n * A styled code block with optional copy button and max-lines truncation.\n * Supports block (`<pre><code>`) and inline (`<code>`) rendering modes.\n * No external syntax highlighting dependency — use the `language` attribute\n * as a hint for consumers integrating their own highlighter via slotted content.\n *\n * @summary Styled code display component with copy-to-clipboard and expand/collapse.\n *\n * @tag hx-code-snippet\n *\n * @slot - Code content as plain text. Note: HTML markup in slot content will be\n * stripped — only text content is extracted. Pre-highlighted HTML is not supported.\n *\n * @fires {CustomEvent<{text: string}>} hx-copy - Dispatched when the copy button is clicked.\n *\n * @csspart base - The outermost container (block: `<div>`, inline: `<code>`).\n * @csspart header - The header bar containing the copy button (block mode only).\n * @csspart code - The `<code>` element containing the content.\n * @csspart copy-button - The copy-to-clipboard button.\n * @csspart expand-button - The \"Show more / Show less\" button.\n *\n * @cssprop [--hx-code-snippet-bg=var(--hx-color-neutral-900,#0f172a)] - Background color.\n * @cssprop [--hx-code-snippet-color=var(--hx-color-neutral-100,#f1f5f9)] - Text color.\n * @cssprop [--hx-code-snippet-font-family=var(--hx-font-family-mono,monospace)] - Font family.\n * @cssprop [--hx-code-snippet-font-size=var(--hx-font-size-sm,0.875rem)] - Font size.\n * @cssprop [--hx-code-snippet-border-radius=var(--hx-border-radius-md,0.375rem)] - Border radius.\n * @cssprop [--hx-code-snippet-padding=var(--hx-space-4,1rem)] - Inner padding (block mode).\n * @cssprop [--hx-border-radius-md] - CSS custom property.\n * @cssprop [--hx-border-radius-sm] - CSS custom property.\n * @cssprop [--hx-border-width-thin] - Width.\n * @cssprop [--hx-code-snippet-inline-bg=var(--hx-color-neutral-100)] - Background color.\n * @cssprop [--hx-code-snippet-inline-color=var(--hx-color-neutral-900)] - Color.\n * @cssprop [--hx-code-snippet-inline-padding-x=0.375em] - Padding.\n * @cssprop [--hx-code-snippet-inline-padding-y=0.125em] - Padding.\n * @cssprop [--hx-code-snippet-line-number-color=var(--hx-color-neutral-500)] - Color.\n * @cssprop [--hx-code-snippet-tab-size=2] - Number of spaces per tab character.\n * @cssprop [--hx-color-neutral-100] - Color.\n * @cssprop [--hx-color-neutral-200] - Color.\n * @cssprop [--hx-color-neutral-300] - Color.\n * @cssprop [--hx-color-neutral-500] - Color.\n * @cssprop [--hx-color-neutral-600] - Color.\n * @cssprop [--hx-color-neutral-700] - Color.\n * @cssprop [--hx-color-neutral-800] - Color.\n * @cssprop [--hx-color-neutral-900] - Color.\n * @cssprop [--hx-color-primary-400] - Color.\n * @cssprop [--hx-filter-brightness-active] - CSS filter.\n * @cssprop [--hx-focus-ring-color] - Color.\n * @cssprop [--hx-focus-ring-offset] - CSS custom property.\n * @cssprop [--hx-focus-ring-width] - Width.\n * @cssprop [--hx-font-family-mono] - Font family.\n * @cssprop [--hx-font-family-sans] - Font family.\n * @cssprop [--hx-font-size-sm] - Font size.\n * @cssprop [--hx-font-size-xs] - Font size.\n * @cssprop [--hx-font-weight-medium] - Font weight.\n * @cssprop [--hx-line-height-relaxed] - Line height.\n * @cssprop [--hx-space-1] - Spacing token.\n * @cssprop [--hx-space-2] - Spacing token.\n * @cssprop [--hx-space-3] - Spacing token.\n * @cssprop [--hx-space-4] - Spacing token.\n * @cssprop [--hx-space-8] - Spacing token.\n * @cssprop [--hx-touch-target-min] - Minimum touch target size.\n * @cssprop [--hx-transition-fast] - Transition timing.\n */\n@customElement('hx-code-snippet')\nexport class HelixCodeSnippet extends HelixElement {\n static override styles = [helixCodeSnippetStyles, forcedColorsSurface];\n\n // ─── Public Properties ───\n\n /**\n * Language hint for consumers to apply syntax highlighting.\n * Does not affect rendering directly; it is applied as a `language-*` class\n * on the `<code>` element so external highlighters can target it.\n * @attr language\n */\n @property({ type: String, reflect: true })\n language: string = '';\n\n /**\n * When true, renders as an inline `<code>` element instead of a `<pre><code>` block.\n * @attr inline\n */\n @property({ type: Boolean, reflect: true })\n inline: boolean = false;\n\n /**\n * When true, enables word-wrap in block mode.\n * @attr wrap\n */\n @property({ type: Boolean, reflect: true })\n wrap: boolean = false;\n\n /**\n * When true, shows a copy-to-clipboard button. Add the `copyable` attribute to enable it.\n * @attr copyable\n */\n @property({ type: Boolean, reflect: true })\n copyable: boolean = false;\n\n /**\n * Maximum number of lines to display before showing a \"Show more\" button.\n * Set to 0 (default) to disable truncation.\n * @attr max-lines\n */\n @property({ type: Number, attribute: 'max-lines', reflect: true })\n maxLines: number = 0;\n\n /**\n * When true, prepends line numbers to each displayed line in block mode.\n * Line numbers are rendered as `aria-hidden` spans so screen readers skip them.\n * @attr line-numbers\n */\n @property({ type: Boolean, attribute: 'line-numbers', reflect: true })\n lineNumbers: boolean = false;\n\n /**\n * Label for the copy button in idle state.\n * @attr label-copy\n */\n @property({ type: String, attribute: 'label-copy' })\n labelCopy = 'Copy code';\n\n /**\n * Label for the copy button after successful copy.\n * @attr label-copied\n */\n @property({ type: String, attribute: 'label-copied' })\n labelCopied = 'Copied!';\n\n /**\n * Label for the expand button when content is collapsed.\n * @attr label-show-more\n */\n @property({ type: String, attribute: 'label-show-more' })\n labelShowMore = 'Show more';\n\n /**\n * Label for the expand button when content is expanded.\n * @attr label-show-less\n */\n @property({ type: String, attribute: 'label-show-less' })\n labelShowLess = 'Show less';\n\n // ─── Internal State ───\n\n /** @internal */\n @state() private _copied: boolean = false;\n /** @internal */\n @state() private _expanded: boolean = false;\n /** @internal */\n @state() private _codeText: string = '';\n\n /** @internal */\n private _copyTimer: ReturnType<typeof setTimeout> | null = null;\n\n // ─── Lifecycle ───\n\n override firstUpdated(): void {\n // Prevent flash of empty <code> before slotchange fires by eagerly reading\n // text content from host children that are already present on first render.\n if (!this._codeText) {\n const text = this.textContent?.trim() ?? '';\n if (text) {\n this._codeText = text;\n }\n }\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n if (this._copyTimer !== null) {\n clearTimeout(this._copyTimer);\n this._copyTimer = null;\n }\n }\n\n // ─── Event Handlers ───\n\n /** @internal */\n private _handleSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement | null;\n if (!slot) return;\n const nodes = slot.assignedNodes({ flatten: true });\n this._codeText = nodes.map((n) => n.textContent ?? '').join('');\n }\n\n /** @internal */\n private _handleCopy(): void {\n const text = this._codeText;\n\n navigator?.clipboard?.writeText(text).catch(() => {\n // Clipboard API unavailable (non-HTTPS environments such as Drupal staging) — emit event only.\n // Note: navigator.clipboard requires a secure context (HTTPS or localhost).\n // On HTTP, the copy event still fires but the clipboard is not populated.\n });\n\n this.dispatchEvent(\n new CustomEvent<{ text: string }>('hx-copy', {\n bubbles: true,\n composed: true,\n detail: { text },\n }),\n );\n\n this._copied = true;\n if (this._copyTimer !== null) clearTimeout(this._copyTimer);\n this._copyTimer = setTimeout(() => {\n this._copied = false;\n }, 2000);\n }\n\n /** @internal */\n private _handleExpand(): void {\n this._expanded = !this._expanded;\n }\n\n // ─── Helpers ───\n\n /** @internal */\n private _getDisplayLines(): string[] {\n const lines = this._codeText.split('\\n');\n if (!this.maxLines || this.maxLines <= 0 || this._expanded) {\n return lines;\n }\n if (lines.length <= this.maxLines) {\n return lines;\n }\n return lines.slice(0, this.maxLines);\n }\n\n /** @internal */\n private _isTruncated(): boolean {\n if (!this.maxLines || this.maxLines <= 0) return false;\n const lines = this._codeText.split('\\n');\n return lines.length > this.maxLines;\n }\n\n /** @internal */\n private _renderLines(lines: string[]): TemplateResult {\n if (!this.lineNumbers) {\n return html`${lines.join('\\n')}`;\n }\n return html`${lines.map(\n (line, i) =>\n html`<span aria-hidden=\"true\" class=\"code-snippet__line-number\">${i + 1}</span>${line +\n '\\n'}`,\n )}`;\n }\n\n // ─── Render ───\n\n override render(): TemplateResult | typeof nothing {\n if (this.inline) {\n return html`\n <code part=\"base code\" class=\"code-snippet code-snippet--inline\">\n <slot @slotchange=${this._handleSlotChange}></slot>\n </code>\n `;\n }\n\n const displayLines = this._getDisplayLines();\n const truncated = this._isTruncated();\n const preLabel = this.language ? `Code snippet: ${this.language}` : 'Code snippet';\n const codeClasses = classMap({\n 'code-snippet__code': true,\n [`language-${this.language}`]: Boolean(this.language),\n });\n\n return html`\n <div part=\"base\" class=\"code-snippet\">\n <div part=\"header\" class=\"code-snippet__header\">\n ${this.copyable\n ? html`\n <button\n part=\"copy-button\"\n class=\"code-snippet__copy-button\"\n type=\"button\"\n aria-label=${this._copied ? this.labelCopied : this.labelCopy}\n @click=${this._handleCopy}\n >\n ${this._copied ? this.labelCopied : this.labelCopy}\n </button>\n `\n : nothing}\n </div>\n\n <!-- Visually-hidden live region announces copy confirmation to assistive technology -->\n <span\n aria-live=\"polite\"\n style=\"position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0;\"\n >${this._copied ? this.labelCopied : ''}</span\n >\n\n <pre\n role=\"region\"\n aria-label=${preLabel}\n class=${classMap({\n 'code-snippet__pre': true,\n 'code-snippet__pre--wrap': this.wrap,\n })}\n ><code part=\"code\" class=${codeClasses}>${this._renderLines(displayLines)}</code></pre>\n\n <!-- Hidden slot to capture text content for display and copy -->\n <slot class=\"code-snippet__slot\" @slotchange=${this._handleSlotChange}></slot>\n\n ${truncated\n ? html`\n <button\n part=\"expand-button\"\n class=\"code-snippet__expand-button\"\n type=\"button\"\n aria-expanded=${this._expanded ? 'true' : 'false'}\n @click=${this._handleExpand}\n >\n ${this._expanded ? this.labelShowLess : this.labelShowMore}\n </button>\n `\n : nothing}\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-code-snippet': HelixCodeSnippet;\n }\n}\n"],"names":["helixCodeSnippetStyles","css","HelixCodeSnippet","HelixElement","text","_a","slot","nodes","n","lines","html","line","i","displayLines","truncated","preLabel","codeClasses","classMap","nothing","forcedColorsSurface","__decorateClass","property","state","customElement"],"mappings":"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"}
@@ -51,17 +51,11 @@ const T = m`
51
51
  box-shadow var(--hx-transition-fast, 150ms ease);
52
52
  }
53
53
  .field__input-wrapper:focus-within {
54
- border-color: var(
55
- --hx-combobox-focus-ring-color,
56
- var(--hx-focus-ring-color, var(--hx-color-primary-600, #0f7078))
57
- );
54
+ border-color: var(--hx-combobox-focus-ring-color, var(--hx-focus-ring-color, #0f7078));
58
55
  box-shadow: 0 0 0 var(--hx-focus-ring-width, 2px)
59
56
  color-mix(
60
57
  in srgb,
61
- var(
62
- --hx-combobox-focus-ring-color,
63
- var(--hx-focus-ring-color, var(--hx-color-primary-600, #0f7078))
64
- )
58
+ var(--hx-combobox-focus-ring-color, var(--hx-focus-ring-color, #0f7078))
65
59
  calc(var(--hx-focus-ring-opacity, 0.25) * 100%),
66
60
  transparent
67
61
  );
@@ -708,14 +702,14 @@ let r = class extends y(k) {
708
702
 
709
703
  <!-- P0-1: Selected value chips for multiple mode -->
710
704
  ${this.multiple && this._selectedValuesSet.size > 0 ? [...this._selectedValuesSet].map((c) => {
711
- const x = this._options.find((f) => f.value === c), b = x ? x.label : c;
705
+ const b = this._options.find((f) => f.value === c), x = b ? b.label : c;
712
706
  return h`
713
707
  <span class="field__chip">
714
- <span class="field__chip-label">${b}</span>
708
+ <span class="field__chip-label">${x}</span>
715
709
  <button
716
710
  type="button"
717
711
  class="field__chip-remove"
718
- aria-label=${this.labelRemoveOption(b)}
712
+ aria-label=${this.labelRemoveOption(x)}
719
713
  @click=${(f) => {
720
714
  f.stopPropagation(), this._removeValue(c);
721
715
  }}
@@ -927,4 +921,4 @@ r = l([
927
921
  export {
928
922
  r as H
929
923
  };
930
- //# sourceMappingURL=hx-combobox-ClhNRAS5.js.map
924
+ //# sourceMappingURL=hx-combobox-DDzqNKEW.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hx-combobox-DDzqNKEW.js","sources":["../../src/components/hx-combobox/hx-combobox.styles.ts","../../src/components/hx-combobox/hx-combobox.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixComboboxStyles = css`\n :host {\n display: block;\n }\n :host([disabled]) {\n opacity: var(--hx-opacity-disabled, 0.5);\n pointer-events: none;\n }\n * {\n box-sizing: border-box;\n }\n .field {\n display: flex;\n flex-direction: column;\n gap: var(--hx-space-1, 0.25rem);\n font-family: var(--hx-combobox-font-family, var(--hx-font-family-sans, sans-serif));\n position: relative;\n }\n .field__label {\n display: flex;\n align-items: baseline;\n gap: var(--hx-space-1, 0.25rem);\n font-size: var(--hx-font-size-sm, 0.875rem);\n font-weight: var(--hx-font-weight-medium, 500);\n color: var(--hx-combobox-label-color, var(--hx-color-text-strong, #202b39));\n line-height: var(--hx-line-height-normal, 1.5);\n }\n .field__required-marker {\n color: var(--hx-combobox-error-color, var(--hx-color-error-text, #c92a2a));\n font-weight: var(--hx-font-weight-bold, 700);\n }\n .field__input-wrapper {\n position: relative;\n display: flex;\n align-items: center;\n border: var(--hx-border-width-thin, 1px) solid\n var(--hx-combobox-border-color, var(--hx-color-border-strong, #66787b));\n border-radius: var(--hx-combobox-border-radius, var(--hx-border-radius-md, 0.375rem));\n background-color: var(--hx-combobox-bg, var(--hx-color-surface-default, #ffffff));\n transition:\n border-color var(--hx-transition-fast, 150ms ease),\n box-shadow var(--hx-transition-fast, 150ms ease);\n }\n .field__input-wrapper:focus-within {\n border-color: var(--hx-combobox-focus-ring-color, var(--hx-focus-ring-color, #0f7078));\n box-shadow: 0 0 0 var(--hx-focus-ring-width, 2px)\n color-mix(\n in srgb,\n var(--hx-combobox-focus-ring-color, var(--hx-focus-ring-color, #0f7078))\n calc(var(--hx-focus-ring-opacity, 0.25) * 100%),\n transparent\n );\n }\n .field--error .field__input-wrapper {\n border-color: var(--hx-combobox-error-color, var(--hx-color-error-500, #e5493e));\n }\n .field--error .field__input-wrapper:focus-within {\n border-color: var(--hx-combobox-error-color, var(--hx-color-error-500, #e5493e));\n box-shadow: 0 0 0 var(--hx-focus-ring-width, 2px)\n color-mix(\n in srgb,\n var(--hx-combobox-error-color, var(--hx-color-error-500, #e5493e))\n calc(var(--hx-focus-ring-opacity, 0.25) * 100%),\n transparent\n );\n }\n .field__prefix,\n .field__suffix {\n display: flex;\n align-items: center;\n padding: 0 var(--hx-space-2, 0.5rem);\n color: var(--hx-color-text-muted, #4a5362);\n flex-shrink: 0;\n }\n .field__input {\n flex: 1;\n min-width: 0;\n min-height: var(--hx-input-height-md, var(--hx-size-10, 2.5rem));\n border: none;\n background: transparent;\n outline: none;\n font-family: inherit;\n font-size: var(--hx-font-size-md, 1rem);\n line-height: var(--hx-line-height-normal, 1.5);\n color: var(--hx-combobox-color, var(--hx-color-text-strong, #202b39));\n padding: var(--hx-space-2, 0.5rem) var(--hx-space-3, 0.75rem);\n }\n .field__input::placeholder {\n color: var(--hx-color-text-placeholder, #66787b);\n }\n .field__input--sm {\n min-height: var(--hx-input-height-sm, var(--hx-size-8, 2rem));\n font-size: var(--hx-font-size-sm, 0.875rem);\n padding: var(--hx-space-1, 0.25rem) var(--hx-space-3, 0.75rem);\n }\n .field__input--lg {\n min-height: var(--hx-input-height-lg, var(--hx-size-12, 3rem));\n font-size: var(--hx-font-size-lg, 1.125rem);\n padding: var(--hx-space-3, 0.75rem) var(--hx-space-4, 1rem);\n }\n .field__clear-button,\n .field__loading-indicator {\n display: flex;\n align-items: center;\n justify-content: center;\n margin-inline-end: var(--hx-space-2, 0.5rem);\n flex-shrink: 0;\n color: var(--hx-color-text-placeholder, #66787b);\n }\n .field__clear-button {\n width: 1.25rem;\n height: 1.25rem;\n border: none;\n background: transparent;\n cursor: pointer;\n padding: 0;\n border-radius: var(--hx-border-radius-full, 9999px);\n transition: color var(--hx-transition-fast, 150ms ease);\n }\n .field__clear-button:hover {\n color: var(--hx-color-text-strong, #202b39);\n }\n .field__clear-button:focus-visible {\n outline: var(--hx-focus-ring-width, 2px) solid\n var(--hx-combobox-focus-ring-color, var(--hx-focus-ring-color, #0f7078));\n outline-offset: var(--hx-focus-ring-offset, 2px);\n }\n .field__loading-indicator {\n width: 1rem;\n height: 1rem;\n }\n .field__loading-spinner {\n width: 1rem;\n height: 1rem;\n border: 2px solid currentColor;\n border-top-color: transparent;\n border-radius: 50%;\n animation: hx-spin 0.7s linear infinite;\n }\n @keyframes hx-spin {\n to {\n transform: rotate(360deg);\n }\n }\n @media (prefers-reduced-motion: reduce) {\n .field__loading-spinner {\n animation: none;\n }\n }\n .field__listbox {\n position: absolute;\n top: calc(100% + var(--hx-space-1, 0.25rem));\n left: 0;\n right: 0;\n z-index: var(--hx-z-index-dropdown, 1000);\n background-color: var(--hx-combobox-listbox-bg, var(--hx-color-surface-default, #ffffff));\n border: var(--hx-border-width-thin, 1px) solid\n var(--hx-combobox-border-color, var(--hx-color-border-strong, #66787b));\n border-radius: var(--hx-combobox-border-radius, var(--hx-border-radius-md, 0.375rem));\n box-shadow: var(\n --hx-combobox-listbox-shadow,\n 0 4px 16px color-mix(in srgb, var(--hx-color-neutral-900, #0d1825) 12%, transparent)\n );\n max-height: var(--hx-combobox-listbox-max-height, 16rem);\n overflow: hidden;\n display: flex;\n flex-direction: column;\n }\n .field__listbox[hidden] {\n display: none;\n }\n .field__options {\n overflow-y: auto;\n flex: 1;\n padding: var(--hx-space-1, 0.25rem) 0;\n }\n .field__option {\n display: flex;\n align-items: center;\n gap: var(--hx-space-2, 0.5rem);\n padding: var(--hx-space-2, 0.5rem) var(--hx-space-3, 0.75rem);\n font-size: var(--hx-font-size-md, 1rem);\n color: var(--hx-combobox-color, var(--hx-color-text-strong, #202b39));\n cursor: pointer;\n user-select: none;\n -webkit-user-select: none;\n transition: background-color var(--hx-transition-fast, 150ms ease);\n }\n .field__option:hover {\n background-color: var(--hx-combobox-option-hover-bg, var(--hx-color-primary-50, #ebf8f8));\n }\n .field__option--selected {\n background-color: var(--hx-combobox-option-selected-bg, var(--hx-color-primary-100, #dbf0f0));\n font-weight: var(--hx-font-weight-medium, 500);\n }\n .field__option--focused {\n background-color: var(--hx-combobox-option-hover-bg, var(--hx-color-primary-50, #ebf8f8));\n outline: var(--hx-focus-ring-width, 2px) solid\n var(--hx-combobox-focus-ring-color, var(--hx-focus-ring-color, #0f7078));\n outline-offset: var(--hx-combobox-option-focus-ring-offset, -2px);\n }\n .field__option--focused.field__option--selected {\n background-color: var(--hx-combobox-option-selected-bg, var(--hx-color-primary-100, #dbf0f0));\n }\n .field__option--disabled {\n opacity: var(--hx-opacity-disabled, 0.5);\n cursor: not-allowed;\n pointer-events: none;\n }\n .field__option-label {\n flex: 1;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n .field__no-options {\n padding: var(--hx-space-3, 0.75rem);\n text-align: center;\n color: var(--hx-color-text-placeholder, #66787b);\n font-size: var(--hx-font-size-sm, 0.875rem);\n }\n .field__sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n }\n .field__help-text,\n .field__error {\n font-size: var(--hx-font-size-xs, 0.75rem);\n line-height: var(--hx-line-height-normal, 1.5);\n }\n .field__help-text {\n color: var(--hx-color-text-muted, #4a5362);\n }\n .field__error {\n color: var(--hx-combobox-error-color, var(--hx-color-error-text, #c92a2a));\n }\n @media (prefers-reduced-motion: reduce) {\n .field__input-wrapper,\n .field__option,\n .field__clear-button,\n .field__chip-remove {\n transition: none;\n }\n }\n @media (forced-colors: active) {\n .field__input-wrapper {\n forced-color-adjust: none;\n background-color: Field;\n color: FieldText;\n border: 2px solid ButtonText;\n }\n .field__input {\n color: FieldText;\n }\n .field__input::placeholder {\n color: GrayText;\n }\n .field__input-wrapper:focus-within {\n border-color: Highlight;\n box-shadow: none;\n }\n .field__listbox {\n forced-color-adjust: none;\n background-color: Canvas;\n border: 2px solid CanvasText;\n box-shadow: none;\n }\n .field__option {\n color: CanvasText;\n }\n .field__option:hover {\n background-color: Highlight;\n color: HighlightText;\n }\n .field__option--selected {\n background-color: Highlight;\n color: HighlightText;\n }\n .field__option--focused {\n outline-color: Highlight;\n background-color: Highlight;\n color: HighlightText;\n }\n .field__option--disabled {\n color: GrayText;\n opacity: 1;\n }\n .field__chip {\n forced-color-adjust: none;\n background-color: Highlight;\n color: HighlightText;\n border: 1px solid HighlightText;\n }\n .field__chip-remove:focus-visible {\n outline-color: Highlight;\n }\n .field__clear-button:focus-visible {\n outline-color: Highlight;\n }\n .field--error .field__input-wrapper {\n border-color: LinkText;\n }\n :host([disabled]) {\n opacity: 1;\n }\n :host([disabled]) .field__input-wrapper {\n border-color: GrayText;\n color: GrayText;\n }\n :host([disabled]) .field__input {\n color: GrayText;\n }\n .field__label {\n color: CanvasText;\n }\n .field__help-text {\n color: GrayText;\n }\n .field__error {\n color: LinkText;\n }\n }\n :host([multiple]) .field__input-wrapper {\n flex-wrap: wrap;\n padding: var(--hx-space-1, 0.25rem);\n gap: var(--hx-space-1, 0.25rem);\n align-items: center;\n }\n :host([multiple]) .field__input {\n min-width: 8rem;\n padding: var(--hx-space-1, 0.25rem) var(--hx-space-2, 0.5rem);\n flex-shrink: 1;\n }\n .field__chip {\n display: inline-flex;\n align-items: center;\n gap: var(--hx-space-1, 0.25rem);\n padding: 0 var(--hx-space-1, 0.25rem) 0 var(--hx-space-2, 0.5rem);\n height: 1.5rem;\n background-color: var(--hx-combobox-chip-bg, var(--hx-color-primary-100, #dbf0f0));\n color: var(--hx-combobox-chip-color, var(--hx-color-primary-800, #07494a));\n border-radius: var(--hx-border-radius-full, 9999px);\n font-size: var(--hx-font-size-sm, 0.875rem);\n white-space: nowrap;\n max-width: 12rem;\n flex-shrink: 0;\n }\n .field__chip-label {\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 8rem;\n }\n .field__chip-remove {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n width: 1rem;\n height: 1rem;\n border: none;\n background: none;\n cursor: pointer;\n padding: 0;\n color: inherit;\n opacity: 0.7;\n border-radius: 50%;\n line-height: 1;\n transition: opacity var(--hx-transition-fast, 150ms ease);\n }\n .field__chip-remove:hover {\n opacity: 1;\n background-color: var(--hx-combobox-chip-remove-hover-bg, var(--hx-color-primary-200, #bce1e1));\n }\n .field__chip-remove:focus-visible {\n outline: var(--hx-focus-ring-width, 2px) solid\n var(--hx-combobox-focus-ring-color, var(--hx-focus-ring-color, #0f7078));\n outline-offset: var(--hx-focus-ring-offset, 2px);\n opacity: 1;\n }\n`;\n","import { html, nothing, type PropertyValues } from 'lit';\nimport '../../utilities/document-token-adoption.js';\nimport { customElement, property, query, state } from 'lit/decorators.js';\nimport { HelixElement, createIdCounter } from '../../base/index.js';\nimport { FormMixin } from '../../mixins/FormMixin.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { helixComboboxStyles } from './hx-combobox.styles.js';\nimport { forcedColorsField } from '../../styles/forced-colors.js';\n\n// PERF: hx-combobox exceeds 5KB budget (6.87kb gzipped) -- typeahead filtering, multi-select chips, async loading\n\n// ─── Internal option model ───\n\n// P1-7: Exported so TypeScript consumers can type option arrays programmatically\nexport interface ComboboxOption {\n value: string;\n label: string;\n disabled: boolean;\n}\n\n// P2-13: Exported size type for TypeScript consumers\nexport type HxComboboxSize = 'sm' | 'md' | 'lg';\n\nconst _nextComboboxId = createIdCounter('hx-combobox');\n\n/** Detail for hx-input and hx-change events dispatched by hx-combobox. */\nexport interface HxComboboxDetail {\n value: string;\n}\n\n/**\n * A form-associated combobox component combining a text input with a listbox\n * for autocomplete and typeahead. Supports filtering, free-text entry,\n * keyboard navigation, and async option loading.\n *\n * @summary Form-associated combobox with autocomplete, filtering, and keyboard navigation.\n *\n * @tag hx-combobox\n *\n * @slot option - Slot for `<option>` elements that populate the listbox.\n * @slot prefix - Content to display before the text input.\n * @slot suffix - Content to display after the text input.\n * @slot empty-label - Content shown when no options match the filter.\n * @slot label - Custom label content (overrides the label property).\n * @slot error - Custom error content (overrides the error property).\n * @slot help-text - Custom help text content (overrides the helpText property).\n *\n * @fires {CustomEvent<{value: string}>} hx-input - Dispatched on each keystroke as the user types.\n * @fires {CustomEvent<{value: string}>} hx-change - Dispatched when an option is selected.\n * @fires {CustomEvent<void>} hx-clear - Dispatched when the clear button is activated.\n * @fires {CustomEvent<void>} hx-show - Dispatched when the listbox opens.\n * @fires {CustomEvent<void>} hx-hide - Dispatched when the listbox closes.\n *\n * @csspart input - The native text input element.\n * @csspart listbox - The dropdown panel containing options.\n * @csspart trigger - The input wrapper element acting as the combobox trigger.\n * @csspart clear-button - The button that clears the current value.\n * @csspart loading-indicator - The loading spinner shown during async operations.\n * @csspart field - The outer field wrapper element.\n * @csspart label - The label element.\n * @csspart option - An individual option item in the listbox.\n * @csspart error - The error message element.\n * @csspart help-text - The help text element.\n *\n * @cssprop [--hx-combobox-bg=var(--hx-color-neutral-0)] - Input background color.\n * @cssprop [--hx-combobox-color=var(--hx-color-neutral-800)] - Input text color.\n * @cssprop [--hx-combobox-border-color=var(--hx-color-neutral-300)] - Border color.\n * @cssprop [--hx-combobox-border-radius=var(--hx-border-radius-md)] - Border radius.\n * @cssprop [--hx-combobox-font-family=var(--hx-font-family-sans)] - Font family.\n * @cssprop [--hx-combobox-focus-ring-color=var(--hx-focus-ring-color)] - Focus ring color.\n * @cssprop [--hx-combobox-error-color=var(--hx-color-error-500)] - Error state color.\n * @cssprop [--hx-combobox-label-color=var(--hx-color-neutral-700)] - Label text color.\n * @cssprop [--hx-combobox-listbox-bg=var(--hx-color-neutral-0)] - Listbox background color.\n * @cssprop [--hx-combobox-option-hover-bg=var(--hx-color-primary-50)] - Option hover background.\n * @cssprop [--hx-combobox-option-selected-bg=var(--hx-color-primary-100)] - Selected option background.\n * @cssprop [--hx-opacity-disabled] - Opacity.\n * @cssprop [--hx-space-1] - Spacing token.\n * @cssprop [--hx-font-family-sans] - Font family.\n * @cssprop [--hx-font-size-sm] - Font size.\n * @cssprop [--hx-font-weight-medium] - Font weight.\n * @cssprop [--hx-color-neutral-700] - Color.\n * @cssprop [--hx-line-height-normal] - Line height.\n * @cssprop [--hx-color-error-text] - Color.\n * @cssprop [--hx-font-weight-bold] - Font weight.\n * @cssprop [--hx-border-width-thin] - Width.\n * @cssprop [--hx-color-neutral-300] - Color.\n * @cssprop [--hx-border-radius-md] - CSS custom property.\n * @cssprop [--hx-color-neutral-0] - Color.\n * @cssprop [--hx-transition-fast] - Transition timing.\n * @cssprop [--hx-focus-ring-color] - Color.\n * @cssprop [--hx-color-primary-400] - Color.\n * @cssprop [--hx-focus-ring-width] - Width.\n * @cssprop [--hx-focus-ring-opacity] - CSS custom property.\n * @cssprop [--hx-color-error-500] - Color.\n * @cssprop [--hx-space-2] - Spacing token.\n * @cssprop [--hx-color-neutral-500] - Color.\n * @cssprop [--hx-input-height-md] - Height.\n * @cssprop [--hx-size-10] - Size token.\n * @cssprop [--hx-font-size-md] - Font size.\n * @cssprop [--hx-color-neutral-800] - Color.\n * @cssprop [--hx-space-3] - Spacing token.\n * @cssprop [--hx-color-neutral-400] - Color.\n * @cssprop [--hx-input-height-sm] - Height.\n * @cssprop [--hx-size-8] - Size token.\n * @cssprop [--hx-input-height-lg] - Height.\n * @cssprop [--hx-size-12] - Size token.\n * @cssprop [--hx-font-size-lg] - Font size.\n * @cssprop [--hx-space-4] - Spacing token.\n * @cssprop [--hx-border-radius-full] - CSS custom property.\n * @cssprop [--hx-color-primary-500] - Color.\n * @cssprop [--hx-focus-ring-offset] - CSS custom property.\n * @cssprop [--hx-z-index-dropdown] - Z-index layer.\n * @cssprop [--hx-combobox-listbox-shadow] - CSS custom property.\n * @cssprop [--hx-color-neutral-900] - Color.\n * @cssprop [--hx-combobox-listbox-max-height=16rem] - Height.\n * @cssprop [--hx-color-primary-50] - Color.\n * @cssprop [--hx-color-primary-100] - Color.\n * @cssprop [--hx-combobox-option-focus-ring-offset=-2px] - Focus ring styling.\n * @cssprop [--hx-font-size-xs] - Font size.\n * @cssprop [--hx-combobox-chip-bg=var(--hx-color-primary-100)] - Background color.\n * @cssprop [--hx-combobox-chip-color=var(--hx-color-primary-800)] - Color.\n * @cssprop [--hx-color-primary-800] - Color.\n * @cssprop [--hx-combobox-chip-remove-hover-bg=var(--hx-color-primary-200)] - Background color.\n * @cssprop [--hx-color-primary-200] - Color.\n */\n@customElement('hx-combobox')\nexport class HelixCombobox extends FormMixin(HelixElement) {\n static override styles = [helixComboboxStyles, forcedColorsField];\n\n // ─── Form Association ───\n\n /** Marks this element as form-associated for ElementInternals support. @internal */\n static override formAssociated = true;\n\n // ─── Stable IDs ───\n\n /** @internal */\n private _id = _nextComboboxId();\n /** @internal */\n private _listboxId = `${this._id}-listbox`;\n /** @internal */\n private _helpTextId = `${this._id}-help`;\n /** @internal */\n private _errorId = `${this._id}-error`;\n /** @internal */\n private _labelId = `${this._id}-label`;\n /** @internal */\n private _liveRegionId = `${this._id}-live`;\n\n // ─── Public Properties ───\n\n /**\n * The visible label text for the combobox.\n * @attr label\n */\n @property({ type: String })\n label = '';\n\n /**\n * Placeholder text shown in the input when no value is entered.\n * @attr placeholder\n */\n @property({ type: String })\n placeholder = '';\n\n /**\n * The current value of the combobox.\n * @attr value\n */\n @property({ type: String, reflect: true })\n value = '';\n\n /**\n * Whether the combobox is required for form submission.\n * @attr required\n */\n @property({ type: Boolean, reflect: true })\n required = false;\n\n /**\n * Whether the combobox is disabled.\n * @attr disabled\n */\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /**\n * The name used for form submission.\n * @attr name\n */\n @property({ type: String, reflect: true })\n name = '';\n\n /**\n * Error message to display. When set, the field enters an error state.\n * @attr error\n */\n @property({ type: String })\n error = '';\n\n /**\n * Help text displayed below the combobox for guidance.\n * @attr help-text\n */\n @property({ type: String, attribute: 'help-text' })\n helpText = '';\n\n /**\n * Size variant of the combobox.\n * @attr hx-size\n */\n @property({ type: String, attribute: 'hx-size', reflect: true })\n size: 'sm' | 'md' | 'lg' = 'md';\n\n /**\n * Whether multiple options can be selected.\n * @attr multiple\n */\n @property({ type: Boolean, reflect: true })\n multiple = false;\n\n /**\n * Whether the combobox shows a clear button when a value is set.\n * @attr clearable\n */\n @property({ type: Boolean, reflect: true })\n clearable = false;\n\n /**\n * Whether the combobox is in a loading state (shows spinner).\n * @attr loading\n */\n @property({ type: Boolean, reflect: true })\n loading = false;\n\n /**\n * Debounce delay in milliseconds for the filter input event.\n * @attr filter-debounce\n */\n @property({ type: Number, attribute: 'filter-debounce' })\n filterDebounce = 0;\n\n /**\n * Accessible name for screen readers, if different from the visible label.\n * Uses `accessible-label` attribute instead of `aria-label` to avoid\n * ARIAMixin shadowing on the host element.\n *\n * Note: `mixinDelegatesAria` is not applied to this component because form\n * inputs with associated labels delegate accessible naming via `<label>`\n * association and `aria-labelledby`, not host-level ARIA delegation. The\n * `accessible-label` attribute is a fallback for label-free usage. The value is forwarded to the\n * internal input's `aria-label`.\n * @attr accessible-label\n */\n @property({ type: String, attribute: 'accessible-label' })\n accessibleLabel: string | null = null;\n\n /**\n * Text shown when no options match the current filter.\n * @attr label-no-options\n */\n @property({ type: String, attribute: 'label-no-options' })\n labelNoOptions = 'No options found';\n\n /**\n * Validation message shown when the field is required but empty.\n * @attr label-required\n */\n @property({ type: String, attribute: 'label-required' })\n labelRequired = 'Please select an option.';\n\n /**\n * Generates the accessible label for multi-select chip remove buttons.\n * @param label - the option label text\n */\n @property({ attribute: false })\n labelRemoveOption: (label: string) => string = (label) => `Remove ${label}`;\n\n // ─── Internal State ───\n\n /** Parsed option models derived from slotted `<option>` and `<optgroup>` elements. @internal */\n @state() private _options: ComboboxOption[] = [];\n /** Current text typed in the input, used to filter the option list. @internal */\n @state() private _filterText = '';\n /** Whether the listbox dropdown is currently visible. @internal */\n @state() private _open = false;\n /** Zero-based index of the keyboard-focused option within the filtered list; -1 means none. @internal */\n @state() private _focusedOptionIndex = -1;\n /** Whether the named error slot contains projected content. @internal */\n @state() private _hasErrorSlot = false;\n /** Live-region announcement text describing the current number of filtered options. @internal */\n @state() private _filterAnnouncement = '';\n\n // ─── Queries ───\n\n /** Reference to the native text input element inside the shadow DOM. @internal */\n @query('.field__input')\n private _input: HTMLInputElement | undefined;\n\n // ─── Debounce timer ───\n\n /** @internal */\n private _debounceTimer: ReturnType<typeof setTimeout> | null = null;\n\n // ─── Multiple Selection ───\n\n // P0-1: Derive selected values Set from the comma-separated value property\n /** @internal */\n private get _selectedValuesSet(): Set<string> {\n if (!this.multiple || !this.value) return new Set();\n return new Set(this.value.split(',').filter(Boolean));\n }\n\n // ─── Filtered options ───\n\n /** @internal */\n private get _filteredOptions(): ComboboxOption[] {\n if (!this._filterText) return this._options;\n const lower = this._filterText.toLowerCase();\n return this._options.filter((o) => o.label.toLowerCase().includes(lower));\n }\n\n // ─── Lifecycle ───\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n // Safety net: remove listener if component is removed while dropdown is open\n if (typeof document !== 'undefined') {\n document.removeEventListener('click', this._handleOutsideClick);\n }\n if (this._debounceTimer !== null) {\n clearTimeout(this._debounceTimer);\n }\n // Reset open state to prevent persisted open state on reconnect\n if (this._open) {\n this._open = false;\n }\n }\n\n override updated(changedProperties: PropertyValues<this>): void {\n super.updated(changedProperties);\n if (changedProperties.has('value')) {\n this._updateFormValue();\n }\n // Force screen reader re-announcement when error text changes (a11y-v3-005)\n if (changedProperties.has('error') && this.error) {\n const errorEl = this.shadowRoot?.querySelector('[role=\"alert\"]');\n if (errorEl) {\n const msg = this.error;\n requestAnimationFrame(() => {\n errorEl.textContent = '';\n requestAnimationFrame(() => {\n errorEl.textContent = msg;\n });\n });\n }\n }\n }\n\n // ─── Form Integration ───\n\n /** @internal */\n private _updateFormValue(): void {\n this._internals.setFormValue(this.value || null);\n }\n\n /** @internal */\n override _updateValidity(): void {\n if (this.required && !this.value) {\n this._internals.setValidity(\n { valueMissing: true },\n this.error || this.labelRequired,\n this._input,\n );\n } else {\n this._internals.setValidity({});\n }\n }\n\n /** @internal */\n protected override _onFormReset(): void {\n this.value = '';\n this._filterText = '';\n this._internals.setFormValue(null);\n this._resetInteractionState();\n }\n\n /** @internal */\n // P1-6: Correct signature per WHATWG spec — includes mode param and all state types\n protected override _onFormStateRestore(\n state: File | string | FormData | null,\n _mode: 'restore' | 'autocomplete',\n ): void {\n if (typeof state === 'string') {\n this.value = state;\n }\n }\n\n /** @internal */\n protected override _onFormDisabled(disabled: boolean): void {\n this.disabled = disabled;\n }\n\n // ─── Option Syncing from Slot ───\n\n /** @internal */\n private _handleSlotChange(): void {\n this._readOptions();\n }\n\n /** @internal */\n private _parseOption(el: HTMLOptionElement): ComboboxOption {\n return { value: el.value, label: el.textContent?.trim() ?? el.value, disabled: el.disabled };\n }\n\n /** @internal */\n private _readOptions(): void {\n const slot = this.shadowRoot?.querySelector<HTMLSlotElement>('slot[name=\"option\"]');\n if (!slot) return;\n\n const parsed: ComboboxOption[] = [];\n\n for (const el of slot.assignedElements({ flatten: true })) {\n if (el instanceof HTMLOptionElement) {\n parsed.push(this._parseOption(el));\n } else if (el instanceof HTMLOptGroupElement) {\n for (const child of Array.from(el.children)) {\n if (child instanceof HTMLOptionElement) parsed.push(this._parseOption(child));\n }\n }\n }\n\n this._options = parsed;\n }\n\n // ─── Slot Change Handlers ───\n\n /** @internal */\n private _handleErrorSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n this._hasErrorSlot = slot.assignedNodes({ flatten: true }).length > 0;\n }\n\n // ─── Dropdown Control ───\n\n /** @internal */\n private _openDropdown(): void {\n if (this.disabled || this._open) return;\n this._open = true;\n this._focusedOptionIndex = -1;\n if (typeof document !== 'undefined') {\n document.addEventListener('click', this._handleOutsideClick);\n }\n this.dispatchEvent(new CustomEvent<void>('hx-show', { bubbles: true, composed: true }));\n }\n\n /** @internal */\n private _closeDropdown(): void {\n if (!this._open) return;\n this._open = false;\n this._focusedOptionIndex = -1;\n this._handleInteractionBlur();\n if (typeof document !== 'undefined') {\n document.removeEventListener('click', this._handleOutsideClick);\n }\n this.dispatchEvent(new CustomEvent<void>('hx-hide', { bubbles: true, composed: true }));\n }\n\n // ─── Input Handling ───\n\n /** @internal */\n private _handleInput(e: Event): void {\n const input = e.target as HTMLInputElement;\n this._filterText = input.value;\n\n if (!this._open) {\n this._openDropdown();\n }\n\n this._focusedOptionIndex = -1;\n\n if (this.filterDebounce > 0) {\n if (this._debounceTimer !== null) {\n clearTimeout(this._debounceTimer);\n }\n this._debounceTimer = setTimeout(() => {\n this._emitInput();\n this._announceFilterResults();\n }, this.filterDebounce);\n } else {\n this._emitInput();\n this._announceFilterResults();\n }\n }\n\n /** @internal */\n private _announceFilterResults(): void {\n const count = this._filteredOptions.length;\n this._filterAnnouncement =\n count === 0\n ? 'No matching options'\n : `${count} ${count === 1 ? 'option' : 'options'} available`;\n }\n\n /** @internal */\n private _emitInput(): void {\n this.dispatchEvent(\n new CustomEvent<{ value: string }>('hx-input', {\n bubbles: true,\n composed: true,\n detail: { value: this._filterText },\n }),\n );\n }\n\n /** @internal */\n private _handleFocus(): void {\n this._openDropdown();\n }\n\n // ─── Keyboard Navigation ───\n\n /** @internal */\n private _handleKeydown(e: KeyboardEvent): void {\n if (this.disabled) return;\n\n const filtered = this._filteredOptions;\n const enabledIndices = filtered\n .map((o, i) => ({ o, i }))\n .filter(({ o }) => !o.disabled)\n .map(({ i }) => i);\n\n switch (e.key) {\n case 'ArrowDown': {\n e.preventDefault();\n if (!this._open) {\n this._openDropdown();\n this._focusedOptionIndex = enabledIndices.length > 0 ? (enabledIndices[0] ?? 0) : -1;\n break;\n }\n const nextDown = enabledIndices.find((i) => i > this._focusedOptionIndex);\n this._focusedOptionIndex =\n nextDown !== undefined ? nextDown : (enabledIndices[0] ?? this._focusedOptionIndex);\n break;\n }\n case 'ArrowUp': {\n e.preventDefault();\n if (!this._open) {\n this._openDropdown();\n const lastEnabled = enabledIndices[enabledIndices.length - 1];\n this._focusedOptionIndex = lastEnabled !== undefined ? lastEnabled : -1;\n break;\n }\n const prevUp = [...enabledIndices].reverse().find((i) => i < this._focusedOptionIndex);\n const lastEnabledUp = enabledIndices[enabledIndices.length - 1];\n this._focusedOptionIndex =\n prevUp !== undefined ? prevUp : (lastEnabledUp ?? this._focusedOptionIndex);\n break;\n }\n case 'Enter': {\n e.preventDefault();\n if (!this._open) {\n this._openDropdown();\n break;\n }\n if (this._focusedOptionIndex >= 0 && this._focusedOptionIndex < filtered.length) {\n const opt = filtered[this._focusedOptionIndex];\n if (opt) this._selectOption(opt);\n }\n break;\n }\n case 'Escape': {\n e.preventDefault();\n this._closeDropdown();\n this._filterText = '';\n if (this._input) this._input.value = '';\n break;\n }\n case 'Tab': {\n this._closeDropdown();\n break;\n }\n // P1-1: Home/End keyboard navigation for option list\n case 'Home': {\n e.preventDefault();\n if (!this._open) this._openDropdown();\n this._focusedOptionIndex = enabledIndices.length > 0 ? (enabledIndices[0] ?? -1) : -1;\n break;\n }\n case 'End': {\n e.preventDefault();\n if (!this._open) this._openDropdown();\n this._focusedOptionIndex =\n enabledIndices.length > 0 ? (enabledIndices[enabledIndices.length - 1] ?? -1) : -1;\n break;\n }\n default:\n break;\n }\n }\n\n // ─── Selection ───\n\n // P0-1: Handle both single and multiple selection modes\n /** @internal */\n private _selectOption(option: ComboboxOption): void {\n if (option.disabled) return;\n if (this.multiple) {\n const current = this._selectedValuesSet;\n const next = new Set(current);\n if (next.has(option.value)) {\n next.delete(option.value);\n } else {\n next.add(option.value);\n }\n this.value = [...next].join(',');\n // Keep dropdown open for multiple selection so user can pick more\n } else {\n this.value = option.value;\n this._closeDropdown();\n }\n this._handleInteractionInput();\n this._filterText = '';\n if (this._input) this._input.value = '';\n this._dispatchChange();\n }\n\n // P0-1: Remove a single value from multi-selection\n /** @internal */\n private _removeValue(val: string): void {\n const next = this._selectedValuesSet;\n next.delete(val);\n this.value = [...next].join(',');\n this._dispatchChange();\n }\n\n // ─── Clear ───\n\n /** @internal */\n private _handleClear(e: Event): void {\n e.stopPropagation();\n this.value = '';\n this._filterText = '';\n if (this._input) {\n this._input.value = '';\n this._input.focus();\n }\n this._internals.setFormValue(null);\n this._updateValidity();\n this.dispatchEvent(new CustomEvent<void>('hx-clear', { bubbles: true, composed: true }));\n }\n\n // ─── Event Dispatchers ───\n\n /** @internal */\n private _dispatchChange(): void {\n this.dispatchEvent(\n new CustomEvent<{ value: string }>('hx-change', {\n bubbles: true,\n composed: true,\n detail: { value: this.value },\n }),\n );\n }\n\n // ─── Outside Click Handler ───\n\n /** @internal */\n private _handleOutsideClick = (e: MouseEvent): void => {\n if (this._open && !e.composedPath().includes(this)) {\n this._closeDropdown();\n }\n };\n\n // ─── Public Methods ───\n\n /** Moves focus to the text input. */\n override focus(options?: FocusOptions): void {\n this._input?.focus(options);\n }\n\n // ─── Render Helpers ───\n\n /** @internal */\n private _optionId(index: number): string {\n return `${this._id}-option-${index}`;\n }\n\n /** @internal */\n private get _displayValue(): string {\n // P0-1: In multiple mode, chips render selected values — input shows only filter text\n if (this.multiple) return '';\n if (!this.value) return '';\n const opt = this._options.find((o) => o.value === this.value);\n return opt ? opt.label : this.value;\n }\n\n /** @internal */\n private _renderOptions() {\n const filtered = this._filteredOptions;\n\n if (filtered.length === 0) {\n return html`\n <slot name=\"empty-label\">\n <div class=\"field__no-options\">${this.labelNoOptions}</div>\n </slot>\n `;\n }\n\n return repeat(\n filtered,\n (opt) => opt.value,\n (opt, index) => {\n // P0-1: Use Set membership for multiple mode, direct equality for single mode\n const isSelected = this.multiple\n ? this._selectedValuesSet.has(opt.value)\n : opt.value === this.value;\n const isFocused = index === this._focusedOptionIndex;\n\n return html`\n <div\n id=${this._optionId(index)}\n part=\"option\"\n role=\"option\"\n class=${classMap({\n field__option: true,\n 'field__option--selected': isSelected,\n 'field__option--focused': isFocused,\n 'field__option--disabled': opt.disabled,\n })}\n aria-selected=${this.multiple\n ? isSelected\n ? 'true'\n : 'false'\n : isSelected\n ? 'true'\n : nothing}\n aria-disabled=${opt.disabled ? 'true' : nothing}\n @click=${() => this._selectOption(opt)}\n >\n <span class=\"field__option-label\">${opt.label}</span>\n </div>\n `;\n },\n );\n }\n\n // ─── Main Render ───\n\n override render() {\n const hasError = !!this.error || this._hasErrorSlot;\n const showClear = this.clearable && !!this.value && !this.disabled;\n\n const fieldClasses = {\n field: true,\n 'field--error': hasError,\n 'field--disabled': this.disabled,\n 'field--required': this.required,\n 'field--open': this._open,\n };\n\n const inputClasses = {\n field__input: true,\n [`field__input--${this.size}`]: true,\n };\n\n const describedBy =\n [\n hasError || this._hasErrorSlot ? this._errorId : null,\n this.helpText ? this._helpTextId : null,\n ]\n .filter(Boolean)\n .join(' ') || undefined;\n\n const activedescendant =\n this._open && this._focusedOptionIndex >= 0\n ? this._optionId(this._focusedOptionIndex)\n : undefined;\n\n return html`\n <div part=\"field\" class=${classMap(fieldClasses)}>\n <!-- Label -->\n <slot name=\"label\">\n ${this.label\n ? html`<label id=${this._labelId} for=${this._id} part=\"label\" class=\"field__label\">\n ${this.label}\n ${this.required\n ? html`<span class=\"field__required-marker\" aria-hidden=\"true\">*</span>`\n : nothing}\n </label>`\n : nothing}\n </slot>\n\n <!-- Input Wrapper -->\n <div part=\"trigger\" class=\"field__input-wrapper\">\n <!-- Prefix Slot -->\n <slot name=\"prefix\" class=\"field__prefix\"></slot>\n\n <!-- P0-1: Selected value chips for multiple mode -->\n ${this.multiple && this._selectedValuesSet.size > 0\n ? [...this._selectedValuesSet].map((val) => {\n const opt = this._options.find((o) => o.value === val);\n const label = opt ? opt.label : val;\n return html`\n <span class=\"field__chip\">\n <span class=\"field__chip-label\">${label}</span>\n <button\n type=\"button\"\n class=\"field__chip-remove\"\n aria-label=${this.labelRemoveOption(label)}\n @click=${(e: Event) => {\n e.stopPropagation();\n this._removeValue(val);\n }}\n >\n <svg\n width=\"8\"\n height=\"8\"\n viewBox=\"0 0 8 8\"\n fill=\"none\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <path\n d=\"M1 1L7 7M7 1L1 7\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n />\n </svg>\n </button>\n </span>\n `;\n })\n : nothing}\n\n <!-- Text Input (combobox role) -->\n <input\n part=\"input\"\n type=\"text\"\n id=${this._id}\n class=${classMap(inputClasses)}\n role=\"combobox\"\n aria-expanded=${this._open ? 'true' : 'false'}\n aria-autocomplete=\"list\"\n aria-controls=${this._listboxId}\n aria-activedescendant=${ifDefined(activedescendant)}\n aria-invalid=${hasError ? 'true' : nothing}\n aria-describedby=${ifDefined(describedBy)}\n aria-required=${this.required ? 'true' : nothing}\n aria-label=${ifDefined(this.accessibleLabel || undefined)}\n aria-labelledby=${ifDefined(\n this.label && !this.accessibleLabel ? this._labelId : undefined,\n )}\n aria-busy=${this.loading ? 'true' : nothing}\n .value=${this._filterText || (this._open ? '' : this._displayValue)}\n placeholder=${ifDefined(this.placeholder || undefined)}\n ?disabled=${this.disabled}\n ?required=${this.required}\n name=${ifDefined(this.name || undefined)}\n autocomplete=\"off\"\n @input=${this._handleInput}\n @focus=${this._handleFocus}\n @keydown=${this._handleKeydown}\n />\n\n <!-- Loading Indicator -->\n ${this.loading\n ? html`\n <div part=\"loading-indicator\" class=\"field__loading-indicator\" aria-hidden=\"true\">\n <div class=\"field__loading-spinner\"></div>\n </div>\n `\n : nothing}\n\n <!-- Clear Button -->\n ${showClear\n ? html`\n <button\n part=\"clear-button\"\n type=\"button\"\n class=\"field__clear-button\"\n aria-label=${`Clear ${this.label || this.accessibleLabel || 'selection'}`}\n tabindex=\"0\"\n @click=${this._handleClear}\n >\n <svg\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 12 12\"\n fill=\"none\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <path\n d=\"M1 1L11 11M11 1L1 11\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n />\n </svg>\n </button>\n `\n : nothing}\n\n <!-- Suffix Slot -->\n <slot name=\"suffix\" class=\"field__suffix\"></slot>\n </div>\n\n <!-- Listbox -->\n <div\n part=\"listbox\"\n role=\"listbox\"\n id=${this._listboxId}\n class=\"field__listbox\"\n aria-label=${ifDefined(this.label || this.accessibleLabel || undefined)}\n aria-multiselectable=${this.multiple ? 'true' : nothing}\n ?hidden=${!this._open}\n >\n <div class=\"field__options\">${this._renderOptions()}</div>\n </div>\n\n <!-- Hidden slot (options read from here) -->\n <slot name=\"option\" @slotchange=${this._handleSlotChange} style=\"display:none;\"></slot>\n\n <!-- Error -->\n <slot name=\"error\" @slotchange=${this._handleErrorSlotChange}>\n ${hasError\n ? html`<div part=\"error\" class=\"field__error\" id=${this._errorId} role=\"alert\">\n ${this.error}\n </div>`\n : nothing}\n </slot>\n\n <!-- Help Text -->\n ${this.helpText && !hasError\n ? html`\n <div part=\"help-text\" class=\"field__help-text\" id=${this._helpTextId}>\n <slot name=\"help-text\">${this.helpText}</slot>\n </div>\n `\n : nothing}\n\n <!-- Filter results live region -->\n <div id=${this._liveRegionId} aria-live=\"polite\" aria-atomic=\"true\" class=\"field__sr-only\">\n ${this._filterAnnouncement}\n </div>\n </div>\n `;\n }\n}\n\n/**\n * Per-component event map for type-safe addEventListener on hx-combobox.\n * The `hx-change` detail is `{ value: string }` only — no `checked` property.\n */\nexport interface HxComboboxEventMap {\n 'hx-input': CustomEvent<{ value: string }>;\n 'hx-change': CustomEvent<{ value: string }>;\n 'hx-clear': CustomEvent<void>;\n 'hx-show': CustomEvent<void>;\n 'hx-hide': CustomEvent<void>;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-combobox': HelixCombobox;\n }\n interface HTMLElementEventMap {\n 'hx-input': CustomEvent<{ value: string }>;\n 'hx-clear': CustomEvent<void>;\n 'hx-show': CustomEvent<void>;\n 'hx-hide': CustomEvent<void>;\n }\n}\n\nexport type { HelixCombobox as HxCombobox };\n"],"names":["helixComboboxStyles","css","_nextComboboxId","createIdCounter","HelixCombobox","FormMixin","HelixElement","label","lower","o","changedProperties","errorEl","_a","msg","state","_mode","disabled","el","slot","parsed","child","input","count","filtered","enabledIndices","i","nextDown","lastEnabled","prevUp","lastEnabledUp","opt","option","current","next","val","options","index","html","repeat","isSelected","isFocused","classMap","nothing","hasError","showClear","fieldClasses","inputClasses","describedBy","activedescendant","e","ifDefined","forcedColorsField","__decorateClass","property","query","customElement"],"mappings":";;;;;;;;;AAEO,MAAMA,IAAsBC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAA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"}
@@ -2,7 +2,7 @@ import { css as D, html as _, nothing as u } from "lit";
2
2
  import { property as d, state as f, query as y, customElement as k } from "lit/decorators.js";
3
3
  import { F as M } from "./FormMixin-B8PXk5RQ.js";
4
4
  import { classMap as b } from "lit/directives/class-map.js";
5
- import { ifDefined as g } from "lit/directives/if-defined.js";
5
+ import { ifDefined as m } from "lit/directives/if-defined.js";
6
6
  import { b as $ } from "./forced-colors-CTEDFRGa.js";
7
7
  import { H as S } from "./helix-element-BNEYeiys.js";
8
8
  import { c as C } from "./id-counter-DuX8vsui.js";
@@ -74,17 +74,11 @@ const I = D`
74
74
  }
75
75
 
76
76
  .field__input-wrapper:focus-within {
77
- border-color: var(
78
- --hx-date-picker-focus-ring-color,
79
- var(--hx-focus-ring-color, var(--hx-color-primary-600, #0f7078))
80
- );
77
+ border-color: var(--hx-date-picker-focus-ring-color, var(--hx-focus-ring-color, #0f7078));
81
78
  box-shadow: 0 0 0 var(--hx-focus-ring-width, 2px)
82
79
  color-mix(
83
80
  in srgb,
84
- var(
85
- --hx-date-picker-focus-ring-color,
86
- var(--hx-focus-ring-color, var(--hx-color-primary-600, #0f7078))
87
- )
81
+ var(--hx-date-picker-focus-ring-color, var(--hx-focus-ring-color, #0f7078))
88
82
  calc(var(--hx-focus-ring-opacity, 0.25) * 100%),
89
83
  transparent
90
84
  );
@@ -153,17 +147,10 @@ const I = D`
153
147
  }
154
148
 
155
149
  .field__trigger:focus-visible {
156
- color: var(
157
- --hx-date-picker-focus-ring-color,
158
- var(--hx-focus-ring-color, var(--hx-color-primary-600, #0f7078))
159
- );
150
+ color: var(--hx-date-picker-focus-ring-color, var(--hx-focus-ring-color, #0f7078));
160
151
  background-color: color-mix(
161
152
  in srgb,
162
- var(
163
- --hx-date-picker-focus-ring-color,
164
- var(--hx-focus-ring-color, var(--hx-color-primary-600, #0f7078))
165
- )
166
- 8%,
153
+ var(--hx-date-picker-focus-ring-color, var(--hx-focus-ring-color, #0f7078)) 8%,
167
154
  transparent
168
155
  );
169
156
  }
@@ -260,10 +247,7 @@ const I = D`
260
247
 
261
248
  :is(.calendar__nav-btn, .calendar__day):focus-visible {
262
249
  box-shadow: 0 0 0 var(--hx-focus-ring-width, 2px)
263
- var(
264
- --hx-date-picker-focus-ring-color,
265
- var(--hx-focus-ring-color, var(--hx-color-primary-600, #0f7078))
266
- );
250
+ var(--hx-date-picker-focus-ring-color, var(--hx-focus-ring-color, #0f7078));
267
251
  z-index: 1;
268
252
  }
269
253
 
@@ -807,7 +791,7 @@ let s = class extends M(S) {
807
791
  const o = t.slice(i, i + 7).map((l) => {
808
792
  if (l === null)
809
793
  return _`<div class="calendar__day-cell" role="gridcell" aria-hidden="true"></div>`;
810
- const c = e ? this._isSameDay(l, e) : !1, h = this._isSameDay(l, r), p = this._isDateDisabled(l), v = this._focusedDay === l.getDate(), x = l.getDate(), m = this._toISO(l), w = this._dayAriaLabels.get(m) ?? m;
794
+ const c = e ? this._isSameDay(l, e) : !1, h = this._isSameDay(l, r), p = this._isDateDisabled(l), v = this._focusedDay === l.getDate(), x = l.getDate(), g = this._toISO(l), w = this._dayAriaLabels.get(g) ?? g;
811
795
  return _`<div
812
796
  class="calendar__day-cell"
813
797
  role="gridcell"
@@ -825,7 +809,7 @@ let s = class extends M(S) {
825
809
  })}
826
810
  type="button"
827
811
  data-day=${x}
828
- data-date=${m}
812
+ data-date=${g}
829
813
  aria-label=${w}
830
814
  tabindex=${v ? "0" : "-1"}
831
815
  ?disabled=${p}
@@ -869,13 +853,13 @@ let s = class extends M(S) {
869
853
  type="text"
870
854
  readonly
871
855
  .value=${e}
872
- placeholder=${g(this.format || void 0)}
856
+ placeholder=${m(this.format || void 0)}
873
857
  ?disabled=${this.disabled}
874
- aria-labelledby=${g(
858
+ aria-labelledby=${m(
875
859
  this._hasLabelSlot ? `${this._inputId}-slotted-label` : void 0
876
860
  )}
877
861
  aria-invalid=${t ? "true" : u}
878
- aria-describedby=${g(i)}
862
+ aria-describedby=${m(i)}
879
863
  aria-required=${this.required ? "true" : u}
880
864
  aria-haspopup="dialog"
881
865
  @click=${this._openCalendar}
@@ -1075,4 +1059,4 @@ s = n([
1075
1059
  export {
1076
1060
  s as H
1077
1061
  };
1078
- //# sourceMappingURL=hx-date-picker-BJm7Yrda.js.map
1062
+ //# sourceMappingURL=hx-date-picker-2iRG1p74.js.map