@helixui/library 0.1.3 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/custom-elements.json +262 -67
- package/dist/components/hx-accordion/hx-accordion-item.d.ts.map +1 -1
- package/dist/components/hx-accordion/hx-accordion.d.ts +2 -0
- package/dist/components/hx-accordion/hx-accordion.d.ts.map +1 -1
- package/dist/components/hx-accordion/index.js +1 -1
- package/dist/components/hx-action-bar/hx-action-bar.d.ts +1 -0
- package/dist/components/hx-action-bar/hx-action-bar.d.ts.map +1 -1
- package/dist/components/hx-action-bar/index.js +1 -1
- package/dist/components/hx-alert/hx-alert.d.ts +1 -1
- package/dist/components/hx-alert/hx-alert.d.ts.map +1 -1
- package/dist/components/hx-alert/index.d.ts +1 -0
- package/dist/components/hx-alert/index.d.ts.map +1 -1
- package/dist/components/hx-avatar/hx-avatar.d.ts +1 -1
- package/dist/components/hx-avatar/hx-avatar.d.ts.map +1 -1
- package/dist/components/hx-avatar/hx-avatar.styles.d.ts.map +1 -1
- package/dist/components/hx-avatar/index.js +1 -1
- package/dist/components/hx-button/hx-button.d.ts +10 -4
- package/dist/components/hx-button/hx-button.d.ts.map +1 -1
- package/dist/components/hx-button/hx-button.styles.d.ts.map +1 -1
- package/dist/components/hx-button/index.js +1 -1
- package/dist/components/hx-button-group/hx-button-group.d.ts +6 -3
- package/dist/components/hx-button-group/hx-button-group.d.ts.map +1 -1
- package/dist/components/hx-button-group/hx-button-group.styles.d.ts.map +1 -1
- package/dist/components/hx-button-group/index.js +1 -1
- package/dist/components/hx-card/hx-card.d.ts +9 -0
- package/dist/components/hx-card/hx-card.d.ts.map +1 -1
- package/dist/components/hx-card/index.js +1 -1
- package/dist/components/hx-checkbox/hx-checkbox.d.ts +3 -0
- package/dist/components/hx-checkbox/hx-checkbox.d.ts.map +1 -1
- package/dist/components/hx-checkbox/hx-checkbox.styles.d.ts.map +1 -1
- package/dist/components/hx-checkbox/index.js +1 -1
- package/dist/components/hx-checkbox-group/hx-checkbox-group.d.ts +1 -0
- package/dist/components/hx-checkbox-group/hx-checkbox-group.d.ts.map +1 -1
- package/dist/components/hx-checkbox-group/index.js +1 -1
- package/dist/components/hx-code-snippet/hx-code-snippet.d.ts.map +1 -1
- package/dist/components/hx-code-snippet/index.js +1 -1
- package/dist/components/hx-color-picker/hx-color-picker.d.ts.map +1 -1
- package/dist/components/hx-color-picker/index.js +1 -1
- package/dist/components/hx-combobox/index.d.ts +1 -2
- package/dist/components/hx-combobox/index.d.ts.map +1 -1
- package/dist/components/hx-container/hx-container.d.ts +2 -0
- package/dist/components/hx-container/hx-container.d.ts.map +1 -1
- package/dist/components/hx-container/hx-container.styles.d.ts.map +1 -1
- package/dist/components/hx-container/index.js +1 -1
- package/dist/components/hx-dialog/index.js +1 -1
- package/dist/components/hx-divider/index.js +1 -1
- package/dist/components/hx-drawer/hx-drawer.d.ts +3 -2
- package/dist/components/hx-drawer/hx-drawer.d.ts.map +1 -1
- package/dist/components/hx-dropdown/index.d.ts +1 -1
- package/dist/components/hx-dropdown/index.d.ts.map +1 -1
- package/dist/components/hx-field/index.js +1 -1
- package/dist/components/hx-field-label/hx-field-label.d.ts +17 -7
- package/dist/components/hx-field-label/hx-field-label.d.ts.map +1 -1
- package/dist/components/hx-file-upload/hx-file-upload.d.ts +1 -0
- package/dist/components/hx-file-upload/hx-file-upload.d.ts.map +1 -1
- package/dist/components/hx-link/hx-link.d.ts +5 -1
- package/dist/components/hx-link/hx-link.d.ts.map +1 -1
- package/dist/components/hx-link/hx-link.styles.d.ts.map +1 -1
- package/dist/components/hx-link/index.js +1 -1
- package/dist/components/hx-menu/hx-menu-divider.d.ts.map +1 -1
- package/dist/components/hx-menu/hx-menu-divider.styles.d.ts +2 -0
- package/dist/components/hx-menu/hx-menu-divider.styles.d.ts.map +1 -0
- package/dist/components/hx-menu/hx-menu-item.d.ts +7 -0
- package/dist/components/hx-menu/hx-menu-item.d.ts.map +1 -1
- package/dist/components/hx-menu/hx-menu-item.styles.d.ts.map +1 -1
- package/dist/components/hx-menu/hx-menu.d.ts +11 -0
- package/dist/components/hx-menu/hx-menu.d.ts.map +1 -1
- package/dist/components/hx-menu/index.js +1 -1
- package/dist/components/hx-nav/hx-nav.d.ts +2 -0
- package/dist/components/hx-nav/hx-nav.d.ts.map +1 -1
- package/dist/components/hx-nav/hx-nav.styles.d.ts.map +1 -1
- package/dist/components/hx-nav/index.js +1 -1
- package/dist/components/hx-number-input/hx-number-input.styles.d.ts.map +1 -1
- package/dist/components/hx-number-input/index.js +1 -1
- package/dist/components/hx-progress-ring/hx-progress-ring.d.ts +3 -3
- package/dist/components/hx-progress-ring/hx-progress-ring.d.ts.map +1 -1
- package/dist/components/hx-progress-ring/index.js +1 -1
- package/dist/components/hx-radio-group/hx-radio-group.d.ts +1 -1
- package/dist/components/hx-radio-group/hx-radio-group.d.ts.map +1 -1
- package/dist/components/hx-radio-group/index.js +1 -1
- package/dist/components/hx-side-nav/hx-side-nav.d.ts.map +1 -1
- package/dist/components/hx-side-nav/index.js +1 -1
- package/dist/components/hx-slider/hx-slider.d.ts +2 -0
- package/dist/components/hx-slider/hx-slider.d.ts.map +1 -1
- package/dist/components/hx-slider/hx-slider.styles.d.ts.map +1 -1
- package/dist/components/hx-slider/index.js +1 -1
- package/dist/components/hx-split-panel/hx-split-panel.d.ts +1 -1
- package/dist/components/hx-split-panel/hx-split-panel.d.ts.map +1 -1
- package/dist/components/hx-split-panel/index.js +1 -1
- package/dist/components/hx-status-indicator/hx-status-indicator.d.ts +2 -0
- package/dist/components/hx-status-indicator/hx-status-indicator.d.ts.map +1 -1
- package/dist/components/hx-status-indicator/index.d.ts +1 -2
- package/dist/components/hx-status-indicator/index.d.ts.map +1 -1
- package/dist/components/hx-status-indicator/index.js +1 -1
- package/dist/components/hx-switch/hx-switch.d.ts.map +1 -1
- package/dist/components/hx-switch/index.d.ts +1 -0
- package/dist/components/hx-switch/index.d.ts.map +1 -1
- package/dist/components/hx-textarea/hx-textarea.d.ts +7 -1
- package/dist/components/hx-textarea/hx-textarea.d.ts.map +1 -1
- package/dist/components/hx-textarea/hx-textarea.styles.d.ts.map +1 -1
- package/dist/components/hx-textarea/index.js +1 -1
- package/dist/index.d.ts +11 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +25 -25
- package/dist/shared/{hx-accordion-C84oGPj7.js → hx-accordion-D95XSAft.js} +33 -38
- package/dist/shared/hx-accordion-D95XSAft.js.map +1 -0
- package/dist/shared/{hx-action-bar-DxpGLABm.js → hx-action-bar-D43v5rA2.js} +11 -11
- package/dist/shared/hx-action-bar-D43v5rA2.js.map +1 -0
- package/dist/shared/hx-alert-BQpT4gL3.js.map +1 -1
- package/dist/shared/{hx-avatar-ekyZvOCm.js → hx-avatar-yHjmNdtf.js} +80 -58
- package/dist/shared/hx-avatar-yHjmNdtf.js.map +1 -0
- package/dist/shared/{hx-button-DpFW7PO3.js → hx-button-SAbf4_jC.js} +37 -30
- package/dist/shared/hx-button-SAbf4_jC.js.map +1 -0
- package/dist/shared/{hx-button-group-DxCwaWnu.js → hx-button-group-DET_Pkxt.js} +15 -26
- package/dist/shared/hx-button-group-DET_Pkxt.js.map +1 -0
- package/dist/shared/{hx-card-VdiB2Pc4.js → hx-card-DAkEfpJd.js} +12 -8
- package/dist/shared/hx-card-DAkEfpJd.js.map +1 -0
- package/dist/shared/{hx-checkbox-Dq2xXIvl.js → hx-checkbox-BMayOpAM.js} +13 -1
- package/dist/shared/hx-checkbox-BMayOpAM.js.map +1 -0
- package/dist/shared/{hx-checkbox-group-BLePVahw.js → hx-checkbox-group-CIIijwmc.js} +24 -24
- package/dist/shared/hx-checkbox-group-CIIijwmc.js.map +1 -0
- package/dist/shared/{hx-code-snippet-DjY96OY8.js → hx-code-snippet-DdEqy-1B.js} +3 -2
- package/dist/shared/{hx-code-snippet-DjY96OY8.js.map → hx-code-snippet-DdEqy-1B.js.map} +1 -1
- package/dist/shared/{hx-color-picker-O4b_6QXT.js → hx-color-picker-K2x_dyeG.js} +64 -66
- package/dist/shared/hx-color-picker-K2x_dyeG.js.map +1 -0
- package/dist/shared/{hx-container-COinHjxn.js → hx-container-BXZBaOGG.js} +13 -12
- package/dist/shared/hx-container-BXZBaOGG.js.map +1 -0
- package/dist/shared/{hx-dialog-1VegS0l1.js → hx-dialog-e4CSD8xX.js} +23 -23
- package/dist/shared/hx-dialog-e4CSD8xX.js.map +1 -0
- package/dist/shared/{hx-divider-UdSFzALX.js → hx-divider-XgWIz4Mr.js} +2 -2
- package/dist/shared/{hx-divider-UdSFzALX.js.map → hx-divider-XgWIz4Mr.js.map} +1 -1
- package/dist/shared/hx-drawer-CenIAGuR.js.map +1 -1
- package/dist/shared/{hx-field-BMyp6hBx.js → hx-field-Dz-7M_SC.js} +2 -2
- package/dist/shared/hx-field-Dz-7M_SC.js.map +1 -0
- package/dist/shared/hx-field-label-Bg-EWvqF.js.map +1 -1
- package/dist/shared/hx-file-upload-DnYiIhyN.js.map +1 -1
- package/dist/shared/{hx-link-D73HP4Lq.js → hx-link-DfNy_UU8.js} +4 -5
- package/dist/shared/hx-link-DfNy_UU8.js.map +1 -0
- package/dist/shared/{hx-menu-divider-Bds6Gn6b.js → hx-menu-divider-Buc5XA9E.js} +79 -52
- package/dist/shared/hx-menu-divider-Buc5XA9E.js.map +1 -0
- package/dist/shared/{hx-nav-TK0mPfU6.js → hx-nav-CWwByFdq.js} +78 -63
- package/dist/shared/hx-nav-CWwByFdq.js.map +1 -0
- package/dist/shared/{hx-nav-item-XvXQzMwc.js → hx-nav-item-DItaMWl0.js} +1 -2
- package/dist/shared/hx-nav-item-DItaMWl0.js.map +1 -0
- package/dist/shared/{hx-number-input-BJ5XSvjL.js → hx-number-input-CS6_w1lT.js} +7 -1
- package/dist/shared/hx-number-input-CS6_w1lT.js.map +1 -0
- package/dist/shared/{hx-progress-ring-QGg5fdis.js → hx-progress-ring-wOSv2y_I.js} +32 -35
- package/dist/shared/hx-progress-ring-wOSv2y_I.js.map +1 -0
- package/dist/shared/{hx-radio-CWzYFy-I.js → hx-radio-reSaVmIB.js} +41 -40
- package/dist/shared/hx-radio-reSaVmIB.js.map +1 -0
- package/dist/shared/{hx-slider-BMofa55D.js → hx-slider-CzHOl3Ur.js} +11 -2
- package/dist/shared/hx-slider-CzHOl3Ur.js.map +1 -0
- package/dist/shared/{hx-split-panel-D9Jg5qKO.js → hx-split-panel-Cxkeauwe.js} +22 -22
- package/dist/shared/hx-split-panel-Cxkeauwe.js.map +1 -0
- package/dist/shared/{hx-status-indicator-Mv44COA-.js → hx-status-indicator-oYWOkWlD.js} +31 -24
- package/dist/shared/{hx-status-indicator-Mv44COA-.js.map → hx-status-indicator-oYWOkWlD.js.map} +1 -1
- package/dist/shared/hx-switch-BPvIcDpM.js.map +1 -1
- package/dist/shared/{hx-textarea-Bsq5aJf8.js → hx-textarea-BLcReynr.js} +42 -26
- package/dist/shared/hx-textarea-BLcReynr.js.map +1 -0
- package/fouc.css +88 -0
- package/package.json +5 -3
- package/dist/shared/hx-accordion-C84oGPj7.js.map +0 -1
- package/dist/shared/hx-action-bar-DxpGLABm.js.map +0 -1
- package/dist/shared/hx-avatar-ekyZvOCm.js.map +0 -1
- package/dist/shared/hx-button-DpFW7PO3.js.map +0 -1
- package/dist/shared/hx-button-group-DxCwaWnu.js.map +0 -1
- package/dist/shared/hx-card-VdiB2Pc4.js.map +0 -1
- package/dist/shared/hx-checkbox-Dq2xXIvl.js.map +0 -1
- package/dist/shared/hx-checkbox-group-BLePVahw.js.map +0 -1
- package/dist/shared/hx-color-picker-O4b_6QXT.js.map +0 -1
- package/dist/shared/hx-container-COinHjxn.js.map +0 -1
- package/dist/shared/hx-dialog-1VegS0l1.js.map +0 -1
- package/dist/shared/hx-field-BMyp6hBx.js.map +0 -1
- package/dist/shared/hx-link-D73HP4Lq.js.map +0 -1
- package/dist/shared/hx-menu-divider-Bds6Gn6b.js.map +0 -1
- package/dist/shared/hx-nav-TK0mPfU6.js.map +0 -1
- package/dist/shared/hx-nav-item-XvXQzMwc.js.map +0 -1
- package/dist/shared/hx-number-input-BJ5XSvjL.js.map +0 -1
- package/dist/shared/hx-progress-ring-QGg5fdis.js.map +0 -1
- package/dist/shared/hx-radio-CWzYFy-I.js.map +0 -1
- package/dist/shared/hx-slider-BMofa55D.js.map +0 -1
- package/dist/shared/hx-split-panel-D9Jg5qKO.js.map +0 -1
- package/dist/shared/hx-textarea-Bsq5aJf8.js.map +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { css as u, LitElement as _, nothing as d, html as h } from "lit";
|
|
2
|
-
import { property as l, state as p, customElement as
|
|
3
|
-
import { classMap as
|
|
2
|
+
import { property as l, state as p, customElement as g } from "lit/decorators.js";
|
|
3
|
+
import { classMap as x } from "lit/directives/class-map.js";
|
|
4
4
|
import { tokenStyles as f } from "@helixui/tokens/lit";
|
|
5
|
-
const
|
|
5
|
+
const m = u`
|
|
6
6
|
:host {
|
|
7
7
|
display: block;
|
|
8
8
|
}
|
|
@@ -43,7 +43,7 @@ const b = u`
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
.fieldset__required-marker {
|
|
46
|
-
color: var(--hx-checkbox-group-error-color, var(--hx-color-error-
|
|
46
|
+
color: var(--hx-checkbox-group-error-color, var(--hx-color-error-500, #dc3545));
|
|
47
47
|
font-weight: var(--hx-font-weight-bold);
|
|
48
48
|
}
|
|
49
49
|
|
|
@@ -63,27 +63,27 @@ const b = u`
|
|
|
63
63
|
/* ─── Error State ─── */
|
|
64
64
|
|
|
65
65
|
.fieldset--error .fieldset__legend {
|
|
66
|
-
color: var(--hx-checkbox-group-error-color, var(--hx-color-error-
|
|
66
|
+
color: var(--hx-checkbox-group-error-color, var(--hx-color-error-500, #dc3545));
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
/* ─── Help Text & Error Messages ─── */
|
|
70
70
|
|
|
71
71
|
.fieldset__help-text {
|
|
72
72
|
font-size: var(--hx-font-size-xs);
|
|
73
|
-
color: var(--hx-color-neutral-500);
|
|
73
|
+
color: var(--hx-checkbox-group-help-text-color, var(--hx-color-neutral-500));
|
|
74
74
|
line-height: var(--hx-line-height-normal);
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
.fieldset__error {
|
|
78
78
|
font-size: var(--hx-font-size-xs);
|
|
79
|
-
color: var(--hx-checkbox-group-error-color, var(--hx-color-error-
|
|
79
|
+
color: var(--hx-checkbox-group-error-color, var(--hx-color-error-500, #dc3545));
|
|
80
80
|
line-height: var(--hx-line-height-normal);
|
|
81
81
|
}
|
|
82
82
|
`;
|
|
83
|
-
var
|
|
84
|
-
for (var
|
|
85
|
-
(c = e[n]) && (
|
|
86
|
-
return o &&
|
|
83
|
+
var b = Object.defineProperty, k = Object.getOwnPropertyDescriptor, a = (e, t, s, o) => {
|
|
84
|
+
for (var i = o > 1 ? void 0 : o ? k(t, s) : t, n = e.length - 1, c; n >= 0; n--)
|
|
85
|
+
(c = e[n]) && (i = (o ? c(t, s, i) : c(i)) || i);
|
|
86
|
+
return o && i && b(t, s, i), i;
|
|
87
87
|
};
|
|
88
88
|
let y = 0, r = class extends _ {
|
|
89
89
|
constructor() {
|
|
@@ -213,7 +213,7 @@ let y = 0, r = class extends _ {
|
|
|
213
213
|
return h`
|
|
214
214
|
<fieldset
|
|
215
215
|
part="group"
|
|
216
|
-
class=${
|
|
216
|
+
class=${x(t)}
|
|
217
217
|
aria-describedby=${s ?? d}
|
|
218
218
|
>
|
|
219
219
|
<legend part="label" class="fieldset__legend">
|
|
@@ -236,36 +236,36 @@ let y = 0, r = class extends _ {
|
|
|
236
236
|
`;
|
|
237
237
|
}
|
|
238
238
|
};
|
|
239
|
-
r.styles = [f,
|
|
239
|
+
r.styles = [f, m];
|
|
240
240
|
r.formAssociated = !0;
|
|
241
|
-
|
|
241
|
+
a([
|
|
242
242
|
l({ type: String })
|
|
243
243
|
], r.prototype, "name", 2);
|
|
244
|
-
|
|
244
|
+
a([
|
|
245
245
|
l({ type: String })
|
|
246
246
|
], r.prototype, "label", 2);
|
|
247
|
-
|
|
247
|
+
a([
|
|
248
248
|
l({ type: Boolean, reflect: !0 })
|
|
249
249
|
], r.prototype, "required", 2);
|
|
250
|
-
|
|
250
|
+
a([
|
|
251
251
|
l({ type: Boolean, reflect: !0 })
|
|
252
252
|
], r.prototype, "disabled", 2);
|
|
253
|
-
|
|
253
|
+
a([
|
|
254
254
|
l({ type: String })
|
|
255
255
|
], r.prototype, "error", 2);
|
|
256
|
-
|
|
256
|
+
a([
|
|
257
257
|
l({ type: String, reflect: !0 })
|
|
258
258
|
], r.prototype, "orientation", 2);
|
|
259
|
-
|
|
259
|
+
a([
|
|
260
260
|
p()
|
|
261
261
|
], r.prototype, "_hasErrorSlot", 2);
|
|
262
|
-
|
|
262
|
+
a([
|
|
263
263
|
p()
|
|
264
264
|
], r.prototype, "_hasHelpSlot", 2);
|
|
265
|
-
r =
|
|
266
|
-
|
|
265
|
+
r = a([
|
|
266
|
+
g("hx-checkbox-group")
|
|
267
267
|
], r);
|
|
268
268
|
export {
|
|
269
269
|
r as H
|
|
270
270
|
};
|
|
271
|
-
//# sourceMappingURL=hx-checkbox-group-
|
|
271
|
+
//# sourceMappingURL=hx-checkbox-group-CIIijwmc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hx-checkbox-group-CIIijwmc.js","sources":["../../src/components/hx-checkbox-group/hx-checkbox-group.styles.ts","../../src/components/hx-checkbox-group/hx-checkbox-group.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixCheckboxGroupStyles = css`\n :host {\n display: block;\n }\n\n :host([disabled]) {\n opacity: var(--hx-opacity-disabled);\n cursor: not-allowed;\n }\n\n * {\n box-sizing: border-box;\n }\n\n /* ─── Fieldset ─── */\n\n .fieldset {\n border: none;\n margin: 0;\n padding: 0;\n display: flex;\n flex-direction: column;\n gap: var(--hx-space-2);\n font-family: var(--hx-font-family-sans);\n }\n\n /* ─── Legend ─── */\n\n .fieldset__legend {\n display: flex;\n align-items: baseline;\n gap: var(--hx-space-1);\n font-size: var(--hx-font-size-sm);\n font-weight: var(--hx-font-weight-medium);\n color: var(--hx-checkbox-group-label-color, var(--hx-color-neutral-700));\n line-height: var(--hx-line-height-normal);\n padding: 0;\n margin-bottom: var(--hx-space-1);\n }\n\n .fieldset__required-marker {\n color: var(--hx-checkbox-group-error-color, var(--hx-color-error-500, #dc3545));\n font-weight: var(--hx-font-weight-bold);\n }\n\n /* ─── Items Container ─── */\n\n .fieldset__items {\n display: flex;\n flex-direction: column;\n gap: var(--hx-checkbox-group-gap, var(--hx-space-3));\n }\n\n :host([orientation='horizontal']) .fieldset__items {\n flex-direction: row;\n flex-wrap: wrap;\n }\n\n /* ─── Error State ─── */\n\n .fieldset--error .fieldset__legend {\n color: var(--hx-checkbox-group-error-color, var(--hx-color-error-500, #dc3545));\n }\n\n /* ─── Help Text & Error Messages ─── */\n\n .fieldset__help-text {\n font-size: var(--hx-font-size-xs);\n color: var(--hx-checkbox-group-help-text-color, var(--hx-color-neutral-500));\n line-height: var(--hx-line-height-normal);\n }\n\n .fieldset__error {\n font-size: var(--hx-font-size-xs);\n color: var(--hx-checkbox-group-error-color, var(--hx-color-error-500, #dc3545));\n line-height: var(--hx-line-height-normal);\n }\n`;\n","import { LitElement, html, nothing } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { tokenStyles } from '@helixui/tokens/lit';\nimport { helixCheckboxGroupStyles } from './hx-checkbox-group.styles.js';\nimport type { HelixCheckbox } from '../hx-checkbox/hx-checkbox.js';\n\n/** Monotonic counter for stable, SSR-safe IDs. */\nlet _uid = 0;\n\n/**\n * A form-associated checkbox group that manages a set of `<hx-checkbox>` children.\n *\n * @summary Form-associated checkbox group with label, validation, help text, and multi-value form submission.\n *\n * @tag hx-checkbox-group\n *\n * @slot - `<hx-checkbox>` elements.\n * @slot label - Rich HTML group label (overrides the label property when used).\n * @slot error - Custom error content (overrides the error property).\n * @slot help - Group-level help text.\n *\n * @fires {CustomEvent<{values: string[]}>} hx-change - Dispatched when any child checkbox changes.\n *\n * @csspart group - The fieldset wrapper.\n * @csspart label - The legend/label.\n * @csspart help-text - The help text container.\n * @csspart error-message - The error message container.\n *\n * @cssprop [--hx-checkbox-group-gap=var(--hx-space-3, 0.75rem)] - Gap between checkbox items.\n * @cssprop [--hx-checkbox-group-label-color=var(--hx-color-neutral-700, #343a40)] - Label text color.\n * @cssprop [--hx-checkbox-group-error-color=var(--hx-color-error-500, #dc3545)] - Error message color.\n * @cssprop [--hx-checkbox-group-help-text-color=var(--hx-color-neutral-500)] - Help text color.\n *\n * @drupal\n * Form-associated; render via Twig:\n * ```twig\n * <hx-checkbox-group name=\"{{ field_name }}\" label=\"{{ label }}\"{{ required ? ' required' : '' }}>\n * {% for option in options %}\n * <hx-checkbox value=\"{{ option.value }}\" label=\"{{ option.label }}\"></hx-checkbox>\n * {% endfor %}\n * </hx-checkbox-group>\n * ```\n * The `name` attribute propagates automatically to child checkboxes — no Drupal behavior required.\n */\n@customElement('hx-checkbox-group')\nexport class HelixCheckboxGroup extends LitElement {\n static override styles = [tokenStyles, helixCheckboxGroupStyles];\n\n // ─── Form Association ───\n\n static formAssociated = true;\n\n private _internals: ElementInternals;\n\n constructor() {\n super();\n this._internals = this.attachInternals();\n }\n\n // ─── Properties ───\n\n /**\n * The name used for form submission. Passed to child `hx-checkbox` elements.\n * @attr name\n */\n @property({ type: String })\n name = '';\n\n /**\n * The fieldset legend/label text.\n * @attr label\n */\n @property({ type: String })\n label = '';\n\n /**\n * Whether at least one checkbox must be checked for form submission.\n * @attr required\n */\n @property({ type: Boolean, reflect: true })\n required = false;\n\n /**\n * Whether the entire group is disabled.\n * @attr disabled\n */\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /**\n * Error message to display. When set, the group enters an error state.\n * @attr error\n */\n @property({ type: String })\n error = '';\n\n /**\n * Layout orientation of the checkbox items.\n * @attr orientation\n */\n @property({ type: String, reflect: true })\n orientation: 'vertical' | 'horizontal' = 'vertical';\n\n @state() private _hasErrorSlot = false;\n @state() private _hasHelpSlot = false;\n\n // ─── Internal IDs ───\n\n private _groupId = `hx-checkbox-group-${++_uid}`;\n private _helpTextId = `${this._groupId}-help`;\n private _errorId = `${this._groupId}-error`;\n\n // ─── Slot Handlers ───\n\n private _handleErrorSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n this._hasErrorSlot = slot.assignedNodes({ flatten: true }).length > 0;\n }\n\n private _handleHelpSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n this._hasHelpSlot = slot.assignedNodes({ flatten: true }).length > 0;\n }\n\n // ─── Lifecycle ───\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.addEventListener('hx-change', this._handleCheckboxChange as EventListener);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener('hx-change', this._handleCheckboxChange as EventListener);\n }\n\n override updated(changedProperties: Map<string, unknown>): void {\n super.updated(changedProperties);\n if (changedProperties.has('disabled')) {\n this._syncCheckboxes();\n }\n if (changedProperties.has('name')) {\n this._syncCheckboxNames();\n }\n if (changedProperties.has('required')) {\n this._updateValidity();\n }\n }\n\n override firstUpdated(changedProperties: Map<string, unknown>): void {\n super.firstUpdated(changedProperties);\n this._syncCheckboxes();\n this._syncCheckboxNames();\n const checkedValues = this._getCheckedValues();\n this._updateFormValue(checkedValues);\n this._updateValidity(checkedValues);\n }\n\n // ─── Checkbox Management ───\n\n private _getCheckboxes(): HelixCheckbox[] {\n return Array.from(this.children).filter((c): c is HelixCheckbox => c.tagName === 'HX-CHECKBOX');\n }\n\n private _getCheckedValues(): string[] {\n return this._getCheckboxes()\n .filter((cb) => cb.checked)\n .map((cb) => cb.value);\n }\n\n private _syncCheckboxes(): void {\n const checkboxes = this._getCheckboxes();\n checkboxes.forEach((cb) => {\n cb.disabled = this.disabled;\n });\n }\n\n private _syncCheckboxNames(): void {\n if (!this.name) return;\n const checkboxes = this._getCheckboxes();\n checkboxes.forEach((cb) => {\n cb.name = this.name;\n });\n }\n\n // ─── Event Handling ───\n\n private _handleCheckboxChange = (e: CustomEvent<{ checked: boolean; value: string }>): void => {\n // Only intercept events from direct hx-checkbox children — do not re-intercept\n // the hx-change we dispatch ourselves from this element.\n if (e.target === this) return;\n\n e.stopImmediatePropagation();\n\n const values = this._getCheckedValues();\n this._updateFormValue(values);\n this._updateValidity(values);\n\n /**\n * Dispatched when any child checkbox changes.\n * @event hx-change\n */\n this.dispatchEvent(\n new CustomEvent('hx-change', {\n bubbles: true,\n composed: true,\n detail: { values },\n }),\n );\n };\n\n private _handleSlotChange(): void {\n this._syncCheckboxes();\n this._syncCheckboxNames();\n const checkedValues = this._getCheckedValues();\n this._updateFormValue(checkedValues);\n this._updateValidity(checkedValues);\n }\n\n // ─── Form Integration ───\n\n private _updateFormValue(values: string[]): void {\n if (values.length === 0) {\n this._internals.setFormValue(null);\n return;\n }\n const formData = new FormData();\n values.forEach((v) => formData.append(this.name, v));\n this._internals.setFormValue(formData);\n }\n\n private _updateValidity(values?: string[]): void {\n const checkedValues = values ?? this._getCheckedValues();\n if (this.required && checkedValues.length === 0) {\n const firstCheckbox = this._getCheckboxes()[0];\n this._internals.setValidity(\n { valueMissing: true },\n this.error || 'Please select at least one option.',\n firstCheckbox,\n );\n } else {\n this._internals.setValidity({});\n }\n }\n\n /** Returns the associated form element, if any. */\n get form(): HTMLFormElement | null {\n return this._internals.form;\n }\n\n /** Returns the validation message. */\n get validationMessage(): string {\n return this._internals.validationMessage;\n }\n\n /** Returns the ValidityState object. */\n get validity(): ValidityState {\n return this._internals.validity;\n }\n\n /** Checks whether the group satisfies its constraints. */\n checkValidity(): boolean {\n return this._internals.checkValidity();\n }\n\n /** Reports validity and shows the browser's constraint validation UI. */\n reportValidity(): boolean {\n return this._internals.reportValidity();\n }\n\n /** Called by the form when it resets. */\n formResetCallback(): void {\n const checkboxes = this._getCheckboxes();\n checkboxes.forEach((cb) => {\n cb.checked = false;\n });\n this._internals.setFormValue(null);\n this._updateValidity([]);\n }\n\n /** Called when the form restores state (e.g., back/forward navigation). */\n formStateRestoreCallback(state: string | File | FormData): void {\n if (!(state instanceof FormData)) return;\n const restoredValues = state.getAll(this.name).map((v) => String(v));\n const checkboxes = this._getCheckboxes();\n checkboxes.forEach((cb) => {\n cb.checked = restoredValues.includes(cb.value);\n });\n this._updateFormValue(restoredValues);\n this._updateValidity(restoredValues);\n }\n\n // ─── Render ───\n\n override render() {\n const hasError = !!this.error || this._hasErrorSlot;\n\n const fieldsetClasses = {\n fieldset: true,\n 'fieldset--error': hasError,\n 'fieldset--disabled': this.disabled,\n 'fieldset--required': this.required,\n };\n\n const describedBy =\n [hasError ? this._errorId : null, this._hasHelpSlot ? this._helpTextId : null]\n .filter(Boolean)\n .join(' ') || undefined;\n\n return html`\n <fieldset\n part=\"group\"\n class=${classMap(fieldsetClasses)}\n aria-describedby=${describedBy ?? nothing}\n >\n <legend part=\"label\" class=\"fieldset__legend\">\n <slot name=\"label\">${this.label}</slot>\n ${this.required\n ? html`<span class=\"fieldset__required-marker\" aria-hidden=\"true\">*</span>`\n : nothing}\n </legend>\n\n <div class=\"fieldset__items\">\n <slot @slotchange=${this._handleSlotChange}></slot>\n </div>\n\n ${hasError\n ? html`<div part=\"error-message\" class=\"fieldset__error\" id=${this._errorId} role=\"alert\">\n <slot name=\"error\" @slotchange=${this._handleErrorSlotChange}> ${this.error} </slot>\n </div>`\n : html`<slot name=\"error\" @slotchange=${this._handleErrorSlotChange}></slot>`}\n\n <div part=\"help-text\" class=\"fieldset__help-text\" id=${this._helpTextId}>\n <slot name=\"help\" @slotchange=${this._handleHelpSlotChange}></slot>\n </div>\n </fieldset>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-checkbox-group': HelixCheckboxGroup;\n }\n}\n"],"names":["helixCheckboxGroupStyles","css","_uid","HelixCheckboxGroup","LitElement","values","slot","changedProperties","checkedValues","c","cb","formData","v","firstCheckbox","state","restoredValues","hasError","fieldsetClasses","describedBy","html","classMap","nothing","tokenStyles","__decorateClass","property","customElement"],"mappings":";;;;AAEO,MAAMA,IAA2BC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;ACMxC,IAAIC,IAAO,GAsCEC,IAAN,cAAiCC,EAAW;AAAA,EASjD,cAAc;AACZ,UAAA,GAWF,KAAA,OAAO,IAOP,KAAA,QAAQ,IAOR,KAAA,WAAW,IAOX,KAAA,WAAW,IAOX,KAAA,QAAQ,IAOR,KAAA,cAAyC,YAEhC,KAAQ,gBAAgB,IACxB,KAAQ,eAAe,IAIhC,KAAQ,WAAW,qBAAqB,EAAEF,CAAI,IAC9C,KAAQ,cAAc,GAAG,KAAK,QAAQ,SACtC,KAAQ,WAAW,GAAG,KAAK,QAAQ,UA6EnC,KAAQ,wBAAwB,CAAC,MAA8D;AAG7F,UAAI,EAAE,WAAW,KAAM;AAEvB,QAAE,yBAAA;AAEF,YAAMG,IAAS,KAAK,kBAAA;AACpB,WAAK,iBAAiBA,CAAM,GAC5B,KAAK,gBAAgBA,CAAM,GAM3B,KAAK;AAAA,QACH,IAAI,YAAY,aAAa;AAAA,UAC3B,SAAS;AAAA,UACT,UAAU;AAAA,UACV,QAAQ,EAAE,QAAAA,EAAA;AAAA,QAAO,CAClB;AAAA,MAAA;AAAA,IAEL,GAzJE,KAAK,aAAa,KAAK,gBAAA;AAAA,EACzB;AAAA;AAAA,EAyDQ,uBAAuB,GAAgB;AAC7C,UAAMC,IAAO,EAAE;AACf,SAAK,gBAAgBA,EAAK,cAAc,EAAE,SAAS,GAAA,CAAM,EAAE,SAAS;AAAA,EACtE;AAAA,EAEQ,sBAAsB,GAAgB;AAC5C,UAAMA,IAAO,EAAE;AACf,SAAK,eAAeA,EAAK,cAAc,EAAE,SAAS,GAAA,CAAM,EAAE,SAAS;AAAA,EACrE;AAAA;AAAA,EAIS,oBAA0B;AACjC,UAAM,kBAAA,GACN,KAAK,iBAAiB,aAAa,KAAK,qBAAsC;AAAA,EAChF;AAAA,EAES,uBAA6B;AACpC,UAAM,qBAAA,GACN,KAAK,oBAAoB,aAAa,KAAK,qBAAsC;AAAA,EACnF;AAAA,EAES,QAAQC,GAA+C;AAC9D,UAAM,QAAQA,CAAiB,GAC3BA,EAAkB,IAAI,UAAU,KAClC,KAAK,gBAAA,GAEHA,EAAkB,IAAI,MAAM,KAC9B,KAAK,mBAAA,GAEHA,EAAkB,IAAI,UAAU,KAClC,KAAK,gBAAA;AAAA,EAET;AAAA,EAES,aAAaA,GAA+C;AACnE,UAAM,aAAaA,CAAiB,GACpC,KAAK,gBAAA,GACL,KAAK,mBAAA;AACL,UAAMC,IAAgB,KAAK,kBAAA;AAC3B,SAAK,iBAAiBA,CAAa,GACnC,KAAK,gBAAgBA,CAAa;AAAA,EACpC;AAAA;AAAA,EAIQ,iBAAkC;AACxC,WAAO,MAAM,KAAK,KAAK,QAAQ,EAAE,OAAO,CAACC,MAA0BA,EAAE,YAAY,aAAa;AAAA,EAChG;AAAA,EAEQ,oBAA8B;AACpC,WAAO,KAAK,eAAA,EACT,OAAO,CAACC,MAAOA,EAAG,OAAO,EACzB,IAAI,CAACA,MAAOA,EAAG,KAAK;AAAA,EACzB;AAAA,EAEQ,kBAAwB;AAE9B,IADmB,KAAK,eAAA,EACb,QAAQ,CAACA,MAAO;AACzB,MAAAA,EAAG,WAAW,KAAK;AAAA,IACrB,CAAC;AAAA,EACH;AAAA,EAEQ,qBAA2B;AACjC,QAAI,CAAC,KAAK,KAAM;AAEhB,IADmB,KAAK,eAAA,EACb,QAAQ,CAACA,MAAO;AACzB,MAAAA,EAAG,OAAO,KAAK;AAAA,IACjB,CAAC;AAAA,EACH;AAAA,EA4BQ,oBAA0B;AAChC,SAAK,gBAAA,GACL,KAAK,mBAAA;AACL,UAAMF,IAAgB,KAAK,kBAAA;AAC3B,SAAK,iBAAiBA,CAAa,GACnC,KAAK,gBAAgBA,CAAa;AAAA,EACpC;AAAA;AAAA,EAIQ,iBAAiBH,GAAwB;AAC/C,QAAIA,EAAO,WAAW,GAAG;AACvB,WAAK,WAAW,aAAa,IAAI;AACjC;AAAA,IACF;AACA,UAAMM,IAAW,IAAI,SAAA;AACrB,IAAAN,EAAO,QAAQ,CAACO,MAAMD,EAAS,OAAO,KAAK,MAAMC,CAAC,CAAC,GACnD,KAAK,WAAW,aAAaD,CAAQ;AAAA,EACvC;AAAA,EAEQ,gBAAgBN,GAAyB;AAC/C,UAAMG,IAAgBH,KAAU,KAAK,kBAAA;AACrC,QAAI,KAAK,YAAYG,EAAc,WAAW,GAAG;AAC/C,YAAMK,IAAgB,KAAK,eAAA,EAAiB,CAAC;AAC7C,WAAK,WAAW;AAAA,QACd,EAAE,cAAc,GAAA;AAAA,QAChB,KAAK,SAAS;AAAA,QACdA;AAAA,MAAA;AAAA,IAEJ;AACE,WAAK,WAAW,YAAY,EAAE;AAAA,EAElC;AAAA;AAAA,EAGA,IAAI,OAA+B;AACjC,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA;AAAA,EAGA,IAAI,oBAA4B;AAC9B,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA;AAAA,EAGA,IAAI,WAA0B;AAC5B,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA;AAAA,EAGA,gBAAyB;AACvB,WAAO,KAAK,WAAW,cAAA;AAAA,EACzB;AAAA;AAAA,EAGA,iBAA0B;AACxB,WAAO,KAAK,WAAW,eAAA;AAAA,EACzB;AAAA;AAAA,EAGA,oBAA0B;AAExB,IADmB,KAAK,eAAA,EACb,QAAQ,CAACH,MAAO;AACzB,MAAAA,EAAG,UAAU;AAAA,IACf,CAAC,GACD,KAAK,WAAW,aAAa,IAAI,GACjC,KAAK,gBAAgB,EAAE;AAAA,EACzB;AAAA;AAAA,EAGA,yBAAyBI,GAAuC;AAC9D,QAAI,EAAEA,aAAiB,UAAW;AAClC,UAAMC,IAAiBD,EAAM,OAAO,KAAK,IAAI,EAAE,IAAI,CAACF,MAAM,OAAOA,CAAC,CAAC;AAEnE,IADmB,KAAK,eAAA,EACb,QAAQ,CAACF,MAAO;AACzB,MAAAA,EAAG,UAAUK,EAAe,SAASL,EAAG,KAAK;AAAA,IAC/C,CAAC,GACD,KAAK,iBAAiBK,CAAc,GACpC,KAAK,gBAAgBA,CAAc;AAAA,EACrC;AAAA;AAAA,EAIS,SAAS;AAChB,UAAMC,IAAW,CAAC,CAAC,KAAK,SAAS,KAAK,eAEhCC,IAAkB;AAAA,MACtB,UAAU;AAAA,MACV,mBAAmBD;AAAA,MACnB,sBAAsB,KAAK;AAAA,MAC3B,sBAAsB,KAAK;AAAA,IAAA,GAGvBE,IACJ,CAACF,IAAW,KAAK,WAAW,MAAM,KAAK,eAAe,KAAK,cAAc,IAAI,EAC1E,OAAO,OAAO,EACd,KAAK,GAAG,KAAK;AAElB,WAAOG;AAAA;AAAA;AAAA,gBAGKC,EAASH,CAAe,CAAC;AAAA,2BACdC,KAAeG,CAAO;AAAA;AAAA;AAAA,+BAGlB,KAAK,KAAK;AAAA,YAC7B,KAAK,WACHF,yEACAE,CAAO;AAAA;AAAA;AAAA;AAAA,8BAIS,KAAK,iBAAiB;AAAA;AAAA;AAAA,UAG1CL,IACEG,yDAA4D,KAAK,QAAQ;AAAA,+CACtC,KAAK,sBAAsB,KAAK,KAAK,KAAK;AAAA,sBAE7EA,mCAAsC,KAAK,sBAAsB,UAAU;AAAA;AAAA,+DAExB,KAAK,WAAW;AAAA,0CACrC,KAAK,qBAAqB;AAAA;AAAA;AAAA;AAAA,EAIlE;AACF;AArSahB,EACK,SAAS,CAACmB,GAAatB,CAAwB;AADpDG,EAKJ,iBAAiB;AAgBxBoB,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GApBfrB,EAqBX,WAAA,QAAA,CAAA;AAOAoB,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GA3BfrB,EA4BX,WAAA,SAAA,CAAA;AAOAoB,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,SAAS,SAAS,IAAM;AAAA,GAlC/BrB,EAmCX,WAAA,YAAA,CAAA;AAOAoB,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,SAAS,SAAS,IAAM;AAAA,GAzC/BrB,EA0CX,WAAA,YAAA,CAAA;AAOAoB,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GAhDfrB,EAiDX,WAAA,SAAA,CAAA;AAOAoB,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,QAAQ,SAAS,IAAM;AAAA,GAvD9BrB,EAwDX,WAAA,eAAA,CAAA;AAEiBoB,EAAA;AAAA,EAAhBT,EAAA;AAAM,GA1DIX,EA0DM,WAAA,iBAAA,CAAA;AACAoB,EAAA;AAAA,EAAhBT,EAAA;AAAM,GA3DIX,EA2DM,WAAA,gBAAA,CAAA;AA3DNA,IAANoB,EAAA;AAAA,EADNE,EAAc,mBAAmB;AAAA,GACrBtB,CAAA;"}
|
|
@@ -219,7 +219,8 @@ let o = class extends f {
|
|
|
219
219
|
}
|
|
220
220
|
_renderLines(e) {
|
|
221
221
|
return this.lineNumbers ? s`${e.map(
|
|
222
|
-
(t, r) => s`<span aria-hidden="true" class="code-snippet__line-number">${r + 1}</span>${t
|
|
222
|
+
(t, r) => s`<span aria-hidden="true" class="code-snippet__line-number">${r + 1}</span>${t + `
|
|
223
|
+
`}`
|
|
223
224
|
)}` : s`${e.join(`
|
|
224
225
|
`)}`;
|
|
225
226
|
}
|
|
@@ -319,4 +320,4 @@ o = i([
|
|
|
319
320
|
export {
|
|
320
321
|
o as H
|
|
321
322
|
};
|
|
322
|
-
//# sourceMappingURL=hx-code-snippet-
|
|
323
|
+
//# sourceMappingURL=hx-code-snippet-DdEqy-1B.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hx-code-snippet-DjY96OY8.js","sources":["../../src/components/hx-code-snippet/hx-code-snippet.styles.ts","../../src/components/hx-code-snippet/hx-code-snippet.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixCodeSnippetStyles = css`\n :host {\n display: block;\n }\n\n :host([inline]) {\n display: inline;\n }\n\n /* ─── Inline Mode ─── */\n\n .code-snippet--inline {\n display: inline;\n font-family: var(--hx-code-snippet-font-family, var(--hx-font-family-mono, monospace));\n font-size: var(--hx-code-snippet-font-size, var(--hx-font-size-sm, 0.875em));\n background-color: var(--hx-code-snippet-inline-bg, var(--hx-color-neutral-100, #f1f5f9));\n color: var(--hx-code-snippet-inline-color, var(--hx-color-neutral-900, #0f172a));\n padding: var(--hx-code-snippet-inline-padding-y, 0.125em)\n var(--hx-code-snippet-inline-padding-x, 0.375em);\n border-radius: var(--hx-code-snippet-border-radius, var(--hx-border-radius-sm, 0.25rem));\n }\n\n /* ─── Block Mode Container ─── */\n\n .code-snippet {\n position: relative;\n background-color: var(--hx-code-snippet-bg, var(--hx-color-neutral-900, #0f172a));\n border-radius: var(--hx-code-snippet-border-radius, var(--hx-border-radius-md, 0.375rem));\n overflow: hidden;\n }\n\n /* ─── Hidden Slot ─── */\n\n .code-snippet__slot {\n display: none;\n }\n\n /* ─── Header ─── */\n\n .code-snippet__header {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n padding: var(--hx-space-2, 0.5rem) var(--hx-space-2, 0.5rem) 0;\n min-height: var(--hx-space-8, 2rem);\n }\n\n /* ─── Pre / Code ─── */\n\n .code-snippet__pre {\n margin: 0;\n padding: var(--hx-code-snippet-padding, var(--hx-space-4, 1rem));\n overflow-x: auto;\n white-space: pre;\n }\n\n .code-snippet__pre--wrap {\n white-space: pre-wrap;\n word-break: break-word;\n }\n\n .code-snippet__code {\n display: block;\n font-family: var(--hx-code-snippet-font-family, var(--hx-font-family-mono, monospace));\n font-size: var(--hx-code-snippet-font-size, var(--hx-font-size-sm, 0.875rem));\n line-height: var(--hx-line-height-relaxed, 1.625);\n color: var(--hx-code-snippet-color, var(--hx-color-neutral-100, #f1f5f9));\n tab-size: var(--hx-code-snippet-tab-size, 2);\n }\n\n /* ─── Copy Button ─── */\n\n .code-snippet__copy-button {\n display: inline-flex;\n align-items: center;\n gap: var(--hx-space-1, 0.25rem);\n padding: var(--hx-space-1, 0.25rem) var(--hx-space-2, 0.5rem);\n border: var(--hx-border-width-thin, 1px) solid var(--hx-color-neutral-600, #475569);\n border-radius: var(--hx-border-radius-sm, 0.25rem);\n background-color: var(--hx-color-neutral-800, #1e293b);\n color: var(--hx-color-neutral-200, #e2e8f0);\n font-family: var(--hx-font-family-sans, sans-serif);\n font-size: var(--hx-font-size-xs, 0.75rem);\n font-weight: var(--hx-font-weight-medium, 500);\n line-height: var(--hx-line-height-none, 1);\n cursor: pointer;\n transition:\n background-color var(--hx-transition-fast, 150ms ease),\n color var(--hx-transition-fast, 150ms ease),\n border-color var(--hx-transition-fast, 150ms ease);\n white-space: nowrap;\n z-index: var(--hx-z-index-raised, 1);\n }\n\n .code-snippet__copy-button:hover {\n background-color: var(--hx-color-neutral-700, #334155);\n border-color: var(--hx-color-neutral-500, #64748b);\n }\n\n .code-snippet__copy-button:focus-visible {\n outline: var(--hx-focus-ring-width, 2px) solid var(--hx-focus-ring-color, #2563eb);\n outline-offset: var(--hx-focus-ring-offset, 2px);\n }\n\n .code-snippet__copy-button:active {\n /* Non-standard token — fallback 0.8 applies if token is absent */\n filter: brightness(var(--hx-filter-brightness-active, 0.8));\n }\n\n /* ─── Expand Button ─── */\n\n .code-snippet__expand-button {\n display: block;\n width: 100%;\n padding: var(--hx-space-2, 0.5rem) var(--hx-space-4, 1rem);\n border: none;\n border-top: var(--hx-border-width-thin, 1px) solid var(--hx-color-neutral-700, #334155);\n background-color: var(--hx-color-neutral-800, #1e293b);\n color: var(--hx-color-neutral-300, #cbd5e1);\n font-family: var(--hx-font-family-sans, sans-serif);\n font-size: var(--hx-font-size-sm, 0.875rem);\n font-weight: var(--hx-font-weight-medium, 500);\n text-align: center;\n cursor: pointer;\n transition: background-color var(--hx-transition-fast, 150ms ease);\n }\n\n .code-snippet__expand-button:hover {\n background-color: var(--hx-color-neutral-700, #334155);\n color: var(--hx-color-neutral-100, #f1f5f9);\n }\n\n .code-snippet__expand-button:focus-visible {\n outline: var(--hx-focus-ring-width, 2px) solid var(--hx-focus-ring-color, #2563eb);\n outline-offset: var(--hx-focus-ring-offset, 2px);\n }\n\n /* ─── Line Numbers ─── */\n\n .code-snippet__line-number {\n display: inline-block;\n min-width: var(--hx-space-8, 2rem);\n padding-right: var(--hx-space-3, 0.75rem);\n color: var(--hx-code-snippet-line-number-color, var(--hx-color-neutral-500, #64748b));\n user-select: none;\n text-align: right;\n }\n\n /* ─── Screen-reader only ─── */\n\n .sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n }\n`;\n","import { LitElement, html, nothing, TemplateResult } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { tokenStyles } from '@helixui/tokens/lit';\nimport { helixCodeSnippetStyles } from './hx-code-snippet.styles.js';\n\n/**\n * A styled code block with optional copy button and max-lines truncation.\n * Supports block (`<pre><code>`) and inline (`<code>`) rendering modes.\n * No external syntax highlighting dependency — use the `language` attribute\n * as a hint for consumers integrating their own highlighter via slotted content.\n *\n * @summary Styled code display component with copy-to-clipboard and expand/collapse.\n *\n * @tag hx-code-snippet\n *\n * @slot - Code content as plain text. Note: HTML markup in slot content will be\n * stripped — only text content is extracted. Pre-highlighted HTML is not supported.\n *\n * @fires {CustomEvent<{text: string}>} hx-copy - Dispatched when the copy button is clicked.\n *\n * @csspart base - The outermost container (block: `<div>`, inline: `<code>`).\n * @csspart header - The header bar containing the copy button (block mode only).\n * @csspart code - The `<code>` element containing the content.\n * @csspart copy-button - The copy-to-clipboard button.\n * @csspart expand-button - The \"Show more / Show less\" button.\n *\n * @cssprop [--hx-code-snippet-bg=var(--hx-color-neutral-900,#0f172a)] - Background color.\n * @cssprop [--hx-code-snippet-color=var(--hx-color-neutral-100,#f1f5f9)] - Text color.\n * @cssprop [--hx-code-snippet-font-family=var(--hx-font-family-mono,monospace)] - Font family.\n * @cssprop [--hx-code-snippet-font-size=var(--hx-font-size-sm,0.875rem)] - Font size.\n * @cssprop [--hx-code-snippet-border-radius=var(--hx-border-radius-md,0.375rem)] - Border radius.\n * @cssprop [--hx-code-snippet-padding=var(--hx-space-4,1rem)] - Inner padding (block mode).\n */\n@customElement('hx-code-snippet')\nexport class HelixCodeSnippet extends LitElement {\n static override styles = [tokenStyles, helixCodeSnippetStyles];\n\n // ─── Public Properties ───\n\n /**\n * Language hint for consumers to apply syntax highlighting.\n * Does not affect rendering directly; it is applied as a `language-*` class\n * on the `<code>` element so external highlighters can target it.\n * @attr language\n */\n @property({ type: String, reflect: true })\n language: string = '';\n\n /**\n * When true, renders as an inline `<code>` element instead of a `<pre><code>` block.\n * @attr inline\n */\n @property({ type: Boolean, reflect: true })\n inline: boolean = false;\n\n /**\n * When true, enables word-wrap in block mode.\n * @attr wrap\n */\n @property({ type: Boolean, reflect: true })\n wrap: boolean = false;\n\n /**\n * When true, shows a copy-to-clipboard button.\n * @attr copyable\n *\n * IMPORTANT: This is a standard boolean attribute. Setting `copyable=\"false\"` in HTML\n * will NOT disable the copy button — the attribute presence alone signals `true`.\n * To disable programmatically, set `el.copyable = false` via JavaScript.\n * In Lit/HTML templates, use `?copyable=${false}` (Lit boolean binding) to remove the attribute.\n */\n @property({ type: Boolean, reflect: true })\n copyable: boolean = true;\n\n /**\n * Maximum number of lines to display before showing a \"Show more\" button.\n * Set to 0 (default) to disable truncation.\n * @attr max-lines\n */\n @property({ type: Number, attribute: 'max-lines', reflect: true })\n maxLines: number = 0;\n\n /**\n * When true, prepends line numbers to each displayed line in block mode.\n * Line numbers are rendered as `aria-hidden` spans so screen readers skip them.\n * @attr line-numbers\n */\n @property({ type: Boolean, attribute: 'line-numbers', reflect: true })\n lineNumbers: boolean = false;\n\n // ─── Internal State ───\n\n @state() private _copied: boolean = false;\n @state() private _expanded: boolean = false;\n @state() private _codeText: string = '';\n\n private _copyTimer: ReturnType<typeof setTimeout> | null = null;\n\n // ─── Lifecycle ───\n\n override firstUpdated(): void {\n // Prevent flash of empty <code> before slotchange fires by eagerly reading\n // text content from host children that are already present on first render.\n if (!this._codeText) {\n const text = this.textContent?.trim() ?? '';\n if (text) {\n this._codeText = text;\n }\n }\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n if (this._copyTimer !== null) {\n clearTimeout(this._copyTimer);\n this._copyTimer = null;\n }\n }\n\n // ─── Event Handlers ───\n\n private _handleSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement | null;\n if (!slot) return;\n const nodes = slot.assignedNodes({ flatten: true });\n this._codeText = nodes.map((n) => n.textContent ?? '').join('');\n }\n\n private _handleCopy(): void {\n const text = this._codeText;\n\n navigator.clipboard.writeText(text).catch(() => {\n // Clipboard API unavailable (non-HTTPS environments such as Drupal staging) — emit event only.\n // Note: navigator.clipboard requires a secure context (HTTPS or localhost).\n // On HTTP, the copy event still fires but the clipboard is not populated.\n });\n\n this.dispatchEvent(\n new CustomEvent('hx-copy', {\n bubbles: true,\n composed: true,\n detail: { text },\n }),\n );\n\n this._copied = true;\n if (this._copyTimer !== null) clearTimeout(this._copyTimer);\n this._copyTimer = setTimeout(() => {\n this._copied = false;\n }, 2000);\n }\n\n private _handleExpand(): void {\n this._expanded = !this._expanded;\n }\n\n // ─── Helpers ───\n\n private _getDisplayLines(): string[] {\n const lines = this._codeText.split('\\n');\n if (!this.maxLines || this.maxLines <= 0 || this._expanded) {\n return lines;\n }\n if (lines.length <= this.maxLines) {\n return lines;\n }\n return lines.slice(0, this.maxLines);\n }\n\n private _isTruncated(): boolean {\n if (!this.maxLines || this.maxLines <= 0) return false;\n const lines = this._codeText.split('\\n');\n return lines.length > this.maxLines;\n }\n\n private _renderLines(lines: string[]): TemplateResult {\n if (!this.lineNumbers) {\n return html`${lines.join('\\n')}`;\n }\n return html`${lines.map(\n (line, i) =>\n html`<span aria-hidden=\"true\" class=\"code-snippet__line-number\">${i + 1}</span>${line} `,\n )}`;\n }\n\n // ─── Render ───\n\n override render(): TemplateResult | typeof nothing {\n if (this.inline) {\n return html`\n <code part=\"base code\" class=\"code-snippet code-snippet--inline\">\n <slot @slotchange=${this._handleSlotChange}></slot>\n </code>\n `;\n }\n\n const displayLines = this._getDisplayLines();\n const truncated = this._isTruncated();\n const preLabel = this.language ? `Code snippet: ${this.language}` : 'Code snippet';\n const codeClasses = classMap({\n 'code-snippet__code': true,\n [`language-${this.language}`]: Boolean(this.language),\n });\n\n return html`\n <div part=\"base\" class=\"code-snippet\">\n <div part=\"header\" class=\"code-snippet__header\">\n ${this.copyable\n ? html`\n <button\n part=\"copy-button\"\n class=\"code-snippet__copy-button\"\n type=\"button\"\n aria-label=${this._copied ? 'Copied!' : 'Copy code'}\n @click=${this._handleCopy}\n >\n ${this._copied ? 'Copied!' : 'Copy'}\n </button>\n `\n : nothing}\n </div>\n\n <!-- Visually-hidden live region announces copy confirmation to assistive technology -->\n <span\n aria-live=\"polite\"\n style=\"position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0;\"\n >${this._copied ? 'Copied!' : ''}</span\n >\n\n <pre\n role=\"region\"\n aria-label=${preLabel}\n class=${classMap({\n 'code-snippet__pre': true,\n 'code-snippet__pre--wrap': this.wrap,\n })}\n ><code part=\"code\" class=${codeClasses}>${this._renderLines(displayLines)}</code></pre>\n\n <!-- Hidden slot to capture text content for display and copy -->\n <slot class=\"code-snippet__slot\" @slotchange=${this._handleSlotChange}></slot>\n\n ${truncated\n ? html`\n <button\n part=\"expand-button\"\n class=\"code-snippet__expand-button\"\n type=\"button\"\n aria-expanded=${this._expanded ? 'true' : 'false'}\n @click=${this._handleExpand}\n >\n ${this._expanded ? 'Show less' : 'Show more'}\n </button>\n `\n : nothing}\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-code-snippet': HelixCodeSnippet;\n }\n}\n"],"names":["helixCodeSnippetStyles","css","HelixCodeSnippet","LitElement","text","_a","slot","nodes","lines","html","line","i","displayLines","truncated","preLabel","codeClasses","classMap","nothing","tokenStyles","__decorateClass","property","state","customElement"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"hx-code-snippet-DdEqy-1B.js","sources":["../../src/components/hx-code-snippet/hx-code-snippet.styles.ts","../../src/components/hx-code-snippet/hx-code-snippet.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixCodeSnippetStyles = css`\n :host {\n display: block;\n }\n\n :host([inline]) {\n display: inline;\n }\n\n /* ─── Inline Mode ─── */\n\n .code-snippet--inline {\n display: inline;\n font-family: var(--hx-code-snippet-font-family, var(--hx-font-family-mono, monospace));\n font-size: var(--hx-code-snippet-font-size, var(--hx-font-size-sm, 0.875em));\n background-color: var(--hx-code-snippet-inline-bg, var(--hx-color-neutral-100, #f1f5f9));\n color: var(--hx-code-snippet-inline-color, var(--hx-color-neutral-900, #0f172a));\n padding: var(--hx-code-snippet-inline-padding-y, 0.125em)\n var(--hx-code-snippet-inline-padding-x, 0.375em);\n border-radius: var(--hx-code-snippet-border-radius, var(--hx-border-radius-sm, 0.25rem));\n }\n\n /* ─── Block Mode Container ─── */\n\n .code-snippet {\n position: relative;\n background-color: var(--hx-code-snippet-bg, var(--hx-color-neutral-900, #0f172a));\n border-radius: var(--hx-code-snippet-border-radius, var(--hx-border-radius-md, 0.375rem));\n overflow: hidden;\n }\n\n /* ─── Hidden Slot ─── */\n\n .code-snippet__slot {\n display: none;\n }\n\n /* ─── Header ─── */\n\n .code-snippet__header {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n padding: var(--hx-space-2, 0.5rem) var(--hx-space-2, 0.5rem) 0;\n min-height: var(--hx-space-8, 2rem);\n }\n\n /* ─── Pre / Code ─── */\n\n .code-snippet__pre {\n margin: 0;\n padding: var(--hx-code-snippet-padding, var(--hx-space-4, 1rem));\n overflow-x: auto;\n white-space: pre;\n }\n\n .code-snippet__pre--wrap {\n white-space: pre-wrap;\n word-break: break-word;\n }\n\n .code-snippet__code {\n display: block;\n font-family: var(--hx-code-snippet-font-family, var(--hx-font-family-mono, monospace));\n font-size: var(--hx-code-snippet-font-size, var(--hx-font-size-sm, 0.875rem));\n line-height: var(--hx-line-height-relaxed, 1.625);\n color: var(--hx-code-snippet-color, var(--hx-color-neutral-100, #f1f5f9));\n tab-size: var(--hx-code-snippet-tab-size, 2);\n }\n\n /* ─── Copy Button ─── */\n\n .code-snippet__copy-button {\n display: inline-flex;\n align-items: center;\n gap: var(--hx-space-1, 0.25rem);\n padding: var(--hx-space-1, 0.25rem) var(--hx-space-2, 0.5rem);\n border: var(--hx-border-width-thin, 1px) solid var(--hx-color-neutral-600, #475569);\n border-radius: var(--hx-border-radius-sm, 0.25rem);\n background-color: var(--hx-color-neutral-800, #1e293b);\n color: var(--hx-color-neutral-200, #e2e8f0);\n font-family: var(--hx-font-family-sans, sans-serif);\n font-size: var(--hx-font-size-xs, 0.75rem);\n font-weight: var(--hx-font-weight-medium, 500);\n line-height: var(--hx-line-height-none, 1);\n cursor: pointer;\n transition:\n background-color var(--hx-transition-fast, 150ms ease),\n color var(--hx-transition-fast, 150ms ease),\n border-color var(--hx-transition-fast, 150ms ease);\n white-space: nowrap;\n z-index: var(--hx-z-index-raised, 1);\n }\n\n .code-snippet__copy-button:hover {\n background-color: var(--hx-color-neutral-700, #334155);\n border-color: var(--hx-color-neutral-500, #64748b);\n }\n\n .code-snippet__copy-button:focus-visible {\n outline: var(--hx-focus-ring-width, 2px) solid var(--hx-focus-ring-color, #2563eb);\n outline-offset: var(--hx-focus-ring-offset, 2px);\n }\n\n .code-snippet__copy-button:active {\n /* Non-standard token — fallback 0.8 applies if token is absent */\n filter: brightness(var(--hx-filter-brightness-active, 0.8));\n }\n\n /* ─── Expand Button ─── */\n\n .code-snippet__expand-button {\n display: block;\n width: 100%;\n padding: var(--hx-space-2, 0.5rem) var(--hx-space-4, 1rem);\n border: none;\n border-top: var(--hx-border-width-thin, 1px) solid var(--hx-color-neutral-700, #334155);\n background-color: var(--hx-color-neutral-800, #1e293b);\n color: var(--hx-color-neutral-300, #cbd5e1);\n font-family: var(--hx-font-family-sans, sans-serif);\n font-size: var(--hx-font-size-sm, 0.875rem);\n font-weight: var(--hx-font-weight-medium, 500);\n text-align: center;\n cursor: pointer;\n transition: background-color var(--hx-transition-fast, 150ms ease);\n }\n\n .code-snippet__expand-button:hover {\n background-color: var(--hx-color-neutral-700, #334155);\n color: var(--hx-color-neutral-100, #f1f5f9);\n }\n\n .code-snippet__expand-button:focus-visible {\n outline: var(--hx-focus-ring-width, 2px) solid var(--hx-focus-ring-color, #2563eb);\n outline-offset: var(--hx-focus-ring-offset, 2px);\n }\n\n /* ─── Line Numbers ─── */\n\n .code-snippet__line-number {\n display: inline-block;\n min-width: var(--hx-space-8, 2rem);\n padding-right: var(--hx-space-3, 0.75rem);\n color: var(--hx-code-snippet-line-number-color, var(--hx-color-neutral-500, #64748b));\n user-select: none;\n text-align: right;\n }\n\n /* ─── Screen-reader only ─── */\n\n .sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n }\n`;\n","import { LitElement, html, nothing, TemplateResult } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { tokenStyles } from '@helixui/tokens/lit';\nimport { helixCodeSnippetStyles } from './hx-code-snippet.styles.js';\n\n/**\n * A styled code block with optional copy button and max-lines truncation.\n * Supports block (`<pre><code>`) and inline (`<code>`) rendering modes.\n * No external syntax highlighting dependency — use the `language` attribute\n * as a hint for consumers integrating their own highlighter via slotted content.\n *\n * @summary Styled code display component with copy-to-clipboard and expand/collapse.\n *\n * @tag hx-code-snippet\n *\n * @slot - Code content as plain text. Note: HTML markup in slot content will be\n * stripped — only text content is extracted. Pre-highlighted HTML is not supported.\n *\n * @fires {CustomEvent<{text: string}>} hx-copy - Dispatched when the copy button is clicked.\n *\n * @csspart base - The outermost container (block: `<div>`, inline: `<code>`).\n * @csspart header - The header bar containing the copy button (block mode only).\n * @csspart code - The `<code>` element containing the content.\n * @csspart copy-button - The copy-to-clipboard button.\n * @csspart expand-button - The \"Show more / Show less\" button.\n *\n * @cssprop [--hx-code-snippet-bg=var(--hx-color-neutral-900,#0f172a)] - Background color.\n * @cssprop [--hx-code-snippet-color=var(--hx-color-neutral-100,#f1f5f9)] - Text color.\n * @cssprop [--hx-code-snippet-font-family=var(--hx-font-family-mono,monospace)] - Font family.\n * @cssprop [--hx-code-snippet-font-size=var(--hx-font-size-sm,0.875rem)] - Font size.\n * @cssprop [--hx-code-snippet-border-radius=var(--hx-border-radius-md,0.375rem)] - Border radius.\n * @cssprop [--hx-code-snippet-padding=var(--hx-space-4,1rem)] - Inner padding (block mode).\n */\n@customElement('hx-code-snippet')\nexport class HelixCodeSnippet extends LitElement {\n static override styles = [tokenStyles, helixCodeSnippetStyles];\n\n // ─── Public Properties ───\n\n /**\n * Language hint for consumers to apply syntax highlighting.\n * Does not affect rendering directly; it is applied as a `language-*` class\n * on the `<code>` element so external highlighters can target it.\n * @attr language\n */\n @property({ type: String, reflect: true })\n language: string = '';\n\n /**\n * When true, renders as an inline `<code>` element instead of a `<pre><code>` block.\n * @attr inline\n */\n @property({ type: Boolean, reflect: true })\n inline: boolean = false;\n\n /**\n * When true, enables word-wrap in block mode.\n * @attr wrap\n */\n @property({ type: Boolean, reflect: true })\n wrap: boolean = false;\n\n /**\n * When true, shows a copy-to-clipboard button.\n * @attr copyable\n *\n * IMPORTANT: This is a standard boolean attribute. Setting `copyable=\"false\"` in HTML\n * will NOT disable the copy button — the attribute presence alone signals `true`.\n * To disable programmatically, set `el.copyable = false` via JavaScript.\n * In Lit/HTML templates, use `?copyable=${false}` (Lit boolean binding) to remove the attribute.\n */\n @property({ type: Boolean, reflect: true })\n copyable: boolean = true;\n\n /**\n * Maximum number of lines to display before showing a \"Show more\" button.\n * Set to 0 (default) to disable truncation.\n * @attr max-lines\n */\n @property({ type: Number, attribute: 'max-lines', reflect: true })\n maxLines: number = 0;\n\n /**\n * When true, prepends line numbers to each displayed line in block mode.\n * Line numbers are rendered as `aria-hidden` spans so screen readers skip them.\n * @attr line-numbers\n */\n @property({ type: Boolean, attribute: 'line-numbers', reflect: true })\n lineNumbers: boolean = false;\n\n // ─── Internal State ───\n\n @state() private _copied: boolean = false;\n @state() private _expanded: boolean = false;\n @state() private _codeText: string = '';\n\n private _copyTimer: ReturnType<typeof setTimeout> | null = null;\n\n // ─── Lifecycle ───\n\n override firstUpdated(): void {\n // Prevent flash of empty <code> before slotchange fires by eagerly reading\n // text content from host children that are already present on first render.\n if (!this._codeText) {\n const text = this.textContent?.trim() ?? '';\n if (text) {\n this._codeText = text;\n }\n }\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n if (this._copyTimer !== null) {\n clearTimeout(this._copyTimer);\n this._copyTimer = null;\n }\n }\n\n // ─── Event Handlers ───\n\n private _handleSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement | null;\n if (!slot) return;\n const nodes = slot.assignedNodes({ flatten: true });\n this._codeText = nodes.map((n) => n.textContent ?? '').join('');\n }\n\n private _handleCopy(): void {\n const text = this._codeText;\n\n navigator.clipboard.writeText(text).catch(() => {\n // Clipboard API unavailable (non-HTTPS environments such as Drupal staging) — emit event only.\n // Note: navigator.clipboard requires a secure context (HTTPS or localhost).\n // On HTTP, the copy event still fires but the clipboard is not populated.\n });\n\n this.dispatchEvent(\n new CustomEvent('hx-copy', {\n bubbles: true,\n composed: true,\n detail: { text },\n }),\n );\n\n this._copied = true;\n if (this._copyTimer !== null) clearTimeout(this._copyTimer);\n this._copyTimer = setTimeout(() => {\n this._copied = false;\n }, 2000);\n }\n\n private _handleExpand(): void {\n this._expanded = !this._expanded;\n }\n\n // ─── Helpers ───\n\n private _getDisplayLines(): string[] {\n const lines = this._codeText.split('\\n');\n if (!this.maxLines || this.maxLines <= 0 || this._expanded) {\n return lines;\n }\n if (lines.length <= this.maxLines) {\n return lines;\n }\n return lines.slice(0, this.maxLines);\n }\n\n private _isTruncated(): boolean {\n if (!this.maxLines || this.maxLines <= 0) return false;\n const lines = this._codeText.split('\\n');\n return lines.length > this.maxLines;\n }\n\n private _renderLines(lines: string[]): TemplateResult {\n if (!this.lineNumbers) {\n return html`${lines.join('\\n')}`;\n }\n return html`${lines.map(\n (line, i) =>\n html`<span aria-hidden=\"true\" class=\"code-snippet__line-number\">${i + 1}</span>${line +\n '\\n'}`,\n )}`;\n }\n\n // ─── Render ───\n\n override render(): TemplateResult | typeof nothing {\n if (this.inline) {\n return html`\n <code part=\"base code\" class=\"code-snippet code-snippet--inline\">\n <slot @slotchange=${this._handleSlotChange}></slot>\n </code>\n `;\n }\n\n const displayLines = this._getDisplayLines();\n const truncated = this._isTruncated();\n const preLabel = this.language ? `Code snippet: ${this.language}` : 'Code snippet';\n const codeClasses = classMap({\n 'code-snippet__code': true,\n [`language-${this.language}`]: Boolean(this.language),\n });\n\n return html`\n <div part=\"base\" class=\"code-snippet\">\n <div part=\"header\" class=\"code-snippet__header\">\n ${this.copyable\n ? html`\n <button\n part=\"copy-button\"\n class=\"code-snippet__copy-button\"\n type=\"button\"\n aria-label=${this._copied ? 'Copied!' : 'Copy code'}\n @click=${this._handleCopy}\n >\n ${this._copied ? 'Copied!' : 'Copy'}\n </button>\n `\n : nothing}\n </div>\n\n <!-- Visually-hidden live region announces copy confirmation to assistive technology -->\n <span\n aria-live=\"polite\"\n style=\"position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0;\"\n >${this._copied ? 'Copied!' : ''}</span\n >\n\n <pre\n role=\"region\"\n aria-label=${preLabel}\n class=${classMap({\n 'code-snippet__pre': true,\n 'code-snippet__pre--wrap': this.wrap,\n })}\n ><code part=\"code\" class=${codeClasses}>${this._renderLines(displayLines)}</code></pre>\n\n <!-- Hidden slot to capture text content for display and copy -->\n <slot class=\"code-snippet__slot\" @slotchange=${this._handleSlotChange}></slot>\n\n ${truncated\n ? html`\n <button\n part=\"expand-button\"\n class=\"code-snippet__expand-button\"\n type=\"button\"\n aria-expanded=${this._expanded ? 'true' : 'false'}\n @click=${this._handleExpand}\n >\n ${this._expanded ? 'Show less' : 'Show more'}\n </button>\n `\n : nothing}\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-code-snippet': HelixCodeSnippet;\n }\n}\n"],"names":["helixCodeSnippetStyles","css","HelixCodeSnippet","LitElement","text","_a","slot","nodes","lines","html","line","i","displayLines","truncated","preLabel","codeClasses","classMap","nothing","tokenStyles","__decorateClass","property","state","customElement"],"mappings":"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"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { css as H, LitElement as O, html as p, nothing as k } from "lit";
|
|
2
|
-
import { property as m, state as F, customElement as
|
|
2
|
+
import { property as m, state as F, customElement as E } from "lit/decorators.js";
|
|
3
3
|
import { styleMap as v } from "lit/directives/style-map.js";
|
|
4
|
-
import { tokenStyles as
|
|
5
|
-
const
|
|
4
|
+
import { tokenStyles as G } from "@helixui/tokens/lit";
|
|
5
|
+
const V = H`
|
|
6
6
|
:host {
|
|
7
7
|
display: inline-block;
|
|
8
8
|
position: relative;
|
|
@@ -294,10 +294,10 @@ const I = H`
|
|
|
294
294
|
}
|
|
295
295
|
}
|
|
296
296
|
`;
|
|
297
|
-
var
|
|
298
|
-
for (var
|
|
299
|
-
(o = t[s]) && (
|
|
300
|
-
return
|
|
297
|
+
var I = Object.defineProperty, U = Object.getOwnPropertyDescriptor, c = (t, e, r, i) => {
|
|
298
|
+
for (var a = i > 1 ? void 0 : i ? U(e, r) : e, s = t.length - 1, o; s >= 0; s--)
|
|
299
|
+
(o = t[s]) && (a = (i ? o(e, r, a) : o(a)) || a);
|
|
300
|
+
return i && a && I(e, r, a), a;
|
|
301
301
|
};
|
|
302
302
|
function g(t, e, r) {
|
|
303
303
|
return Math.max(e, Math.min(r, t));
|
|
@@ -321,55 +321,55 @@ function T(t, e) {
|
|
|
321
321
|
return e && t.a < 1 ? r + $(t.a * 255) : r;
|
|
322
322
|
}
|
|
323
323
|
function S(t) {
|
|
324
|
-
const e = t.r / 255, r = t.g / 255,
|
|
324
|
+
const e = t.r / 255, r = t.g / 255, i = t.b / 255, a = Math.max(e, r, i), s = Math.min(e, r, i), o = a - s, h = a === 0 ? 0 : o / a, l = a;
|
|
325
325
|
let n = 0;
|
|
326
|
-
return o !== 0 && (
|
|
326
|
+
return o !== 0 && (a === e ? n = ((r - i) / o + (r < i ? 6 : 0)) / 6 : a === r ? n = ((i - e) / o + 2) / 6 : n = ((e - r) / o + 4) / 6), { h: n * 360, s: h * 100, v: l * 100, a: t.a };
|
|
327
327
|
}
|
|
328
328
|
function D(t) {
|
|
329
|
-
const e = t.h / 360, r = t.s / 100,
|
|
329
|
+
const e = t.h / 360, r = t.s / 100, i = t.v / 100, a = Math.floor(e * 6), s = e * 6 - a, o = i * (1 - r), h = i * (1 - s * r), l = i * (1 - (1 - s) * r);
|
|
330
330
|
let n = 0, u = 0, f = 0;
|
|
331
|
-
switch (
|
|
331
|
+
switch (a % 6) {
|
|
332
332
|
case 0:
|
|
333
|
-
n =
|
|
333
|
+
n = i, u = l, f = o;
|
|
334
334
|
break;
|
|
335
335
|
case 1:
|
|
336
|
-
n = h, u =
|
|
336
|
+
n = h, u = i, f = o;
|
|
337
337
|
break;
|
|
338
338
|
case 2:
|
|
339
|
-
n = o, u =
|
|
339
|
+
n = o, u = i, f = l;
|
|
340
340
|
break;
|
|
341
341
|
case 3:
|
|
342
|
-
n = o, u = h, f =
|
|
342
|
+
n = o, u = h, f = i;
|
|
343
343
|
break;
|
|
344
344
|
case 4:
|
|
345
|
-
n = l, u = o, f =
|
|
345
|
+
n = l, u = o, f = i;
|
|
346
346
|
break;
|
|
347
347
|
case 5:
|
|
348
|
-
n =
|
|
348
|
+
n = i, u = o, f = h;
|
|
349
349
|
break;
|
|
350
350
|
}
|
|
351
351
|
return { r: Math.round(n * 255), g: Math.round(u * 255), b: Math.round(f * 255), a: t.a };
|
|
352
352
|
}
|
|
353
353
|
function z(t) {
|
|
354
|
-
const e = t.r / 255, r = t.g / 255,
|
|
354
|
+
const e = t.r / 255, r = t.g / 255, i = t.b / 255, a = Math.max(e, r, i), s = Math.min(e, r, i), o = (a + s) / 2;
|
|
355
355
|
let h = 0, l = 0;
|
|
356
|
-
if (
|
|
357
|
-
const n =
|
|
358
|
-
l = o > 0.5 ? n / (2 -
|
|
356
|
+
if (a !== s) {
|
|
357
|
+
const n = a - s;
|
|
358
|
+
l = o > 0.5 ? n / (2 - a - s) : n / (a + s), a === e ? h = ((r - i) / n + (r < i ? 6 : 0)) / 6 : a === r ? h = ((i - e) / n + 2) / 6 : h = ((e - r) / n + 4) / 6;
|
|
359
359
|
}
|
|
360
360
|
return { h: h * 360, s: l * 100, l: o * 100, a: t.a };
|
|
361
361
|
}
|
|
362
362
|
function P(t) {
|
|
363
363
|
if (!t) return null;
|
|
364
364
|
if (t.startsWith("#")) {
|
|
365
|
-
const
|
|
366
|
-
return
|
|
365
|
+
const a = R(t);
|
|
366
|
+
return a ? S(a) : null;
|
|
367
367
|
}
|
|
368
368
|
const e = t.match(/rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)(?:\s*,\s*([\d.]+))?\s*\)/);
|
|
369
369
|
if (e) {
|
|
370
|
-
const [,
|
|
370
|
+
const [, a, s, o, h] = e;
|
|
371
371
|
return S({
|
|
372
|
-
r: parseInt(
|
|
372
|
+
r: parseInt(a ?? "0", 10),
|
|
373
373
|
g: parseInt(s ?? "0", 10),
|
|
374
374
|
b: parseInt(o ?? "0", 10),
|
|
375
375
|
a: h !== void 0 ? parseFloat(h) : 1
|
|
@@ -379,22 +379,22 @@ function P(t) {
|
|
|
379
379
|
/hsla?\(\s*([\d.]+)\s*,\s*([\d.]+)%\s*,\s*([\d.]+)%(?:\s*,\s*([\d.]+))?\s*\)/
|
|
380
380
|
);
|
|
381
381
|
if (r) {
|
|
382
|
-
const [,
|
|
382
|
+
const [, a, s, o, h] = r, l = parseFloat(a ?? "0"), n = parseFloat(s ?? "0") / 100, u = parseFloat(o ?? "0") / 100, f = h !== void 0 ? parseFloat(h) : 1, b = (1 - Math.abs(2 * u - 1)) * n, _ = b * (1 - Math.abs(l / 60 % 2 - 1)), M = u - b / 2;
|
|
383
383
|
let x = 0, w = 0, y = 0;
|
|
384
384
|
return l < 60 ? (x = b, w = _) : l < 120 ? (x = _, w = b) : l < 180 ? (w = b, y = _) : l < 240 ? (w = _, y = b) : l < 300 ? (x = _, y = b) : (x = b, y = _), S({
|
|
385
|
-
r: Math.round((x +
|
|
386
|
-
g: Math.round((w +
|
|
387
|
-
b: Math.round((y +
|
|
385
|
+
r: Math.round((x + M) * 255),
|
|
386
|
+
g: Math.round((w + M) * 255),
|
|
387
|
+
b: Math.round((y + M) * 255),
|
|
388
388
|
a: f
|
|
389
389
|
});
|
|
390
390
|
}
|
|
391
|
-
const
|
|
391
|
+
const i = t.match(
|
|
392
392
|
/hsva?\(\s*([\d.]+)\s*,\s*([\d.]+)%\s*,\s*([\d.]+)%(?:\s*,\s*([\d.]+))?\s*\)/
|
|
393
393
|
);
|
|
394
|
-
if (
|
|
395
|
-
const [,
|
|
394
|
+
if (i) {
|
|
395
|
+
const [, a, s, o, h] = i;
|
|
396
396
|
return {
|
|
397
|
-
h: parseFloat(
|
|
397
|
+
h: parseFloat(a ?? "0"),
|
|
398
398
|
s: parseFloat(s ?? "0"),
|
|
399
399
|
v: parseFloat(o ?? "0"),
|
|
400
400
|
a: h !== void 0 ? parseFloat(h) : 1
|
|
@@ -402,16 +402,16 @@ function P(t) {
|
|
|
402
402
|
}
|
|
403
403
|
return null;
|
|
404
404
|
}
|
|
405
|
-
function
|
|
406
|
-
const
|
|
405
|
+
function C(t, e, r) {
|
|
406
|
+
const i = D(t);
|
|
407
407
|
switch (e) {
|
|
408
408
|
case "hex":
|
|
409
|
-
return T(
|
|
409
|
+
return T(i, r);
|
|
410
410
|
case "rgb":
|
|
411
|
-
return r && t.a < 1 ? `rgba(${
|
|
411
|
+
return r && t.a < 1 ? `rgba(${i.r}, ${i.g}, ${i.b}, ${Math.round(t.a * 100) / 100})` : `rgb(${i.r}, ${i.g}, ${i.b})`;
|
|
412
412
|
case "hsl": {
|
|
413
|
-
const
|
|
414
|
-
return r && t.a < 1 ? `hsla(${Math.round(
|
|
413
|
+
const a = z(i);
|
|
414
|
+
return r && t.a < 1 ? `hsla(${Math.round(a.h)}, ${Math.round(a.s)}%, ${Math.round(a.l)}%, ${Math.round(t.a * 100) / 100})` : `hsl(${Math.round(a.h)}, ${Math.round(a.s)}%, ${Math.round(a.l)}%)`;
|
|
415
415
|
}
|
|
416
416
|
case "hsv":
|
|
417
417
|
return r && t.a < 1 ? `hsva(${Math.round(t.h)}, ${Math.round(t.s)}%, ${Math.round(t.v)}%, ${Math.round(t.a * 100) / 100})` : `hsv(${Math.round(t.h)}, ${Math.round(t.s)}%, ${Math.round(t.v)}%)`;
|
|
@@ -434,19 +434,17 @@ let d = class extends O {
|
|
|
434
434
|
// ─── Sync ────────────────────────────────────────────────────────────────
|
|
435
435
|
_syncFromValue() {
|
|
436
436
|
const t = P(this.value);
|
|
437
|
-
t && (this._hsv = t), this._inputValue =
|
|
437
|
+
t && (this._hsv = t), this._inputValue = C(this._hsv, this.format, this.opacity), this._internals.setFormValue(this.value);
|
|
438
438
|
}
|
|
439
439
|
_commit(t) {
|
|
440
|
-
const e =
|
|
440
|
+
const e = C(this._hsv, this.format, this.opacity);
|
|
441
441
|
this.value = e, this._inputValue = e, this._internals.setFormValue(e);
|
|
442
|
-
const
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
})
|
|
449
|
-
);
|
|
442
|
+
const i = {
|
|
443
|
+
bubbles: !0,
|
|
444
|
+
composed: !0,
|
|
445
|
+
detail: { value: e }
|
|
446
|
+
};
|
|
447
|
+
t === "drag" ? this.dispatchEvent(new CustomEvent("hx-input", i)) : this.dispatchEvent(new CustomEvent("hx-change", i));
|
|
450
448
|
}
|
|
451
449
|
// ─── Panel open/close ────────────────────────────────────────────────────
|
|
452
450
|
_show() {
|
|
@@ -473,8 +471,8 @@ let d = class extends O {
|
|
|
473
471
|
var s;
|
|
474
472
|
const e = (s = this.shadowRoot) == null ? void 0 : s.querySelector('[part="grid"]');
|
|
475
473
|
if (!e) return;
|
|
476
|
-
const r = e.getBoundingClientRect(),
|
|
477
|
-
this._hsv = { ...this._hsv, s:
|
|
474
|
+
const r = e.getBoundingClientRect(), i = g((t.clientX - r.left) / r.width, 0, 1), a = g((t.clientY - r.top) / r.height, 0, 1);
|
|
475
|
+
this._hsv = { ...this._hsv, s: i * 100, v: (1 - a) * 100 }, this._commit("drag"), this.requestUpdate();
|
|
478
476
|
}
|
|
479
477
|
// P0-1: Keyboard support for gradient grid — fixes WCAG 2.1 SC 2.1.1 failure
|
|
480
478
|
_handleGridKeydown(t) {
|
|
@@ -503,22 +501,22 @@ let d = class extends O {
|
|
|
503
501
|
this.disabled || (t.preventDefault(), this._draggingHue = !0, t.currentTarget.setPointerCapture(t.pointerId), this._updateHueFromPointer(t));
|
|
504
502
|
}
|
|
505
503
|
_updateHueFromPointer(t) {
|
|
506
|
-
var
|
|
507
|
-
const e = (
|
|
504
|
+
var a;
|
|
505
|
+
const e = (a = this.shadowRoot) == null ? void 0 : a.querySelector('[part="hue-slider"]');
|
|
508
506
|
if (!e) return;
|
|
509
|
-
const r = e.getBoundingClientRect(),
|
|
510
|
-
this._hsv = { ...this._hsv, h:
|
|
507
|
+
const r = e.getBoundingClientRect(), i = g((t.clientX - r.left) / r.width, 0, 1);
|
|
508
|
+
this._hsv = { ...this._hsv, h: i * 360 }, this._commit("drag"), this.requestUpdate();
|
|
511
509
|
}
|
|
512
510
|
// ─── Opacity slider dragging ──────────────────────────────────────────────
|
|
513
511
|
_handleOpacityPointerDown(t) {
|
|
514
512
|
this.disabled || (t.preventDefault(), this._draggingOpacity = !0, t.currentTarget.setPointerCapture(t.pointerId), this._updateOpacityFromPointer(t));
|
|
515
513
|
}
|
|
516
514
|
_updateOpacityFromPointer(t) {
|
|
517
|
-
var
|
|
518
|
-
const e = (
|
|
515
|
+
var a;
|
|
516
|
+
const e = (a = this.shadowRoot) == null ? void 0 : a.querySelector('[part="opacity-slider"]');
|
|
519
517
|
if (!e) return;
|
|
520
|
-
const r = e.getBoundingClientRect(),
|
|
521
|
-
this._hsv = { ...this._hsv, a }, this._commit("drag"), this.requestUpdate();
|
|
518
|
+
const r = e.getBoundingClientRect(), i = g((t.clientX - r.left) / r.width, 0, 1);
|
|
519
|
+
this._hsv = { ...this._hsv, a: i }, this._commit("drag"), this.requestUpdate();
|
|
522
520
|
}
|
|
523
521
|
// ─── Document-level pointer handlers ─────────────────────────────────────
|
|
524
522
|
_handlePointerMove(t) {
|
|
@@ -566,11 +564,11 @@ let d = class extends O {
|
|
|
566
564
|
}
|
|
567
565
|
_handleInputBlur(t) {
|
|
568
566
|
const e = t.target, r = P(e.value.trim());
|
|
569
|
-
r ? (this._hsv = r, this._commit("change")) : this._inputValue =
|
|
567
|
+
r ? (this._hsv = r, this._commit("change")) : this._inputValue = C(this._hsv, this.format, this.opacity);
|
|
570
568
|
}
|
|
571
569
|
_handleFormatCycle() {
|
|
572
570
|
const t = ["hex", "rgb", "hsl", "hsv"], e = t.indexOf(this.format), r = t[(e + 1) % t.length];
|
|
573
|
-
r !== void 0 && (this.format = r), this._inputValue =
|
|
571
|
+
r !== void 0 && (this.format = r), this._inputValue = C(this._hsv, this.format, this.opacity);
|
|
574
572
|
}
|
|
575
573
|
// ─── Swatches ────────────────────────────────────────────────────────────
|
|
576
574
|
_handleSwatchClick(t) {
|
|
@@ -637,7 +635,7 @@ let d = class extends O {
|
|
|
637
635
|
}
|
|
638
636
|
_renderOpacitySlider() {
|
|
639
637
|
if (!this.opacity) return k;
|
|
640
|
-
const t = `${this._hsv.a * 100}%`, e = D(this._hsv), r = `rgba(${e.r}, ${e.g}, ${e.b}, ${this._hsv.a})`,
|
|
638
|
+
const t = `${this._hsv.a * 100}%`, e = D(this._hsv), r = `rgba(${e.r}, ${e.g}, ${e.b}, ${this._hsv.a})`, i = this._hueColor();
|
|
641
639
|
return p`
|
|
642
640
|
<div
|
|
643
641
|
part="slider opacity-slider"
|
|
@@ -649,7 +647,7 @@ let d = class extends O {
|
|
|
649
647
|
aria-valuemax="100"
|
|
650
648
|
aria-valuenow=${Math.round(this._hsv.a * 100)}
|
|
651
649
|
aria-valuetext="${Math.round(this._hsv.a * 100)}%"
|
|
652
|
-
style=${v({ "--_hue-color":
|
|
650
|
+
style=${v({ "--_hue-color": i })}
|
|
653
651
|
@pointerdown=${this._handleOpacityPointerDown}
|
|
654
652
|
@keydown=${this._handleOpacityKeydown}
|
|
655
653
|
>
|
|
@@ -751,7 +749,7 @@ let d = class extends O {
|
|
|
751
749
|
`;
|
|
752
750
|
}
|
|
753
751
|
};
|
|
754
|
-
d.styles = [
|
|
752
|
+
d.styles = [G, V];
|
|
755
753
|
d.formAssociated = !0;
|
|
756
754
|
c([
|
|
757
755
|
m({ type: String, reflect: !0 })
|
|
@@ -787,9 +785,9 @@ c([
|
|
|
787
785
|
F()
|
|
788
786
|
], d.prototype, "_inputValue", 2);
|
|
789
787
|
d = c([
|
|
790
|
-
|
|
788
|
+
E("hx-color-picker")
|
|
791
789
|
], d);
|
|
792
790
|
export {
|
|
793
791
|
d as H
|
|
794
792
|
};
|
|
795
|
-
//# sourceMappingURL=hx-color-picker-
|
|
793
|
+
//# sourceMappingURL=hx-color-picker-K2x_dyeG.js.map
|