@helixui/library 2.1.2-next.44 → 2.1.2-next.46

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.
@@ -180,43 +180,64 @@
180
180
  .badge--primary {
181
181
  --hx-badge-bg: var(--hx-color-primary-500, #2563eb);
182
182
  --hx-badge-color: var(--hx-color-neutral-0, #ffffff);
183
- --hx-badge-pulse-color: var(--hx-color-primary-500, #2563eb);
183
+ --hx-badge-pulse-color-internal: var(
184
+ --hx-badge-pulse-color,
185
+ var(--hx-color-primary-500, #2563eb)
186
+ );
184
187
  }
185
188
 
186
189
  .badge--secondary {
187
190
  --hx-badge-bg: var(--hx-badge-secondary-bg, var(--hx-color-neutral-100, #f3f4f6));
188
191
  --hx-badge-color: var(--hx-badge-secondary-color, var(--hx-color-neutral-700, #374151));
189
- --hx-badge-pulse-color: var(--hx-badge-secondary-bg, var(--hx-color-neutral-100, #f3f4f6));
192
+ --hx-badge-pulse-color-internal: var(
193
+ --hx-badge-pulse-color,
194
+ var(--hx-badge-secondary-bg, var(--hx-color-neutral-100, #f3f4f6))
195
+ );
190
196
  }
191
197
 
192
198
  .badge--success {
193
199
  --hx-badge-bg: var(--hx-color-success-700, #15803d);
194
200
  --hx-badge-color: var(--hx-color-neutral-0, #ffffff);
195
- --hx-badge-pulse-color: var(--hx-color-success-700, #15803d);
201
+ --hx-badge-pulse-color-internal: var(
202
+ --hx-badge-pulse-color,
203
+ var(--hx-color-success-700, #15803d)
204
+ );
196
205
  }
197
206
 
198
207
  .badge--warning {
199
208
  --hx-badge-bg: var(--hx-color-warning-500, #eab308);
200
209
  --hx-badge-color: var(--hx-color-neutral-900, #1a1a1a);
201
- --hx-badge-pulse-color: var(--hx-color-warning-500, #eab308);
210
+ --hx-badge-pulse-color-internal: var(
211
+ --hx-badge-pulse-color,
212
+ var(--hx-color-warning-500, #eab308)
213
+ );
202
214
  }
203
215
 
204
216
  .badge--error {
205
217
  --hx-badge-bg: var(--hx-color-error-500, #dc2626);
206
218
  --hx-badge-color: var(--hx-color-neutral-0, #ffffff);
207
- --hx-badge-pulse-color: var(--hx-color-error-500, #dc2626);
219
+ --hx-badge-pulse-color-internal: var(
220
+ --hx-badge-pulse-color,
221
+ var(--hx-color-error-500, #dc2626)
222
+ );
208
223
  }
209
224
 
210
225
  .badge--neutral {
211
226
  --hx-badge-bg: var(--hx-color-neutral-200, #e5e7eb);
212
227
  --hx-badge-color: var(--hx-color-neutral-700, #374151);
213
- --hx-badge-pulse-color: var(--hx-color-neutral-200, #e5e7eb);
228
+ --hx-badge-pulse-color-internal: var(
229
+ --hx-badge-pulse-color,
230
+ var(--hx-color-neutral-200, #e5e7eb)
231
+ );
214
232
  }
215
233
 
216
234
  .badge--info {
217
235
  --hx-badge-bg: var(--hx-badge-info-bg, var(--hx-color-info-700, #0369a1));
218
236
  --hx-badge-color: var(--hx-badge-info-color, var(--hx-color-neutral-0, #ffffff));
219
- --hx-badge-pulse-color: var(--hx-badge-info-bg, var(--hx-color-info-700, #0369a1));
237
+ --hx-badge-pulse-color-internal: var(
238
+ --hx-badge-pulse-color,
239
+ var(--hx-badge-info-bg, var(--hx-color-info-700, #0369a1))
240
+ );
220
241
  }
221
242
 
222
243
  /* ─── Semantic Variant Label (WCAG 1.4.1) ─── */
@@ -250,13 +271,11 @@
250
271
  border-radius: var(--hx-border-radius-full, 9999px);
251
272
  }
252
273
 
253
- /* Guard: hide prefix slot and slotted content in dot mode to prevent overflow */
254
- .badge--dot ::slotted(*) {
255
- display: none;
256
- }
257
-
274
+ /* Guard: hide all inner content in dot mode the dot is purely visual */
275
+ .badge--dot ::slotted(*),
276
+ .badge--dot slot,
258
277
  .badge--dot slot[name='prefix'] {
259
- display: none;
278
+ display: none !important;
260
279
  }
261
280
 
262
281
  /* ─── Pulse Animation ─── */
@@ -265,7 +284,7 @@
265
284
  0%,
266
285
  100% {
267
286
  opacity: 1;
268
- box-shadow: 0 0 0 2px var(--hx-badge-pulse-color, currentColor);
287
+ box-shadow: 0 0 0 2px var(--hx-badge-pulse-color-internal, currentColor);
269
288
  }
270
289
  50% {
271
290
  opacity: var(--hx-opacity-75, 0.75);
@@ -44,43 +44,64 @@
44
44
  .badge--primary {
45
45
  --hx-badge-bg: var(--hx-color-primary-500, #2563eb);
46
46
  --hx-badge-color: var(--hx-color-neutral-0, #ffffff);
47
- --hx-badge-pulse-color: var(--hx-color-primary-500, #2563eb);
47
+ --hx-badge-pulse-color-internal: var(
48
+ --hx-badge-pulse-color,
49
+ var(--hx-color-primary-500, #2563eb)
50
+ );
48
51
  }
49
52
 
50
53
  .badge--secondary {
51
54
  --hx-badge-bg: var(--hx-badge-secondary-bg, var(--hx-color-neutral-100, #f3f4f6));
52
55
  --hx-badge-color: var(--hx-badge-secondary-color, var(--hx-color-neutral-700, #374151));
53
- --hx-badge-pulse-color: var(--hx-badge-secondary-bg, var(--hx-color-neutral-100, #f3f4f6));
56
+ --hx-badge-pulse-color-internal: var(
57
+ --hx-badge-pulse-color,
58
+ var(--hx-badge-secondary-bg, var(--hx-color-neutral-100, #f3f4f6))
59
+ );
54
60
  }
55
61
 
56
62
  .badge--success {
57
63
  --hx-badge-bg: var(--hx-color-success-700, #15803d);
58
64
  --hx-badge-color: var(--hx-color-neutral-0, #ffffff);
59
- --hx-badge-pulse-color: var(--hx-color-success-700, #15803d);
65
+ --hx-badge-pulse-color-internal: var(
66
+ --hx-badge-pulse-color,
67
+ var(--hx-color-success-700, #15803d)
68
+ );
60
69
  }
61
70
 
62
71
  .badge--warning {
63
72
  --hx-badge-bg: var(--hx-color-warning-500, #eab308);
64
73
  --hx-badge-color: var(--hx-color-neutral-900, #1a1a1a);
65
- --hx-badge-pulse-color: var(--hx-color-warning-500, #eab308);
74
+ --hx-badge-pulse-color-internal: var(
75
+ --hx-badge-pulse-color,
76
+ var(--hx-color-warning-500, #eab308)
77
+ );
66
78
  }
67
79
 
68
80
  .badge--error {
69
81
  --hx-badge-bg: var(--hx-color-error-500, #dc2626);
70
82
  --hx-badge-color: var(--hx-color-neutral-0, #ffffff);
71
- --hx-badge-pulse-color: var(--hx-color-error-500, #dc2626);
83
+ --hx-badge-pulse-color-internal: var(
84
+ --hx-badge-pulse-color,
85
+ var(--hx-color-error-500, #dc2626)
86
+ );
72
87
  }
73
88
 
74
89
  .badge--neutral {
75
90
  --hx-badge-bg: var(--hx-color-neutral-200, #e5e7eb);
76
91
  --hx-badge-color: var(--hx-color-neutral-700, #374151);
77
- --hx-badge-pulse-color: var(--hx-color-neutral-200, #e5e7eb);
92
+ --hx-badge-pulse-color-internal: var(
93
+ --hx-badge-pulse-color,
94
+ var(--hx-color-neutral-200, #e5e7eb)
95
+ );
78
96
  }
79
97
 
80
98
  .badge--info {
81
99
  --hx-badge-bg: var(--hx-badge-info-bg, var(--hx-color-info-700, #0369a1));
82
100
  --hx-badge-color: var(--hx-badge-info-color, var(--hx-color-neutral-0, #ffffff));
83
- --hx-badge-pulse-color: var(--hx-badge-info-bg, var(--hx-color-info-700, #0369a1));
101
+ --hx-badge-pulse-color-internal: var(
102
+ --hx-badge-pulse-color,
103
+ var(--hx-badge-info-bg, var(--hx-color-info-700, #0369a1))
104
+ );
84
105
  }
85
106
 
86
107
  /* ─── Semantic Variant Label (WCAG 1.4.1) ─── */
@@ -114,13 +135,11 @@
114
135
  border-radius: var(--hx-border-radius-full, 9999px);
115
136
  }
116
137
 
117
- /* Guard: hide prefix slot and slotted content in dot mode to prevent overflow */
118
- .badge--dot ::slotted(*) {
119
- display: none;
120
- }
121
-
138
+ /* Guard: hide all inner content in dot mode the dot is purely visual */
139
+ .badge--dot ::slotted(*),
140
+ .badge--dot slot,
122
141
  .badge--dot slot[name='prefix'] {
123
- display: none;
142
+ display: none !important;
124
143
  }
125
144
 
126
145
  /* ─── Pulse Animation ─── */
@@ -129,7 +148,7 @@
129
148
  0%,
130
149
  100% {
131
150
  opacity: 1;
132
- box-shadow: 0 0 0 2px var(--hx-badge-pulse-color, currentColor);
151
+ box-shadow: 0 0 0 2px var(--hx-badge-pulse-color-internal, currentColor);
133
152
  }
134
153
  50% {
135
154
  opacity: var(--hx-opacity-75, 0.75);
@@ -1,4 +1,4 @@
1
- /* index.css — generated 2026-04-12T07:28:50.152Z */
1
+ /* index.css — generated 2026-04-12T13:03:12.000Z */
2
2
  /* Imports all per-component CSS files for Drupal asset pipeline */
3
3
 
4
4
  @import './hx-accordion.css';
@@ -1,5 +1,5 @@
1
1
  {
2
- "generated": "2026-04-12T07:28:50.151Z",
2
+ "generated": "2026-04-12T13:03:11.999Z",
3
3
  "components": [
4
4
  {
5
5
  "name": "hx-accordion",
@@ -130,7 +130,7 @@
130
130
  "--hx-badge-info-color",
131
131
  "--hx-badge-padding-x",
132
132
  "--hx-badge-padding-y",
133
- "--hx-badge-pulse-color",
133
+ "--hx-badge-pulse-color-internal",
134
134
  "--hx-badge-pulse-duration",
135
135
  "--hx-badge-pulse-easing",
136
136
  "--hx-badge-secondary-bg",
package/dist/index.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import { e as d } from "./shared/document-token-adoption-DuYNKd4k.js";
2
2
  import { H as u, a as T } from "./shared/hx-accordion-CpfO0YQo.js";
3
- import { H as S } from "./shared/hx-action-bar-BpY1Z1UV.js";
3
+ import { H as S } from "./shared/hx-action-bar-CNLYufVd.js";
4
4
  import { H as g } from "./shared/hx-alert-CHOjTBds.js";
5
5
  import { H as v } from "./shared/hx-avatar-an-WsuLl.js";
6
- import { H as y } from "./shared/hx-badge-DDXTLoWi.js";
6
+ import { H as y } from "./shared/hx-badge-RPzd-t5l.js";
7
7
  import { H as E } from "./shared/hx-banner-B-WEDiq7.js";
8
8
  import { H as P, a as k } from "./shared/hx-breadcrumb-item-DzLyeL5Z.js";
9
9
  import { H as A } from "./shared/hx-button-DoN8jjQT.js";
@@ -35,7 +35,7 @@ import { H as ke } from "./shared/hx-help-text-Bmb80bP4.js";
35
35
  import { H as Ae } from "./shared/hx-icon-BKHs3OLu.js";
36
36
  import { H as Le } from "./shared/hx-icon-button-CJuy9xbw.js";
37
37
  import { H as Ne } from "./shared/hx-image-ztiXumZB.js";
38
- import { H as Ge } from "./shared/hx-link-IVsXmsKx.js";
38
+ import { H as Ge } from "./shared/hx-link-B8IwUMSc.js";
39
39
  import { H as $e, a as Ve } from "./shared/hx-list-CoTDMp19.js";
40
40
  import { H as We, a as Xe, b as Ye } from "./shared/hx-menu-divider-DRT8yHRZ.js";
41
41
  import { H as qe } from "./shared/hx-meter-BvSJoqDp.js";
@@ -1,8 +1,8 @@
1
- import { css as d, LitElement as b, html as p } from "lit";
1
+ import { css as d, LitElement as b, html as f } from "lit";
2
2
  import "./document-token-adoption-DuYNKd4k.js";
3
- import { property as c, state as f, customElement as u } from "lit/decorators.js";
4
- import { d as x } from "./dev-warn-YlwPHjtX.js";
5
- const v = d`
3
+ import { property as c, state as p, customElement as u } from "lit/decorators.js";
4
+ import { d as v } from "./dev-warn-YlwPHjtX.js";
5
+ const x = d`
6
6
  :host {
7
7
  display: block;
8
8
  }
@@ -121,13 +121,13 @@ const v = d`
121
121
  }
122
122
  `;
123
123
  var g = Object.defineProperty, m = Object.getOwnPropertyDescriptor, l = (t, e, i, s) => {
124
- for (var a = s > 1 ? void 0 : s ? m(e, i) : e, o = t.length - 1, r; o >= 0; o--)
125
- (r = t[o]) && (a = (s ? r(e, i, a) : r(a)) || a);
124
+ for (var a = s > 1 ? void 0 : s ? m(e, i) : e, o = t.length - 1, n; o >= 0; o--)
125
+ (n = t[o]) && (a = (s ? n(e, i, a) : n(a)) || a);
126
126
  return s && a && g(e, i, a), a;
127
127
  };
128
- let n = class extends b {
128
+ let r = class extends b {
129
129
  constructor() {
130
- super(...arguments), this.size = "md", this.variant = "default", this.position = "top", this._sticky = !1, this.ariaLabel = "Actions", this._focusableCache = null, this._hasOverflow = !1, this._handleKeydown = (t) => {
130
+ super(...arguments), this.size = "md", this.variant = "default", this.position = "top", this._sticky = !1, this.accessibleLabel = "", this._ariaLabelAttr = "", this._focusableCache = null, this._hasOverflow = !1, this._handleKeydown = (t) => {
131
131
  var e, i;
132
132
  if (t.key === "ArrowRight")
133
133
  t.preventDefault(), this._moveFocus("next");
@@ -140,7 +140,7 @@ let n = class extends b {
140
140
  } else if (t.key === "End") {
141
141
  t.preventDefault();
142
142
  const s = this._getFocusableItems(), a = s.length - 1;
143
- s.length && (s.forEach((o, r) => o.setAttribute("tabindex", r === a ? "0" : "-1")), (i = s[a]) == null || i.focus());
143
+ s.length && (s.forEach((o, n) => o.setAttribute("tabindex", n === a ? "0" : "-1")), (i = s[a]) == null || i.focus());
144
144
  }
145
145
  };
146
146
  }
@@ -151,10 +151,18 @@ let n = class extends b {
151
151
  const e = this._sticky;
152
152
  this._sticky = t, this.requestUpdate("sticky", e);
153
153
  }
154
+ /**
155
+ * Returns the effective label for the toolbar, checking accessible-label first,
156
+ * then the aria-label attribute, falling back to 'Actions'.
157
+ * @internal
158
+ */
159
+ get _effectiveLabel() {
160
+ return this.accessibleLabel || this._ariaLabelAttr || "Actions";
161
+ }
154
162
  connectedCallback() {
155
163
  super.connectedCallback();
156
164
  const t = this.getAttribute("size");
157
- t !== null && !this.hasAttribute("hx-size") && (this.size = t), this.hasAttribute("role") ? this.getAttribute("role") !== "none" && x(
165
+ t !== null && !this.hasAttribute("hx-size") && (this.size = t), this.hasAttribute("role") ? this.getAttribute("role") !== "none" && v(
158
166
  "hx-action-bar",
159
167
  `Setting role="${this.getAttribute("role")}" on the host creates a duplicate toolbar announcement. The shadow DOM already contains role="toolbar". Set role="none" on the host to suppress it.`
160
168
  ) : this.setAttribute("role", "none"), this.addEventListener("keydown", this._handleKeydown);
@@ -185,8 +193,8 @@ let n = class extends b {
185
193
  if (this._isFocusable(o))
186
194
  e.push(o);
187
195
  else {
188
- const r = o.querySelectorAll("*");
189
- for (const h of Array.from(r))
196
+ const n = o.querySelectorAll("*");
197
+ for (const h of Array.from(n))
190
198
  this._isFocusable(h) && e.push(h);
191
199
  }
192
200
  }
@@ -208,8 +216,8 @@ let n = class extends b {
208
216
  if (!e.length) return;
209
217
  const i = document.activeElement, s = e.indexOf(i);
210
218
  let a;
211
- t === "next" ? a = s < e.length - 1 ? s + 1 : 0 : a = s > 0 ? s - 1 : e.length - 1, e.forEach((r, h) => {
212
- r.setAttribute("tabindex", h === a ? "0" : "-1");
219
+ t === "next" ? a = s < e.length - 1 ? s + 1 : 0 : a = s > 0 ? s - 1 : e.length - 1, e.forEach((n, h) => {
220
+ n.setAttribute("tabindex", h === a ? "0" : "-1");
213
221
  }), (o = e[a]) == null || o.focus();
214
222
  }
215
223
  // ─── Event Handlers ───
@@ -221,11 +229,11 @@ let n = class extends b {
221
229
  // ─── Render ───
222
230
  render() {
223
231
  const t = this.position === "sticky" || this.sticky, e = this.position === "bottom", i = t ? " base--sticky" : e ? " base--bottom" : "";
224
- return p`
232
+ return f`
225
233
  <div
226
234
  part="base"
227
235
  role="toolbar"
228
- aria-label=${this.ariaLabel}
236
+ aria-label=${this._effectiveLabel}
229
237
  aria-orientation="horizontal"
230
238
  class="base base--${this.size} base--${this.variant}${i}"
231
239
  >
@@ -245,29 +253,32 @@ let n = class extends b {
245
253
  `;
246
254
  }
247
255
  };
248
- n.styles = [v];
256
+ r.styles = [x];
249
257
  l([
250
258
  c({ type: String, reflect: !0, attribute: "hx-size" })
251
- ], n.prototype, "size", 2);
259
+ ], r.prototype, "size", 2);
252
260
  l([
253
261
  c({ type: String, reflect: !0 })
254
- ], n.prototype, "variant", 2);
262
+ ], r.prototype, "variant", 2);
255
263
  l([
256
264
  c({ type: String, reflect: !0 })
257
- ], n.prototype, "position", 2);
265
+ ], r.prototype, "position", 2);
258
266
  l([
259
267
  c({ type: Boolean, reflect: !0 })
260
- ], n.prototype, "sticky", 1);
268
+ ], r.prototype, "sticky", 1);
269
+ l([
270
+ c({ attribute: "accessible-label" })
271
+ ], r.prototype, "accessibleLabel", 2);
261
272
  l([
262
273
  c({ attribute: "aria-label" })
263
- ], n.prototype, "ariaLabel", 2);
274
+ ], r.prototype, "_ariaLabelAttr", 2);
264
275
  l([
265
- f()
266
- ], n.prototype, "_hasOverflow", 2);
267
- n = l([
276
+ p()
277
+ ], r.prototype, "_hasOverflow", 2);
278
+ r = l([
268
279
  u("hx-action-bar")
269
- ], n);
280
+ ], r);
270
281
  export {
271
- n as H
282
+ r as H
272
283
  };
273
- //# sourceMappingURL=hx-action-bar-BpY1Z1UV.js.map
284
+ //# sourceMappingURL=hx-action-bar-CNLYufVd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hx-action-bar-CNLYufVd.js","sources":["../../src/components/hx-action-bar/hx-action-bar.styles.ts","../../src/components/hx-action-bar/hx-action-bar.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixActionBarStyles = css`\n :host {\n display: block;\n }\n\n /* ─── Base ─── */\n\n .base {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: var(--hx-action-bar-gap, var(--hx-space-2, 0.5rem));\n padding: var(--hx-action-bar-padding, var(--hx-space-2, 0.5rem) var(--hx-space-3, 0.75rem));\n background: var(--hx-action-bar-bg, transparent);\n border: var(--hx-action-bar-border, none);\n box-sizing: border-box;\n width: 100%;\n }\n\n /* ─── Sticky (top) ─── */\n\n .base--sticky {\n position: sticky;\n top: 0;\n padding-top: max(var(--hx-action-bar-padding-block-start, 0px), env(safe-area-inset-top, 0px));\n z-index: var(--hx-action-bar-z-index, 10);\n /*\n * Consumers: when this bar is sticky, add scroll-padding-top to the scroll container\n * equal to the bar's rendered height so anchor targets are not hidden behind the bar.\n * Example: .scroll-container { scroll-padding-top: 2.5rem; }\n */\n }\n\n /* ─── Bottom sticky ─── */\n\n .base--bottom {\n position: sticky;\n bottom: 0;\n /*\n * Respect iOS home-indicator safe area on devices with notch/home bar.\n * Falls back to 0px on devices that do not support env().\n */\n padding-bottom: max(\n var(--hx-action-bar-padding-block-end, 0px),\n env(safe-area-inset-bottom, 0px)\n );\n z-index: var(--hx-action-bar-z-index, 10);\n }\n\n /* ─── Variant: outlined ─── */\n\n .base--outlined {\n background: var(--hx-action-bar-bg, var(--hx-color-neutral-0, #fff));\n border: var(\n --hx-action-bar-border,\n var(--hx-border-width-thin, 1px) solid var(--hx-color-neutral-200, #e5e7eb)\n );\n border-radius: var(--hx-border-radius-md, 0.375rem);\n }\n\n /* ─── Variant: filled ─── */\n\n .base--filled {\n background: var(--hx-action-bar-bg, var(--hx-color-neutral-50, #f9fafb));\n border-radius: var(--hx-border-radius-md, 0.375rem);\n }\n\n /* ─── Size modifiers ─── */\n\n .base--sm {\n padding: var(--hx-action-bar-padding, var(--hx-space-1, 0.25rem) var(--hx-space-2, 0.5rem));\n gap: var(--hx-action-bar-gap, var(--hx-space-1, 0.25rem));\n min-height: var(--hx-size-8, 2rem);\n }\n\n .base--md {\n min-height: var(--hx-size-10, 2.5rem);\n }\n\n .base--lg {\n padding: var(--hx-action-bar-padding, var(--hx-space-3, 0.75rem) var(--hx-space-4, 1rem));\n gap: var(--hx-action-bar-gap, var(--hx-space-3, 0.75rem));\n min-height: var(--hx-size-12, 3rem);\n }\n\n /* ─── Sections ─── */\n\n .section {\n display: flex;\n align-items: center;\n gap: inherit;\n }\n\n /*\n * Equal flex-basis on start and end guarantees the center section is visually centered\n * within the full bar width, regardless of how wide start and end content are.\n */\n .section--start {\n flex: 1 1 0;\n justify-content: flex-start;\n }\n\n .section--center {\n flex: 0 0 auto;\n justify-content: center;\n }\n\n .section--end {\n flex: 1 1 0;\n justify-content: flex-end;\n }\n\n /* ─── Slotted content ─── */\n\n ::slotted(*) {\n flex-shrink: 0;\n }\n`;\n","import { LitElement, html } from 'lit';\nimport '../../utilities/document-token-adoption.js';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { helixActionBarStyles } from './hx-action-bar.styles.js';\nimport { devWarn } from '../../utils/dev-warn.js';\n\n// Re-export size type for external consumers.\nexport type ActionBarSize = 'sm' | 'md' | 'lg';\n\n/**\n * A horizontal toolbar container for grouping related action buttons and controls.\n * Implements the ARIA toolbar pattern with roving tabindex keyboard navigation.\n *\n * @summary Horizontal action bar for grouping related controls.\n *\n * @tag hx-action-bar\n *\n * @slot start - Left-aligned actions.\n * @slot - Center content (default slot).\n * @slot end - Right-aligned actions.\n * @slot overflow - Actions revealed when the bar is constrained for space.\n *\n * @csspart base - The root toolbar container element.\n * @csspart start - The start (left) slot wrapper.\n * @csspart center - The center (default) slot wrapper.\n * @csspart end - The end (right) slot wrapper.\n * @csspart overflow - The overflow slot wrapper (hidden when no overflow content).\n *\n * @cssprop [--hx-action-bar-bg=transparent] - Bar background color (default variant).\n * @cssprop [--hx-action-bar-border=none] - Bar border (default variant).\n * @cssprop [--hx-action-bar-padding=var(--hx-space-2,0.5rem) var(--hx-space-3,0.75rem)] - Inner padding.\n * @cssprop [--hx-action-bar-gap=var(--hx-space-2,0.5rem)] - Gap between slotted items.\n * @cssprop [--hx-action-bar-z-index=10] - Z-index when sticky or bottom position.\n *\n * @attr {string} accessible-label - Identifies the toolbar to assistive technology.\n * When multiple toolbars appear on the same page, each must have a unique, descriptive label.\n * Falls back to the native `aria-label` attribute if not set.\n *\n * @example\n * ```html\n * <hx-action-bar aria-label=\"Patient actions\">\n * <hx-button slot=\"start\">Save</hx-button>\n * <hx-button slot=\"end\" variant=\"ghost\">Cancel</hx-button>\n * </hx-action-bar>\n * ```\n */\n@customElement('hx-action-bar')\nexport class HelixActionBar extends LitElement {\n static override styles = [helixActionBarStyles];\n\n /**\n * Size of the action bar — propagated as a data attribute to slotted children.\n * @attr hx-size\n */\n @property({ type: String, reflect: true, attribute: 'hx-size' })\n size: 'sm' | 'md' | 'lg' = 'md';\n\n /**\n * Visual variant controlling the bar background.\n * @attr variant\n */\n @property({ type: String, reflect: true })\n variant: 'default' | 'outlined' | 'filled' = 'default';\n\n /**\n * Position and sticky behavior of the action bar.\n * - `top` — normal flow (default)\n * - `sticky` — sticks to the top of the scroll container; add `scroll-padding-top` to the\n * scroll container equal to the bar height to prevent anchor targets from scrolling behind it\n * - `bottom` — sticks to the bottom of the scroll container with iOS safe-area-inset support\n * @attr position\n */\n @property({ type: String, reflect: true })\n position: 'top' | 'bottom' | 'sticky' = 'top';\n\n /**\n * @deprecated Use `position=\"sticky\"` instead.\n * When true, the bar sticks to the top of its scroll container.\n * @attr sticky\n */\n @property({ type: Boolean, reflect: true })\n get sticky(): boolean {\n return this._sticky;\n }\n set sticky(value: boolean) {\n if (value) {\n devWarn(\n 'hx-action-bar',\n 'The `sticky` property is deprecated. Use `position=\"sticky\"` instead.',\n );\n }\n const old = this._sticky;\n this._sticky = value;\n this.requestUpdate('sticky', old);\n }\n /** @internal */\n private _sticky = false;\n\n /**\n * Accessible label for the toolbar.\n * Required when multiple toolbars appear on the same page.\n *\n * Accepts both `accessible-label` and the standard `aria-label` HTML attribute.\n * The `accessible-label` attribute takes precedence when both are set.\n *\n * Previously this was exposed as the `ariaLabel` JS property, which shadowed\n * the native `HTMLElement.ariaLabel`. That shadowing is removed; use\n * `accessibleLabel` or the HTML attributes instead.\n *\n * @attr accessible-label\n */\n @property({ attribute: 'accessible-label' })\n accessibleLabel: string = '';\n\n /**\n * Observed mirror of the host's `aria-label` attribute so Lit re-renders\n * when consumers set `aria-label` (the standard HTML pattern).\n * @internal\n */\n @property({ attribute: 'aria-label' })\n private _ariaLabelAttr: string = '';\n\n /**\n * Returns the effective label for the toolbar, checking accessible-label first,\n * then the aria-label attribute, falling back to 'Actions'.\n * @internal\n */\n private get _effectiveLabel(): string {\n return this.accessibleLabel || this._ariaLabelAttr || 'Actions';\n }\n\n /** Cached list of focusable items — invalidated on slot change. */\n /** @internal */\n private _focusableCache: HTMLElement[] | null = null;\n\n /** Whether the overflow slot has assigned content. * @internal\n */\n @state()\n private _hasOverflow = false;\n\n // ─── Lifecycle ───\n\n /** Arrow function field — stable reference for add/removeEventListener. */\n /** @internal */\n private _handleKeydown = (e: KeyboardEvent): void => {\n if (e.key === 'ArrowRight') {\n e.preventDefault();\n this._moveFocus('next');\n } else if (e.key === 'ArrowLeft') {\n e.preventDefault();\n this._moveFocus('prev');\n } else if (e.key === 'Home') {\n e.preventDefault();\n // Move directly to first item — do NOT call _moveFocus which would visit other items first.\n const items = this._getFocusableItems();\n if (items.length) {\n items.forEach((el, i) => el.setAttribute('tabindex', i === 0 ? '0' : '-1'));\n items[0]?.focus();\n }\n } else if (e.key === 'End') {\n e.preventDefault();\n const items = this._getFocusableItems();\n const last = items.length - 1;\n if (items.length) {\n items.forEach((el, i) => el.setAttribute('tabindex', i === last ? '0' : '-1'));\n items[last]?.focus();\n }\n }\n };\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-action-bar', 'The \"size\" attribute is deprecated. Use \"hx-size\" instead.');\n this.size = legacySize as ActionBarSize;\n }\n // Prevent dual aria-label announcement: the host carries the consumer's\n // aria-label attribute while the inner div[role=\"toolbar\"] receives the\n // same value. Setting role=\"none\" on the host hides it from the\n // accessibility tree so only the toolbar is announced.\n if (!this.hasAttribute('role')) {\n this.setAttribute('role', 'none');\n } else if (this.getAttribute('role') !== 'none') {\n devWarn(\n 'hx-action-bar',\n `Setting role=\"${this.getAttribute('role')}\" on the host creates a duplicate toolbar announcement. ` +\n 'The shadow DOM already contains role=\"toolbar\". Set role=\"none\" on the host to suppress it.',\n );\n }\n this.addEventListener('keydown', this._handleKeydown);\n }\n\n override firstUpdated(): void {\n // Slot assignments are complete by firstUpdated; initialize roving tabindex\n // immediately rather than waiting for the async slotchange event.\n this._initRovingTabindex();\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener('keydown', this._handleKeydown);\n }\n\n // ─── Focusable item discovery ───\n\n /** @internal */\n private _isFocusable(el: HTMLElement): boolean {\n // Check disabled via DOM attribute (native elements) or property (custom elements)\n if (el.hasAttribute('disabled')) return false;\n const elWithDisabled = el as HTMLElement & { disabled?: boolean };\n if (elWithDisabled.disabled === true) return false;\n\n // Use the IDL tabIndex property — covers both DOM attribute and ElementInternals settings.\n // Custom elements (e.g. hx-button) that set tabIndex via ElementInternals are discoverable.\n if (el.tabIndex >= 0) return true;\n\n const tag = el.tagName.toLowerCase();\n return tag === 'button' || tag === 'input' || tag === 'select' || tag === 'textarea';\n }\n\n /** @internal */\n private _getFocusableItems(): HTMLElement[] {\n if (this._focusableCache) return this._focusableCache;\n\n const slots = this.shadowRoot?.querySelectorAll('slot') ?? [];\n const items: HTMLElement[] = [];\n\n for (const slot of Array.from(slots)) {\n const assigned = (slot as HTMLSlotElement).assignedElements({ flatten: true });\n for (const el of assigned) {\n if (!(el instanceof HTMLElement)) continue;\n if (this._isFocusable(el)) {\n // Element is itself focusable — include it and do NOT also recurse into its children\n // to prevent double-counting compound components (e.g. <a><button>).\n items.push(el);\n } else {\n // Element is a non-focusable wrapper (e.g. <div>, <span>) — find focusable children.\n const descendants = el.querySelectorAll<HTMLElement>('*');\n for (const d of Array.from(descendants)) {\n if (this._isFocusable(d)) {\n items.push(d);\n }\n }\n }\n }\n }\n\n this._focusableCache = items;\n return items;\n }\n\n // ─── Roving tabindex helpers ───\n\n /** @internal */\n private _initRovingTabindex(): void {\n this._focusableCache = null; // invalidate cache on slot change\n const items = this._getFocusableItems();\n if (!items.length) return;\n // Find the currently active item. If none exists (e.g. first render or active item was\n // removed), fall back to index 0. Then set ALL items explicitly so newly added items and\n // items whose tabindex changed externally are always in a correct state.\n const activeIndex = items.findIndex((el) => el.getAttribute('tabindex') === '0');\n const targetIndex = activeIndex === -1 ? 0 : activeIndex;\n items.forEach((el, i) => el.setAttribute('tabindex', i === targetIndex ? '0' : '-1'));\n }\n\n /** @internal */\n private _moveFocus(direction: 'next' | 'prev'): void {\n const items = this._getFocusableItems();\n if (!items.length) return;\n\n const focused = document.activeElement as HTMLElement | null;\n const currentIndex = items.indexOf(focused as HTMLElement);\n\n let nextIndex: number;\n if (direction === 'next') {\n nextIndex = currentIndex < items.length - 1 ? currentIndex + 1 : 0;\n } else {\n nextIndex = currentIndex > 0 ? currentIndex - 1 : items.length - 1;\n }\n\n items.forEach((el, i) => {\n el.setAttribute('tabindex', i === nextIndex ? '0' : '-1');\n });\n\n items[nextIndex]?.focus();\n }\n\n // ─── Event Handlers ───\n\n /** @internal */\n private _handleSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n if (slot.name === 'overflow') {\n this._hasOverflow = slot.assignedElements({ flatten: true }).length > 0;\n }\n this._initRovingTabindex();\n }\n\n // ─── Render ───\n\n override render() {\n const isSticky = this.position === 'sticky' || this.sticky;\n const isBottom = this.position === 'bottom';\n const positionClass = isSticky ? ' base--sticky' : isBottom ? ' base--bottom' : '';\n\n return html`\n <div\n part=\"base\"\n role=\"toolbar\"\n aria-label=${this._effectiveLabel}\n aria-orientation=\"horizontal\"\n class=\"base base--${this.size} base--${this.variant}${positionClass}\"\n >\n <div part=\"start\" class=\"section section--start\">\n <slot name=\"start\" @slotchange=${this._handleSlotChange}></slot>\n </div>\n <div part=\"center\" class=\"section section--center\">\n <slot @slotchange=${this._handleSlotChange}></slot>\n </div>\n <div part=\"end\" class=\"section section--end\">\n <slot name=\"end\" @slotchange=${this._handleSlotChange}></slot>\n </div>\n <div part=\"overflow\" class=\"section section--overflow\" ?hidden=${!this._hasOverflow}>\n <slot name=\"overflow\" @slotchange=${this._handleSlotChange}></slot>\n </div>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-action-bar': HelixActionBar;\n }\n}\n"],"names":["helixActionBarStyles","css","HelixActionBar","LitElement","e","items","el","i","_a","last","_b","value","old","legacySize","devWarn","tag","slots","slot","assigned","descendants","d","activeIndex","targetIndex","direction","focused","currentIndex","nextIndex","isSticky","isBottom","positionClass","html","__decorateClass","property","state","customElement"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { css as c, LitElement as g, nothing as l, html as d } from "lit";
1
+ import { css as c, LitElement as g, nothing as s, html as d } from "lit";
2
2
  import "./document-token-adoption-DuYNKd4k.js";
3
3
  import { property as i, state as p, customElement as x } from "lit/decorators.js";
4
4
  import { classMap as u } from "lit/directives/class-map.js";
@@ -48,43 +48,64 @@ const v = c`
48
48
  .badge--primary {
49
49
  --hx-badge-bg: var(--hx-color-primary-500, #2563eb);
50
50
  --hx-badge-color: var(--hx-color-neutral-0, #ffffff);
51
- --hx-badge-pulse-color: var(--hx-color-primary-500, #2563eb);
51
+ --hx-badge-pulse-color-internal: var(
52
+ --hx-badge-pulse-color,
53
+ var(--hx-color-primary-500, #2563eb)
54
+ );
52
55
  }
53
56
 
54
57
  .badge--secondary {
55
58
  --hx-badge-bg: var(--hx-badge-secondary-bg, var(--hx-color-neutral-100, #f3f4f6));
56
59
  --hx-badge-color: var(--hx-badge-secondary-color, var(--hx-color-neutral-700, #374151));
57
- --hx-badge-pulse-color: var(--hx-badge-secondary-bg, var(--hx-color-neutral-100, #f3f4f6));
60
+ --hx-badge-pulse-color-internal: var(
61
+ --hx-badge-pulse-color,
62
+ var(--hx-badge-secondary-bg, var(--hx-color-neutral-100, #f3f4f6))
63
+ );
58
64
  }
59
65
 
60
66
  .badge--success {
61
67
  --hx-badge-bg: var(--hx-color-success-700, #15803d);
62
68
  --hx-badge-color: var(--hx-color-neutral-0, #ffffff);
63
- --hx-badge-pulse-color: var(--hx-color-success-700, #15803d);
69
+ --hx-badge-pulse-color-internal: var(
70
+ --hx-badge-pulse-color,
71
+ var(--hx-color-success-700, #15803d)
72
+ );
64
73
  }
65
74
 
66
75
  .badge--warning {
67
76
  --hx-badge-bg: var(--hx-color-warning-500, #eab308);
68
77
  --hx-badge-color: var(--hx-color-neutral-900, #1a1a1a);
69
- --hx-badge-pulse-color: var(--hx-color-warning-500, #eab308);
78
+ --hx-badge-pulse-color-internal: var(
79
+ --hx-badge-pulse-color,
80
+ var(--hx-color-warning-500, #eab308)
81
+ );
70
82
  }
71
83
 
72
84
  .badge--error {
73
85
  --hx-badge-bg: var(--hx-color-error-500, #dc2626);
74
86
  --hx-badge-color: var(--hx-color-neutral-0, #ffffff);
75
- --hx-badge-pulse-color: var(--hx-color-error-500, #dc2626);
87
+ --hx-badge-pulse-color-internal: var(
88
+ --hx-badge-pulse-color,
89
+ var(--hx-color-error-500, #dc2626)
90
+ );
76
91
  }
77
92
 
78
93
  .badge--neutral {
79
94
  --hx-badge-bg: var(--hx-color-neutral-200, #e5e7eb);
80
95
  --hx-badge-color: var(--hx-color-neutral-700, #374151);
81
- --hx-badge-pulse-color: var(--hx-color-neutral-200, #e5e7eb);
96
+ --hx-badge-pulse-color-internal: var(
97
+ --hx-badge-pulse-color,
98
+ var(--hx-color-neutral-200, #e5e7eb)
99
+ );
82
100
  }
83
101
 
84
102
  .badge--info {
85
103
  --hx-badge-bg: var(--hx-badge-info-bg, var(--hx-color-info-700, #0369a1));
86
104
  --hx-badge-color: var(--hx-badge-info-color, var(--hx-color-neutral-0, #ffffff));
87
- --hx-badge-pulse-color: var(--hx-badge-info-bg, var(--hx-color-info-700, #0369a1));
105
+ --hx-badge-pulse-color-internal: var(
106
+ --hx-badge-pulse-color,
107
+ var(--hx-badge-info-bg, var(--hx-color-info-700, #0369a1))
108
+ );
88
109
  }
89
110
 
90
111
  /* ─── Semantic Variant Label (WCAG 1.4.1) ─── */
@@ -118,13 +139,11 @@ const v = c`
118
139
  border-radius: var(--hx-border-radius-full, 9999px);
119
140
  }
120
141
 
121
- /* Guard: hide prefix slot and slotted content in dot mode to prevent overflow */
122
- .badge--dot ::slotted(*) {
123
- display: none;
124
- }
125
-
142
+ /* Guard: hide all inner content in dot mode the dot is purely visual */
143
+ .badge--dot ::slotted(*),
144
+ .badge--dot slot,
126
145
  .badge--dot slot[name='prefix'] {
127
- display: none;
146
+ display: none !important;
128
147
  }
129
148
 
130
149
  /* ─── Pulse Animation ─── */
@@ -133,7 +152,7 @@ const v = c`
133
152
  0%,
134
153
  100% {
135
154
  opacity: 1;
136
- box-shadow: 0 0 0 2px var(--hx-badge-pulse-color, currentColor);
155
+ box-shadow: 0 0 0 2px var(--hx-badge-pulse-color-internal, currentColor);
137
156
  }
138
157
  50% {
139
158
  opacity: var(--hx-opacity-75, 0.75);
@@ -182,9 +201,9 @@ const v = c`
182
201
  }
183
202
  `;
184
203
  var f = Object.defineProperty, m = Object.getOwnPropertyDescriptor, o = (a, r, n, t) => {
185
- for (var s = t > 1 ? void 0 : t ? m(r, n) : r, h = a.length - 1, b; h >= 0; h--)
186
- (b = a[h]) && (s = (t ? b(r, n, s) : b(s)) || s);
187
- return t && s && f(r, n, s), s;
204
+ for (var l = t > 1 ? void 0 : t ? m(r, n) : r, h = a.length - 1, b; h >= 0; h--)
205
+ (b = a[h]) && (l = (t ? b(r, n, l) : b(l)) || l);
206
+ return t && l && f(r, n, l), l;
188
207
  };
189
208
  let e = class extends g {
190
209
  constructor() {
@@ -237,12 +256,12 @@ let e = class extends g {
237
256
  <span
238
257
  part="badge"
239
258
  class=${u(n)}
240
- role=${r && this.dotLabel ? "img" : l}
241
- aria-label=${r && this.dotLabel ? this.dotLabel : l}
242
- aria-live=${a ? "polite" : l}
259
+ role=${r && this.dotLabel ? "img" : s}
260
+ aria-label=${r && this.dotLabel ? this.dotLabel : s}
261
+ aria-live=${a ? "polite" : s}
243
262
  >
244
- ${t ? d`<span class="badge__variant-label">${t}: </span>` : l}
245
- ${r ? l : d`<slot name="prefix"></slot>`}
263
+ ${t ? d`<span class="badge__variant-label">${t}: </span>` : s}
264
+ ${r ? s : d`<slot name="prefix"></slot>`}
246
265
  ${a ? this._countDisplay : d`<slot @slotchange=${this._handleSlotChange}></slot>`}
247
266
  ${this.removable ? d`<button
248
267
  part="remove-button"
@@ -256,7 +275,7 @@ let e = class extends g {
256
275
  fill="currentColor"
257
276
  />
258
277
  </svg>
259
- </button>` : l}
278
+ </button>` : s}
260
279
  </span>
261
280
  `;
262
281
  }
@@ -304,4 +323,4 @@ e = o([
304
323
  export {
305
324
  e as H
306
325
  };
307
- //# sourceMappingURL=hx-badge-DDXTLoWi.js.map
326
+ //# sourceMappingURL=hx-badge-RPzd-t5l.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hx-badge-RPzd-t5l.js","sources":["../../src/components/hx-badge/hx-badge.styles.ts","../../src/components/hx-badge/hx-badge.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixBadgeStyles = css`\n :host {\n display: inline-block;\n }\n\n .badge {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--hx-space-1, 0.25rem);\n border-radius: var(--hx-badge-border-radius, var(--hx-border-radius-md, 0.375rem));\n background-color: var(--hx-badge-bg, var(--hx-color-primary-500, #2563eb));\n color: var(--hx-badge-color, var(--hx-color-neutral-0, #ffffff));\n font-family: var(--hx-badge-font-family, var(--hx-font-family-sans, sans-serif));\n font-weight: var(--hx-badge-font-weight, var(--hx-font-weight-semibold, 600));\n line-height: var(--hx-line-height-tight, 1.25);\n white-space: nowrap;\n vertical-align: middle;\n position: relative;\n }\n\n /* ─── Size Variants ─── */\n\n .badge--sm {\n font-size: var(--hx-badge-font-size, var(--hx-font-size-2xs, 0.625rem));\n padding: var(--hx-badge-padding-y, var(--hx-space-0-5, 0.125rem))\n var(--hx-badge-padding-x, var(--hx-space-1-5, 0.375rem));\n }\n\n .badge--md {\n font-size: var(--hx-badge-font-size, var(--hx-font-size-xs, 0.75rem));\n padding: var(--hx-badge-padding-y, var(--hx-space-1, 0.25rem))\n var(--hx-badge-padding-x, var(--hx-space-2, 0.5rem));\n }\n\n .badge--lg {\n font-size: var(--hx-badge-font-size, var(--hx-font-size-sm, 0.875rem));\n padding: var(--hx-badge-padding-y, var(--hx-space-1, 0.25rem))\n var(--hx-badge-padding-x, var(--hx-space-3, 0.75rem));\n }\n\n /* ─── Style Variants ─── */\n\n .badge--primary {\n --hx-badge-bg: var(--hx-color-primary-500, #2563eb);\n --hx-badge-color: var(--hx-color-neutral-0, #ffffff);\n --hx-badge-pulse-color-internal: var(\n --hx-badge-pulse-color,\n var(--hx-color-primary-500, #2563eb)\n );\n }\n\n .badge--secondary {\n --hx-badge-bg: var(--hx-badge-secondary-bg, var(--hx-color-neutral-100, #f3f4f6));\n --hx-badge-color: var(--hx-badge-secondary-color, var(--hx-color-neutral-700, #374151));\n --hx-badge-pulse-color-internal: var(\n --hx-badge-pulse-color,\n var(--hx-badge-secondary-bg, var(--hx-color-neutral-100, #f3f4f6))\n );\n }\n\n .badge--success {\n --hx-badge-bg: var(--hx-color-success-700, #15803d);\n --hx-badge-color: var(--hx-color-neutral-0, #ffffff);\n --hx-badge-pulse-color-internal: var(\n --hx-badge-pulse-color,\n var(--hx-color-success-700, #15803d)\n );\n }\n\n .badge--warning {\n --hx-badge-bg: var(--hx-color-warning-500, #eab308);\n --hx-badge-color: var(--hx-color-neutral-900, #1a1a1a);\n --hx-badge-pulse-color-internal: var(\n --hx-badge-pulse-color,\n var(--hx-color-warning-500, #eab308)\n );\n }\n\n .badge--error {\n --hx-badge-bg: var(--hx-color-error-500, #dc2626);\n --hx-badge-color: var(--hx-color-neutral-0, #ffffff);\n --hx-badge-pulse-color-internal: var(\n --hx-badge-pulse-color,\n var(--hx-color-error-500, #dc2626)\n );\n }\n\n .badge--neutral {\n --hx-badge-bg: var(--hx-color-neutral-200, #e5e7eb);\n --hx-badge-color: var(--hx-color-neutral-700, #374151);\n --hx-badge-pulse-color-internal: var(\n --hx-badge-pulse-color,\n var(--hx-color-neutral-200, #e5e7eb)\n );\n }\n\n .badge--info {\n --hx-badge-bg: var(--hx-badge-info-bg, var(--hx-color-info-700, #0369a1));\n --hx-badge-color: var(--hx-badge-info-color, var(--hx-color-neutral-0, #ffffff));\n --hx-badge-pulse-color-internal: var(\n --hx-badge-pulse-color,\n var(--hx-badge-info-bg, var(--hx-color-info-700, #0369a1))\n );\n }\n\n /* ─── Semantic Variant Label (WCAG 1.4.1) ─── */\n /* Visually hidden text prefix for semantic variants (success/warning/error/info). */\n /* Ensures the variant is not conveyed by color alone. */\n\n .badge__variant-label {\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 /* ─── Pill Mode ─── */\n\n .badge--pill {\n border-radius: var(--hx-badge-border-radius, var(--hx-border-radius-full, 9999px));\n }\n\n /* ─── Dot Indicator (empty + pulse) ─── */\n\n .badge--dot {\n width: var(--hx-badge-dot-size, var(--hx-space-2, 0.5rem));\n height: var(--hx-badge-dot-size, var(--hx-space-2, 0.5rem));\n padding: 0;\n border-radius: var(--hx-border-radius-full, 9999px);\n }\n\n /* Guard: hide all inner content in dot mode — the dot is purely visual */\n .badge--dot ::slotted(*),\n .badge--dot slot,\n .badge--dot slot[name='prefix'] {\n display: none !important;\n }\n\n /* ─── Pulse Animation ─── */\n\n @keyframes hx-badge-pulse {\n 0%,\n 100% {\n opacity: 1;\n box-shadow: 0 0 0 2px var(--hx-badge-pulse-color-internal, currentColor);\n }\n 50% {\n opacity: var(--hx-opacity-75, 0.75);\n box-shadow: 0 0 0 6px transparent;\n }\n }\n\n .badge--pulse {\n animation: hx-badge-pulse var(--hx-badge-pulse-duration, var(--hx-duration-slow, 2s))\n var(--hx-badge-pulse-easing, var(--hx-easing-in-out, ease-in-out)) infinite;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .badge--pulse {\n animation: none;\n }\n }\n\n /* ─── Remove Button ─── */\n\n .badge__remove-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n background: none;\n border: none;\n padding: 0;\n margin-inline-start: var(--hx-space-1, 0.25rem);\n cursor: pointer;\n color: inherit;\n opacity: var(--hx-opacity-75, 0.75);\n border-radius: var(--hx-border-radius-sm, 0.125rem);\n line-height: 0;\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 }\n\n .badge__remove-button:hover {\n opacity: var(--hx-opacity-100, 1);\n }\n\n .badge__remove-button:focus-visible {\n outline: var(--hx-focus-ring-width, 2px) solid var(--hx-focus-ring-color, currentColor);\n outline-offset: var(--hx-focus-ring-offset, 1px);\n }\n`;\n","import { LitElement, html, nothing } from 'lit';\nimport '../../utilities/document-token-adoption.js';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { helixBadgeStyles } from './hx-badge.styles.js';\nimport { devWarn } from '../../utils/dev-warn.js';\n\n/**\n * A small status indicator for notifications, counts, and labels.\n *\n * @summary Presentational badge for status indicators, notification counts, and labels.\n *\n * @tag hx-badge\n *\n * @slot - Default slot for badge content (text, number). When empty with pulse enabled, renders as a dot indicator.\n * @slot prefix - Icon or content rendered before the badge text.\n *\n * @fires {CustomEvent<void>} hx-remove - Dispatched when the user clicks the remove button.\n *\n * @csspart badge - The badge element.\n * @csspart remove-button - The remove/dismiss button.\n *\n * @cssprop [--hx-badge-bg=var(--hx-color-primary-500)] - Badge background color. The primary override point.\n * @cssprop [--hx-badge-color=var(--hx-color-neutral-0)] - Badge text color. The primary override point.\n * @cssprop [--hx-badge-font-size] - Badge font size (set per size variant).\n * @cssprop [--hx-badge-font-weight=var(--hx-font-weight-semibold)] - Badge font weight.\n * @cssprop [--hx-badge-font-family=var(--hx-font-family-sans)] - Badge font family.\n * @cssprop [--hx-badge-border-radius=var(--hx-border-radius-md)] - Badge border radius.\n * @cssprop [--hx-badge-padding-x] - Badge horizontal padding (set per size variant).\n * @cssprop [--hx-badge-padding-y] - Badge vertical padding (set per size variant).\n * @cssprop [--hx-badge-pulse-color] - Pulse color matching variant background with reduced opacity.\n * @cssprop [--hx-badge-dot-size=var(--hx-size-2)] - Dot indicator size when rendered without content.\n * @cssprop [--hx-badge-secondary-bg=var(--hx-color-neutral-100)] - Background for the secondary variant.\n * @cssprop [--hx-badge-secondary-color=var(--hx-color-neutral-700)] - Text color for the secondary variant.\n * @cssprop [--hx-badge-info-bg=var(--hx-color-info-700)] - Background for the info variant.\n * @cssprop [--hx-badge-info-color=var(--hx-color-neutral-0)] - Text color for the info variant.\n */\n@customElement('hx-badge')\nexport class HelixBadge extends LitElement {\n static override styles = [helixBadgeStyles];\n\n /**\n * Visual style variant of the badge.\n * @attr variant\n */\n @property({ type: String, reflect: true })\n variant: 'primary' | 'secondary' | 'success' | 'warning' | 'error' | 'neutral' | 'info' =\n 'primary';\n\n /**\n * Size of the badge.\n * @attr hx-size\n */\n @property({ type: String, reflect: true, attribute: 'hx-size' })\n size: 'sm' | 'md' | 'lg' = 'md';\n\n /**\n * Whether the badge uses fully rounded (pill) styling.\n * @attr pill\n */\n @property({ type: Boolean, reflect: true })\n pill = false;\n\n /**\n * Whether the badge displays an animated pulse for attention.\n * @attr pulse\n */\n @property({ type: Boolean, reflect: true })\n pulse = false;\n\n /**\n * Whether the badge renders a dismiss button.\n * @attr removable\n */\n @property({ type: Boolean, reflect: true })\n removable = false;\n\n /**\n * Numeric count to display. When set, renders the count as badge content.\n * When count exceeds `max`, displays `${max}+` (e.g. `99+`).\n * @attr count\n */\n @property({ type: Number, reflect: true })\n count: number | undefined = undefined;\n\n /**\n * Maximum count value before truncation to `${max}+`. Defaults to 99.\n * @attr max\n */\n @property({ type: Number, reflect: true })\n max = 99;\n\n /**\n * Accessible label for the dot indicator mode (pulse + empty slot).\n * Required for WCAG 4.1.2 compliance when using the dot indicator pattern.\n * Example: `dot-label=\"3 new messages\"`.\n * @attr dot-label\n */\n @property({ type: String, attribute: 'dot-label' })\n dotLabel = '';\n\n /**\n * Accessible label for the remove button. Should describe what is being removed.\n * Defaults to \"Remove\". For better accessibility, include context: e.g. \"Remove Critical badge\".\n * @attr remove-label\n */\n @property({ type: String, attribute: 'remove-label' })\n removeLabel = 'Remove';\n\n /**\n * Tracks whether the default slot has assigned content.\n * @internal\n */\n @state()\n private _hasSlotContent = false;\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-badge', 'The \"size\" attribute is deprecated. Use \"hx-size\" instead.');\n this.size = legacySize as 'sm' | 'md' | 'lg';\n }\n }\n\n // ─── Slot Change Handling ───\n\n /** @internal */\n private _handleSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n const nodes = slot.assignedNodes({ flatten: true });\n // Check if any assigned node has non-whitespace content\n this._hasSlotContent = nodes.some((node) => {\n if (node.nodeType === Node.ELEMENT_NODE) return true;\n if (node.nodeType === Node.TEXT_NODE) {\n return (node.textContent ?? '').trim().length > 0;\n }\n return false;\n });\n }\n\n // ─── Event Handling ───\n\n /** @internal */\n private _handleRemove(): void {\n this.dispatchEvent(\n new CustomEvent<void>('hx-remove', {\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n // ─── Count Display ───\n\n /** @internal */\n private get _countDisplay(): string {\n if (this.count === undefined) return '';\n return this.count > this.max ? `${this.max}+` : String(this.count);\n }\n\n // ─── WCAG 1.4.1: Semantic variant label map ───\n // Variants that carry semantic meaning beyond decoration need a non-color cue.\n // Visually-hidden text is prepended so screen reader users and color-blind\n // users get the variant context even when no icon is slotted.\n\n /** @internal */\n private static readonly _SEMANTIC_VARIANT_LABELS: Partial<Record<HelixBadge['variant'], string>> =\n {\n success: 'Success',\n warning: 'Warning',\n error: 'Error',\n info: 'Info',\n };\n\n /** @internal */\n private get _semanticVariantLabel(): string {\n return HelixBadge._SEMANTIC_VARIANT_LABELS[this.variant] ?? '';\n }\n\n // ─── Render ───\n\n override render() {\n const hasCount = this.count !== undefined;\n const isDot = !this._hasSlotContent && !hasCount && this.pulse;\n\n if (isDot && !this.dotLabel) {\n devWarn(\n 'hx-badge',\n 'Dot badge is missing an accessible label. Set `dotLabel` so screen readers can announce the badge purpose (WCAG 4.1.2).',\n );\n }\n\n const classes = {\n badge: true,\n [`badge--${this.variant}`]: true,\n [`badge--${this.size}`]: true,\n 'badge--pill': this.pill,\n 'badge--pulse': this.pulse,\n 'badge--dot': isDot,\n };\n\n const variantLabel = this._semanticVariantLabel;\n\n return html`\n <span\n part=\"badge\"\n class=${classMap(classes)}\n role=${isDot && this.dotLabel ? 'img' : nothing}\n aria-label=${isDot && this.dotLabel ? this.dotLabel : nothing}\n aria-live=${hasCount ? 'polite' : nothing}\n >\n ${variantLabel\n ? html`<span class=\"badge__variant-label\">${variantLabel}: </span>`\n : nothing}\n ${isDot ? nothing : html`<slot name=\"prefix\"></slot>`}\n ${hasCount ? this._countDisplay : html`<slot @slotchange=${this._handleSlotChange}></slot>`}\n ${this.removable\n ? html`<button\n part=\"remove-button\"\n class=\"badge__remove-button\"\n aria-label=${this.removeLabel}\n @click=${this._handleRemove}\n >\n <svg viewBox=\"0 0 12 12\" aria-hidden=\"true\" width=\"10\" height=\"10\">\n <path\n d=\"M2.22 2.22a.75.75 0 011.06 0L6 4.94l2.72-2.72a.75.75 0 011.06 1.06L7.06 6l2.72 2.72a.75.75 0 01-1.06 1.06L6 7.06 3.28 9.78a.75.75 0 01-1.06-1.06L4.94 6 2.22 3.28a.75.75 0 010-1.06z\"\n fill=\"currentColor\"\n />\n </svg>\n </button>`\n : nothing}\n </span>\n `;\n }\n}\n\n/**\n * @deprecated Use `HelixBadge` instead. This alias will be removed in a future\n * major version as part of the project-wide migration from `Wc` to `Hx` prefixes.\n * @since 0.1.0\n * @removal-target 1.0.0\n */\nexport type WcBadge = HelixBadge;\n\n/** Canonical type alias for the hx-badge component. */\nexport type HxBadge = HelixBadge;\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-badge': HelixBadge;\n }\n}\n"],"names":["helixBadgeStyles","css","HelixBadge","LitElement","legacySize","e","nodes","node","hasCount","isDot","classes","variantLabel","html","classMap","nothing","__decorateClass","property","state","customElement"],"mappings":"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"}