@helixui/library 1.1.2-next.2 → 1.1.2-next.25

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 (125) hide show
  1. package/custom-elements.json +387 -405
  2. package/dist/components/hx-avatar/hx-avatar.styles.d.ts.map +1 -1
  3. package/dist/components/hx-avatar/index.js +1 -1
  4. package/dist/components/hx-breadcrumb/hx-breadcrumb-item.d.ts +1 -0
  5. package/dist/components/hx-breadcrumb/hx-breadcrumb-item.d.ts.map +1 -1
  6. package/dist/components/hx-breadcrumb/hx-breadcrumb.d.ts +10 -8
  7. package/dist/components/hx-breadcrumb/hx-breadcrumb.d.ts.map +1 -1
  8. package/dist/components/hx-breadcrumb/index.js +1 -1
  9. package/dist/components/hx-button/hx-button.d.ts +12 -6
  10. package/dist/components/hx-button/hx-button.d.ts.map +1 -1
  11. package/dist/components/hx-button/hx-button.styles.d.ts.map +1 -1
  12. package/dist/components/hx-button/index.js +1 -1
  13. package/dist/components/hx-clinical-status/hx-clinical-status.d.ts +14 -6
  14. package/dist/components/hx-clinical-status/hx-clinical-status.d.ts.map +1 -1
  15. package/dist/components/hx-clinical-status/hx-clinical-status.styles.d.ts.map +1 -1
  16. package/dist/components/hx-clinical-status/index.d.ts +1 -1
  17. package/dist/components/hx-clinical-status/index.d.ts.map +1 -1
  18. package/dist/components/hx-clinical-status/index.js +1 -1
  19. package/dist/components/hx-menu/hx-menu-item.d.ts +5 -0
  20. package/dist/components/hx-menu/hx-menu-item.d.ts.map +1 -1
  21. package/dist/components/hx-menu/hx-menu.d.ts +1 -0
  22. package/dist/components/hx-menu/hx-menu.d.ts.map +1 -1
  23. package/dist/components/hx-menu/hx-menu.styles.d.ts.map +1 -1
  24. package/dist/components/hx-menu/index.js +1 -1
  25. package/dist/components/hx-nav/hx-nav.d.ts +10 -0
  26. package/dist/components/hx-nav/hx-nav.d.ts.map +1 -1
  27. package/dist/components/hx-nav/index.js +1 -1
  28. package/dist/components/hx-pagination/hx-pagination.d.ts.map +1 -1
  29. package/dist/components/hx-pagination/index.js +1 -1
  30. package/dist/components/hx-patient-banner/hx-patient-banner.d.ts +8 -0
  31. package/dist/components/hx-patient-banner/hx-patient-banner.d.ts.map +1 -1
  32. package/dist/components/hx-patient-banner/hx-patient-banner.styles.d.ts.map +1 -1
  33. package/dist/components/hx-patient-banner/index.js +1 -1
  34. package/dist/components/hx-phi-field/hx-phi-field.d.ts +27 -2
  35. package/dist/components/hx-phi-field/hx-phi-field.d.ts.map +1 -1
  36. package/dist/components/hx-phi-field/hx-phi-field.styles.d.ts.map +1 -1
  37. package/dist/components/hx-phi-field/index.js +1 -1
  38. package/dist/components/hx-select/hx-select.d.ts +1 -0
  39. package/dist/components/hx-select/hx-select.d.ts.map +1 -1
  40. package/dist/components/hx-select/hx-select.styles.d.ts.map +1 -1
  41. package/dist/components/hx-select/index.js +1 -1
  42. package/dist/components/hx-side-nav/hx-nav-item.d.ts +5 -0
  43. package/dist/components/hx-side-nav/hx-nav-item.d.ts.map +1 -1
  44. package/dist/components/hx-side-nav/hx-side-nav.d.ts.map +1 -1
  45. package/dist/components/hx-side-nav/index.js +1 -1
  46. package/dist/components/hx-status-indicator/hx-status-indicator.d.ts +17 -1
  47. package/dist/components/hx-status-indicator/hx-status-indicator.d.ts.map +1 -1
  48. package/dist/components/hx-status-indicator/hx-status-indicator.styles.d.ts.map +1 -1
  49. package/dist/components/hx-status-indicator/index.js +1 -1
  50. package/dist/components/hx-steps/hx-step.d.ts +7 -0
  51. package/dist/components/hx-steps/hx-step.d.ts.map +1 -1
  52. package/dist/components/hx-steps/hx-steps.d.ts.map +1 -1
  53. package/dist/components/hx-steps/index.js +1 -1
  54. package/dist/components/hx-tabs/hx-tab.styles.d.ts.map +1 -1
  55. package/dist/components/hx-tabs/hx-tabs.d.ts +10 -0
  56. package/dist/components/hx-tabs/hx-tabs.d.ts.map +1 -1
  57. package/dist/components/hx-tabs/index.js +1 -1
  58. package/dist/components/hx-tree-view/hx-tree-item.d.ts +5 -0
  59. package/dist/components/hx-tree-view/hx-tree-item.d.ts.map +1 -1
  60. package/dist/components/hx-tree-view/hx-tree-view.d.ts +6 -0
  61. package/dist/components/hx-tree-view/hx-tree-view.d.ts.map +1 -1
  62. package/dist/components/hx-tree-view/index.js +1 -1
  63. package/dist/css/helix-all.css +202 -51
  64. package/dist/css/helix-core.css +52 -1
  65. package/dist/css/helix-feedback.css +33 -4
  66. package/dist/css/helix-forms.css +68 -41
  67. package/dist/css/helix-navigation.css +2 -0
  68. package/dist/css/hx-avatar.css +18 -1
  69. package/dist/css/hx-button.css +34 -0
  70. package/dist/css/hx-clinical-status.css +4 -2
  71. package/dist/css/hx-menu.css +2 -0
  72. package/dist/css/hx-patient-banner.css +31 -3
  73. package/dist/css/hx-phi-field.css +12 -0
  74. package/dist/css/hx-select.css +68 -41
  75. package/dist/css/hx-status-indicator.css +33 -4
  76. package/dist/css/index.css +1 -1
  77. package/dist/css/manifest.json +13 -5
  78. package/dist/index.d.ts +1 -1
  79. package/dist/index.d.ts.map +1 -1
  80. package/dist/index.js +15 -15
  81. package/dist/shared/{hx-avatar-7p1cj3lG.js → hx-avatar-CZfA9KEl.js} +27 -10
  82. package/dist/shared/hx-avatar-CZfA9KEl.js.map +1 -0
  83. package/dist/shared/{hx-breadcrumb-item-B2rjepqy.js → hx-breadcrumb-item-CObc-WJl.js} +8 -6
  84. package/dist/shared/hx-breadcrumb-item-CObc-WJl.js.map +1 -0
  85. package/dist/shared/{hx-button-6S3DwuIj.js → hx-button-CC1YH9RZ.js} +52 -12
  86. package/dist/shared/hx-button-CC1YH9RZ.js.map +1 -0
  87. package/dist/shared/{hx-clinical-status-De8yrA5I.js → hx-clinical-status-D6eaplvs.js} +5 -3
  88. package/dist/shared/hx-clinical-status-D6eaplvs.js.map +1 -0
  89. package/dist/shared/{hx-menu-divider-DR4G_rqw.js → hx-menu-divider-puPmRAdN.js} +40 -20
  90. package/dist/shared/hx-menu-divider-puPmRAdN.js.map +1 -0
  91. package/dist/shared/{hx-nav-D377Ngz4.js → hx-nav-CiyqaW2I.js} +112 -99
  92. package/dist/shared/hx-nav-CiyqaW2I.js.map +1 -0
  93. package/dist/shared/{hx-nav-item-CuGiJPAf.js → hx-nav-item-tM_6bolB.js} +132 -92
  94. package/dist/shared/hx-nav-item-tM_6bolB.js.map +1 -0
  95. package/dist/shared/{hx-pagination-DYhYPqDn.js → hx-pagination-Cb9UEWXz.js} +74 -66
  96. package/dist/shared/{hx-pagination-DYhYPqDn.js.map → hx-pagination-Cb9UEWXz.js.map} +1 -1
  97. package/dist/shared/{hx-patient-banner-BoJHddAL.js → hx-patient-banner-wk4qWmsH.js} +88 -47
  98. package/dist/shared/hx-patient-banner-wk4qWmsH.js.map +1 -0
  99. package/dist/shared/{hx-phi-field-EDWna59z.js → hx-phi-field-DX9z3nu0.js} +67 -33
  100. package/dist/shared/hx-phi-field-DX9z3nu0.js.map +1 -0
  101. package/dist/shared/{hx-select-4-nHL0vd.js → hx-select-BWzxWZs_.js} +82 -55
  102. package/dist/shared/hx-select-BWzxWZs_.js.map +1 -0
  103. package/dist/shared/{hx-status-indicator-4ClvA5mU.js → hx-status-indicator-Dl3Y34mc.js} +76 -35
  104. package/dist/shared/hx-status-indicator-Dl3Y34mc.js.map +1 -0
  105. package/dist/shared/{hx-step-DlANlr2A.js → hx-step-CmNwfcJx.js} +30 -26
  106. package/dist/shared/hx-step-CmNwfcJx.js.map +1 -0
  107. package/dist/shared/{hx-tab-panel-GGjk6Qg4.js → hx-tab-panel-Dnt8aA74.js} +89 -61
  108. package/dist/shared/hx-tab-panel-Dnt8aA74.js.map +1 -0
  109. package/dist/shared/{hx-tree-item-DTDIBRrI.js → hx-tree-item-C1PhX-HE.js} +50 -19
  110. package/dist/shared/hx-tree-item-C1PhX-HE.js.map +1 -0
  111. package/package.json +2 -2
  112. package/dist/shared/hx-avatar-7p1cj3lG.js.map +0 -1
  113. package/dist/shared/hx-breadcrumb-item-B2rjepqy.js.map +0 -1
  114. package/dist/shared/hx-button-6S3DwuIj.js.map +0 -1
  115. package/dist/shared/hx-clinical-status-De8yrA5I.js.map +0 -1
  116. package/dist/shared/hx-menu-divider-DR4G_rqw.js.map +0 -1
  117. package/dist/shared/hx-nav-D377Ngz4.js.map +0 -1
  118. package/dist/shared/hx-nav-item-CuGiJPAf.js.map +0 -1
  119. package/dist/shared/hx-patient-banner-BoJHddAL.js.map +0 -1
  120. package/dist/shared/hx-phi-field-EDWna59z.js.map +0 -1
  121. package/dist/shared/hx-select-4-nHL0vd.js.map +0 -1
  122. package/dist/shared/hx-status-indicator-4ClvA5mU.js.map +0 -1
  123. package/dist/shared/hx-step-DlANlr2A.js.map +0 -1
  124. package/dist/shared/hx-tab-panel-GGjk6Qg4.js.map +0 -1
  125. package/dist/shared/hx-tree-item-DTDIBRrI.js.map +0 -1
@@ -1,5 +1,5 @@
1
- import { css as x, LitElement as u, nothing as m, html as d } from "lit";
2
- import { property as a, customElement as v } from "lit/decorators.js";
1
+ import { css as x, LitElement as v, nothing as m, html as d } from "lit";
2
+ import { property as a, customElement as u } from "lit/decorators.js";
3
3
  import { tokenStyles as f } from "@helixui/tokens/lit";
4
4
  const b = x`
5
5
  :host {
@@ -54,27 +54,27 @@ const b = x`
54
54
  --hx-steps-description-font-size: var(--hx-font-size-sm, 0.875rem);
55
55
  }
56
56
  `;
57
- var _ = Object.defineProperty, y = Object.getOwnPropertyDescriptor, p = (t, r, i, s) => {
58
- for (var e = s > 1 ? void 0 : s ? y(r, i) : r, l = t.length - 1, h; l >= 0; l--)
59
- (h = t[l]) && (e = (s ? h(r, i, e) : h(e)) || e);
60
- return s && e && _(r, i, e), e;
57
+ var _ = Object.defineProperty, g = Object.getOwnPropertyDescriptor, p = (t, i, r, s) => {
58
+ for (var e = s > 1 ? void 0 : s ? g(i, r) : i, l = t.length - 1, h; l >= 0; l--)
59
+ (h = t[l]) && (e = (s ? h(i, r, e) : h(e)) || e);
60
+ return s && e && _(i, r, e), e;
61
61
  };
62
- let c = class extends u {
62
+ let c = class extends v {
63
63
  constructor() {
64
64
  super(...arguments), this.orientation = "horizontal", this.size = "md", this.ariaLabel = null, this._handleSlotChange = () => {
65
65
  this._syncChildren();
66
66
  }, this._handleStepClickInternal = (t) => {
67
67
  t.stopPropagation();
68
- const r = this._getSteps(), i = t.composedPath().find(
68
+ const i = this._getSteps(), r = t.composedPath().find(
69
69
  (e) => e instanceof Element && e.tagName.toLowerCase() === "hx-step"
70
70
  );
71
- if (!i) return;
72
- const s = r.indexOf(i);
71
+ if (!r) return;
72
+ const s = i.indexOf(r);
73
73
  this.dispatchEvent(
74
74
  new CustomEvent("hx-step-click", {
75
75
  bubbles: !0,
76
76
  composed: !0,
77
- detail: { step: i, index: s }
77
+ detail: { step: r, index: s }
78
78
  })
79
79
  );
80
80
  };
@@ -83,7 +83,7 @@ let c = class extends u {
83
83
  connectedCallback() {
84
84
  super.connectedCallback();
85
85
  const t = this.getAttribute("size");
86
- t !== null && !this.hasAttribute("hx-size") && (this.size = t), this.hasAttribute("role") || this.setAttribute("role", "none"), this.addEventListener("hx-step-click-internal", this._handleStepClickInternal);
86
+ t !== null && !this.hasAttribute("hx-size") && (this.size = t), this.ariaLabel, this.hasAttribute("role") || this.setAttribute("role", "none"), this.addEventListener("hx-step-click-internal", this._handleStepClickInternal);
87
87
  }
88
88
  disconnectedCallback() {
89
89
  super.disconnectedCallback(), this.removeEventListener("hx-step-click-internal", this._handleStepClickInternal);
@@ -101,8 +101,8 @@ let c = class extends u {
101
101
  }
102
102
  /** @internal */
103
103
  _syncChildren() {
104
- this._getSteps().forEach((r, i) => {
105
- r.orientation = this.orientation, r.size = this.size, r.index = i;
104
+ this._getSteps().forEach((i, r) => {
105
+ i.orientation = this.orientation, i.size = this.size, i.index = r;
106
106
  });
107
107
  }
108
108
  // ─── Render ───
@@ -125,9 +125,9 @@ p([
125
125
  a({ type: String, attribute: "aria-label" })
126
126
  ], c.prototype, "ariaLabel", 2);
127
127
  c = p([
128
- v("hx-steps")
128
+ u("hx-steps")
129
129
  ], c);
130
- const g = x`
130
+ const y = x`
131
131
  :host {
132
132
  display: flex;
133
133
  flex: var(--hx-steps-item-flex, 1);
@@ -348,14 +348,14 @@ const g = x`
348
348
  }
349
349
  }
350
350
  `;
351
- var z = Object.defineProperty, w = Object.getOwnPropertyDescriptor, n = (t, r, i, s) => {
352
- for (var e = s > 1 ? void 0 : s ? w(r, i) : r, l = t.length - 1, h; l >= 0; l--)
353
- (h = t[l]) && (e = (s ? h(r, i, e) : h(e)) || e);
354
- return s && e && z(r, i, e), e;
351
+ var z = Object.defineProperty, w = Object.getOwnPropertyDescriptor, n = (t, i, r, s) => {
352
+ for (var e = s > 1 ? void 0 : s ? w(i, r) : i, l = t.length - 1, h; l >= 0; l--)
353
+ (h = t[l]) && (e = (s ? h(i, r, e) : h(e)) || e);
354
+ return s && e && z(i, r, e), e;
355
355
  };
356
- let o = class extends u {
356
+ let o = class extends v {
357
357
  constructor() {
358
- super(...arguments), this.label = "", this.status = "pending", this.description = "", this.disabled = !1, this.orientation = "horizontal", this.size = "md", this.index = 0, this._handleKeydown = (t) => {
358
+ super(...arguments), this.label = "", this.status = "pending", this.description = "", this.disabled = !1, this.orientation = "horizontal", this.size = "md", this.index = 0, this._liveMessage = "", this._handleKeydown = (t) => {
359
359
  (t.key === "Enter" || t.key === " ") && (t.preventDefault(), this._handleClick());
360
360
  };
361
361
  }
@@ -366,6 +366,9 @@ let o = class extends u {
366
366
  disconnectedCallback() {
367
367
  super.disconnectedCallback(), this.removeEventListener("keydown", this._handleKeydown);
368
368
  }
369
+ willUpdate(t) {
370
+ t.has("status") && t.get("status") !== void 0 && (this.status === "complete" ? this._liveMessage = "Complete" : this.status === "error" ? this._liveMessage = "Error" : this._liveMessage = "");
371
+ }
369
372
  updated(t) {
370
373
  super.updated(t), t.has("status") && (this.status === "active" ? this.setAttribute("aria-current", "step") : this.removeAttribute("aria-current")), t.has("disabled") && (this.disabled ? (this.setAttribute("tabindex", "-1"), this.setAttribute("aria-disabled", "true")) : (this.setAttribute("tabindex", "0"), this.removeAttribute("aria-disabled"))), t.has("orientation") && this.setAttribute("orientation", this.orientation), t.has("size") && this.setAttribute("size", this.size);
371
374
  }
@@ -419,7 +422,7 @@ let o = class extends u {
419
422
  // ─── Render ───
420
423
  render() {
421
424
  return d`
422
- <div part="base" class="step" role="button" @click=${this._handleClick}>
425
+ <div part="base" class="step" @click=${this._handleClick}>
423
426
  <div class="step__track">
424
427
  <div part="indicator" class="step__indicator">${this._renderIndicatorContent()}</div>
425
428
  <div part="connector" class="step__connector" aria-hidden="true"></div>
@@ -433,10 +436,11 @@ let o = class extends u {
433
436
  </div>
434
437
  </div>
435
438
  </div>
439
+ <div aria-live="polite" aria-atomic="true" class="sr-only">${this._liveMessage}</div>
436
440
  `;
437
441
  }
438
442
  };
439
- o.styles = [f, g];
443
+ o.styles = [f, y];
440
444
  n([
441
445
  a({ type: String, reflect: !0 })
442
446
  ], o.prototype, "label", 2);
@@ -459,10 +463,10 @@ n([
459
463
  a({ type: Number })
460
464
  ], o.prototype, "index", 2);
461
465
  o = n([
462
- v("hx-step")
466
+ u("hx-step")
463
467
  ], o);
464
468
  export {
465
469
  o as H,
466
470
  c as a
467
471
  };
468
- //# sourceMappingURL=hx-step-DlANlr2A.js.map
472
+ //# sourceMappingURL=hx-step-CmNwfcJx.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hx-step-CmNwfcJx.js","sources":["../../src/components/hx-steps/hx-steps.styles.ts","../../src/components/hx-steps/hx-steps.ts","../../src/components/hx-steps/hx-step.styles.ts","../../src/components/hx-steps/hx-step.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixStepsStyles = css`\n :host {\n display: block;\n\n /* ─── Size defaults (md) ─── */\n --hx-steps-indicator-size: var(--hx-size-8, 2rem);\n --hx-steps-indicator-font-size: var(--hx-font-size-sm, 0.875rem);\n --hx-steps-indicator-icon-size: var(--hx-size-4, 1rem);\n --hx-steps-label-font-size: var(--hx-font-size-sm, 0.875rem);\n --hx-steps-description-font-size: var(--hx-font-size-xs, 0.75rem);\n\n /* ─── Item layout defaults (horizontal) ─── */\n --hx-steps-item-flex: 1;\n --hx-steps-item-width: auto;\n }\n\n .steps {\n display: flex;\n flex-direction: row;\n align-items: flex-start;\n }\n\n /* ─── Orientation: vertical ─── */\n\n :host([orientation='vertical']) {\n --hx-steps-item-flex: initial;\n --hx-steps-item-width: 100%;\n }\n\n :host([orientation='vertical']) .steps {\n flex-direction: column;\n }\n\n /* ─── Size: sm ─── */\n\n :host([size='sm']) {\n --hx-steps-indicator-size: var(--hx-size-6, 1.5rem);\n --hx-steps-indicator-font-size: var(--hx-font-size-xs, 0.75rem);\n --hx-steps-indicator-icon-size: var(--hx-space-3, 0.75rem);\n --hx-steps-label-font-size: var(--hx-font-size-xs, 0.75rem);\n --hx-steps-description-font-size: var(--hx-font-size-xs, 0.75rem);\n }\n\n /* ─── Size: lg ─── */\n\n :host([size='lg']) {\n --hx-steps-indicator-size: var(--hx-size-10, 2.5rem);\n --hx-steps-indicator-font-size: var(--hx-font-size-md, 1rem);\n --hx-steps-indicator-icon-size: var(--hx-size-5, 1.25rem);\n --hx-steps-label-font-size: var(--hx-font-size-md, 1rem);\n --hx-steps-description-font-size: var(--hx-font-size-sm, 0.875rem);\n }\n`;\n","import { LitElement, html, nothing, type PropertyValues } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { tokenStyles } from '@helixui/tokens/lit';\nimport { devWarn } from '../../utils/dev-warn.js';\nimport { helixStepsStyles } from './hx-steps.styles.js';\nimport type { HelixStep } from './hx-step.js';\n\n/**\n * A multi-step wizard / stepper progress indicator. Renders a sequence of\n * `<hx-step>` children as a horizontal or vertical step tracker with connector\n * lines and status-based styling.\n *\n * Provide an `aria-label` on `<hx-steps>` to describe the step process for assistive technology.\n *\n * @summary Multi-step progress indicator container.\n *\n * @tag hx-steps\n *\n * @slot - Default slot for `<hx-step>` elements.\n *\n * @fires {CustomEvent<{step: HelixStep, index: number}>} hx-step-click - Dispatched when\n * a step is clicked. Detail contains the clicked `step` element and its zero-based `index`.\n *\n * @csspart base - The inner wrapper element.\n *\n * @cssprop [--hx-steps-indicator-size=2rem] - Step indicator circle diameter.\n * @cssprop [--hx-steps-connector-color=var(--hx-color-neutral-200)] - Connector line color.\n * @cssprop [--hx-steps-label-color=var(--hx-color-neutral-600)] - Step label text color.\n * @cssprop [--hx-steps-description-color=var(--hx-color-neutral-500)] - Step description color.\n */\n@customElement('hx-steps')\nexport class HelixSteps extends LitElement {\n static override styles = [tokenStyles, helixStepsStyles];\n\n // ─── Public Properties ───\n\n /**\n * Layout orientation of the steps.\n * @attr orientation\n */\n @property({ type: String, reflect: true })\n orientation: 'horizontal' | 'vertical' = 'horizontal';\n\n /**\n * Size variant of the steps.\n * @attr hx-size\n */\n @property({ type: String, reflect: true, attribute: 'hx-size' })\n size: 'sm' | 'md' | 'lg' = 'md';\n\n /**\n * Accessible label for the list. Forwarded to the inner list element.\n * @attr aria-label\n */\n @property({ type: String, attribute: 'aria-label' })\n ariaLabel: string | null = null;\n\n // ─── Lifecycle ───\n\n override connectedCallback(): void {\n super.connectedCallback();\n // Backward compat: accept legacy `size` attribute. When present and `hx-size`\n // is not set, map the value and emit a deprecation warning.\n const legacySize = this.getAttribute('size');\n if (legacySize !== null && !this.hasAttribute('hx-size')) {\n devWarn('hx-steps', 'The \"size\" attribute is deprecated. Use \"hx-size\" instead.');\n this.size = legacySize as 'sm' | 'md' | 'lg';\n }\n // STEPS-002: WCAG 2.1 SC 4.1.2 — the inner list must have an accessible name.\n // Warn developers when aria-label is missing so the list is not anonymous.\n if (!this.ariaLabel) {\n devWarn(\n 'hx-steps',\n 'An \"aria-label\" attribute is required to provide an accessible name for the steps list (WCAG 2.1 SC 4.1.2).',\n );\n }\n // WCAG 4.1.2: suppress the host element's implicit ARIA role so only the\n // inner div[role=\"list\"] is announced. Mirrors the hx-action-bar pattern.\n // Without this, the consumer's aria-label attribute on the host causes dual\n // announcement — once for the host element and once for the inner list.\n if (!this.hasAttribute('role')) {\n this.setAttribute('role', 'none');\n }\n this.addEventListener('hx-step-click-internal', this._handleStepClickInternal);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener('hx-step-click-internal', this._handleStepClickInternal);\n }\n\n override firstUpdated(): void {\n this._syncChildren();\n }\n\n override updated(changedProperties: PropertyValues<this>): void {\n super.updated(changedProperties);\n if (changedProperties.has('orientation') || changedProperties.has('size')) {\n this._syncChildren();\n }\n }\n\n // ─── Child Sync ───\n\n /** @internal */\n private _getSteps(): HelixStep[] {\n return Array.from(this.querySelectorAll(':scope > hx-step')) as HelixStep[];\n }\n\n /** @internal */\n private _syncChildren(): void {\n const steps = this._getSteps();\n steps.forEach((step, i) => {\n step.orientation = this.orientation;\n step.size = this.size;\n step.index = i;\n });\n }\n\n // ─── Event Handling ───\n\n /** @internal */\n private _handleSlotChange = (): void => {\n this._syncChildren();\n };\n\n /** @internal */\n private _handleStepClickInternal = (e: Event): void => {\n e.stopPropagation();\n const steps = this._getSteps();\n const step = e\n .composedPath()\n .find(\n (el): el is HelixStep => el instanceof Element && el.tagName.toLowerCase() === 'hx-step',\n );\n if (!step) return;\n const index = steps.indexOf(step);\n\n /**\n * Dispatched when a step is clicked.\n * @event hx-step-click\n */\n this.dispatchEvent(\n new CustomEvent<{ step: HelixStep; index: number }>('hx-step-click', {\n bubbles: true,\n composed: true,\n detail: { step, index },\n }),\n );\n };\n\n // ─── Render ───\n\n override render() {\n return html`\n <div part=\"base\" class=\"steps\" role=\"list\" aria-label=${this.ariaLabel ?? nothing}>\n <slot @slotchange=${this._handleSlotChange}></slot>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-steps': HelixSteps;\n }\n}\n","import { css } from 'lit';\n\nexport const helixStepStyles = css`\n :host {\n display: flex;\n flex: var(--hx-steps-item-flex, 1);\n width: var(--hx-steps-item-width, auto);\n min-width: 0;\n }\n\n /* ─── Visually Hidden (SR 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-width: 0;\n }\n\n /* ─── Step Wrapper ─── */\n\n .step {\n display: flex;\n flex-direction: column;\n align-items: center;\n width: 100%;\n cursor: pointer;\n }\n\n /* ─── Focus ─── */\n\n :host(:focus-visible) .step__indicator {\n outline: var(--hx-focus-ring-width, 2px) solid var(--hx-color-primary-500);\n outline-offset: var(--hx-focus-ring-offset, 2px);\n }\n\n /* ─── Track (indicator + connector) ─── */\n\n .step__track {\n display: flex;\n flex-direction: row;\n align-items: center;\n width: 100%;\n }\n\n /* ─── Indicator ─── */\n\n .step__indicator {\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n width: var(--hx-steps-indicator-size, 2rem);\n height: var(--hx-steps-indicator-size, 2rem);\n border-radius: var(--hx-border-radius-full, 9999px);\n border: var(--hx-border-width-medium, 2px) solid var(--hx-color-neutral-300);\n background-color: var(--hx-color-neutral-0);\n color: var(--hx-color-neutral-500);\n font-size: var(--hx-steps-indicator-font-size, var(--hx-font-size-sm));\n font-weight: var(--hx-font-weight-semibold);\n font-family: var(--hx-font-family-sans);\n transition:\n background-color var(--hx-transition-fast, 150ms ease),\n border-color var(--hx-transition-fast, 150ms ease),\n color var(--hx-transition-fast, 150ms ease);\n position: relative;\n z-index: 1;\n }\n\n .step__indicator svg {\n width: var(--hx-steps-indicator-icon-size, 1rem);\n height: var(--hx-steps-indicator-icon-size, 1rem);\n }\n\n /* ─── Connector ─── */\n\n .step__connector {\n flex: 1;\n height: var(--hx-steps-connector-thickness, var(--hx-border-width, 2px));\n min-width: 0;\n background-color: var(--hx-steps-connector-color, var(--hx-color-neutral-200));\n transition: background-color var(--hx-transition-fast, 150ms ease);\n }\n\n :host(:last-child) .step__connector {\n display: none;\n }\n\n /* ─── Label Area ─── */\n\n .step__label-area {\n text-align: center;\n margin-top: var(--hx-space-2, 0.5rem);\n width: 100%;\n padding: 0 var(--hx-space-1, 0.25rem);\n }\n\n .step__label {\n font-family: var(--hx-font-family-sans);\n font-size: var(--hx-steps-label-font-size, var(--hx-font-size-sm));\n font-weight: var(--hx-font-weight-medium);\n color: var(--hx-steps-label-color, var(--hx-color-neutral-600));\n line-height: var(--hx-line-height-tight, 1.25);\n }\n\n .step__description {\n font-family: var(--hx-font-family-sans);\n font-size: var(--hx-steps-description-font-size, var(--hx-font-size-xs));\n color: var(--hx-steps-description-color, var(--hx-color-neutral-500));\n margin-top: var(--hx-space-1, 0.25rem);\n line-height: var(--hx-line-height-normal, 1.5);\n }\n\n /* ─── Status: active ─── */\n\n /* Active: outlined indicator (in-progress) — visually distinct from complete (filled) */\n :host([status='active']) .step__indicator {\n border-color: var(--hx-color-primary-500);\n background-color: var(--hx-color-primary-500);\n color: var(--hx-color-neutral-0);\n }\n\n :host([status='active']) .step__label {\n color: var(--hx-color-primary-700);\n font-weight: var(--hx-font-weight-semibold);\n }\n\n /* ─── Status: complete ─── */\n\n /* Complete: filled indicator with darker shade — visually distinct from active */\n :host([status='complete']) .step__indicator {\n border-color: var(--hx-color-primary-700);\n background-color: var(--hx-color-primary-700);\n color: var(--hx-color-neutral-0);\n }\n\n :host([status='complete']) .step__connector {\n background-color: var(--hx-steps-connector-complete-color, var(--hx-color-primary-500));\n }\n\n :host([status='complete']) .step__label {\n color: var(--hx-color-neutral-700);\n }\n\n /* ─── Status: error ─── */\n\n :host([status='error']) .step__indicator {\n border-color: var(--hx-color-error-500);\n background-color: var(--hx-color-error-500);\n color: var(--hx-color-neutral-0);\n }\n\n :host([status='error']) .step__label {\n color: var(--hx-color-error-700);\n }\n\n /* ─── Status: disabled ─── */\n\n :host([disabled]) .step {\n cursor: not-allowed;\n opacity: var(--hx-opacity-disabled, 0.5);\n pointer-events: none;\n }\n\n :host([disabled]) .step__indicator {\n border-color: var(--hx-color-neutral-300);\n background-color: var(--hx-color-neutral-100);\n color: var(--hx-color-neutral-400);\n }\n\n /* ─── Vertical Layout ─── */\n\n :host([orientation='vertical']) {\n flex: initial;\n width: 100%;\n }\n\n :host([orientation='vertical']) .step {\n flex-direction: row;\n align-items: flex-start;\n gap: var(--hx-space-3, 0.75rem);\n }\n\n :host([orientation='vertical']) .step__track {\n flex-direction: column;\n align-items: center;\n width: auto;\n flex-shrink: 0;\n }\n\n :host([orientation='vertical']) .step__connector {\n width: var(--hx-steps-connector-thickness, var(--hx-border-width, 2px));\n height: auto;\n min-height: var(--hx-space-8, 2rem);\n flex: 1;\n }\n\n :host([orientation='vertical']) .step__label-area {\n text-align: start;\n margin-top: 0;\n padding-bottom: var(--hx-space-4, 1rem);\n padding-inline-start: 0;\n }\n\n :host([orientation='vertical']:last-child) .step__label-area {\n padding-bottom: 0;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .step__indicator {\n transition: none;\n }\n\n .step__connector {\n transition: none;\n }\n }\n`;\n","import { LitElement, html, type PropertyValues } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { tokenStyles } from '@helixui/tokens/lit';\nimport { helixStepStyles } from './hx-step.styles.js';\n\n/**\n * An individual step, designed to be used inside an `<hx-steps>` container.\n * Represents a single step in a multi-step wizard or progress indicator.\n *\n * @summary Individual step item within an `<hx-steps>` progress indicator.\n *\n * @tag hx-step\n *\n * @slot icon - Custom icon for the step indicator. Shown when status is `pending` or `active`.\n * @slot label - Step label text. Falls back to the `label` property.\n * @slot description - Step description text. Falls back to the `description` property.\n *\n * @csspart base - The outermost wrapper element.\n * @csspart indicator - The circular step indicator.\n * @csspart connector - The line connecting this step to the next.\n * @csspart label - The step label element.\n * @csspart description - The step description element.\n *\n * @cssprop [--hx-steps-indicator-size=2rem] - Indicator circle diameter.\n * @cssprop [--hx-steps-indicator-font-size=var(--hx-font-size-sm)] - Indicator text size.\n * @cssprop [--hx-steps-indicator-icon-size=1rem] - Indicator icon size.\n * @cssprop [--hx-steps-label-font-size=var(--hx-font-size-sm)] - Label font size.\n * @cssprop [--hx-steps-description-font-size=var(--hx-font-size-xs)] - Description font size.\n * @cssprop [--hx-steps-connector-color=var(--hx-color-neutral-200)] - Connector line color.\n * @cssprop [--hx-steps-connector-complete-color=var(--hx-color-primary-500)] - Connector color when step is complete.\n * @cssprop [--hx-steps-connector-thickness=var(--hx-border-width,2px)] - Connector line thickness.\n * @cssprop [--hx-steps-label-color=var(--hx-color-neutral-600)] - Label text color.\n * @cssprop [--hx-steps-description-color=var(--hx-color-neutral-500)] - Description text color.\n */\n@customElement('hx-step')\nexport class HelixStep extends LitElement {\n static override styles = [tokenStyles, helixStepStyles];\n\n // ─── Public Properties ───\n\n /**\n * The step label text.\n * @attr label\n */\n @property({ type: String, reflect: true })\n label = '';\n\n /**\n * Current status of the step.\n * @attr status\n */\n @property({ type: String, reflect: true })\n status: 'pending' | 'active' | 'complete' | 'error' = 'pending';\n\n /**\n * Optional description text shown below the label.\n * @attr description\n */\n @property({ type: String, reflect: true })\n description = '';\n\n /**\n * Whether the step is disabled and non-interactive.\n * @attr disabled\n */\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n // ─── Internal Properties (set by parent hx-steps) ───\n\n /**\n * Layout orientation. Set by the parent `<hx-steps>` container via JS property.\n * Do not set this attribute directly on `<hx-step>` — use the `orientation`\n * property on the parent `<hx-steps>` container instead. The parent will\n * propagate the value to all child steps via `_syncChildren()`.\n * @internal\n */\n @property({ attribute: false })\n orientation: 'horizontal' | 'vertical' = 'horizontal';\n\n /**\n * Size variant. Set by the parent `<hx-steps>` container via JS property.\n * Do not set this attribute directly on `<hx-step>` — use the `size` property\n * on the parent `<hx-steps>` container instead. The parent will propagate the\n * value to all child steps via `_syncChildren()`.\n * @internal\n */\n @property({ attribute: false })\n size: 'sm' | 'md' | 'lg' = 'md';\n\n /**\n * Zero-based index of this step. Set by the parent `<hx-steps>` container.\n * @internal\n */\n @property({ type: Number })\n index = 0;\n\n // ─── Internal State ───\n\n /**\n * Text for the aria-live region, updated on status transitions.\n * Non-reactive: computed in willUpdate() to avoid an extra render cycle.\n * @internal\n */\n private _liveMessage = '';\n\n // ─── Lifecycle ───\n\n override connectedCallback(): void {\n super.connectedCallback();\n if (!this.hasAttribute('role')) {\n this.setAttribute('role', 'listitem');\n }\n this.setAttribute('tabindex', this.disabled ? '-1' : '0');\n this.addEventListener('keydown', this._handleKeydown);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener('keydown', this._handleKeydown);\n }\n\n override willUpdate(changedProperties: PropertyValues<this>): void {\n if (changedProperties.has('status')) {\n // STEPS-003: announce status transitions to screen readers via aria-live region.\n // Only announce on transitions (not initial render) by checking the previous value.\n // Using a non-reactive field here avoids scheduling an extra render cycle.\n const prev = changedProperties.get('status');\n if (prev !== undefined) {\n if (this.status === 'complete') {\n this._liveMessage = 'Complete';\n } else if (this.status === 'error') {\n this._liveMessage = 'Error';\n } else {\n this._liveMessage = '';\n }\n }\n }\n }\n\n override updated(changedProperties: PropertyValues<this>): void {\n super.updated(changedProperties);\n if (changedProperties.has('status')) {\n if (this.status === 'active') {\n this.setAttribute('aria-current', 'step');\n } else {\n this.removeAttribute('aria-current');\n }\n }\n if (changedProperties.has('disabled')) {\n if (this.disabled) {\n this.setAttribute('tabindex', '-1');\n this.setAttribute('aria-disabled', 'true');\n } else {\n this.setAttribute('tabindex', '0');\n this.removeAttribute('aria-disabled');\n }\n }\n if (changedProperties.has('orientation')) {\n this.setAttribute('orientation', this.orientation);\n }\n if (changedProperties.has('size')) {\n this.setAttribute('size', this.size);\n }\n }\n\n // ─── Event Handling ───\n\n /** @internal */\n private _handleKeydown = (event: KeyboardEvent): void => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n this._handleClick();\n }\n };\n\n /** @internal */\n private _handleClick(): void {\n if (this.disabled) {\n return;\n }\n\n /**\n * Internal event dispatched to signal step click to the parent container.\n * @internal\n */\n this.dispatchEvent(\n new CustomEvent<void>('hx-step-click-internal', {\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n // ─── Render Helpers ───\n\n /** @internal */\n private _renderCheckmark() {\n return html`\n <svg\n aria-hidden=\"true\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <path d=\"M20 6L9 17l-5-5\" />\n </svg>\n <span class=\"sr-only\">Complete</span>\n `;\n }\n\n /** @internal */\n private _renderXMark() {\n return html`\n <svg\n aria-hidden=\"true\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2.5\"\n stroke-linecap=\"round\"\n >\n <path d=\"M18 6L6 18M6 6l12 12\" />\n </svg>\n <span class=\"sr-only\">Error</span>\n `;\n }\n\n /** @internal */\n private _renderIndicatorContent() {\n if (this.status === 'complete') {\n return this._renderCheckmark();\n }\n if (this.status === 'error') {\n return this._renderXMark();\n }\n return html`<slot name=\"icon\">${this.index + 1}</slot>`;\n }\n\n // ─── Render ───\n\n override render() {\n return html`\n <div part=\"base\" class=\"step\" @click=${this._handleClick}>\n <div class=\"step__track\">\n <div part=\"indicator\" class=\"step__indicator\">${this._renderIndicatorContent()}</div>\n <div part=\"connector\" class=\"step__connector\" aria-hidden=\"true\"></div>\n </div>\n <div class=\"step__label-area\">\n <div part=\"label\" class=\"step__label\">\n <slot name=\"label\">${this.label}</slot>\n </div>\n <div part=\"description\" class=\"step__description\">\n <slot name=\"description\">${this.description}</slot>\n </div>\n </div>\n </div>\n <div aria-live=\"polite\" aria-atomic=\"true\" class=\"sr-only\">${this._liveMessage}</div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-step': HelixStep;\n }\n}\n"],"names":["helixStepsStyles","css","HelixSteps","LitElement","e","steps","step","el","index","legacySize","changedProperties","i","html","nothing","tokenStyles","__decorateClass","property","customElement","helixStepStyles","HelixStep","event"],"mappings":"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"}
@@ -1,8 +1,8 @@
1
- import { css as x, LitElement as _, html as m, nothing as O } from "lit";
2
- import { property as d, state as g, customElement as y } from "lit/decorators.js";
1
+ import { css as v, LitElement as _, html as m, nothing as N } from "lit";
2
+ import { property as h, state as g, customElement as y } from "lit/decorators.js";
3
3
  import { tokenStyles as w } from "@helixui/tokens/lit";
4
4
  import { d as E } from "./dev-warn-YlwPHjtX.js";
5
- const N = x`
5
+ const O = v`
6
6
  :host {
7
7
  display: block;
8
8
  font-family: var(--hx-font-family-sans, sans-serif);
@@ -79,14 +79,14 @@ const N = x`
79
79
  }
80
80
  }
81
81
  `;
82
- var k = Object.defineProperty, L = Object.getOwnPropertyDescriptor, p = (e, t, a, i) => {
83
- for (var s = i > 1 ? void 0 : i ? L(t, a) : t, o = e.length - 1, r; o >= 0; o--)
84
- (r = e[o]) && (s = (i ? r(t, a, s) : r(s)) || s);
85
- return i && s && k(t, a, s), s;
82
+ var I = Object.defineProperty, k = Object.getOwnPropertyDescriptor, p = (e, t, a, i) => {
83
+ for (var s = i > 1 ? void 0 : i ? k(t, a) : t, r = e.length - 1, n; r >= 0; r--)
84
+ (n = e[r]) && (s = (i ? n(t, a, s) : n(s)) || s);
85
+ return i && s && I(t, a, s), s;
86
86
  };
87
- let z = 0, b = class extends _ {
87
+ let L = 0, b = class extends _ {
88
88
  constructor() {
89
- super(...arguments), this._id = `hx-tabs-${++z}`, this.orientation = "horizontal", this.activation = "automatic", this.label = "", this._activePanel = "", this._cachedTabs = null, this._cachedPanels = null, this._observer = null, this._handleTabSelect = (e) => {
89
+ super(...arguments), this._id = `hx-tabs-${++L}`, this.orientation = "horizontal", this.activation = "automatic", this.label = "", this._activePanel = "", this._cachedTabs = null, this._cachedPanels = null, this._observer = null, this._pendingIndex = null, this._handleTabSelect = (e) => {
90
90
  if (!(e instanceof CustomEvent)) return;
91
91
  e.stopPropagation();
92
92
  const t = e.composedPath().find((a) => a instanceof Element && a.tagName.toLowerCase() === "hx-tab");
@@ -97,34 +97,51 @@ let z = 0, b = class extends _ {
97
97
  a ? this._activateTab(a, !1) : this._activePanel = "";
98
98
  }
99
99
  }, this._handleKeydown = (e) => {
100
- var P, S, T, C;
101
- const t = this._getEnabledTabs();
100
+ var T, P, S, C;
101
+ const t = this._getTabs();
102
102
  if (t.length === 0)
103
103
  return;
104
104
  const a = this.orientation === "horizontal", i = a ? "ArrowLeft" : "ArrowUp", s = a ? "ArrowRight" : "ArrowDown";
105
105
  if (![i, s, "Home", "End", " ", "Enter"].includes(e.key))
106
106
  return;
107
- const r = t.find((u) => u === document.activeElement);
107
+ const n = t.find((u) => u === document.activeElement);
108
108
  if (e.key === " " || e.key === "Enter") {
109
- r && (e.preventDefault(), this._activateTab(r), (S = (P = r.shadowRoot) == null ? void 0 : P.querySelector("button")) == null || S.focus());
109
+ n && !n.disabled && (e.preventDefault(), this._activateTab(n), (P = (T = n.shadowRoot) == null ? void 0 : T.querySelector("button")) == null || P.focus());
110
110
  return;
111
111
  }
112
112
  e.preventDefault();
113
- let n = r ? t.indexOf(r) : -1;
114
- if (n === -1) {
115
- const u = t.find((A) => A.panel === this._activePanel);
116
- n = u ? t.indexOf(u) : 0;
113
+ let o = n ? t.indexOf(n) : -1;
114
+ if (o === -1) {
115
+ const u = t.find(($) => $.panel === this._activePanel);
116
+ o = u ? t.indexOf(u) : 0;
117
117
  }
118
- let h;
119
- e.key === "Home" ? h = 0 : e.key === "End" ? h = t.length - 1 : e.key === s ? h = (n + 1) % t.length : h = n <= 0 ? t.length - 1 : n - 1;
120
- const l = t[h];
121
- l && ((C = (T = l.shadowRoot) == null ? void 0 : T.querySelector("button")) == null || C.focus(), this.activation === "automatic" && this._activateTab(l));
118
+ let d;
119
+ e.key === "Home" ? d = 0 : e.key === "End" ? d = t.length - 1 : e.key === s ? d = (o + 1) % t.length : d = o <= 0 ? t.length - 1 : o - 1;
120
+ const l = t[d];
121
+ l && ((C = (S = l.shadowRoot) == null ? void 0 : S.querySelector("button")) == null || C.focus(), this.activation === "automatic" && !l.disabled && this._activateTab(l));
122
122
  };
123
123
  }
124
+ // ─── Attribute Observation ───
125
+ static get observedAttributes() {
126
+ return [...super.observedAttributes ?? [], "selected-index"];
127
+ }
128
+ attributeChangedCallback(e, t, a) {
129
+ if (super.attributeChangedCallback(e, t, a), e === "selected-index" && a !== null && t !== a) {
130
+ const i = parseInt(a, 10);
131
+ if (!isNaN(i) && i >= 0)
132
+ if (this.hasUpdated) {
133
+ const s = this._getTabs()[i];
134
+ s && !s.disabled && this._activateTab(s, !1);
135
+ } else
136
+ this._pendingIndex = i;
137
+ }
138
+ }
124
139
  // ─── Public API ───
125
140
  /**
126
141
  * Gets or sets the zero-based index of the currently selected tab.
127
142
  * Setting this programmatically activates the tab at the given index.
143
+ * Can also be set via the `selected-index` HTML attribute for server-side
144
+ * pre-selection (e.g. Drupal Twig templates).
128
145
  */
129
146
  get selectedIndex() {
130
147
  return this._getTabs().findIndex((e) => e.panel === this._activePanel);
@@ -163,7 +180,14 @@ let z = 0, b = class extends _ {
163
180
  super.disconnectedCallback(), this.removeEventListener("hx-tab-select", this._handleTabSelect), this.removeEventListener("keydown", this._handleKeydown), (e = this._observer) == null || e.disconnect(), this._observer = null;
164
181
  }
165
182
  firstUpdated() {
166
- if (this.label, this._syncTabsAndPanels(), !this._activePanel) {
183
+ if (this.label, this._syncTabsAndPanels(), this._pendingIndex !== null) {
184
+ const e = this._getTabs()[this._pendingIndex];
185
+ if (this._pendingIndex = null, e && !e.disabled) {
186
+ this._activateTab(e, !1);
187
+ return;
188
+ }
189
+ }
190
+ if (!this._activePanel) {
167
191
  const e = this._getEnabledTabs()[0];
168
192
  e && this._activateTab(e, !1);
169
193
  }
@@ -178,14 +202,14 @@ let z = 0, b = class extends _ {
178
202
  e.forEach((a, i) => {
179
203
  const s = a.id || `hx-tab-${this._id}-${i}`;
180
204
  a.id = s;
181
- const o = a.panel, r = t.find((n) => n.name === o) ?? t[i];
182
- if (r) {
183
- const n = r.id || `hx-panel-${this._id}-${i}`;
184
- r.id = n, a.controls = n;
185
- const h = Array.from(a.childNodes).filter(
205
+ const r = a.panel, n = t.find((o) => o.name === r) ?? t[i];
206
+ if (n) {
207
+ const o = n.id || `hx-panel-${this._id}-${i}`;
208
+ n.id = o, a.controls = o;
209
+ const d = Array.from(a.childNodes).filter(
186
210
  (l) => l.nodeType === Node.TEXT_NODE || l.nodeType === Node.ELEMENT_NODE && !l.hasAttribute("slot")
187
211
  ).map((l) => l.textContent ?? "").join("").trim();
188
- h ? (r.setAttribute("aria-label", h), r.removeAttribute("aria-labelledby")) : r.setAttribute("aria-labelledby", s);
212
+ d ? (n.setAttribute("aria-label", d), n.removeAttribute("aria-labelledby")) : n.setAttribute("aria-labelledby", s);
189
213
  }
190
214
  }), this._updateTabsAndPanels();
191
215
  }
@@ -221,17 +245,17 @@ let z = 0, b = class extends _ {
221
245
  var a, i;
222
246
  const e = (a = this.shadowRoot) == null ? void 0 : a.querySelector('slot[name="tab"]'), t = (i = this.shadowRoot) == null ? void 0 : i.querySelector("slot:not([name])");
223
247
  if (e) {
224
- const s = e.assignedElements().filter((o) => o.tagName.toLowerCase() !== "hx-tab");
248
+ const s = e.assignedElements().filter((r) => r.tagName.toLowerCase() !== "hx-tab");
225
249
  s.length > 0 && E(
226
250
  "hx-tabs",
227
- `Slot "tab" expects <hx-tab> elements. Found unexpected: ${s.map((o) => `<${o.tagName.toLowerCase()}>`).join(", ")}`
251
+ `Slot "tab" expects <hx-tab> elements. Found unexpected: ${s.map((r) => `<${r.tagName.toLowerCase()}>`).join(", ")}`
228
252
  );
229
253
  }
230
254
  if (t) {
231
- const s = t.assignedElements().filter((o) => o.tagName.toLowerCase() !== "hx-tab-panel");
255
+ const s = t.assignedElements().filter((r) => r.tagName.toLowerCase() !== "hx-tab-panel");
232
256
  s.length > 0 && E(
233
257
  "hx-tabs",
234
- `Default slot expects <hx-tab-panel> elements. Found unexpected: ${s.map((o) => `<${o.tagName.toLowerCase()}>`).join(", ")}`
258
+ `Default slot expects <hx-tab-panel> elements. Found unexpected: ${s.map((r) => `<${r.tagName.toLowerCase()}>`).join(", ")}`
235
259
  );
236
260
  }
237
261
  }
@@ -255,15 +279,15 @@ let z = 0, b = class extends _ {
255
279
  `;
256
280
  }
257
281
  };
258
- b.styles = [w, N];
282
+ b.styles = [w, O];
259
283
  p([
260
- d({ type: String, reflect: !0 })
284
+ h({ type: String, reflect: !0 })
261
285
  ], b.prototype, "orientation", 2);
262
286
  p([
263
- d({ type: String, attribute: "activation", reflect: !0 })
287
+ h({ type: String, attribute: "activation", reflect: !0 })
264
288
  ], b.prototype, "activation", 2);
265
289
  p([
266
- d({ type: String, reflect: !0 })
290
+ h({ type: String, reflect: !0 })
267
291
  ], b.prototype, "label", 2);
268
292
  p([
269
293
  g()
@@ -271,7 +295,7 @@ p([
271
295
  b = p([
272
296
  y("hx-tabs")
273
297
  ], b);
274
- const D = x`
298
+ const z = v`
275
299
  :host {
276
300
  display: inline-block;
277
301
  }
@@ -345,8 +369,12 @@ const D = x`
345
369
 
346
370
  /* ─── Disabled State ─── */
347
371
 
348
- .tab[aria-disabled='true'] {
372
+ :host([disabled]) {
349
373
  cursor: not-allowed;
374
+ }
375
+
376
+ .tab[aria-disabled='true'] {
377
+ pointer-events: none;
350
378
  color: var(--hx-color-neutral-400, #adb5bd);
351
379
  }
352
380
 
@@ -367,10 +395,10 @@ const D = x`
367
395
  }
368
396
  }
369
397
  `;
370
- var I = Object.defineProperty, j = Object.getOwnPropertyDescriptor, f = (e, t, a, i) => {
371
- for (var s = i > 1 ? void 0 : i ? j(t, a) : t, o = e.length - 1, r; o >= 0; o--)
372
- (r = e[o]) && (s = (i ? r(t, a, s) : r(s)) || s);
373
- return i && s && I(t, a, s), s;
398
+ var D = Object.defineProperty, j = Object.getOwnPropertyDescriptor, f = (e, t, a, i) => {
399
+ for (var s = i > 1 ? void 0 : i ? j(t, a) : t, r = e.length - 1, n; r >= 0; r--)
400
+ (n = e[r]) && (s = (i ? n(t, a, s) : n(s)) || s);
401
+ return i && s && D(t, a, s), s;
374
402
  };
375
403
  let c = class extends _ {
376
404
  constructor() {
@@ -410,7 +438,7 @@ let c = class extends _ {
410
438
  role="tab"
411
439
  aria-selected=${this.selected ? "true" : "false"}
412
440
  aria-disabled=${this.disabled ? "true" : "false"}
413
- aria-controls=${this.controls || O}
441
+ aria-controls=${this.controls || N}
414
442
  tabindex=${this.selected ? "0" : "-1"}
415
443
  @click=${this._handleClick}
416
444
  >
@@ -425,18 +453,18 @@ let c = class extends _ {
425
453
  `;
426
454
  }
427
455
  };
428
- c.styles = [w, D];
456
+ c.styles = [w, z];
429
457
  f([
430
- d({ type: String, reflect: !0 })
458
+ h({ type: String, reflect: !0 })
431
459
  ], c.prototype, "panel", 2);
432
460
  f([
433
- d({ type: Boolean, reflect: !0 })
461
+ h({ type: Boolean, reflect: !0 })
434
462
  ], c.prototype, "selected", 2);
435
463
  f([
436
- d({ type: Boolean, reflect: !0 })
464
+ h({ type: Boolean, reflect: !0 })
437
465
  ], c.prototype, "disabled", 2);
438
466
  f([
439
- d({ type: String, attribute: !1 })
467
+ h({ type: String, attribute: !1 })
440
468
  ], c.prototype, "controls", 2);
441
469
  f([
442
470
  g()
@@ -447,7 +475,7 @@ f([
447
475
  c = f([
448
476
  y("hx-tab")
449
477
  ], c);
450
- const H = x`
478
+ const H = v`
451
479
  :host {
452
480
  display: block;
453
481
  }
@@ -479,12 +507,12 @@ const H = x`
479
507
  outline: none;
480
508
  }
481
509
  `;
482
- var K = Object.defineProperty, R = Object.getOwnPropertyDescriptor, $ = (e, t, a, i) => {
483
- for (var s = i > 1 ? void 0 : i ? R(t, a) : t, o = e.length - 1, r; o >= 0; o--)
484
- (r = e[o]) && (s = (i ? r(t, a, s) : r(s)) || s);
510
+ var K = Object.defineProperty, R = Object.getOwnPropertyDescriptor, A = (e, t, a, i) => {
511
+ for (var s = i > 1 ? void 0 : i ? R(t, a) : t, r = e.length - 1, n; r >= 0; r--)
512
+ (n = e[r]) && (s = (i ? n(t, a, s) : n(s)) || s);
485
513
  return i && s && K(t, a, s), s;
486
514
  };
487
- let v = class extends _ {
515
+ let x = class extends _ {
488
516
  constructor() {
489
517
  super(...arguments), this.name = "";
490
518
  }
@@ -501,16 +529,16 @@ let v = class extends _ {
501
529
  `;
502
530
  }
503
531
  };
504
- v.styles = [w, H];
505
- $([
506
- d({ type: String, reflect: !0 })
507
- ], v.prototype, "name", 2);
508
- v = $([
532
+ x.styles = [w, H];
533
+ A([
534
+ h({ type: String, reflect: !0 })
535
+ ], x.prototype, "name", 2);
536
+ x = A([
509
537
  y("hx-tab-panel")
510
- ], v);
538
+ ], x);
511
539
  export {
512
540
  c as H,
513
- v as a,
541
+ x as a,
514
542
  b
515
543
  };
516
- //# sourceMappingURL=hx-tab-panel-GGjk6Qg4.js.map
544
+ //# sourceMappingURL=hx-tab-panel-Dnt8aA74.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hx-tab-panel-Dnt8aA74.js","sources":["../../src/components/hx-tabs/hx-tabs.styles.ts","../../src/components/hx-tabs/hx-tabs.ts","../../src/components/hx-tabs/hx-tab.styles.ts","../../src/components/hx-tabs/hx-tab.ts","../../src/components/hx-tabs/hx-tab-panel.styles.ts","../../src/components/hx-tabs/hx-tab-panel.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixTabsStyles = css`\n :host {\n display: block;\n font-family: var(--hx-font-family-sans, sans-serif);\n }\n\n * {\n box-sizing: border-box;\n }\n\n /* ─── Container ─── */\n\n .tabs {\n display: flex;\n flex-direction: column;\n gap: var(--hx-tabs-gap, 0);\n }\n\n :host([orientation='vertical']) .tabs {\n flex-direction: row;\n }\n\n /* ─── Tablist ─── */\n\n .tablist {\n display: flex;\n flex-direction: row;\n flex-wrap: nowrap;\n gap: 0;\n border-bottom: var(--hx-tabs-border-width, 1px) solid\n var(--hx-tabs-border-color, var(--hx-color-neutral-200, #e9ecef));\n overflow-x: auto;\n scrollbar-width: none;\n }\n\n .tablist::-webkit-scrollbar {\n display: none;\n }\n\n /* ─── Vertical Orientation ─── */\n\n :host([orientation='vertical']) {\n --_tab-indicator-bottom: 0px;\n --_tab-indicator-end: var(--hx-tabs-indicator-size, 2px);\n --_tab-indicator-bottom-color: transparent;\n --_tab-indicator-end-color: var(\n --hx-tabs-indicator-color,\n var(--hx-color-primary-500, #2563eb)\n );\n }\n\n :host([orientation='vertical']) .tablist {\n flex-direction: column;\n border-bottom: none;\n border-inline-end: var(--hx-tabs-border-width, 1px) solid\n var(--hx-tabs-border-color, var(--hx-color-neutral-200, #e9ecef));\n overflow-x: visible;\n overflow-y: auto;\n min-width: var(--hx-tabs-vertical-width, 12rem);\n flex-shrink: 0;\n }\n\n /* ─── Panels Container ─── */\n\n .panels {\n flex: 1 1 auto;\n min-width: 0;\n }\n\n /* ─── Reduced Motion ─── */\n\n @media (prefers-reduced-motion: reduce) {\n .tablist {\n scroll-behavior: auto;\n }\n }\n`;\n","import { LitElement, html, type PropertyValues } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { tokenStyles } from '@helixui/tokens/lit';\nimport { helixTabsStyles } from './hx-tabs.styles.js';\nimport type { HelixTab } from './hx-tab.js';\nimport type { HelixTabPanel } from './hx-tab-panel.js';\nimport { devWarn } from '../../utils/dev-warn.js';\n\n// Module-level counter for stable, SSR-safe IDs (avoids Math.random() hydration mismatch)\nlet _hxTabsIdCounter = 0;\n\n/**\n * A tabbed content organizer that manages a set of `<hx-tab>` and `<hx-tab-panel>` children.\n * Supports horizontal and vertical orientations, automatic and manual activation modes,\n * and full keyboard navigation per the ARIA Authoring Practices Guide.\n *\n * @summary Tab container that organizes content into selectable panels.\n *\n * @tag hx-tabs\n *\n * @slot tab - Slot for `<hx-tab>` elements. Rendered inside the tablist.\n * @slot - Default slot for `<hx-tab-panel>` elements.\n *\n * @fires {CustomEvent<{tabId: string, index: number}>} hx-tab-change - Dispatched when the active tab changes.\n *\n * @csspart tablist - The tablist container element.\n * @csspart panels - The panel content container element.\n *\n * @cssprop [--hx-tabs-border-color=var(--hx-color-neutral-200, #e9ecef)] - Tablist border color.\n * @cssprop [--hx-tabs-border-width=1px] - Tablist border width.\n * @cssprop [--hx-tabs-vertical-width=12rem] - Width of the tablist in vertical orientation.\n * @cssprop [--hx-tabs-gap=0] - Gap between the tablist and panels container.\n * @cssprop [--hx-tabs-tab-color=var(--hx-color-neutral-600, #495057)] - Inactive tab text color.\n * @cssprop [--hx-tabs-tab-active-color=var(--hx-color-primary-600, #1d4ed8)] - Active tab text color.\n * @cssprop [--hx-tabs-tab-hover-color=var(--hx-color-neutral-800, #212529)] - Tab hover text color.\n * @cssprop [--hx-tabs-tab-hover-bg=var(--hx-color-neutral-50, #f8f9fa)] - Tab hover background.\n * @cssprop [--hx-tabs-tab-font-size=var(--hx-font-size-md, 1rem)] - Tab font size.\n * @cssprop [--hx-tabs-tab-font-weight=var(--hx-font-weight-medium, 500)] - Tab font weight.\n * @cssprop [--hx-tabs-tab-active-font-weight=var(--hx-font-weight-semibold, 600)] - Active tab font weight.\n * @cssprop [--hx-tabs-tab-padding-x=var(--hx-space-4, 1rem)] - Horizontal tab padding.\n * @cssprop [--hx-tabs-tab-padding-y=var(--hx-space-2, 0.5rem)] - Vertical tab padding.\n * @cssprop [--hx-tabs-indicator-color=var(--hx-color-primary-500, #2563eb)] - Active indicator color.\n * @cssprop [--hx-tabs-indicator-size=2px] - Active indicator thickness.\n * @cssprop [--hx-tabs-focus-ring-color=var(--hx-focus-ring-color, #2563eb)] - Focus ring color for tabs and panels.\n * @cssprop [--hx-tabs-panel-padding=var(--hx-space-4, 1rem)] - Panel inner padding.\n * @cssprop [--hx-tabs-panel-color=var(--hx-color-neutral-700, #343a40)] - Panel text color.\n */\n@customElement('hx-tabs')\nexport class HelixTabs extends LitElement {\n static override styles = [tokenStyles, helixTabsStyles];\n\n // ─── Internal ID ───\n\n /** @internal */\n private _id = `hx-tabs-${++_hxTabsIdCounter}`;\n\n // ─── Properties ───\n\n /**\n * The layout orientation of the tabs.\n * @attr orientation\n */\n @property({ type: String, reflect: true })\n orientation: 'horizontal' | 'vertical' = 'horizontal';\n\n /**\n * Controls how keyboard navigation activates tabs.\n * In `automatic` mode, focus also activates the tab.\n * In `manual` mode, focus moves independently; Space or Enter activates.\n * @attr activation\n */\n @property({ type: String, attribute: 'activation', reflect: true })\n activation: 'manual' | 'automatic' = 'automatic';\n\n /**\n * Accessible label for the tablist. Rendered as `aria-label` on the tablist container.\n * Provide a brief description of what the tabs represent (e.g., \"Patient record sections\").\n * @attr label\n */\n @property({ type: String, reflect: true })\n label = '';\n\n // ─── State ───\n\n /** @internal */\n @state() private _activePanel = '';\n\n // ─── Child Accessors ───\n\n /** @internal */\n private _cachedTabs: HelixTab[] | null = null;\n /** @internal */\n private _cachedPanels: HelixTabPanel[] | null = null;\n /** @internal */\n private _observer: MutationObserver | null = null;\n /**\n * Stores a requested tab index from the `selected-index` attribute before the component\n * has finished its first update (e.g. server-rendered Drupal pages).\n * @internal\n */\n private _pendingIndex: number | null = null;\n\n // ─── Attribute Observation ───\n\n static override get observedAttributes(): string[] {\n return [...(super.observedAttributes ?? []), 'selected-index'];\n }\n\n override attributeChangedCallback(name: string, old: string | null, value: string | null): void {\n super.attributeChangedCallback(name, old, value);\n if (name === 'selected-index' && value !== null && old !== value) {\n const index = parseInt(value, 10);\n if (!isNaN(index) && index >= 0) {\n if (this.hasUpdated) {\n // Already initialised — apply immediately\n const tab = this._getTabs()[index];\n if (tab && !tab.disabled) {\n this._activateTab(tab, false);\n }\n } else {\n // Store for application in firstUpdated\n this._pendingIndex = index;\n }\n }\n }\n }\n\n // ─── Public API ───\n\n /**\n * Gets or sets the zero-based index of the currently selected tab.\n * Setting this programmatically activates the tab at the given index.\n * Can also be set via the `selected-index` HTML attribute for server-side\n * pre-selection (e.g. Drupal Twig templates).\n */\n get selectedIndex(): number {\n return this._getTabs().findIndex((tab) => tab.panel === this._activePanel);\n }\n\n set selectedIndex(index: number) {\n const tab = this._getTabs()[index];\n if (tab && !tab.disabled) {\n this._activateTab(tab, true);\n }\n }\n\n /** @internal */\n private _getTabs(): HelixTab[] {\n if (!this._cachedTabs) {\n this._cachedTabs = Array.from(this.querySelectorAll(':scope > hx-tab')).filter(\n (el): el is HelixTab => el.tagName.toLowerCase() === 'hx-tab',\n );\n }\n return this._cachedTabs;\n }\n\n /** @internal */\n private _getPanels(): HelixTabPanel[] {\n if (!this._cachedPanels) {\n this._cachedPanels = Array.from(this.querySelectorAll(':scope > hx-tab-panel')).filter(\n (el): el is HelixTabPanel => el.tagName.toLowerCase() === 'hx-tab-panel',\n );\n }\n return this._cachedPanels;\n }\n\n /** @internal */\n private _getEnabledTabs(): HelixTab[] {\n return this._getTabs().filter((tab) => !tab.disabled);\n }\n\n // ─── Lifecycle ───\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.addEventListener('hx-tab-select', this._handleTabSelect);\n this.addEventListener('keydown', this._handleKeydown);\n // Watch for panel/name attribute changes on child tabs and panels\n if (typeof MutationObserver !== 'undefined') {\n this._observer = new MutationObserver(() => {\n this._cachedTabs = null;\n this._cachedPanels = null;\n this._syncTabsAndPanels();\n });\n this._observer.observe(this, {\n subtree: false,\n attributeFilter: ['panel', 'name'],\n });\n }\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener('hx-tab-select', this._handleTabSelect);\n this.removeEventListener('keydown', this._handleKeydown);\n this._observer?.disconnect();\n this._observer = null;\n }\n\n override firstUpdated(): void {\n if (this.label === '') {\n devWarn(\n 'hx-tabs',\n 'No accessible label provided. Set the `label` attribute on hx-tabs to describe what the tabs represent (e.g., \"Patient record sections\"). An unlabeled tablist violates WCAG 4.1.2.',\n );\n }\n\n this._syncTabsAndPanels();\n\n // Apply a pending selected-index (set via HTML attribute before upgrade, e.g. Drupal Twig)\n if (this._pendingIndex !== null) {\n const pendingTab = this._getTabs()[this._pendingIndex];\n this._pendingIndex = null;\n if (pendingTab && !pendingTab.disabled) {\n this._activateTab(pendingTab, false);\n return;\n }\n }\n\n // Activate the first enabled tab if none is selected\n if (!this._activePanel) {\n const firstEnabled = this._getEnabledTabs()[0];\n if (firstEnabled) {\n this._activateTab(firstEnabled, false);\n }\n }\n }\n\n override updated(changedProperties: PropertyValues<this>): void {\n super.updated(changedProperties);\n if ((changedProperties as Map<PropertyKey, unknown>).has('_activePanel')) {\n this._updateTabsAndPanels();\n }\n }\n\n // ─── Tab / Panel Sync ───\n\n /** @internal */\n private _syncTabsAndPanels(): void {\n const tabs = this._getTabs();\n const panels = this._getPanels();\n\n tabs.forEach((tab, i) => {\n const tabId = tab.id || `hx-tab-${this._id}-${i}`;\n tab.id = tabId;\n\n // Connect tab to its panel by aria-controls\n const panelName = tab.panel;\n const panel = panels.find((p) => p.name === panelName) ?? panels[i];\n if (panel) {\n const panelId = panel.id || `hx-panel-${this._id}-${i}`;\n panel.id = panelId;\n // Set controls on the tab so aria-controls lands on the inner button (role=\"tab\")\n tab.controls = panelId;\n // Use aria-label instead of aria-labelledby to avoid shadow boundary failures.\n // aria-labelledby pointing to hx-tab host IDs fails because the host element's\n // accessible text is inside its shadow DOM (the inner <button>), which AT cannot\n // traverse via aria-labelledby references across shadow roots.\n // Extract only default-slot children (no `slot` attribute) to exclude prefix/suffix\n // slot content (e.g. badge counts) from the panel accessible name (WCAG 1.3.1).\n const tabLabel = Array.from(tab.childNodes)\n .filter(\n (node) =>\n node.nodeType === Node.TEXT_NODE ||\n (node.nodeType === Node.ELEMENT_NODE && !(node as Element).hasAttribute('slot')),\n )\n .map((node) => node.textContent ?? '')\n .join('')\n .trim();\n if (tabLabel) {\n panel.setAttribute('aria-label', tabLabel);\n panel.removeAttribute('aria-labelledby');\n } else {\n // Fall back to aria-labelledby if no text content is yet available;\n // this will be corrected on slotchange once content is assigned.\n panel.setAttribute('aria-labelledby', tabId);\n }\n }\n });\n\n this._updateTabsAndPanels();\n }\n\n /** @internal */\n private _updateTabsAndPanels(): void {\n const tabs = this._getTabs();\n const panels = this._getPanels();\n\n tabs.forEach((tab) => {\n const isSelected = tab.panel === this._activePanel;\n tab.selected = isSelected;\n // Dual tabindex is intentional: the inner button in hx-tab manages its own tabindex\n // via the `selected` property. We also set it on the host element for the roving\n // tabindex pattern so document.activeElement comparisons work correctly when the\n // inner button is focused. This is safe because the inner button is the only\n // focusable element in hx-tab's shadow DOM (WCAG 2.4.3).\n tab.tabIndex = isSelected ? 0 : -1;\n });\n\n panels.forEach((panel) => {\n const isActive = panel.name === this._activePanel;\n if (isActive) {\n panel.removeAttribute('hidden');\n panel.setAttribute('tabindex', '0');\n } else {\n panel.setAttribute('hidden', '');\n panel.setAttribute('tabindex', '-1');\n }\n });\n }\n\n // ─── Tab Activation ───\n\n /** @internal */\n private _activateTab(tab: HelixTab, dispatchEvent = true): void {\n if (tab.disabled) {\n return;\n }\n\n const tabs = this._getTabs();\n const previousPanel = this._activePanel;\n this._activePanel = tab.panel;\n\n if (dispatchEvent && previousPanel !== this._activePanel) {\n const index = tabs.indexOf(tab);\n /**\n * Dispatched when the active tab changes.\n * @event hx-tab-change\n */\n this.dispatchEvent(\n new CustomEvent<{ tabId: string; index: number }>('hx-tab-change', {\n bubbles: true,\n composed: true,\n detail: { tabId: tab.id, index },\n }),\n );\n }\n }\n\n // ─── Event Handling ───\n\n /** @internal */\n private _handleTabSelect = (e: Event): void => {\n if (!(e instanceof CustomEvent)) return;\n e.stopPropagation();\n const tab = e\n .composedPath()\n .find((el): el is HelixTab => el instanceof Element && el.tagName.toLowerCase() === 'hx-tab');\n if (tab) {\n this._activateTab(tab);\n }\n };\n\n /** @internal */\n private _warnInvalidSlotContent(): void {\n const tabSlot = this.shadowRoot?.querySelector<HTMLSlotElement>('slot[name=\"tab\"]');\n const panelSlot = this.shadowRoot?.querySelector<HTMLSlotElement>('slot:not([name])');\n if (tabSlot) {\n const invalid = tabSlot\n .assignedElements()\n .filter((el) => el.tagName.toLowerCase() !== 'hx-tab');\n if (invalid.length > 0) {\n devWarn(\n 'hx-tabs',\n `Slot \"tab\" expects <hx-tab> elements. Found unexpected: ${invalid.map((el) => `<${el.tagName.toLowerCase()}>`).join(', ')}`,\n );\n }\n }\n if (panelSlot) {\n const invalid = panelSlot\n .assignedElements()\n .filter((el) => el.tagName.toLowerCase() !== 'hx-tab-panel');\n if (invalid.length > 0) {\n devWarn(\n 'hx-tabs',\n `Default slot expects <hx-tab-panel> elements. Found unexpected: ${invalid.map((el) => `<${el.tagName.toLowerCase()}>`).join(', ')}`,\n );\n }\n }\n }\n\n /** @internal */\n private _handleSlotChange = (): void => {\n this._warnInvalidSlotContent();\n this._cachedTabs = null;\n this._cachedPanels = null;\n this._syncTabsAndPanels();\n // If the active panel was removed, fall back to the first enabled tab\n const panels = this._getPanels();\n const activePanelExists = panels.some((p) => p.name === this._activePanel);\n if (!activePanelExists) {\n const firstEnabled = this._getEnabledTabs()[0];\n if (firstEnabled) {\n this._activateTab(firstEnabled, false);\n } else {\n this._activePanel = '';\n }\n }\n };\n\n /** @internal */\n private _handleKeydown = (e: KeyboardEvent): void => {\n // Use ALL tabs (including disabled) so keyboard users can discover disabled tabs\n // per ARIA APG tab pattern — disabled tabs receive focus but are not activated.\n const allTabs = this._getTabs();\n if (allTabs.length === 0) {\n return;\n }\n\n const isHorizontal = this.orientation === 'horizontal';\n const prevKey = isHorizontal ? 'ArrowLeft' : 'ArrowUp';\n const nextKey = isHorizontal ? 'ArrowRight' : 'ArrowDown';\n\n const isNavigationKey = [prevKey, nextKey, 'Home', 'End', ' ', 'Enter'].includes(e.key);\n if (!isNavigationKey) {\n return;\n }\n\n // Determine focused tab — when a button inside shadow DOM is focused,\n // document.activeElement returns the shadow host (hx-tab), not the inner button.\n const focusedTab = allTabs.find((tab) => tab === document.activeElement);\n\n if (e.key === ' ' || e.key === 'Enter') {\n // Only activate if the focused tab is not disabled\n if (focusedTab && !focusedTab.disabled) {\n e.preventDefault();\n this._activateTab(focusedTab);\n focusedTab.shadowRoot?.querySelector('button')?.focus();\n }\n return;\n }\n\n e.preventDefault();\n\n let currentIndex = focusedTab ? allTabs.indexOf(focusedTab) : -1;\n // Fall back to the active tab's index if nothing is focused yet\n if (currentIndex === -1) {\n const activeTab = allTabs.find((tab) => tab.panel === this._activePanel);\n currentIndex = activeTab ? allTabs.indexOf(activeTab) : 0;\n }\n\n let nextIndex: number;\n\n if (e.key === 'Home') {\n nextIndex = 0;\n } else if (e.key === 'End') {\n nextIndex = allTabs.length - 1;\n } else if (e.key === nextKey) {\n nextIndex = (currentIndex + 1) % allTabs.length;\n } else {\n // prevKey\n nextIndex = currentIndex <= 0 ? allTabs.length - 1 : currentIndex - 1;\n }\n\n const targetTab = allTabs[nextIndex];\n if (!targetTab) {\n return;\n }\n\n // Focus the tab button inside the shadow root\n targetTab.shadowRoot?.querySelector('button')?.focus();\n\n // Only activate in automatic mode if the target tab is not disabled\n if (this.activation === 'automatic' && !targetTab.disabled) {\n this._activateTab(targetTab);\n }\n };\n\n // ─── Render ───\n\n override render() {\n return html`\n <div class=\"tabs\">\n <div\n part=\"tablist\"\n class=\"tablist\"\n role=\"tablist\"\n aria-orientation=${this.orientation}\n aria-label=${this.label || 'Tabs'}\n >\n <slot name=\"tab\" @slotchange=${this._handleSlotChange}></slot>\n </div>\n <div part=\"panels\" class=\"panels\">\n <slot @slotchange=${this._handleSlotChange}></slot>\n </div>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-tabs': HelixTabs;\n }\n}\n","import { css } from 'lit';\n\nexport const helixTabStyles = css`\n :host {\n display: inline-block;\n }\n\n :host([disabled]) {\n opacity: var(--hx-opacity-disabled, 0.5);\n }\n\n * {\n box-sizing: border-box;\n }\n\n .tab {\n display: inline-flex;\n align-items: center;\n gap: var(--hx-space-2, 0.5rem);\n padding: var(--hx-tabs-tab-padding-y, var(--hx-space-2, 0.5rem))\n var(--hx-tabs-tab-padding-x, var(--hx-space-4, 1rem));\n border: none;\n border-bottom: var(--_tab-indicator-bottom, var(--hx-tabs-indicator-size, 2px)) solid\n transparent;\n border-inline-end: var(--_tab-indicator-end, 0px) solid transparent;\n background: none;\n font-family: var(--hx-tabs-tab-font-family, var(--hx-font-family-sans, sans-serif));\n font-size: var(--hx-tabs-tab-font-size, var(--hx-font-size-md, 1rem));\n font-weight: var(--hx-tabs-tab-font-weight, var(--hx-font-weight-medium, 500));\n color: var(--hx-tabs-tab-color, var(--hx-color-neutral-600, #495057));\n line-height: var(--hx-line-height-tight, 1.25);\n cursor: pointer;\n white-space: nowrap;\n user-select: none;\n -webkit-user-select: none;\n transition:\n color var(--hx-transition-fast, 150ms ease),\n border-color var(--hx-transition-fast, 150ms ease),\n border-inline-end-color var(--hx-transition-fast, 150ms ease),\n background-color var(--hx-transition-fast, 150ms ease);\n position: relative;\n }\n\n /* ─── Hover State ─── */\n\n .tab:not([aria-selected='true']):not([aria-disabled='true']):hover {\n color: var(--hx-tabs-tab-hover-color, var(--hx-color-neutral-800, #212529));\n background-color: var(--hx-tabs-tab-hover-bg, var(--hx-color-neutral-50, #f8f9fa));\n }\n\n /* ─── Selected State ─── */\n\n .tab[aria-selected='true'] {\n color: var(--hx-tabs-tab-active-color, var(--hx-color-primary-600, #1d4ed8));\n border-bottom-color: var(\n --_tab-indicator-bottom-color,\n var(--hx-tabs-indicator-color, var(--hx-color-primary-500, #2563eb))\n );\n border-inline-end-color: var(--_tab-indicator-end-color, transparent);\n font-weight: var(--hx-tabs-tab-active-font-weight, var(--hx-font-weight-semibold, 600));\n }\n\n /* ─── Focus State ─── */\n\n .tab:focus-visible {\n outline: var(--hx-focus-ring-width, 2px) solid\n var(\n --hx-tabs-focus-ring-color,\n var(--hx-focus-ring-color, var(--hx-color-primary-400, #60a5fa))\n );\n outline-offset: var(--hx-focus-ring-offset, 2px);\n border-radius: var(--hx-border-radius-sm, 0.125rem);\n }\n\n /* ─── Disabled State ─── */\n\n :host([disabled]) {\n cursor: not-allowed;\n }\n\n .tab[aria-disabled='true'] {\n pointer-events: none;\n color: var(--hx-color-neutral-400, #adb5bd);\n }\n\n /* ─── Prefix / Suffix Slots ─── */\n\n .tab__prefix,\n .tab__suffix {\n display: inline-flex;\n align-items: center;\n flex-shrink: 0;\n }\n\n /* ─── Reduced Motion ─── */\n\n @media (prefers-reduced-motion: reduce) {\n .tab {\n transition: none;\n }\n }\n`;\n","import { LitElement, html, nothing } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { tokenStyles } from '@helixui/tokens/lit';\nimport { helixTabStyles } from './hx-tab.styles.js';\nimport { devWarn } from '../../utils/dev-warn.js';\n\n/**\n * An individual tab button, designed to be used inside an `<hx-tabs>` container.\n * Must be placed in the `tab` named slot of `<hx-tabs>`.\n *\n * @summary Presentational tab button that activates a corresponding panel.\n *\n * @tag hx-tab\n *\n * @slot - Default slot for the tab label text or content.\n * @slot prefix - Icon or content rendered before the label.\n * @slot suffix - Icon or content rendered after the label.\n *\n * @csspart tab - The underlying button element.\n * @csspart prefix - The container for prefix slot content (e.g. icons).\n * @csspart suffix - The container for suffix slot content (e.g. badges).\n *\n * @cssprop [--hx-tabs-tab-color=var(--hx-color-neutral-600, #495057)] - Inactive tab text color.\n * @cssprop [--hx-tabs-tab-active-color=var(--hx-color-primary-600, #1d4ed8)] - Active tab text color.\n * @cssprop [--hx-tabs-tab-hover-color=var(--hx-color-neutral-800, #212529)] - Tab hover text color.\n * @cssprop [--hx-tabs-tab-hover-bg=var(--hx-color-neutral-50, #f8f9fa)] - Tab hover background.\n * @cssprop [--hx-tabs-tab-font-size=var(--hx-font-size-md, 1rem)] - Tab font size.\n * @cssprop [--hx-tabs-tab-font-weight=var(--hx-font-weight-medium, 500)] - Tab font weight.\n * @cssprop [--hx-tabs-tab-active-font-weight=var(--hx-font-weight-semibold, 600)] - Active tab font weight.\n * @cssprop [--hx-tabs-tab-padding-x=var(--hx-space-4, 1rem)] - Horizontal tab padding.\n * @cssprop [--hx-tabs-tab-padding-y=var(--hx-space-2, 0.5rem)] - Vertical tab padding.\n * @cssprop [--hx-tabs-indicator-color=var(--hx-color-primary-500, #2563eb)] - Active indicator color.\n * @cssprop [--hx-tabs-indicator-size=2px] - Active indicator thickness.\n * @cssprop [--hx-tabs-focus-ring-color=var(--hx-focus-ring-color, #2563eb)] - Focus ring color.\n */\n@customElement('hx-tab')\nexport class HelixTab extends LitElement {\n static override styles = [tokenStyles, helixTabStyles];\n\n // ─── Properties ───\n\n /**\n * The name of the `<hx-tab-panel>` this tab controls. Must match the `name`\n * attribute on the corresponding `<hx-tab-panel>`.\n * @attr panel\n */\n @property({ type: String, reflect: true })\n panel = '';\n\n /**\n * Whether this tab is currently selected. Managed by the parent `<hx-tabs>`.\n * @attr selected\n */\n @property({ type: Boolean, reflect: true })\n selected = false;\n\n /**\n * Whether this tab is disabled. Prevents selection and keyboard navigation.\n * @attr disabled\n */\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /**\n * The id of the panel this tab controls. Set by the parent `<hx-tabs>` to establish the\n * aria-controls relationship on the inner button element (which carries role=\"tab\").\n * @internal\n */\n @property({ type: String, attribute: false })\n controls = '';\n\n // ─── Lifecycle ───\n\n override connectedCallback(): void {\n super.connectedCallback();\n if (!this.closest('hx-tabs')) {\n devWarn('hx-tab', 'hx-tab must be a direct child of hx-tabs to function correctly.');\n }\n }\n\n // ─── Slot Visibility ───\n\n /** @internal */\n @state() private _hasPrefixSlot = false;\n /** @internal */\n @state() private _hasSuffixSlot = false;\n\n // ─── Event Handling ───\n\n /** @internal */\n private _handleClick(): void {\n if (this.disabled) {\n return;\n }\n /**\n * Internal event dispatched to signal tab selection to the parent container.\n * Not part of the public API.\n * @internal\n */\n this.dispatchEvent(\n new CustomEvent<{ panel: string }>('hx-tab-select', {\n bubbles: true,\n composed: true,\n detail: { panel: this.panel },\n }),\n );\n }\n\n /** @internal */\n private _handlePrefixSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n this._hasPrefixSlot = slot.assignedNodes({ flatten: true }).length > 0;\n }\n\n /** @internal */\n private _handleSuffixSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n this._hasSuffixSlot = slot.assignedNodes({ flatten: true }).length > 0;\n }\n\n // ─── Render ───\n\n override render() {\n return html`\n <button\n part=\"tab\"\n class=\"tab\"\n role=\"tab\"\n aria-selected=${this.selected ? 'true' : 'false'}\n aria-disabled=${this.disabled ? 'true' : 'false'}\n aria-controls=${this.controls || nothing}\n tabindex=${this.selected ? '0' : '-1'}\n @click=${this._handleClick}\n >\n <span part=\"prefix\" class=\"tab__prefix\" ?hidden=${!this._hasPrefixSlot}>\n <slot name=\"prefix\" @slotchange=${this._handlePrefixSlotChange}></slot>\n </span>\n <slot></slot>\n <span part=\"suffix\" class=\"tab__suffix\" ?hidden=${!this._hasSuffixSlot}>\n <slot name=\"suffix\" @slotchange=${this._handleSuffixSlotChange}></slot>\n </span>\n </button>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-tab': HelixTab;\n }\n}\n","import { css } from 'lit';\n\nexport const helixTabPanelStyles = css`\n :host {\n display: block;\n }\n\n :host([hidden]) {\n display: none;\n }\n\n * {\n box-sizing: border-box;\n }\n\n :host(:focus-visible) {\n outline: var(--hx-focus-ring-width, 2px) solid\n var(\n --hx-tabs-focus-ring-color,\n var(--hx-focus-ring-color, var(--hx-color-primary-400, #60a5fa))\n );\n outline-offset: var(--hx-focus-ring-offset, 2px);\n border-radius: var(--hx-border-radius-sm, 0.125rem);\n }\n\n .panel {\n padding: var(--hx-tabs-panel-padding, var(--hx-space-4, 1rem));\n font-family: var(--hx-font-family-sans, sans-serif);\n font-size: var(--hx-font-size-md, 1rem);\n color: var(--hx-tabs-panel-color, var(--hx-color-neutral-700, #343a40));\n line-height: var(--hx-line-height-normal, 1.5);\n outline: none;\n }\n`;\n","import { LitElement, html } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { tokenStyles } from '@helixui/tokens/lit';\nimport { helixTabPanelStyles } from './hx-tab-panel.styles.js';\n\n/**\n * A content panel associated with an `<hx-tab>`, managed by a parent `<hx-tabs>`.\n *\n * @summary Tab content panel shown when its corresponding tab is selected.\n *\n * @tag hx-tab-panel\n *\n * @slot - Default slot for panel content.\n *\n * @csspart panel - The panel content wrapper.\n *\n * @cssprop [--hx-tabs-panel-padding=var(--hx-space-4, 1rem)] - Panel inner padding.\n * @cssprop [--hx-tabs-panel-color=var(--hx-color-neutral-700, #343a40)] - Panel text color.\n * @cssprop [--hx-tabs-focus-ring-color=var(--hx-focus-ring-color, #2563eb)] - Focus ring color.\n */\n@customElement('hx-tab-panel')\nexport class HelixTabPanel extends LitElement {\n static override styles = [tokenStyles, helixTabPanelStyles];\n\n // ─── Properties ───\n\n /**\n * The name that corresponds to the `panel` attribute on the associated `<hx-tab>`.\n * @attr name\n */\n @property({ type: String, reflect: true })\n name = '';\n\n // ─── Lifecycle ───\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.setAttribute('role', 'tabpanel');\n // tabindex is managed dynamically by the parent hx-tabs component:\n // active panels get tabindex=\"0\", hidden panels get tabindex=\"-1\"\n }\n\n // ─── Render ───\n\n override render() {\n return html`\n <div part=\"panel\" class=\"panel\">\n <slot></slot>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-tab-panel': HelixTabPanel;\n }\n}\n"],"names":["helixTabsStyles","css","_hxTabsIdCounter","HelixTabs","LitElement","tab","el","p","firstEnabled","allTabs","isHorizontal","prevKey","nextKey","focusedTab","_b","_a","currentIndex","activeTab","nextIndex","targetTab","_d","_c","name","old","value","index","pendingTab","changedProperties","tabs","panels","tabId","panelName","panel","panelId","tabLabel","node","isSelected","dispatchEvent","previousPanel","tabSlot","panelSlot","invalid","devWarn","html","tokenStyles","__decorateClass","property","state","customElement","helixTabStyles","HelixTab","slot","nothing","helixTabPanelStyles","HelixTabPanel"],"mappings":"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"}