@helixui/library 3.2.0 → 3.3.0-next.112
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 +175 -326
- package/dist/components/hx-accordion/hx-accordion-item.styles.d.ts.map +1 -1
- package/dist/components/hx-accordion/index.js +1 -1
- package/dist/components/hx-alert/hx-alert.styles.d.ts.map +1 -1
- package/dist/components/hx-alert/index.js +1 -1
- package/dist/components/hx-banner/hx-banner.styles.d.ts.map +1 -1
- package/dist/components/hx-banner/index.js +1 -1
- package/dist/components/hx-breadcrumb/hx-breadcrumb-item.styles.d.ts.map +1 -1
- package/dist/components/hx-breadcrumb/index.js +1 -1
- package/dist/components/hx-button/hx-button.d.ts +46 -49
- 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-card/hx-card.styles.d.ts.map +1 -1
- package/dist/components/hx-card/index.js +1 -1
- package/dist/components/hx-carousel/index.js +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-clinical-status/hx-clinical-status.styles.d.ts.map +1 -1
- package/dist/components/hx-clinical-status/index.js +1 -1
- package/dist/components/hx-code-snippet/hx-code-snippet.styles.d.ts.map +1 -1
- package/dist/components/hx-code-snippet/index.js +1 -1
- package/dist/components/hx-color-picker/hx-color-picker.styles.d.ts.map +1 -1
- package/dist/components/hx-color-picker/index.js +1 -1
- package/dist/components/hx-combobox/hx-combobox.styles.d.ts.map +1 -1
- package/dist/components/hx-combobox/index.js +1 -1
- package/dist/components/hx-data-table/hx-data-table.styles.d.ts.map +1 -1
- package/dist/components/hx-data-table/index.js +1 -1
- package/dist/components/hx-date-picker/hx-date-picker.styles.d.ts.map +1 -1
- package/dist/components/hx-date-picker/index.js +1 -1
- package/dist/components/hx-dialog/hx-dialog.styles.d.ts.map +1 -1
- package/dist/components/hx-dialog/index.js +1 -1
- package/dist/components/hx-drawer/hx-drawer.styles.d.ts.map +1 -1
- package/dist/components/hx-drawer/index.js +1 -1
- package/dist/components/hx-file-upload/hx-file-upload.styles.d.ts.map +1 -1
- package/dist/components/hx-file-upload/index.js +1 -1
- package/dist/components/hx-icon-button/hx-icon-button.styles.d.ts.map +1 -1
- package/dist/components/hx-icon-button/index.js +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-list/hx-list-item.styles.d.ts.map +1 -1
- package/dist/components/hx-list/index.js +1 -1
- package/dist/components/hx-menu/hx-menu-item.styles.d.ts.map +1 -1
- package/dist/components/hx-menu/index.js +1 -1
- package/dist/components/hx-meter/hx-meter.styles.d.ts.map +1 -1
- package/dist/components/hx-meter/index.js +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-overflow-menu/hx-overflow-menu.styles.d.ts.map +1 -1
- package/dist/components/hx-overflow-menu/index.js +1 -1
- package/dist/components/hx-pagination/hx-pagination.styles.d.ts.map +1 -1
- package/dist/components/hx-pagination/index.js +1 -1
- package/dist/components/hx-phi-field/hx-phi-field.styles.d.ts.map +1 -1
- package/dist/components/hx-phi-field/index.js +1 -1
- package/dist/components/hx-popover/hx-popover.styles.d.ts.map +1 -1
- package/dist/components/hx-popover/index.js +1 -1
- package/dist/components/hx-radio-group/hx-radio.styles.d.ts.map +1 -1
- package/dist/components/hx-radio-group/index.js +1 -1
- package/dist/components/hx-rating/hx-rating.styles.d.ts.map +1 -1
- package/dist/components/hx-rating/index.js +1 -1
- package/dist/components/hx-select/hx-select.styles.d.ts.map +1 -1
- package/dist/components/hx-select/index.js +1 -1
- package/dist/components/hx-side-nav/hx-nav-item.d.ts +7 -5
- package/dist/components/hx-side-nav/hx-nav-item.d.ts.map +1 -1
- package/dist/components/hx-side-nav/hx-nav-item.styles.d.ts.map +1 -1
- package/dist/components/hx-side-nav/hx-side-nav.d.ts +10 -23
- package/dist/components/hx-side-nav/hx-side-nav.d.ts.map +1 -1
- package/dist/components/hx-side-nav/hx-side-nav.styles.d.ts.map +1 -1
- package/dist/components/hx-side-nav/index.js +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-button/hx-split-button.d.ts +1 -1
- package/dist/components/hx-split-button/hx-split-button.styles.d.ts.map +1 -1
- package/dist/components/hx-split-button/index.js +1 -1
- package/dist/components/hx-split-panel/hx-split-panel.styles.d.ts.map +1 -1
- package/dist/components/hx-split-panel/index.js +1 -1
- package/dist/components/hx-steps/hx-step.styles.d.ts.map +1 -1
- package/dist/components/hx-steps/index.js +1 -1
- package/dist/components/hx-switch/hx-switch.styles.d.ts.map +1 -1
- package/dist/components/hx-switch/index.js +1 -1
- package/dist/components/hx-table/hx-table.styles.d.ts.map +1 -1
- package/dist/components/hx-table/index.js +1 -1
- package/dist/components/hx-tabs/hx-tab-panel.styles.d.ts.map +1 -1
- package/dist/components/hx-tabs/hx-tab.styles.d.ts.map +1 -1
- package/dist/components/hx-tabs/index.js +1 -1
- package/dist/components/hx-text-input/hx-text-input.d.ts +18 -35
- package/dist/components/hx-text-input/hx-text-input.d.ts.map +1 -1
- package/dist/components/hx-text-input/hx-text-input.styles.d.ts.map +1 -1
- package/dist/components/hx-text-input/index.js +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/components/hx-theme/hx-theme.d.ts +14 -2
- package/dist/components/hx-theme/hx-theme.d.ts.map +1 -1
- package/dist/components/hx-theme/index.js +1 -1
- package/dist/components/hx-time-picker/index.js +1 -1
- package/dist/components/hx-toast/hx-toast.d.ts +12 -8
- package/dist/components/hx-toast/hx-toast.d.ts.map +1 -1
- package/dist/components/hx-toast/hx-toast.styles.d.ts.map +1 -1
- package/dist/components/hx-toast/index.js +1 -1
- package/dist/components/hx-toggle-button/hx-toggle-button.styles.d.ts.map +1 -1
- package/dist/components/hx-toggle-button/index.js +1 -1
- package/dist/components/hx-top-nav/hx-top-nav.styles.d.ts.map +1 -1
- package/dist/components/hx-top-nav/index.js +1 -1
- package/dist/components/hx-tree-view/hx-tree-item.styles.d.ts.map +1 -1
- package/dist/components/hx-tree-view/hx-tree-view.styles.d.ts.map +1 -1
- package/dist/components/hx-tree-view/index.js +1 -1
- package/dist/css/helix-all.css +351 -308
- package/dist/css/helix-core.css +180 -56
- package/dist/css/helix-data.css +23 -16
- package/dist/css/helix-feedback.css +30 -29
- package/dist/css/helix-forms.css +53 -120
- package/dist/css/helix-layout.css +2 -8
- package/dist/css/helix-media.css +3 -3
- package/dist/css/helix-navigation.css +49 -45
- package/dist/css/helix-overlay.css +3 -12
- package/dist/css/helix-tokens.css +60 -5
- package/dist/css/helix-utility.css +5 -11
- package/dist/css/hx-alert.css +1 -4
- package/dist/css/hx-banner.css +2 -8
- package/dist/css/hx-button.css +176 -43
- package/dist/css/hx-card.css +1 -4
- package/dist/css/hx-carousel.css +3 -3
- package/dist/css/hx-checkbox.css +2 -5
- package/dist/css/hx-clinical-status.css +2 -4
- package/dist/css/hx-code-snippet.css +20 -6
- package/dist/css/hx-color-picker.css +3 -13
- package/dist/css/hx-combobox.css +7 -13
- package/dist/css/hx-data-table.css +2 -8
- package/dist/css/hx-date-picker.css +7 -23
- package/dist/css/hx-dialog.css +1 -4
- package/dist/css/hx-drawer.css +1 -4
- package/dist/css/hx-file-upload.css +4 -13
- package/dist/css/hx-icon-button.css +2 -5
- package/dist/css/hx-link.css +1 -4
- package/dist/css/hx-meter.css +1 -2
- package/dist/css/hx-nav.css +2 -8
- package/dist/css/hx-overflow-menu.css +2 -8
- package/dist/css/hx-pagination.css +2 -8
- package/dist/css/hx-phi-field.css +1 -4
- package/dist/css/hx-popover.css +1 -4
- package/dist/css/hx-rating.css +3 -4
- package/dist/css/hx-select.css +3 -7
- package/dist/css/hx-side-nav.css +41 -15
- package/dist/css/hx-slider.css +4 -7
- package/dist/css/hx-split-button.css +5 -11
- package/dist/css/hx-split-panel.css +2 -8
- package/dist/css/hx-switch.css +3 -6
- package/dist/css/hx-table.css +1 -2
- package/dist/css/hx-text-input.css +8 -14
- package/dist/css/hx-textarea.css +2 -5
- package/dist/css/hx-time-picker.css +3 -3
- package/dist/css/hx-toast.css +26 -15
- package/dist/css/hx-toggle-button.css +4 -7
- package/dist/css/hx-top-nav.css +1 -4
- package/dist/css/hx-tree-view.css +1 -2
- package/dist/css/index.css +1 -1
- package/dist/css/manifest.json +63 -46
- package/dist/index.js +46 -46
- package/dist/shared/{hx-accordion-cnKg4_la.js → hx-accordion-ZVzgDzTG.js} +4 -5
- package/dist/shared/hx-accordion-ZVzgDzTG.js.map +1 -0
- package/dist/shared/{hx-alert-BZH8iHQf.js → hx-alert-CLn7CstP.js} +2 -5
- package/dist/shared/hx-alert-CLn7CstP.js.map +1 -0
- package/dist/shared/{hx-banner-DT7Zn9Bo.js → hx-banner-D3DzpfcP.js} +7 -13
- package/dist/shared/hx-banner-D3DzpfcP.js.map +1 -0
- package/dist/shared/{hx-breadcrumb-item-COeYcB2x.js → hx-breadcrumb-item-3tKppF9h.js} +2 -5
- package/dist/shared/{hx-breadcrumb-item-COeYcB2x.js.map → hx-breadcrumb-item-3tKppF9h.js.map} +1 -1
- package/dist/shared/{hx-button-modUSOpY.js → hx-button-DPY6SPVT.js} +201 -69
- package/dist/shared/hx-button-DPY6SPVT.js.map +1 -0
- package/dist/shared/{hx-card-CU1QnjNb.js → hx-card-qNAM2QNV.js} +6 -9
- package/dist/shared/hx-card-qNAM2QNV.js.map +1 -0
- package/dist/shared/{hx-carousel-item-BaE4hpLl.js → hx-carousel-item-z1Lc24op.js} +4 -4
- package/dist/shared/hx-carousel-item-z1Lc24op.js.map +1 -0
- package/dist/shared/{hx-checkbox-C46TyXhM.js → hx-checkbox-D7xma9YH.js} +7 -10
- package/dist/shared/hx-checkbox-D7xma9YH.js.map +1 -0
- package/dist/shared/{hx-clinical-status-BmSjfSEN.js → hx-clinical-status-D3XQIOqX.js} +3 -5
- package/dist/shared/hx-clinical-status-D3XQIOqX.js.map +1 -0
- package/dist/shared/{hx-code-snippet-CJ0FbQYG.js → hx-code-snippet-fVV3Z2DZ.js} +55 -41
- package/dist/shared/hx-code-snippet-fVV3Z2DZ.js.map +1 -0
- package/dist/shared/{hx-color-picker-DiDLZyvK.js → hx-color-picker-uRc865FJ.js} +23 -33
- package/dist/shared/hx-color-picker-uRc865FJ.js.map +1 -0
- package/dist/shared/{hx-combobox-DaA5dBC4.js → hx-combobox-DDzqNKEW.js} +11 -17
- package/dist/shared/hx-combobox-DDzqNKEW.js.map +1 -0
- package/dist/shared/{hx-data-table-Cq3t86Ic.js → hx-data-table-CLqVqdxr.js} +3 -9
- package/dist/shared/hx-data-table-CLqVqdxr.js.map +1 -0
- package/dist/shared/{hx-date-picker-DMqRQNSB.js → hx-date-picker-2iRG1p74.js} +14 -30
- package/dist/shared/hx-date-picker-2iRG1p74.js.map +1 -0
- package/dist/shared/{hx-dialog-eIS8tcDm.js → hx-dialog-DRN_1-Y-.js} +2 -5
- package/dist/shared/hx-dialog-DRN_1-Y-.js.map +1 -0
- package/dist/shared/{hx-drawer-DDhDz7RI.js → hx-drawer-Y1Ui2IWJ.js} +2 -5
- package/dist/shared/hx-drawer-Y1Ui2IWJ.js.map +1 -0
- package/dist/shared/{hx-file-upload-zTDbjsRw.js → hx-file-upload-D3rKROK5.js} +17 -26
- package/dist/shared/hx-file-upload-D3rKROK5.js.map +1 -0
- package/dist/shared/{hx-icon-button-BmV97nqz.js → hx-icon-button-CGNdQSFM.js} +3 -6
- package/dist/shared/hx-icon-button-CGNdQSFM.js.map +1 -0
- package/dist/shared/{hx-link-DmiV-mPw.js → hx-link-C-O6vq0Q.js} +5 -8
- package/dist/shared/hx-link-C-O6vq0Q.js.map +1 -0
- package/dist/shared/{hx-list-CkphGi9T.js → hx-list-MyEhh8c7.js} +3 -5
- package/dist/shared/hx-list-MyEhh8c7.js.map +1 -0
- package/dist/shared/{hx-menu-divider-j__TZjH2.js → hx-menu-divider-C2omnPtj.js} +2 -5
- package/dist/shared/hx-menu-divider-C2omnPtj.js.map +1 -0
- package/dist/shared/{hx-meter-Cm7k_Ro8.js → hx-meter-BPscsw5t.js} +2 -3
- package/dist/shared/hx-meter-BPscsw5t.js.map +1 -0
- package/dist/shared/{hx-nav-item-D8xHLVOs.js → hx-nav-item-xqRPOCWX.js} +172 -110
- package/dist/shared/hx-nav-item-xqRPOCWX.js.map +1 -0
- package/dist/shared/{hx-nav-LoyEKZQC.js → hx-nav-ldFM3Fle.js} +37 -43
- package/dist/shared/hx-nav-ldFM3Fle.js.map +1 -0
- package/dist/shared/{hx-overflow-menu-BmKyAp5D.js → hx-overflow-menu-DCLsdIBy.js} +3 -9
- package/dist/shared/hx-overflow-menu-DCLsdIBy.js.map +1 -0
- package/dist/shared/{hx-pagination-Dqw5dorC.js → hx-pagination-C7y8GVyU.js} +54 -60
- package/dist/shared/hx-pagination-C7y8GVyU.js.map +1 -0
- package/dist/shared/{hx-phi-field-Bf9TdtC1.js → hx-phi-field-C19oxlrr.js} +2 -5
- package/dist/shared/hx-phi-field-C19oxlrr.js.map +1 -0
- package/dist/shared/{hx-popover-B93rTAfr.js → hx-popover-B-FP3-wW.js} +8 -11
- package/dist/shared/hx-popover-B-FP3-wW.js.map +1 -0
- package/dist/shared/{hx-radio-N8xgDd_5.js → hx-radio-CJvNU2yP.js} +4 -7
- package/dist/shared/{hx-radio-N8xgDd_5.js.map → hx-radio-CJvNU2yP.js.map} +1 -1
- package/dist/shared/{hx-rating-i2FL1WUN.js → hx-rating-C3QP53k9.js} +4 -5
- package/dist/shared/hx-rating-C3QP53k9.js.map +1 -0
- package/dist/shared/{hx-select-vgaBo1Ai.js → hx-select-C8fEHQhC.js} +4 -8
- package/dist/shared/hx-select-C8fEHQhC.js.map +1 -0
- package/dist/shared/{hx-slider-ydBamYhd.js → hx-slider-Blmv_rwS.js} +26 -29
- package/dist/shared/hx-slider-Blmv_rwS.js.map +1 -0
- package/dist/shared/{hx-split-button-BeMsmS6N.js → hx-split-button-Djnc5Aeg.js} +6 -12
- package/dist/shared/hx-split-button-Djnc5Aeg.js.map +1 -0
- package/dist/shared/{hx-split-panel-BVG1VWNT.js → hx-split-panel-B-u0Z3mm.js} +3 -9
- package/dist/shared/hx-split-panel-B-u0Z3mm.js.map +1 -0
- package/dist/shared/{hx-step-DL3PbOzm.js → hx-step-R2rjp1fT.js} +2 -5
- package/dist/shared/hx-step-R2rjp1fT.js.map +1 -0
- package/dist/shared/{hx-switch-Dougzsgp.js → hx-switch-BrZFaRue.js} +8 -11
- package/dist/shared/hx-switch-BrZFaRue.js.map +1 -0
- package/dist/shared/{hx-tab-panel-CbkO9VKu.js → hx-tab-panel-DspCrKqo.js} +3 -9
- package/dist/shared/{hx-tab-panel-CbkO9VKu.js.map → hx-tab-panel-DspCrKqo.js.map} +1 -1
- package/dist/shared/{hx-td-1zwTFLRw.js → hx-td-DnnEMIuA.js} +2 -3
- package/dist/shared/hx-td-DnnEMIuA.js.map +1 -0
- package/dist/shared/{hx-text-input-B-caO5fI.js → hx-text-input-D6FlOZM-.js} +24 -31
- package/dist/shared/hx-text-input-D6FlOZM-.js.map +1 -0
- package/dist/shared/{hx-textarea-D9O4U8cb.js → hx-textarea-CNG590KY.js} +3 -6
- package/dist/shared/hx-textarea-CNG590KY.js.map +1 -0
- package/dist/shared/{hx-theme-BiyQ7UUK.js → hx-theme-BsefFWTO.js} +83 -113
- package/dist/shared/hx-theme-BsefFWTO.js.map +1 -0
- package/dist/shared/{hx-time-picker-m0z4nFB-.js → hx-time-picker-BoEIZwzv.js} +4 -4
- package/dist/shared/{hx-time-picker-m0z4nFB-.js.map → hx-time-picker-BoEIZwzv.js.map} +1 -1
- package/dist/shared/{hx-toggle-button-Dd8clXB4.js → hx-toggle-button-iLiYrMbD.js} +24 -27
- package/dist/shared/hx-toggle-button-iLiYrMbD.js.map +1 -0
- package/dist/shared/{hx-top-nav-CchPYaiV.js → hx-top-nav-DP6OFS8C.js} +11 -14
- package/dist/shared/hx-top-nav-DP6OFS8C.js.map +1 -0
- package/dist/shared/{hx-tree-item-DtMC3DTa.js → hx-tree-item-C2CiWuDE.js} +4 -11
- package/dist/shared/hx-tree-item-C2CiWuDE.js.map +1 -0
- package/dist/shared/{toast-factory-DvDRAh0l.js → toast-factory-YSznocIV.js} +66 -56
- package/dist/shared/toast-factory-YSznocIV.js.map +1 -0
- package/figma-inventory.json +283 -420
- package/package.json +2 -2
- package/dist/shared/hx-accordion-cnKg4_la.js.map +0 -1
- package/dist/shared/hx-alert-BZH8iHQf.js.map +0 -1
- package/dist/shared/hx-banner-DT7Zn9Bo.js.map +0 -1
- package/dist/shared/hx-button-modUSOpY.js.map +0 -1
- package/dist/shared/hx-card-CU1QnjNb.js.map +0 -1
- package/dist/shared/hx-carousel-item-BaE4hpLl.js.map +0 -1
- package/dist/shared/hx-checkbox-C46TyXhM.js.map +0 -1
- package/dist/shared/hx-clinical-status-BmSjfSEN.js.map +0 -1
- package/dist/shared/hx-code-snippet-CJ0FbQYG.js.map +0 -1
- package/dist/shared/hx-color-picker-DiDLZyvK.js.map +0 -1
- package/dist/shared/hx-combobox-DaA5dBC4.js.map +0 -1
- package/dist/shared/hx-data-table-Cq3t86Ic.js.map +0 -1
- package/dist/shared/hx-date-picker-DMqRQNSB.js.map +0 -1
- package/dist/shared/hx-dialog-eIS8tcDm.js.map +0 -1
- package/dist/shared/hx-drawer-DDhDz7RI.js.map +0 -1
- package/dist/shared/hx-file-upload-zTDbjsRw.js.map +0 -1
- package/dist/shared/hx-icon-button-BmV97nqz.js.map +0 -1
- package/dist/shared/hx-link-DmiV-mPw.js.map +0 -1
- package/dist/shared/hx-list-CkphGi9T.js.map +0 -1
- package/dist/shared/hx-menu-divider-j__TZjH2.js.map +0 -1
- package/dist/shared/hx-meter-Cm7k_Ro8.js.map +0 -1
- package/dist/shared/hx-nav-LoyEKZQC.js.map +0 -1
- package/dist/shared/hx-nav-item-D8xHLVOs.js.map +0 -1
- package/dist/shared/hx-overflow-menu-BmKyAp5D.js.map +0 -1
- package/dist/shared/hx-pagination-Dqw5dorC.js.map +0 -1
- package/dist/shared/hx-phi-field-Bf9TdtC1.js.map +0 -1
- package/dist/shared/hx-popover-B93rTAfr.js.map +0 -1
- package/dist/shared/hx-rating-i2FL1WUN.js.map +0 -1
- package/dist/shared/hx-select-vgaBo1Ai.js.map +0 -1
- package/dist/shared/hx-slider-ydBamYhd.js.map +0 -1
- package/dist/shared/hx-split-button-BeMsmS6N.js.map +0 -1
- package/dist/shared/hx-split-panel-BVG1VWNT.js.map +0 -1
- package/dist/shared/hx-step-DL3PbOzm.js.map +0 -1
- package/dist/shared/hx-switch-Dougzsgp.js.map +0 -1
- package/dist/shared/hx-td-1zwTFLRw.js.map +0 -1
- package/dist/shared/hx-text-input-B-caO5fI.js.map +0 -1
- package/dist/shared/hx-textarea-D9O4U8cb.js.map +0 -1
- package/dist/shared/hx-theme-BiyQ7UUK.js.map +0 -1
- package/dist/shared/hx-toggle-button-Dd8clXB4.js.map +0 -1
- package/dist/shared/hx-top-nav-CchPYaiV.js.map +0 -1
- package/dist/shared/hx-tree-item-DtMC3DTa.js.map +0 -1
- package/dist/shared/toast-factory-DvDRAh0l.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@helixui/library",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.3.0-next.112",
|
|
4
4
|
"description": "Enterprise Web Component Library built with Lit 3.x",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": [
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"customElements": "custom-elements.json",
|
|
60
60
|
"dependencies": {
|
|
61
61
|
"lit": "^3.3.2",
|
|
62
|
-
"@helixui/tokens": "3.
|
|
62
|
+
"@helixui/tokens": "3.3.0-next.112"
|
|
63
63
|
},
|
|
64
64
|
"peerDependencies": {
|
|
65
65
|
"@floating-ui/dom": "^1.7.6"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hx-accordion-cnKg4_la.js","sources":["../../src/components/hx-accordion/hx-accordion.styles.ts","../../src/components/hx-accordion/hx-accordion-item.styles.ts","../../src/components/hx-accordion/hx-accordion-item.ts","../../src/components/hx-accordion/hx-accordion.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixAccordionStyles = css`\n :host {\n display: block;\n font-family: var(--hx-accordion-font-family, var(--hx-font-family-sans, sans-serif));\n }\n\n .accordion {\n border-radius: var(--hx-accordion-border-radius, var(--hx-border-radius-md, 0.375rem));\n overflow: hidden;\n }\n\n /* ─── High Contrast Mode (forced-colors) ─── */\n\n @media (forced-colors: active) {\n .accordion {\n border: 2px solid CanvasText;\n }\n }\n`;\n","import { css } from 'lit';\n\nexport const helixAccordionItemStyles = css`\n :host {\n display: block;\n }\n\n .item {\n border-bottom: var(--hx-border-width-thin, 1px) solid\n var(--hx-accordion-border-color, var(--hx-color-neutral-200, #d6dbd5));\n font-family: var(--hx-accordion-item-font-family, var(--hx-font-family-sans, sans-serif));\n }\n\n :host(:first-child) .item {\n border-top: var(--hx-border-width-thin, 1px) solid\n var(--hx-accordion-border-color, var(--hx-color-neutral-200, #d6dbd5));\n }\n\n /* Remove native details marker */\n .trigger {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--hx-space-3, 0.75rem);\n padding: var(--hx-accordion-trigger-padding, var(--hx-space-4, 1rem));\n cursor: pointer;\n list-style: none;\n font-size: var(--hx-font-size-md, 1rem);\n font-weight: var(--hx-font-weight-semibold, 600);\n color: var(--hx-accordion-trigger-color, var(--hx-color-neutral-800, #202b39));\n background-color: var(--hx-accordion-trigger-bg, transparent);\n user-select: none;\n transition: background-color var(--hx-transition-fast, 150ms ease);\n }\n\n /* Hide the native details disclosure triangle */\n .trigger::-webkit-details-marker {\n display: none;\n }\n\n .trigger::marker {\n display: none;\n }\n\n .item--disabled .trigger {\n cursor: not-allowed;\n }\n\n :host(:not([disabled])) .trigger:hover {\n background-color: var(--hx-accordion-trigger-hover-bg, var(--hx-color-neutral-50, #f5f8f3));\n }\n\n .trigger:focus-visible {\n outline: var(--hx-focus-ring-width, 2px) solid\n var(--hx-focus-ring-color, var(--hx-color-primary-500, #429797));\n outline-offset: var(--hx-focus-ring-offset, -2px);\n }\n\n /* ─── Icon ─── */\n\n .icon {\n flex-shrink: 0;\n width: var(--hx-accordion-icon-size, var(--hx-size-5, 1.25rem));\n height: var(--hx-accordion-icon-size, var(--hx-size-5, 1.25rem));\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--hx-accordion-icon-color, var(--hx-color-neutral-500, #66787b));\n transition: transform var(--hx-transition-normal, 250ms ease);\n }\n\n .item--expanded .icon {\n transform: rotate(180deg);\n }\n\n /* ─── Content animation via CSS grid trick ─── */\n\n .content-wrapper {\n display: grid;\n grid-template-rows: 0fr;\n transition: grid-template-rows var(--hx-transition-normal, 250ms ease);\n overflow: hidden;\n }\n\n .item--expanded .content-wrapper,\n details[open]:not(.item--expanded) .content-wrapper {\n grid-template-rows: 1fr;\n }\n\n .content-inner {\n overflow: hidden;\n }\n\n .content {\n padding: var(--hx-accordion-content-padding, 0 var(--hx-space-4, 1rem) var(--hx-space-4, 1rem));\n font-size: var(--hx-font-size-md, 1rem);\n line-height: var(--hx-line-height-normal, 1.5);\n color: var(--hx-accordion-content-color, var(--hx-color-neutral-600, #4a5362));\n }\n\n /* ─── Disabled host ─── */\n\n :host([disabled]) {\n pointer-events: none;\n opacity: var(--hx-opacity-disabled, 0.5);\n }\n\n /* ─── Reduced motion ─── */\n\n @media (prefers-reduced-motion: reduce) {\n .trigger {\n transition: none;\n }\n\n .icon {\n transition: none;\n }\n\n .content-wrapper {\n transition: none;\n }\n }\n\n /* ─── High Contrast Mode (forced-colors) ─── */\n\n @media (forced-colors: active) {\n .trigger {\n forced-color-adjust: none;\n color: ButtonText;\n background-color: ButtonFace;\n }\n\n .trigger:focus-visible {\n outline: 3px solid Highlight;\n outline-offset: -2px;\n }\n\n .item {\n border-bottom-color: CanvasText;\n }\n\n :host(:first-child) .item {\n border-top-color: CanvasText;\n }\n\n .item--disabled .trigger {\n color: GrayText;\n }\n\n :host([disabled]) {\n opacity: 1;\n }\n\n .icon {\n color: ButtonText;\n }\n\n .content {\n color: CanvasText;\n }\n }\n`;\n","import { html, svg, nothing } from 'lit';\nimport '../../utilities/document-token-adoption.js';\nimport { customElement, property } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { HelixElement, createIdCounter } from '../../base/index.js';\nimport { helixAccordionItemStyles } from './hx-accordion-item.styles.js';\nimport { forcedColorsInteractive } from '../../styles/forced-colors.js';\nimport { devWarn } from '../../utils/dev-warn.js';\n\nconst chevronIcon = svg`\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"6 9 12 15 18 9\"></polyline>\n </svg>\n`;\n\nconst _nextAccordionItemId = createIdCounter('hx-accordion-item');\n\n/** Detail for hx-expand and hx-collapse events dispatched by hx-accordion-item. */\nexport interface HxAccordionToggleDetail {\n expanded: boolean;\n itemId: string;\n}\n\n/**\n * An individual accordion item with collapsible content.\n *\n * @summary Collapsible panel that can be expanded or collapsed.\n *\n * @tag hx-accordion-item\n *\n * @slot trigger - The heading/trigger content for this item.\n * @slot - Default slot for the collapsible body content.\n *\n * @attr {number} level - Heading level (1–6) for the trigger via `role=\"heading\" aria-level`.\n * Defaults to 3. Set this to match the document outline — e.g., use `level=\"2\"` when the\n * accordion appears under an `<h1>` landmark.\n *\n * @fires {CustomEvent<{expanded: boolean, itemId: string}>} hx-expand - Dispatched when the item is expanded.\n * @fires {CustomEvent<{expanded: boolean, itemId: string}>} hx-collapse - Dispatched when the item is collapsed.\n *\n * @csspart item - The outer details element container.\n * @csspart trigger - The summary/trigger element.\n * @csspart content - The collapsible content area.\n * @csspart icon - The expand/collapse icon.\n *\n * @cssprop [--hx-accordion-border-color=var(--hx-color-neutral-200)] - Border color between items.\n * @cssprop [--hx-accordion-trigger-padding=var(--hx-space-4)] - Trigger padding.\n * @cssprop [--hx-accordion-trigger-color=var(--hx-color-neutral-800)] - Trigger text color.\n * @cssprop [--hx-accordion-trigger-bg=transparent] - Trigger background color.\n * @cssprop [--hx-accordion-trigger-hover-bg=var(--hx-color-neutral-50)] - Trigger hover background.\n * @cssprop [--hx-accordion-icon-color=var(--hx-color-neutral-500)] - Icon color.\n * @cssprop [--hx-accordion-content-padding=0 var(--hx-space-4) var(--hx-space-4)] - Content padding.\n * @cssprop [--hx-accordion-content-color=var(--hx-color-neutral-600)] - Content text color.\n */\n@customElement('hx-accordion-item')\nexport class HelixAccordionItem extends HelixElement {\n static override styles = [helixAccordionItemStyles, forcedColorsInteractive];\n\n /** @internal */\n private _uid = _nextAccordionItemId();\n\n /**\n * Whether this item is expanded.\n * @attr expanded\n */\n @property({ type: Boolean, reflect: true })\n expanded = false;\n\n /**\n * Whether this item is disabled (cannot be toggled).\n * @attr disabled\n */\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /**\n * Heading level (1–6) applied via `role=\"heading\" aria-level` on the summary\n * trigger. Defaults to 3. Set to match the document outline around the\n * accordion so screen readers surface accordion items in the heading list.\n * @attr level\n */\n @property({ type: Number })\n level: 1 | 2 | 3 | 4 | 5 | 6 = 3;\n\n // ─── Lifecycle ───\n\n override connectedCallback(): void {\n super.connectedCallback();\n if (!this.closest('hx-accordion')) {\n devWarn(\n 'hx-accordion-item',\n 'Used outside hx-accordion. Single-expand coordination will not function.',\n );\n }\n }\n\n // ─── Slot Handlers ───\n\n /** @internal */\n private _handleTriggerSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n const hasContent = slot.assignedNodes({ flatten: true }).length > 0;\n if (!hasContent) {\n devWarn(\n 'hx-accordion-item',\n 'trigger slot is empty — provide a visible label for keyboard and screen reader users.',\n );\n }\n }\n\n // ─── Heading Level Helper ───\n\n /**\n * Returns a clamped heading level (1–6) for use as `aria-level` on the\n * `<summary>` element. Per the WAI-ARIA APG Accordion pattern, the\n * `<summary>` must be a **direct child** of `<details>` for native\n * disclosure behaviour to work. Instead of wrapping `<summary>` inside\n * an `<h3>` (which breaks the native toggle), we apply\n * `role=\"heading\" aria-level=\"N\"` directly on `<summary>`.\n */\n /** @internal */\n private get _headingLevel(): number {\n return Math.max(1, Math.min(6, this.level));\n }\n\n // ─── Toggle Logic ───\n\n /** @internal */\n private _toggle(): void {\n if (this.disabled) return;\n\n const willExpand = !this.expanded;\n this.expanded = willExpand;\n\n this._dispatchToggleEvent(willExpand);\n }\n\n /** @internal */\n _dispatchToggleEvent(expanded: boolean): void {\n const detail = { expanded, itemId: this.id || '' };\n const options = { bubbles: true, composed: true, detail };\n\n if (expanded) {\n this.dispatchEvent(\n new CustomEvent<{ expanded: boolean; itemId: string }>('hx-expand', options),\n );\n } else {\n this.dispatchEvent(\n new CustomEvent<{ expanded: boolean; itemId: string }>('hx-collapse', options),\n );\n }\n }\n\n // ─── Event Handlers ───\n\n /** @internal */\n private _handleSummaryClick(e: MouseEvent): void {\n e.preventDefault();\n this._toggle();\n }\n\n /** @internal */\n private _handleKeyDown(e: KeyboardEvent): void {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n this._toggle();\n }\n }\n\n // ─── Render ───\n\n override render() {\n const itemClasses = {\n item: true,\n 'item--expanded': this.expanded,\n 'item--disabled': this.disabled,\n };\n\n return html`\n <details part=\"item\" class=${classMap(itemClasses)} ?open=${this.expanded}>\n <summary\n id=${`${this._uid}-trigger`}\n part=\"trigger\"\n class=\"trigger\"\n role=\"heading\"\n aria-level=${this._headingLevel}\n tabindex=${this.disabled ? '-1' : '0'}\n aria-expanded=${this.expanded ? 'true' : 'false'}\n aria-disabled=${this.disabled ? 'true' : nothing}\n aria-controls=${`${this._uid}-content`}\n @click=${this._handleSummaryClick}\n @keydown=${this._handleKeyDown}\n >\n <slot name=\"trigger\" @slotchange=${this._handleTriggerSlotChange}></slot>\n <span part=\"icon\" class=\"icon\">${chevronIcon}</span>\n </summary>\n <div class=\"content-wrapper\">\n <div class=\"content-inner\">\n <div\n id=${`${this._uid}-content`}\n part=\"content\"\n class=\"content\"\n role=\"region\"\n aria-labelledby=${`${this._uid}-trigger`}\n aria-hidden=${this.expanded ? nothing : 'true'}\n >\n <slot></slot>\n </div>\n </div>\n </div>\n </details>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-accordion-item': HelixAccordionItem;\n }\n}\n","import { html, type PropertyValues } from 'lit';\nimport '../../utilities/document-token-adoption.js';\nimport { customElement, property } from 'lit/decorators.js';\nimport { HelixElement } from '../../base/index.js';\nimport { helixAccordionStyles } from './hx-accordion.styles.js';\nimport { forcedColorsInteractive } from '../../styles/forced-colors.js';\nimport './hx-accordion-item.js';\nimport type { HelixAccordionItem } from './hx-accordion-item.js';\nimport { devWarn } from '../../utils/dev-warn.js';\n\n/**\n * An accordion container that manages collapsible content sections.\n *\n * @summary Collapsible content sections with single or multi-expand modes.\n *\n * @tag hx-accordion\n *\n * @slot - Default slot for hx-accordion-item elements.\n *\n * @csspart accordion - The outer container wrapping all accordion items.\n *\n * @cssprop [--hx-accordion-border-radius=var(--hx-border-radius-md)] - Outer border radius.\n *\n * @example\n * ```html\n * <hx-accordion mode=\"single\">\n * <hx-accordion-item>\n * <span slot=\"trigger\">What is this?</span>\n * <p>Answer content here.</p>\n * </hx-accordion-item>\n * </hx-accordion>\n * ```\n * @cssprop [--hx-accordion-font-family=var(--hx-font-family-sans)] - CSS custom property.\n * @cssprop [--hx-font-family-sans] - Font family.\n * @cssprop [--hx-border-radius-md] - CSS custom property.\n */\n@customElement('hx-accordion')\nexport class HelixAccordion extends HelixElement {\n static override styles = [helixAccordionStyles, forcedColorsInteractive];\n\n /**\n * Expansion mode: 'single' collapses all other items when one expands.\n * 'multi' allows multiple items open simultaneously.\n * @attr mode\n */\n @property({ type: String, reflect: true })\n mode: 'single' | 'multi' = 'single';\n\n // ─── Lifecycle ───\n\n /** @internal */\n private _mutationObserver: MutationObserver | null = null;\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.addEventListener('hx-expand', this._handleChildExpand);\n this.addEventListener('keydown', this._handleKeyDown);\n // Re-enforce single mode when reconnected with pre-expanded items\n this._enforceSingleMode();\n // Watch for dynamically added accordion items that may violate single-expand\n if (typeof MutationObserver !== 'undefined') {\n this._mutationObserver = new MutationObserver((mutations) => {\n const hasNewItems = mutations.some((m) =>\n Array.from(m.addedNodes).some(\n (n) => n instanceof Element && n.tagName.toLowerCase() === 'hx-accordion-item',\n ),\n );\n if (hasNewItems) {\n this._enforceSingleMode();\n }\n });\n this._mutationObserver.observe(this, { childList: true });\n }\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener('hx-expand', this._handleChildExpand);\n this.removeEventListener('keydown', this._handleKeyDown);\n this._mutationObserver?.disconnect();\n this._mutationObserver = null;\n }\n\n protected override firstUpdated(): void {\n this._enforceSingleMode();\n }\n\n override updated(changedProperties: PropertyValues<this>): void {\n super.updated(changedProperties);\n if (changedProperties.has('mode')) {\n const validModes: string[] = ['single', 'multi'];\n if (!validModes.includes(this.mode)) {\n devWarn(\n 'hx-accordion',\n `Invalid mode \"${this.mode}\". Expected one of: ${validModes.join(', ')}. Clamping to \"single\".`,\n );\n this.mode = 'single';\n return;\n }\n // When switching from multi to single, enforce single-expand immediately\n this._enforceSingleMode();\n }\n }\n\n // ─── Single-expand coordination ───\n\n /** @internal */\n private _enforceSingleMode(): void {\n if (this.mode !== 'single') return;\n\n const items = this.querySelectorAll<HelixAccordionItem>('hx-accordion-item');\n let foundExpanded = false;\n\n items.forEach((item) => {\n if (item.expanded) {\n if (foundExpanded) {\n item.expanded = false;\n } else {\n foundExpanded = true;\n }\n }\n });\n }\n\n /**\n * Handles expand events from child accordion items to enforce single-expand mode.\n * @internal\n */\n private _handleChildExpand = (e: Event): void => {\n if (this.mode !== 'single') return;\n\n const expandedItem = e.composedPath()[0] as HelixAccordionItem;\n const items = this.querySelectorAll<HelixAccordionItem>('hx-accordion-item');\n\n items.forEach((item) => {\n if (item !== expandedItem && item.expanded) {\n item.expanded = false;\n item._dispatchToggleEvent(false);\n }\n });\n };\n\n // ─── Arrow key navigation (ARIA APG Accordion pattern) ───\n\n /**\n * Handles keyboard navigation between accordion triggers using arrow, Home, and End keys.\n * @internal\n */\n private _handleKeyDown = (e: KeyboardEvent): void => {\n const triggers = this._getTriggers();\n if (triggers.length === 0) return;\n\n const activeEl = this.shadowRoot?.activeElement ?? document.activeElement;\n let currentItem: HelixAccordionItem | null = null;\n\n const items = Array.from(this.querySelectorAll<HelixAccordionItem>('hx-accordion-item'));\n for (const item of items) {\n const summary = item.shadowRoot?.querySelector('[part=\"trigger\"]');\n if (summary === activeEl || item.shadowRoot?.activeElement === summary) {\n currentItem = item;\n break;\n }\n }\n\n if (!currentItem) return;\n\n const enabledItems = items.filter((item) => !item.disabled);\n const currentIndex = enabledItems.indexOf(currentItem);\n if (currentIndex === -1) return;\n\n let targetIndex = -1;\n\n switch (e.key) {\n case 'ArrowDown':\n targetIndex = (currentIndex + 1) % enabledItems.length;\n break;\n case 'ArrowUp':\n targetIndex = (currentIndex - 1 + enabledItems.length) % enabledItems.length;\n break;\n case 'Home':\n targetIndex = 0;\n break;\n case 'End':\n targetIndex = enabledItems.length - 1;\n break;\n default:\n return;\n }\n\n e.preventDefault();\n const targetItem = enabledItems[targetIndex];\n const targetSummary = targetItem?.shadowRoot?.querySelector<HTMLElement>('[part=\"trigger\"]');\n targetSummary?.focus();\n };\n\n /** @internal */\n private _getTriggers(): HTMLElement[] {\n const items = this.querySelectorAll<HelixAccordionItem>('hx-accordion-item');\n const triggers: HTMLElement[] = [];\n items.forEach((item) => {\n const summary = item.shadowRoot?.querySelector<HTMLElement>('[part=\"trigger\"]');\n if (summary) triggers.push(summary);\n });\n return triggers;\n }\n\n // ─── Slot validation ───\n\n /** @internal */\n private _handleSlotChange(e: Event): void {\n const slot = e.target;\n if (!(slot instanceof HTMLSlotElement)) return;\n const invalid = slot\n .assignedElements()\n .filter((el) => el.tagName.toLowerCase() !== 'hx-accordion-item');\n if (invalid.length > 0) {\n devWarn(\n 'hx-accordion',\n `Default slot expects <hx-accordion-item> elements. Found unexpected: ${invalid.map((el) => `<${el.tagName.toLowerCase()}>`).join(', ')}`,\n );\n }\n }\n\n // ─── Render ───\n\n override render() {\n return html`\n <div part=\"accordion\" class=\"accordion\">\n <slot @slotchange=${this._handleSlotChange}></slot>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-accordion': HelixAccordion;\n }\n}\n"],"names":["helixAccordionStyles","css","helixAccordionItemStyles","chevronIcon","svg","_nextAccordionItemId","createIdCounter","HelixAccordionItem","HelixElement","willExpand","expanded","options","itemClasses","html","classMap","nothing","forcedColorsInteractive","__decorateClass","property","customElement","HelixAccordion","expandedItem","item","activeEl","_a","currentItem","items","summary","_b","_c","enabledItems","currentIndex","targetIndex","targetItem","targetSummary","_d","mutations","m","n","changedProperties","validModes","devWarn","foundExpanded","triggers","slot","invalid","el"],"mappings":";;;;;;;AAEO,MAAMA,IAAuBC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GCAvBC,IAA2BD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;ACOxC,MAAME,IAAcC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAiBdC,IAAuBC,EAAgB,mBAAmB;AAwCzD,IAAMC,IAAN,cAAiCC,EAAa;AAAA,EAA9C,cAAA;AAAA,UAAA,GAAA,SAAA,GAIL,KAAQ,OAAOH,EAAA,GAOf,KAAA,WAAW,IAOX,KAAA,WAAW,IASX,KAAA,QAA+B;AAAA,EAAA;AAAA;AAAA,EAItB,oBAA0B;AACjC,UAAM,kBAAA,GACD,KAAK,QAAQ,cAAc;AAAA,EAMlC;AAAA;AAAA;AAAA,EAKQ,yBAAyB,GAAgB;AAE5B,IADN,EAAE,OACS,cAAc,EAAE,SAAS,GAAA,CAAM,EAAE,SAAS;AAAA,EAOpE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,IAAY,gBAAwB;AAClC,WAAO,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,KAAK,KAAK,CAAC;AAAA,EAC5C;AAAA;AAAA;AAAA,EAKQ,UAAgB;AACtB,QAAI,KAAK,SAAU;AAEnB,UAAMI,IAAa,CAAC,KAAK;AACzB,SAAK,WAAWA,GAEhB,KAAK,qBAAqBA,CAAU;AAAA,EACtC;AAAA;AAAA,EAGA,qBAAqBC,GAAyB;AAE5C,UAAMC,IAAU,EAAE,SAAS,IAAM,UAAU,IAAM,QADlC,EAAE,UAAAD,GAAU,QAAQ,KAAK,MAAM,GAAA,EACG;AAEjD,IAAIA,IACF,KAAK;AAAA,MACH,IAAI,YAAmD,aAAaC,CAAO;AAAA,IAAA,IAG7E,KAAK;AAAA,MACH,IAAI,YAAmD,eAAeA,CAAO;AAAA,IAAA;AAAA,EAGnF;AAAA;AAAA;AAAA,EAKQ,oBAAoB,GAAqB;AAC/C,MAAE,eAAA,GACF,KAAK,QAAA;AAAA,EACP;AAAA;AAAA,EAGQ,eAAe,GAAwB;AAC7C,KAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,SACjC,EAAE,eAAA,GACF,KAAK,QAAA;AAAA,EAET;AAAA;AAAA,EAIS,SAAS;AAChB,UAAMC,IAAc;AAAA,MAClB,MAAM;AAAA,MACN,kBAAkB,KAAK;AAAA,MACvB,kBAAkB,KAAK;AAAA,IAAA;AAGzB,WAAOC;AAAA,mCACwBC,EAASF,CAAW,CAAC,UAAU,KAAK,QAAQ;AAAA;AAAA,eAEhE,GAAG,KAAK,IAAI,UAAU;AAAA;AAAA;AAAA;AAAA,uBAId,KAAK,aAAa;AAAA,qBACpB,KAAK,WAAW,OAAO,GAAG;AAAA,0BACrB,KAAK,WAAW,SAAS,OAAO;AAAA,0BAChC,KAAK,WAAW,SAASG,CAAO;AAAA,0BAChC,GAAG,KAAK,IAAI,UAAU;AAAA,mBAC7B,KAAK,mBAAmB;AAAA,qBACtB,KAAK,cAAc;AAAA;AAAA,6CAEK,KAAK,wBAAwB;AAAA,2CAC/BZ,CAAW;AAAA;AAAA;AAAA;AAAA;AAAA,mBAKnC,GAAG,KAAK,IAAI,UAAU;AAAA;AAAA;AAAA;AAAA,gCAIT,GAAG,KAAK,IAAI,UAAU;AAAA,4BAC1B,KAAK,WAAWY,IAAU,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQ1D;AACF;AA9JaR,EACK,SAAS,CAACL,GAA0Bc,CAAuB;AAU3EC,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,SAAS,SAAS,IAAM;AAAA,GAV/BX,EAWX,WAAA,YAAA,CAAA;AAOAU,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,SAAS,SAAS,IAAM;AAAA,GAjB/BX,EAkBX,WAAA,YAAA,CAAA;AASAU,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GA1BfX,EA2BX,WAAA,SAAA,CAAA;AA3BWA,IAANU,EAAA;AAAA,EADNE,EAAc,mBAAmB;AAAA,GACrBZ,CAAA;;;;;;AC7BN,IAAMa,IAAN,cAA6BZ,EAAa;AAAA,EAA1C,cAAA;AAAA,UAAA,GAAA,SAAA,GASL,KAAA,OAA2B,UAK3B,KAAQ,oBAA6C,MA6ErD,KAAQ,qBAAqB,CAAC,MAAmB;AAC/C,UAAI,KAAK,SAAS,SAAU;AAE5B,YAAMa,IAAe,EAAE,aAAA,EAAe,CAAC;AAGvC,MAFc,KAAK,iBAAqC,mBAAmB,EAErE,QAAQ,CAACC,MAAS;AACtB,QAAIA,MAASD,KAAgBC,EAAK,aAChCA,EAAK,WAAW,IAChBA,EAAK,qBAAqB,EAAK;AAAA,MAEnC,CAAC;AAAA,IACH,GAQA,KAAQ,iBAAiB,CAAC,MAA2B;;AAEnD,UADiB,KAAK,aAAA,EACT,WAAW,EAAG;AAE3B,YAAMC,MAAWC,IAAA,KAAK,eAAL,gBAAAA,EAAiB,kBAAiB,SAAS;AAC5D,UAAIC,IAAyC;AAE7C,YAAMC,IAAQ,MAAM,KAAK,KAAK,iBAAqC,mBAAmB,CAAC;AACvF,iBAAWJ,KAAQI,GAAO;AACxB,cAAMC,KAAUC,IAAAN,EAAK,eAAL,gBAAAM,EAAiB,cAAc;AAC/C,YAAID,MAAYJ,OAAYM,IAAAP,EAAK,eAAL,gBAAAO,EAAiB,mBAAkBF,GAAS;AACtE,UAAAF,IAAcH;AACd;AAAA,QACF;AAAA,MACF;AAEA,UAAI,CAACG,EAAa;AAElB,YAAMK,IAAeJ,EAAM,OAAO,CAACJ,MAAS,CAACA,EAAK,QAAQ,GACpDS,IAAeD,EAAa,QAAQL,CAAW;AACrD,UAAIM,MAAiB,GAAI;AAEzB,UAAIC,IAAc;AAElB,cAAQ,EAAE,KAAA;AAAA,QACR,KAAK;AACH,UAAAA,KAAeD,IAAe,KAAKD,EAAa;AAChD;AAAA,QACF,KAAK;AACH,UAAAE,KAAeD,IAAe,IAAID,EAAa,UAAUA,EAAa;AACtE;AAAA,QACF,KAAK;AACH,UAAAE,IAAc;AACd;AAAA,QACF,KAAK;AACH,UAAAA,IAAcF,EAAa,SAAS;AACpC;AAAA,QACF;AACE;AAAA,MAAA;AAGJ,QAAE,eAAA;AACF,YAAMG,IAAaH,EAAaE,CAAW,GACrCE,KAAgBC,IAAAF,KAAA,gBAAAA,EAAY,eAAZ,gBAAAE,EAAwB,cAA2B;AACzE,MAAAD,KAAA,QAAAA,EAAe;AAAA,IACjB;AAAA,EAAA;AAAA,EA5IS,oBAA0B;AACjC,UAAM,kBAAA,GACN,KAAK,iBAAiB,aAAa,KAAK,kBAAkB,GAC1D,KAAK,iBAAiB,WAAW,KAAK,cAAc,GAEpD,KAAK,mBAAA,GAED,OAAO,mBAAqB,QAC9B,KAAK,oBAAoB,IAAI,iBAAiB,CAACE,MAAc;AAM3D,MALoBA,EAAU;AAAA,QAAK,CAACC,MAClC,MAAM,KAAKA,EAAE,UAAU,EAAE;AAAA,UACvB,CAACC,MAAMA,aAAa,WAAWA,EAAE,QAAQ,kBAAkB;AAAA,QAAA;AAAA,MAC7D,KAGA,KAAK,mBAAA;AAAA,IAET,CAAC,GACD,KAAK,kBAAkB,QAAQ,MAAM,EAAE,WAAW,IAAM;AAAA,EAE5D;AAAA,EAES,uBAA6B;;AACpC,UAAM,qBAAA,GACN,KAAK,oBAAoB,aAAa,KAAK,kBAAkB,GAC7D,KAAK,oBAAoB,WAAW,KAAK,cAAc,IACvDd,IAAA,KAAK,sBAAL,QAAAA,EAAwB,cACxB,KAAK,oBAAoB;AAAA,EAC3B;AAAA,EAEmB,eAAqB;AACtC,SAAK,mBAAA;AAAA,EACP;AAAA,EAES,QAAQe,GAA+C;AAE9D,QADA,MAAM,QAAQA,CAAiB,GAC3BA,EAAkB,IAAI,MAAM,GAAG;AACjC,YAAMC,IAAuB,CAAC,UAAU,OAAO;AAC/C,UAAI,CAACA,EAAW,SAAS,KAAK,IAAI,GAAG;AACnC,QAAAC;AAAA,UACE;AAAA,UACA,iBAAiB,KAAK,IAAI,uBAAuBD,EAAW,KAAK,IAAI,CAAC;AAAA,QAAA,GAExE,KAAK,OAAO;AACZ;AAAA,MACF;AAEA,WAAK,mBAAA;AAAA,IACP;AAAA,EACF;AAAA;AAAA;AAAA,EAKQ,qBAA2B;AACjC,QAAI,KAAK,SAAS,SAAU;AAE5B,UAAMd,IAAQ,KAAK,iBAAqC,mBAAmB;AAC3E,QAAIgB,IAAgB;AAEpB,IAAAhB,EAAM,QAAQ,CAACJ,MAAS;AACtB,MAAIA,EAAK,aACHoB,IACFpB,EAAK,WAAW,KAEhBoB,IAAgB;AAAA,IAGtB,CAAC;AAAA,EACH;AAAA;AAAA,EA0EQ,eAA8B;AACpC,UAAMhB,IAAQ,KAAK,iBAAqC,mBAAmB,GACrEiB,IAA0B,CAAA;AAChC,WAAAjB,EAAM,QAAQ,CAACJ,MAAS;;AACtB,YAAMK,KAAUH,IAAAF,EAAK,eAAL,gBAAAE,EAAiB,cAA2B;AAC5D,MAAIG,KAASgB,EAAS,KAAKhB,CAAO;AAAA,IACpC,CAAC,GACMgB;AAAA,EACT;AAAA;AAAA;AAAA,EAKQ,kBAAkB,GAAgB;AACxC,UAAMC,IAAO,EAAE;AACf,QAAI,EAAEA,aAAgB,iBAAkB;AACxC,UAAMC,IAAUD,EACb,iBAAA,EACA,OAAO,CAACE,MAAOA,EAAG,QAAQ,YAAA,MAAkB,mBAAmB;AAClE,IAAID,EAAQ,SAAS,KACnBJ;AAAA,MACE;AAAA,MACA,wEAAwEI,EAAQ,IAAI,CAACC,MAAO,IAAIA,EAAG,QAAQ,YAAA,CAAa,GAAG,EAAE,KAAK,IAAI,CAAC;AAAA,IAAA;AAAA,EAG7I;AAAA;AAAA,EAIS,SAAS;AAChB,WAAOjC;AAAA;AAAA,4BAEiB,KAAK,iBAAiB;AAAA;AAAA;AAAA,EAGhD;AACF;AAnMaO,EACK,SAAS,CAACpB,GAAsBgB,CAAuB;AAQvEC,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,QAAQ,SAAS,IAAM;AAAA,GAR9BE,EASX,WAAA,QAAA,CAAA;AATWA,IAANH,EAAA;AAAA,EADNE,EAAc,cAAc;AAAA,GAChBC,CAAA;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hx-alert-BZH8iHQf.js","sources":["../../src/components/hx-alert/hx-alert.styles.ts","../../src/components/hx-alert/hx-alert.ts"],"sourcesContent":["import { css } from 'lit';\n\n/**\n * hx-alert styles.\n *\n * Component-tier tokens with two-level var() fallback:\n * var(--hx-alert-{prop}, var(--hx-color-{semantic}, #hex))\n * Inner hex fallbacks track the \"precision cool\" palette (3.2.0):\n * info-50 = #EFF6FE, info-200 = #BEDCFC, info-500 = #0C8BEB, info-800 = #064172,\n * success-50 = #EAFAEC, success-200 = #BAE6C2, success-500 = #3B9E58, success-800 = #0B4D23,\n * warning-50 = #FFF3EA, warning-200 = #FACFAE, warning-500 = #C2711C, warning-800 = #603301,\n * error-50 = #FFF2F0, error-200 = #FCCBC4, error-500 = #E5493E, error-800 = #7A090A,\n * primary-400 = #6AB1B1.\n */\nexport const helixAlertStyles = css`\n :host {\n display: block;\n }\n\n :host(:not([open])) {\n display: none;\n }\n\n /* ─── Screen-reader-only announcement region ─── */\n /* Always present in DOM so AT registers it before content is injected. */\n /* Visually hidden via clip-path technique (superior to display:none which */\n /* removes the element from the AT tree entirely). */\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 * {\n box-sizing: border-box;\n }\n\n /* ─── Alert Container ─── */\n\n .alert {\n display: flex;\n align-items: flex-start;\n gap: var(--hx-alert-gap, var(--hx-space-3, 0.75rem));\n padding: var(--hx-alert-padding, var(--hx-space-4, 1rem));\n border: var(--hx-alert-border-width, var(--hx-border-width-thin, 1px)) solid\n var(--hx-alert-border-color, var(--hx-color-info-200, #bedcfc));\n border-radius: var(--hx-alert-border-radius, var(--hx-border-radius-md, 0.375rem));\n background-color: var(--hx-alert-bg, var(--hx-color-info-50, #eff6fe));\n color: var(--hx-alert-color, var(--hx-color-info-800, #064172));\n font-family: var(--hx-alert-font-family, var(--hx-font-family-sans, sans-serif));\n font-size: var(--hx-font-size-sm, 0.875rem);\n line-height: var(--hx-line-height-normal, 1.5);\n }\n\n /* ─── Accent Variant (left border stripe) ─── */\n /* Removes full border and replaces with a left-side accent stripe. */\n /* Common healthcare/enterprise dashboard pattern for dense information UIs. */\n\n .alert--accent {\n border-width: 0;\n border-inline-start: var(--hx-alert-accent-width, 4px) solid\n var(--hx-alert-border-color, var(--hx-color-info-200, #bedcfc));\n border-radius: 0;\n }\n\n /* ─── Severity Label (WCAG 1.4.1) ─── */\n /* Visually hidden — provides a non-color cue for screen readers and users */\n /* who cannot distinguish variants by color alone (e.g. color-blind users). */\n /* Always present regardless of showIcon so severity is never color-only. */\n\n .alert__severity-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 /* ─── Icon ─── */\n\n .alert__icon {\n display: flex;\n align-items: center;\n flex-shrink: 0;\n color: var(--hx-alert-icon-color, var(--hx-color-info-500, #0c8beb));\n }\n\n .alert__icon svg {\n width: var(--hx-space-5, 1.25rem);\n height: var(--hx-space-5, 1.25rem);\n fill: currentColor;\n }\n\n /* ─── Title ─── */\n\n .alert__title {\n display: none;\n font-weight: var(--hx-font-weight-semibold, 600);\n margin-bottom: var(--hx-space-1, 0.25rem);\n }\n\n .alert__title--visible {\n display: block;\n }\n\n /* ─── Message ─── */\n\n .alert__message {\n flex: 1;\n min-width: 0;\n }\n\n /* ─── Actions ─── */\n /* Hidden by default; shown via JS slotchange detection to avoid invisible */\n /* margin-top spacing when no actions are slotted. */\n\n .alert__actions {\n display: none;\n align-items: center;\n gap: var(--hx-space-2, 0.5rem);\n margin-top: var(--hx-space-2, 0.5rem);\n }\n\n .alert__actions--visible {\n display: flex;\n }\n\n /* ─── Close Button ─── */\n /* Minimum 44px touch target per WCAG 2.5.8 (Target Size Minimum, AA) and */\n /* Apple HIG / Google Material guidelines. Uses absolute px units to ensure */\n /* the target size is independent of the consumer's base font size. */\n\n .alert__close-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n min-width: var(--hx-touch-target-size, 44px);\n min-height: var(--hx-touch-target-size, 44px);\n margin-inline-start: auto;\n padding: 0;\n border: none;\n border-radius: var(--hx-border-radius-sm, 0.25rem);\n background: transparent;\n color: var(--hx-alert-color, var(--hx-color-info-800, #064172));\n cursor: pointer;\n font-size: var(--hx-font-size-md, 1rem);\n line-height: 1;\n transition:\n background-color var(--hx-transition-fast, 150ms ease),\n opacity var(--hx-transition-fast, 150ms ease);\n opacity: var(--hx-opacity-75, 0.75);\n }\n\n .alert__close-button:hover {\n opacity: var(--hx-opacity-100, 1);\n /* color-mix() is supported in Chrome 111+, Firefox 113+, Safari 16.2+. */\n /* Falls back to transparent (no hover background) in older environments. */\n background-color: color-mix(in srgb, currentColor 10%, transparent);\n }\n\n .alert__close-button:focus-visible {\n outline: var(--hx-focus-ring-width, 2px) solid\n var(\n --hx-alert-close-btn-focus-ring-color,\n var(--hx-focus-ring-color, var(--hx-color-primary-400, #6ab1b1))\n );\n outline-offset: var(--hx-focus-ring-offset, 2px);\n opacity: 1;\n }\n\n .alert__close-button svg {\n width: var(--hx-space-4, 1rem);\n height: var(--hx-space-4, 1rem);\n fill: currentColor;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .alert__close-button {\n transition: none;\n }\n }\n\n /* ─── Variant: info ─── */\n\n :host([variant='info']) .alert,\n :host(:not([variant])) .alert {\n --hx-alert-bg: var(--hx-color-info-50, #eff6fe);\n --hx-alert-border-color: var(--hx-color-info-200, #bedcfc);\n --hx-alert-color: var(--hx-color-info-800, #064172);\n --hx-alert-icon-color: var(--hx-color-info-500, #0c8beb);\n }\n\n /* ─── Variant: success ─── */\n\n :host([variant='success']) .alert {\n --hx-alert-bg: var(--hx-color-success-50, #eafaec);\n --hx-alert-border-color: var(--hx-color-success-200, #bae6c2);\n --hx-alert-color: var(--hx-color-success-800, #0b4d23);\n --hx-alert-icon-color: var(--hx-color-success-500, #3b9e58);\n }\n\n /* ─── Variant: warning ─── */\n\n :host([variant='warning']) .alert {\n --hx-alert-bg: var(--hx-color-warning-50, #fff3ea);\n --hx-alert-border-color: var(--hx-color-warning-200, #facfae);\n --hx-alert-color: var(--hx-color-warning-800, #603301);\n --hx-alert-icon-color: var(--hx-color-warning-500, #c2711c);\n }\n\n /* ─── Variant: error ─── */\n\n :host([variant='error']) .alert {\n --hx-alert-bg: var(--hx-color-error-50, #fff2f0);\n --hx-alert-border-color: var(--hx-color-error-200, #fccbc4);\n --hx-alert-color: var(--hx-color-error-800, #7a090a);\n --hx-alert-icon-color: var(--hx-color-error-500, #e5493e);\n }\n\n /* ─── Forced Colors (Windows High Contrast) ─── */\n /* Belt-and-suspenders: rich per-class HC overrides PLUS the forcedColorsSurface mixin. */\n\n @media (forced-colors: active) {\n .alert {\n border-color: CanvasText;\n }\n\n .alert--accent {\n border-inline-start-color: CanvasText;\n }\n\n .alert__icon svg {\n fill: CanvasText;\n }\n\n .alert__close-button {\n color: ButtonText;\n border: 1px solid ButtonText;\n }\n }\n`;\n","import { html, nothing, type PropertyValues } 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 { HelixElement } from '../../base/index.js';\nimport { helixAlertStyles } from './hx-alert.styles.js';\nimport { forcedColorsSurface } from '../../styles/forced-colors.js';\n\n/** Alert variant determines visual styling and ARIA semantics. */\nexport type AlertVariant = 'info' | 'success' | 'warning' | 'error';\n\n/** Detail for the hx-close event dispatched by hx-alert. */\nexport interface HxAlertCloseDetail {\n reason: string;\n}\n\n/**\n * A feedback component for communicating status messages, warnings, and errors.\n * Critical for healthcare patient safety alerts.\n *\n * @summary Feedback alert for status messages with variant-based styling and ARIA live regions.\n *\n * @tag hx-alert\n *\n * @slot - Default slot for alert message content.\n * @slot title - Optional title/headline for the alert.\n * @slot icon - Custom icon to override the default variant icon.\n * @slot actions - Action buttons rendered within the alert.\n *\n * @attr {string} heading - Text used to build the close button's contextual aria-label\n * (e.g., \"Close Low blood pressure alert\"). When absent the label falls back to \"Close alert\".\n *\n * @fires {CustomEvent<{reason: string}>} hx-close - Dispatched when the user dismisses the alert.\n * @fires {CustomEvent} hx-after-close - Dispatched after the alert is dismissed.\n *\n * @csspart alert - The outer alert container.\n * @csspart title - The title/headline container.\n * @csspart icon - The icon container.\n * @csspart message - The message content area.\n * @csspart close-button - The dismiss button (only rendered when dismissible).\n * @csspart actions - The actions container.\n *\n * @cssprop [--hx-alert-bg=var(--hx-color-info-50)] - Alert background color.\n * @cssprop [--hx-alert-color=var(--hx-color-info-800)] - Alert text color.\n * @cssprop [--hx-alert-border-color=var(--hx-color-info-200)] - Alert border color.\n * @cssprop [--hx-alert-border-radius=var(--hx-border-radius-md)] - Alert border radius.\n * @cssprop [--hx-alert-border-width=var(--hx-border-width-thin)] - Alert border width.\n * @cssprop [--hx-alert-padding=var(--hx-space-4)] - Alert padding.\n * @cssprop [--hx-alert-gap=var(--hx-space-3)] - Gap between alert elements.\n * @cssprop [--hx-alert-icon-color=var(--hx-color-info-500)] - Alert icon color.\n * @cssprop [--hx-alert-font-family=var(--hx-font-family-sans)] - Alert font family.\n * @cssprop [--hx-touch-target-size=44px] - Minimum touch target size for the close button.\n * @cssprop [--hx-alert-accent-width=4px] - Width of the left border accent stripe.\n * @cssprop [--hx-border-radius-md] - CSS custom property.\n * @cssprop [--hx-border-radius-sm] - CSS custom property.\n * @cssprop [--hx-border-width-thin] - Width.\n * @cssprop [--hx-color-error-200] - Color.\n * @cssprop [--hx-color-error-50] - Color.\n * @cssprop [--hx-color-error-500] - Color.\n * @cssprop [--hx-color-error-800] - Color.\n * @cssprop [--hx-color-info-200] - Color.\n * @cssprop [--hx-color-info-50] - Color.\n * @cssprop [--hx-color-info-500] - Color.\n * @cssprop [--hx-color-info-800] - Color.\n * @cssprop [--hx-color-primary-400] - Color.\n * @cssprop [--hx-color-success-200] - Color.\n * @cssprop [--hx-color-success-50] - Color.\n * @cssprop [--hx-color-success-500] - Color.\n * @cssprop [--hx-color-success-800] - Color.\n * @cssprop [--hx-color-warning-200] - Color.\n * @cssprop [--hx-color-warning-50] - Color.\n * @cssprop [--hx-color-warning-500] - Color.\n * @cssprop [--hx-color-warning-800] - Color.\n * @cssprop [--hx-focus-ring-color] - Color.\n * @cssprop [--hx-focus-ring-offset] - CSS custom property.\n * @cssprop [--hx-focus-ring-width] - Width.\n * @cssprop [--hx-font-family-sans] - Font family.\n * @cssprop [--hx-font-size-md] - Font size.\n * @cssprop [--hx-font-size-sm] - Font size.\n * @cssprop [--hx-font-weight-semibold] - Font weight.\n * @cssprop [--hx-line-height-normal] - Line height.\n * @cssprop [--hx-opacity-100] - Opacity.\n * @cssprop [--hx-opacity-75] - Opacity.\n * @cssprop [--hx-space-1] - Spacing token.\n * @cssprop [--hx-space-2] - Spacing token.\n * @cssprop [--hx-space-3] - Spacing token.\n * @cssprop [--hx-space-4] - Spacing token.\n * @cssprop [--hx-space-5] - Spacing token.\n * @cssprop [--hx-transition-fast] - Transition timing.\n */\n@customElement('hx-alert')\nexport class HelixAlert extends HelixElement {\n static override styles = [helixAlertStyles, forcedColorsSurface];\n\n // ─── Properties ───\n\n /**\n * Visual variant of the alert that determines colors and ARIA semantics.\n * @attr variant\n */\n @property({ type: String, reflect: true })\n variant: 'info' | 'success' | 'warning' | 'error' = 'info';\n\n /**\n * Whether the alert can be dismissed by the user.\n * @attr dismissible\n */\n @property({ type: Boolean, reflect: true })\n dismissible = false;\n\n /**\n * Optional heading text that provides context for the close button's accessible label.\n * When provided, the close button is announced as \"Close [heading] alert\".\n * When absent, the close button falls back to \"Close alert\".\n * @attr heading\n */\n @property({ type: String })\n heading = '';\n\n /**\n * Accessible label for the close button. Override for i18n.\n * @attr label-close\n */\n @property({ attribute: 'label-close' }) labelClose = 'Close alert';\n\n /**\n * Whether the alert is visible. Add the `open` attribute to show the alert.\n * @attr open\n */\n @property({ type: Boolean, reflect: true })\n open = false;\n\n /**\n * Whether to show the default variant icon. Add `show-icon` attribute to display the icon.\n * @attr show-icon\n */\n @property({ type: Boolean, reflect: true, attribute: 'show-icon' })\n showIcon = false;\n\n /**\n * When true, applies a left border accent stripe instead of a full border.\n * Common healthcare/enterprise dashboard pattern for visual distinction of alert types.\n * @attr accent\n */\n @property({ type: Boolean, reflect: true })\n accent = false;\n\n /**\n * Override for the severity prefix announced to screen readers (e.g., \"Info:\", \"Error:\").\n * When not set, defaults to the English label matching the current variant.\n * @attr severity-label\n */\n @property({ attribute: 'severity-label' })\n severityLabel: string | undefined;\n\n /**\n * CSS selector for the element to return focus to after the alert is dismissed.\n * When set, the component will find and focus the matching element after dismissal.\n * If not set, focus management is the caller's responsibility via the hx-after-close event.\n * @attr return-focus-to\n */\n @property({ type: String, attribute: 'return-focus-to' })\n returnFocusTo: string | null = null;\n\n // ─── State ───\n\n /** @internal */\n @state()\n private _hasActions = false;\n\n /** @internal */\n @state()\n private _hasTitle = false;\n\n // ─── Private Handler References ───\n\n /** @internal */\n private _actionsSlotChangeHandler: (() => void) | null = null;\n /** @internal */\n private _titleSlotChangeHandler: (() => void) | null = null;\n\n // ─── Private Helpers ───\n\n /** @internal */\n private _defaultSeverityLabel(): string {\n const labels: Record<string, string> = {\n info: 'Info:',\n success: 'Success:',\n warning: 'Warning:',\n error: 'Error:',\n };\n return labels[this.variant] ?? '';\n }\n\n /** @internal */\n private get _effectiveSeverityLabel(): string {\n return this.severityLabel ?? this._defaultSeverityLabel();\n }\n\n /** Returns true when the variant requires assertive announcement. */\n /** @internal */\n private get _isAssertive(): boolean {\n return this.variant === 'error';\n }\n\n /**\n * Returns the appropriate ARIA role based on variant.\n * role=\"alert\" implies aria-live=\"assertive\"; role=\"status\" implies aria-live=\"polite\".\n * We do NOT set aria-live explicitly to avoid double-announcements in JAWS.\n */\n /** @internal */\n private get _role(): string {\n return this._isAssertive ? 'alert' : 'status';\n }\n\n // ─── Lifecycle ───\n\n override connectedCallback(): void {\n super.connectedCallback();\n // Apply ARIA role to the host element for reliable screen reader support across\n // Shadow DOM boundaries. Placing role on a shadow-internal element has inconsistent\n // AT support in JAWS+Chrome and VoiceOver+Safari combinations (particularly pre-2024).\n this.setAttribute('role', this._role);\n if (!this.open) {\n this.setAttribute('aria-hidden', 'true');\n }\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n const actionsSlot = this.renderRoot.querySelector<HTMLSlotElement>('slot[name=\"actions\"]');\n if (actionsSlot && this._actionsSlotChangeHandler) {\n actionsSlot.removeEventListener('slotchange', this._actionsSlotChangeHandler);\n }\n const titleSlot = this.renderRoot.querySelector<HTMLSlotElement>('slot[name=\"title\"]');\n if (titleSlot && this._titleSlotChangeHandler) {\n titleSlot.removeEventListener('slotchange', this._titleSlotChangeHandler);\n }\n }\n\n override firstUpdated(): void {\n // Track actions slot content to avoid invisible spacing when no actions are slotted.\n const actionsSlot = this.renderRoot.querySelector<HTMLSlotElement>('slot[name=\"actions\"]');\n if (actionsSlot) {\n this._actionsSlotChangeHandler = () => {\n this._hasActions = actionsSlot.assignedNodes({ flatten: true }).length > 0;\n };\n actionsSlot.addEventListener('slotchange', this._actionsSlotChangeHandler);\n }\n\n // Track title slot content so the title container doesn't create dead space when empty.\n const titleSlot = this.renderRoot.querySelector<HTMLSlotElement>('slot[name=\"title\"]');\n if (titleSlot) {\n this._titleSlotChangeHandler = () => {\n this._hasTitle = titleSlot.assignedNodes({ flatten: true }).length > 0;\n };\n titleSlot.addEventListener('slotchange', this._titleSlotChangeHandler);\n }\n }\n\n protected override updated(changedProperties: PropertyValues<this>): void {\n super.updated(changedProperties);\n if (changedProperties.has('variant')) {\n // Keep host ARIA role in sync with variant (assertive vs. polite).\n this.setAttribute('role', this._role);\n }\n if (changedProperties.has('open')) {\n // Manage aria-hidden in addition to display:none for reliable AT exclusion.\n // When open transitions from false→true, removing aria-hidden signals to AT\n // that the live region content should be announced.\n if (this.open) {\n this.removeAttribute('aria-hidden');\n // Trigger announcement via the sr-only polite live region for ATs (JAWS+Chrome,\n // NVDA) that do not re-announce existing content when aria-hidden is merely removed.\n // We inject text after a microtask so the DOM has settled and the live region\n // is registered by the AT before content arrives.\n const previousOpen = changedProperties.get('open');\n if (previousOpen === false) {\n Promise.resolve().then(() => {\n const announcer = this.renderRoot.querySelector<HTMLElement>('.sr-only');\n if (announcer) {\n announcer.textContent = '';\n // Second microtask ensures the clear is processed before re-injection,\n // guaranteeing the AT sees a content change rather than no-op.\n Promise.resolve().then(() => {\n const prefix = this._effectiveSeverityLabel;\n const message = this.textContent?.trim() ?? '';\n announcer.textContent = prefix ? `${prefix} ${message}` : message;\n });\n }\n });\n }\n } else {\n this.setAttribute('aria-hidden', 'true');\n // Clear the announcer when hidden so stale text is not re-read on next open.\n const announcer = this.renderRoot.querySelector<HTMLElement>('.sr-only');\n if (announcer) {\n announcer.textContent = '';\n }\n }\n }\n }\n\n // ─── Default Icons ───\n\n /** @internal */\n private _renderInfoIcon() {\n return html`<svg viewBox=\"0 0 20 20\" aria-hidden=\"true\">\n <path\n d=\"M10 2a8 8 0 100 16 8 8 0 000-16zm.75 4.75a.75.75 0 11-1.5 0 .75.75 0 011.5 0zM9.25 9a.75.75 0 011.5 0v4a.75.75 0 01-1.5 0V9z\"\n />\n </svg>`;\n }\n\n /** @internal */\n private _renderSuccessIcon() {\n return html`<svg viewBox=\"0 0 20 20\" aria-hidden=\"true\">\n <path\n d=\"M10 2a8 8 0 100 16 8 8 0 000-16zm3.03 6.28a.75.75 0 00-1.06-1.06L9 10.19 7.78 8.97a.75.75 0 00-1.06 1.06l1.75 1.75a.75.75 0 001.06 0l3.5-3.5z\"\n />\n </svg>`;\n }\n\n /** @internal */\n private _renderWarningIcon() {\n return html`<svg viewBox=\"0 0 20 20\" aria-hidden=\"true\">\n <path\n d=\"M8.49 2.92a1.75 1.75 0 013.02 0l6.25 10.83A1.75 1.75 0 0116.25 16H3.75a1.75 1.75 0 01-1.51-2.25L8.49 2.92zM10 7a.75.75 0 01.75.75v3a.75.75 0 01-1.5 0v-3A.75.75 0 0110 7zm0 7.5a.75.75 0 100-1.5.75.75 0 000 1.5z\"\n />\n </svg>`;\n }\n\n /** @internal */\n private _renderErrorIcon() {\n return html`<svg viewBox=\"0 0 20 20\" aria-hidden=\"true\">\n <path\n d=\"M10 2a8 8 0 100 16 8 8 0 000-16zm-1.72 5.22a.75.75 0 011.06 0L10 7.94l.66-.72a.75.75 0 111.06 1.06L11.06 9l.66.72a.75.75 0 11-1.06 1.06L10 10.06l-.66.72a.75.75 0 01-1.06-1.06L8.94 9l-.66-.72a.75.75 0 010-1.06z\"\n />\n </svg>`;\n }\n\n /** @internal */\n private _renderDefaultIcon() {\n switch (this.variant) {\n case 'success':\n return this._renderSuccessIcon();\n case 'warning':\n return this._renderWarningIcon();\n case 'error':\n return this._renderErrorIcon();\n case 'info':\n default:\n return this._renderInfoIcon();\n }\n }\n\n /** @internal */\n private _renderCloseIcon() {\n return html`<svg viewBox=\"0 0 20 20\" aria-hidden=\"true\">\n <path\n d=\"M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z\"\n />\n </svg>`;\n }\n\n // ─── Event Handling ───\n\n /** @internal */\n private _handleDismiss(): void {\n this.open = false;\n\n /**\n * Dispatched when the user dismisses the alert.\n * @event hx-close\n */\n this.dispatchEvent(\n new CustomEvent<{ reason: string }>('hx-close', {\n bubbles: true,\n composed: true,\n detail: { reason: 'user' },\n }),\n );\n\n /**\n * Dispatched after the alert is dismissed.\n * @event hx-after-close\n */\n this.dispatchEvent(\n new CustomEvent<void>('hx-after-close', {\n bubbles: true,\n composed: true,\n }),\n );\n\n // Return focus to a designated element if specified via returnFocusTo.\n if (this.returnFocusTo) {\n const target = document.querySelector(this.returnFocusTo);\n if (target instanceof HTMLElement) {\n target.focus();\n }\n }\n }\n\n // ─── Render ───\n\n override render() {\n const classes = {\n alert: true,\n [`alert--${this.variant}`]: true,\n 'alert--accent': this.accent,\n };\n\n // WCAG 1.4.1: Always render a visually-hidden severity label so the variant\n // is never conveyed by color alone, regardless of whether showIcon is set.\n const severityLabel = this._effectiveSeverityLabel;\n\n return html`\n <div\n class=\"sr-only\"\n aria-live=${this._isAssertive ? 'assertive' : 'polite'}\n aria-atomic=\"true\"\n ></div>\n <div part=\"alert\" class=${classMap(classes)}>\n <span class=\"alert__severity-label\">${severityLabel}</span>\n ${this.showIcon\n ? html`\n <div part=\"icon\" class=\"alert__icon\">\n <slot name=\"icon\">${this._renderDefaultIcon()}</slot>\n </div>\n `\n : nothing}\n\n <div part=\"message\" class=\"alert__message\">\n <div part=\"title\" class=\"alert__title ${this._hasTitle ? 'alert__title--visible' : ''}\">\n <slot name=\"title\"></slot>\n </div>\n <slot></slot>\n <div\n part=\"actions\"\n class=\"alert__actions ${this._hasActions ? 'alert__actions--visible' : ''}\"\n >\n <slot name=\"actions\"></slot>\n </div>\n </div>\n\n ${this.dismissible\n ? html`\n <button\n part=\"close-button\"\n class=\"alert__close-button\"\n aria-label=${this.labelClose}\n @click=${this._handleDismiss}\n >\n ${this._renderCloseIcon()}\n </button>\n `\n : nothing}\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-alert': HelixAlert;\n }\n}\n\nexport type { HelixAlert as HxAlert };\n"],"names":["helixAlertStyles","css","HelixAlert","HelixElement","actionsSlot","titleSlot","changedProperties","announcer","prefix","message","_a","html","target","classes","severityLabel","classMap","nothing","forcedColorsSurface","__decorateClass","property","state","customElement"],"mappings":";;;;;AAcO,MAAMA,IAAmBC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hx-banner-DT7Zn9Bo.js","sources":["../../src/components/hx-banner/hx-banner.styles.ts","../../src/components/hx-banner/hx-banner.ts"],"sourcesContent":["import { css } from 'lit';\n\n/**\n * hx-banner styles.\n *\n * Component-tier tokens with two-level var() fallback:\n * var(--hx-banner-{prop}, var(--hx-color-{semantic}, #hex))\n * Inner hex fallbacks track the \"precision cool\" palette (3.2.0):\n * info-50 = #EFF6FE, info-200 = #BEDCFC, info-500 = #0C8BEB, info-800 = #064172,\n * success-50 = #EAFAEC, success-200 = #BAE6C2, success-500 = #3B9E58, success-800 = #0B4D23,\n * warning-50 = #FFF3EA, warning-200 = #FACFAE, warning-500 = #C2711C, warning-800 = #603301,\n * error-50 = #FFF2F0, error-200 = #FCCBC4, error-500 = #E5493E, error-800 = #7A090A,\n * primary-400 = #6AB1B1.\n */\nexport const helixBannerStyles = css`\n :host {\n display: block;\n width: 100%;\n position: var(--hx-banner-position, sticky);\n top: 0;\n left: 0;\n right: 0;\n z-index: var(--hx-banner-z-index, 100);\n }\n\n :host(:not([open])) {\n display: none;\n }\n\n * {\n box-sizing: border-box;\n }\n\n /* ─── Severity Label (WCAG 1.4.1) ─── */\n /* Visually hidden — ensures variant is never conveyed by color alone. */\n /* Always rendered so screen readers can identify the banner severity. */\n\n .banner__severity-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 /* ─── Banner Container ─── */\n\n .banner {\n display: flex;\n align-items: center;\n gap: var(--hx-banner-gap, var(--hx-space-3, 0.75rem));\n padding: var(--hx-banner-padding, var(--hx-space-3, 0.75rem) var(--hx-space-4, 1rem));\n background-color: var(--hx-banner-bg, var(--hx-color-info-50, #eff6fe));\n color: var(--hx-banner-color, var(--hx-color-info-800, #064172));\n border-bottom: var(--hx-banner-border-width, var(--hx-border-width-thin, 1px)) solid\n var(--hx-banner-border-color, var(--hx-color-info-200, #bedcfc));\n font-family: var(--hx-banner-font-family, var(--hx-font-family-sans, sans-serif));\n font-size: var(--hx-font-size-sm, 0.875rem);\n line-height: var(--hx-line-height-normal, 1.5);\n width: 100%;\n }\n\n /* ─── Icon ─── */\n\n .banner__icon {\n display: flex;\n align-items: center;\n flex-shrink: 0;\n color: var(--hx-banner-icon-color, var(--hx-color-info-500, #0c8beb));\n }\n\n .banner__icon svg {\n width: var(--hx-space-5, 1.25rem);\n height: var(--hx-space-5, 1.25rem);\n fill: currentColor;\n }\n\n /* ─── Message ─── */\n\n .banner__message {\n flex: 1;\n min-width: 0;\n }\n\n /* ─── Action Link ─── */\n\n .banner__action {\n display: inline-flex;\n align-items: center;\n flex-shrink: 0;\n color: var(--hx-banner-action-color, var(--hx-banner-color, var(--hx-color-info-800, #064172)));\n font-weight: var(--hx-font-weight-semibold, 600);\n text-decoration: underline;\n text-underline-offset: 2px;\n cursor: pointer;\n background: transparent;\n border: none;\n padding: 0;\n font-size: inherit;\n font-family: inherit;\n }\n\n .banner__action:hover {\n opacity: var(--hx-opacity-90, 0.9);\n }\n\n .banner__action:focus-visible {\n outline: var(--hx-focus-ring-width, 2px) solid\n var(\n --hx-banner-action-focus-ring-color,\n var(--hx-focus-ring-color, var(--hx-color-primary-400, #6ab1b1))\n );\n outline-offset: var(--hx-focus-ring-offset, 2px);\n border-radius: var(--hx-border-radius-sm, 0.25rem);\n }\n\n /* ─── Close Button ─── */\n /* Minimum 44px touch target per WCAG 2.5.8 (Target Size Minimum, AA) and */\n /* Apple HIG / Google Material guidelines. Uses absolute px units to ensure */\n /* the target size is independent of the consumer's base font size. */\n\n .banner__close-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n min-width: var(--hx-touch-target-size, 44px);\n min-height: var(--hx-touch-target-size, 44px);\n margin-inline-start: auto;\n padding: 0;\n border: none;\n border-radius: var(--hx-border-radius-sm, 0.25rem);\n background: transparent;\n color: var(--hx-banner-color, var(--hx-color-info-800, #064172));\n cursor: pointer;\n font-size: var(--hx-font-size-md, 1rem);\n line-height: 1;\n transition:\n background-color var(--hx-transition-fast, 150ms ease),\n opacity var(--hx-transition-fast, 150ms ease);\n opacity: var(--hx-opacity-75, 0.75);\n }\n\n .banner__close-button:hover {\n opacity: var(--hx-opacity-100, 1);\n /* color-mix() is supported in Chrome 111+, Firefox 113+, Safari 16.2+. */\n /* Falls back to transparent (no hover background) in older environments. */\n background-color: color-mix(in srgb, currentColor 10%, transparent);\n }\n\n .banner__close-button:focus-visible {\n outline: var(--hx-focus-ring-width, 2px) solid\n var(\n --hx-banner-close-btn-focus-ring-color,\n var(--hx-focus-ring-color, var(--hx-color-primary-400, #6ab1b1))\n );\n outline-offset: var(--hx-focus-ring-offset, 2px);\n opacity: 1;\n }\n\n .banner__close-button svg {\n width: var(--hx-space-4, 1rem);\n height: var(--hx-space-4, 1rem);\n fill: currentColor;\n }\n\n /* ─── Variant: info ─── */\n\n :host([variant='info']) .banner,\n :host(:not([variant])) .banner {\n --hx-banner-bg: var(--hx-color-info-50, #eff6fe);\n --hx-banner-border-color: var(--hx-color-info-200, #bedcfc);\n --hx-banner-color: var(--hx-color-info-800, #064172);\n --hx-banner-icon-color: var(--hx-color-info-500, #0c8beb);\n }\n\n /* ─── Variant: success ─── */\n\n :host([variant='success']) .banner {\n --hx-banner-bg: var(--hx-color-success-50, #eafaec);\n --hx-banner-border-color: var(--hx-color-success-200, #bae6c2);\n --hx-banner-color: var(--hx-color-success-800, #0b4d23);\n --hx-banner-icon-color: var(--hx-color-success-500, #3b9e58);\n }\n\n /* ─── Variant: warning ─── */\n\n :host([variant='warning']) .banner {\n --hx-banner-bg: var(--hx-color-warning-50, #fff3ea);\n --hx-banner-border-color: var(--hx-color-warning-200, #facfae);\n --hx-banner-color: var(--hx-color-warning-800, #603301);\n --hx-banner-icon-color: var(--hx-color-warning-500, #c2711c);\n }\n\n /* ─── Variant: error ─── */\n\n :host([variant='error']) .banner {\n --hx-banner-bg: var(--hx-color-error-50, #fff2f0);\n --hx-banner-border-color: var(--hx-color-error-200, #fccbc4);\n --hx-banner-color: var(--hx-color-error-800, #7a090a);\n --hx-banner-icon-color: var(--hx-color-error-500, #e5493e);\n }\n\n /* ─── Position: fixed ─── */\n /* When position=\"fixed\", override the host-level CSS custom property. */\n /* The :host rule above sets position via var(--hx-banner-position). */\n /* We use an attribute selector to override it cleanly without duplication. */\n\n :host([position='fixed']) {\n position: fixed;\n }\n\n /* ─── Reduced Motion ─── */\n\n @media (prefers-reduced-motion: reduce) {\n .banner__close-button {\n transition: none;\n }\n }\n\n /* ─── Forced Colors (Windows High Contrast) ─── */\n /* Belt-and-suspenders: rich per-class HC overrides PLUS the forcedColorsSurface mixin. */\n\n @media (forced-colors: active) {\n .banner {\n border-bottom-color: CanvasText;\n }\n\n .banner__icon svg {\n fill: CanvasText;\n }\n\n .banner__close-button {\n color: ButtonText;\n border: 1px solid ButtonText;\n }\n }\n`;\n","import { html, nothing, type PropertyValues } from 'lit';\nimport '../../utilities/document-token-adoption.js';\nimport { customElement, property } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { HelixElement } from '../../base/index.js';\nimport { helixBannerStyles } from './hx-banner.styles.js';\nimport { forcedColorsSurface } from '../../styles/forced-colors.js';\n\n/** Banner variant determines visual styling and ARIA semantics. */\nexport type BannerVariant = 'info' | 'success' | 'warning' | 'error';\n\n/** Banner position determines CSS positioning behavior. */\nexport type BannerPosition = 'sticky' | 'fixed';\n\n/**\n * A full-width page-level banner for persistent notifications and announcements.\n * Designed for healthcare applications requiring prominent system-level messaging.\n *\n * @summary Full-width page-level banner for persistent notifications with variant-based styling and ARIA live regions.\n *\n * @tag hx-banner\n *\n * @slot - Default slot for banner message content.\n * @slot action - Optional slot to override the built-in action link with custom content.\n *\n * @fires {CustomEvent<{reason: string}>} hx-dismiss - Dispatched when the user dismisses the banner.\n *\n * @csspart banner - The outer banner container.\n * @csspart icon - The icon container.\n * @csspart message - The message content area.\n * @csspart action - The action link element (only rendered when action-label and action-href are set).\n * @csspart close-button - The dismiss button (only rendered when dismissible).\n *\n * @cssprop [--hx-banner-bg=var(--hx-color-info-50)] - Banner background color.\n * @cssprop [--hx-banner-color=var(--hx-color-info-800)] - Banner text color.\n * @cssprop [--hx-banner-border-color=var(--hx-color-info-200)] - Banner bottom border color.\n * @cssprop [--hx-banner-border-width=var(--hx-border-width-thin)] - Banner bottom border width.\n * @cssprop [--hx-banner-padding=var(--hx-space-3) var(--hx-space-4)] - Banner padding.\n * @cssprop [--hx-banner-gap=var(--hx-space-3)] - Gap between banner elements.\n * @cssprop [--hx-banner-icon-color=var(--hx-color-info-500)] - Banner icon color.\n * @cssprop [--hx-banner-font-family=var(--hx-font-family-sans)] - Banner font family.\n * @cssprop [--hx-banner-action-color=var(--hx-banner-color)] - Action link color.\n * @cssprop [--hx-banner-position=sticky] - CSS position value (sticky or fixed).\n * @cssprop [--hx-banner-z-index=100] - Banner z-index for stacking context.\n * @cssprop [--hx-touch-target-size=44px] - Minimum touch target size for the close button.\n * @cssprop [--hx-space-3] - Spacing token.\n * @cssprop [--hx-space-4] - Spacing token.\n * @cssprop [--hx-color-info-50] - Color.\n * @cssprop [--hx-color-info-800] - Color.\n * @cssprop [--hx-border-width-thin] - Width.\n * @cssprop [--hx-color-info-200] - Color.\n * @cssprop [--hx-font-family-sans] - Font family.\n * @cssprop [--hx-font-size-sm] - Font size.\n * @cssprop [--hx-line-height-normal] - Line height.\n * @cssprop [--hx-color-info-500] - Color.\n * @cssprop [--hx-space-5] - Spacing token.\n * @cssprop [--hx-font-weight-semibold] - Font weight.\n * @cssprop [--hx-opacity-90] - Opacity.\n * @cssprop [--hx-focus-ring-width] - Width.\n * @cssprop [--hx-focus-ring-color] - Color.\n * @cssprop [--hx-color-primary-400] - Color.\n * @cssprop [--hx-focus-ring-offset] - CSS custom property.\n * @cssprop [--hx-border-radius-sm] - CSS custom property.\n * @cssprop [--hx-font-size-md] - Font size.\n * @cssprop [--hx-transition-fast] - Transition timing.\n * @cssprop [--hx-opacity-75] - Opacity.\n * @cssprop [--hx-opacity-100] - Opacity.\n * @cssprop [--hx-color-success-50] - Color.\n * @cssprop [--hx-color-success-200] - Color.\n * @cssprop [--hx-color-success-800] - Color.\n * @cssprop [--hx-color-success-500] - Color.\n * @cssprop [--hx-color-warning-50] - Color.\n * @cssprop [--hx-color-warning-200] - Color.\n * @cssprop [--hx-color-warning-800] - Color.\n * @cssprop [--hx-color-warning-500] - Color.\n * @cssprop [--hx-color-error-50] - Color.\n * @cssprop [--hx-color-error-200] - Color.\n * @cssprop [--hx-color-error-800] - Color.\n * @cssprop [--hx-color-error-500] - Color.\n */\n@customElement('hx-banner')\nexport class HelixBanner extends HelixElement {\n static override styles = [helixBannerStyles, forcedColorsSurface];\n\n // ─── Properties ───\n\n /**\n * Visual variant of the banner that determines colors and ARIA semantics.\n * @attr variant\n */\n @property({ type: String, reflect: true })\n variant: 'info' | 'success' | 'warning' | 'error' = 'info';\n\n /**\n * CSS positioning behavior. \"sticky\" keeps the banner in flow; \"fixed\" pins it to the viewport.\n * @attr position\n */\n @property({ type: String, reflect: true })\n position: 'sticky' | 'fixed' = 'sticky';\n\n /**\n * Whether the banner can be dismissed by the user.\n * @attr dismissible\n */\n @property({ type: Boolean, reflect: true })\n dismissible = false;\n\n /**\n * Heading text for the banner, used to provide context in the action link's and\n * close button's accessible labels.\n * @attr heading\n */\n @property({ type: String })\n heading = '';\n\n /**\n * Label text for the optional action link. Requires action-href to render.\n * @attr action-label\n */\n @property({ type: String, attribute: 'action-label' })\n actionLabel = '';\n\n /**\n * URL for the optional action link. Requires action-label to render.\n * @attr action-href\n */\n @property({ type: String, attribute: 'action-href' })\n actionHref = '';\n\n /**\n * Whether the banner is visible. Defaults to true — banners are shown by default.\n * @attr open\n */\n @property({ type: Boolean, reflect: true })\n open = true;\n\n /** Accessible label for the dismiss button. Override for localized text. */\n @property({ type: String, attribute: 'label-close' })\n labelClose = 'Dismiss banner';\n\n /**\n * Override for the severity prefix announced to screen readers (e.g., \"Info:\", \"Error:\").\n * When not set, defaults to the English label matching the current variant.\n * @attr severity-label\n */\n @property({ attribute: 'severity-label' })\n severityLabel: string | undefined;\n\n // ─── Private Helpers ───\n\n /** Returns the default English severity label for the current variant. */\n private _defaultSeverityLabel(): string {\n const labels: Record<string, string> = {\n info: 'Info:',\n success: 'Success:',\n warning: 'Warning:',\n error: 'Error:',\n };\n return labels[this.variant] ?? '';\n }\n\n /** Returns the effective severity label, using the override if provided. */\n private get _effectiveSeverityLabel(): string {\n return this.severityLabel ?? this._defaultSeverityLabel();\n }\n\n /** Returns true when the variant requires assertive announcement. */\n /** @internal */\n private get _isAssertive(): boolean {\n return this.variant === 'error' || this.variant === 'warning';\n }\n\n /**\n * Returns the appropriate ARIA role based on variant.\n * role=\"alert\" implies aria-live=\"assertive\"; role=\"status\" implies aria-live=\"polite\".\n * We do NOT set aria-live explicitly to avoid double-announcements in JAWS.\n */\n /** @internal */\n private get _role(): string {\n return this._isAssertive ? 'alert' : 'status';\n }\n\n // ─── Lifecycle ───\n\n override connectedCallback(): void {\n super.connectedCallback();\n // Apply ARIA role to the host element for reliable screen reader support across\n // Shadow DOM boundaries. Placing role on a shadow-internal element has inconsistent\n // AT support in JAWS+Chrome and VoiceOver+Safari combinations (particularly pre-2024).\n this.setAttribute('role', this._role);\n if (!this.open) {\n this.setAttribute('aria-hidden', 'true');\n }\n }\n\n protected override updated(changedProperties: PropertyValues<this>): void {\n super.updated(changedProperties);\n if (changedProperties.has('variant')) {\n // Keep host ARIA role in sync with variant (assertive vs. polite).\n this.setAttribute('role', this._role);\n }\n if (changedProperties.has('open')) {\n // Manage aria-hidden in addition to display:none for reliable AT exclusion.\n // When open transitions from false→true, removing aria-hidden signals to AT\n // that the live region content should be announced.\n if (this.open) {\n this.removeAttribute('aria-hidden');\n } else {\n this.setAttribute('aria-hidden', 'true');\n }\n }\n }\n\n // ─── Default Icons ───\n\n /** @internal */\n private _renderInfoIcon() {\n return html`<svg viewBox=\"0 0 20 20\" aria-hidden=\"true\">\n <path\n d=\"M10 2a8 8 0 100 16 8 8 0 000-16zm.75 4.75a.75.75 0 11-1.5 0 .75.75 0 011.5 0zM9.25 9a.75.75 0 011.5 0v4a.75.75 0 01-1.5 0V9z\"\n />\n </svg>`;\n }\n\n /** @internal */\n private _renderSuccessIcon() {\n return html`<svg viewBox=\"0 0 20 20\" aria-hidden=\"true\">\n <path\n d=\"M10 2a8 8 0 100 16 8 8 0 000-16zm3.03 6.28a.75.75 0 00-1.06-1.06L9 10.19 7.78 8.97a.75.75 0 00-1.06 1.06l1.75 1.75a.75.75 0 001.06 0l3.5-3.5z\"\n />\n </svg>`;\n }\n\n /** @internal */\n private _renderWarningIcon() {\n return html`<svg viewBox=\"0 0 20 20\" aria-hidden=\"true\">\n <path\n d=\"M8.49 2.92a1.75 1.75 0 013.02 0l6.25 10.83A1.75 1.75 0 0116.25 16H3.75a1.75 1.75 0 01-1.51-2.25L8.49 2.92zM10 7a.75.75 0 01.75.75v3a.75.75 0 01-1.5 0v-3A.75.75 0 0110 7zm0 7.5a.75.75 0 100-1.5.75.75 0 000 1.5z\"\n />\n </svg>`;\n }\n\n /** @internal */\n private _renderErrorIcon() {\n return html`<svg viewBox=\"0 0 20 20\" aria-hidden=\"true\">\n <path\n d=\"M10 2a8 8 0 100 16 8 8 0 000-16zm-1.72 5.22a.75.75 0 011.06 0L10 7.94l.66-.72a.75.75 0 111.06 1.06L11.06 9l.66.72a.75.75 0 11-1.06 1.06L10 10.06l-.66.72a.75.75 0 01-1.06-1.06L8.94 9l-.66-.72a.75.75 0 010-1.06z\"\n />\n </svg>`;\n }\n\n /** @internal */\n private _renderDefaultIcon() {\n switch (this.variant) {\n case 'success':\n return this._renderSuccessIcon();\n case 'warning':\n return this._renderWarningIcon();\n case 'error':\n return this._renderErrorIcon();\n case 'info':\n default:\n return this._renderInfoIcon();\n }\n }\n\n /** @internal */\n private _renderCloseIcon() {\n return html`<svg viewBox=\"0 0 20 20\" aria-hidden=\"true\">\n <path\n d=\"M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z\"\n />\n </svg>`;\n }\n\n // ─── Public Methods ───\n\n /**\n * Programmatically dismisses the banner. Sets open=false and dispatches hx-dismiss.\n */\n dismiss(): void {\n this._handleDismiss();\n }\n\n // ─── Event Handling ───\n\n /** @internal */\n private _handleDismiss(): void {\n this.open = false;\n\n /**\n * Dispatched when the user (or caller) dismisses the banner.\n * @event hx-dismiss\n */\n this.dispatchEvent(\n new CustomEvent<{ reason: string }>('hx-dismiss', {\n bubbles: true,\n composed: true,\n detail: { reason: 'user' },\n }),\n );\n }\n\n // ─── Render ───\n\n override render() {\n const classes = {\n banner: true,\n [`banner--${this.variant}`]: true,\n };\n\n const hasAction = this.actionLabel.length > 0 && this.actionHref.length > 0;\n\n // WCAG 1.4.1: Always render a visually-hidden severity label so the variant\n // is never conveyed by color alone.\n const severityLabel = this._effectiveSeverityLabel;\n\n return html`\n <div part=\"banner\" class=${classMap(classes)}>\n <span class=\"banner__severity-label\">${severityLabel}</span>\n <div part=\"icon\" class=\"banner__icon\">${this._renderDefaultIcon()}</div>\n\n <div part=\"message\" class=\"banner__message\">\n <slot></slot>\n </div>\n\n ${hasAction\n ? html`\n <a\n part=\"action\"\n class=\"banner__action\"\n href=${ifDefined(this.actionHref || undefined)}\n aria-label=${this.heading\n ? `${this.actionLabel}: ${this.heading}`\n : this.actionLabel}\n >\n <slot name=\"action\">${this.actionLabel}</slot>\n </a>\n `\n : nothing}\n ${this.dismissible\n ? html`\n <button\n part=\"close-button\"\n class=\"banner__close-button\"\n aria-label=${this.labelClose}\n @click=${this._handleDismiss}\n >\n ${this._renderCloseIcon()}\n </button>\n `\n : nothing}\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-banner': HelixBanner;\n }\n}\n\nexport type { HelixBanner as HxBanner };\n"],"names":["helixBannerStyles","css","HelixBanner","HelixElement","changedProperties","html","classes","hasAction","severityLabel","classMap","ifDefined","nothing","forcedColorsSurface","__decorateClass","property","customElement"],"mappings":";;;;;;AAcO,MAAMA,IAAoBC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;ACoE1B,IAAMC,IAAN,cAA0BC,EAAa;AAAA,E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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hx-button-modUSOpY.js","sources":["../../src/components/hx-button/hx-button.styles.ts","../../src/components/hx-button/hx-button.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixButtonStyles = css`\n :host {\n display: inline-block;\n }\n\n :host([disabled]) {\n pointer-events: none;\n opacity: var(--hx-opacity-disabled, 0.5);\n }\n\n :host([full]) {\n display: block;\n width: 100%;\n }\n\n :host([full]) .button {\n width: 100%;\n justify-content: center;\n }\n\n /* ─── Base Button ─── */\n\n .button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--hx-space-2, 0.5rem);\n border: var(--hx-border-width-thin, 1px) solid var(--hx-button-border-color, transparent);\n border-radius: var(--hx-button-border-radius, var(--hx-border-radius-md, 0.375rem));\n background-color: var(--hx-button-bg, var(--hx-color-primary-500, #429797));\n color: var(--hx-button-color, var(--hx-color-neutral-0, #ffffff));\n font-family: var(--hx-button-font-family, var(--hx-font-family-sans, sans-serif));\n font-weight: var(--hx-button-font-weight, var(--hx-font-weight-semibold, 600));\n line-height: var(--hx-line-height-tight, 1.25);\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 box-shadow var(--hx-transition-fast, 150ms ease);\n text-decoration: none;\n white-space: nowrap;\n user-select: none;\n -webkit-user-select: none;\n }\n\n .button:focus-visible {\n outline: var(--hx-focus-ring-width, 2px) solid\n var(\n --hx-button-focus-ring-color,\n var(--hx-focus-ring-color, var(--hx-color-primary-500, #429797))\n );\n outline-offset: var(--hx-focus-ring-offset, 2px);\n }\n\n .button:hover {\n filter: brightness(var(--hx-filter-brightness-hover, 0.9));\n }\n\n .button:active {\n filter: brightness(var(--hx-filter-brightness-active, 0.8));\n }\n\n /* ─── Size Variants ─── */\n\n /* WCAG 2.5.5 (healthcare mandate): minimum 44px touch target for sm variant.\n min-height uses --hx-touch-target-min to guarantee the interactive area\n meets the threshold even though the visual size token is smaller. */\n .button--sm {\n padding: var(--hx-space-1, 0.25rem) var(--hx-space-3, 0.75rem);\n font-size: var(--hx-font-size-sm, 0.875rem);\n min-height: var(--hx-touch-target-min, 2.75rem);\n }\n\n .button--md {\n padding: var(--hx-space-2, 0.5rem) var(--hx-space-4, 1rem);\n font-size: var(--hx-font-size-md, 1rem);\n min-height: var(--hx-size-10, 2.5rem);\n }\n\n .button--lg {\n padding: var(--hx-space-3, 0.75rem) var(--hx-space-6, 1.5rem);\n font-size: var(--hx-font-size-lg, 1.125rem);\n min-height: var(--hx-size-12, 3rem);\n }\n\n /* ─── Style Variants ─── */\n\n .button--primary {\n --hx-button-bg: var(--hx-color-primary-500, #429797);\n --hx-button-color: var(--hx-color-text-on-primary, #ffffff);\n --hx-button-border-color: transparent;\n }\n\n .button--secondary {\n --hx-button-bg: transparent;\n /* primary-500 (#429797) text on white surface = 3.43:1 — fails AA.\n primary-600 (#0F7078) on white = 6.06:1 — AA pass. */\n --hx-button-color: var(--hx-color-primary-600, #0f7078);\n --hx-button-border-color: var(--hx-color-primary-600, #0f7078);\n }\n\n .button--secondary:hover {\n --hx-button-bg: var(--hx-button-hover-bg, var(--hx-color-surface-raised, #f5f8f3));\n }\n\n .button--tertiary {\n --hx-button-bg: var(--hx-color-surface-sunken, #ebeee9);\n --hx-button-color: var(--hx-color-text-primary, #0d1825);\n --hx-button-border-color: transparent;\n }\n\n .button--tertiary:hover {\n --hx-button-bg: var(--hx-button-hover-bg, var(--hx-color-surface-raised, #f5f8f3));\n }\n\n .button--danger {\n --hx-button-bg: var(--hx-color-error-500, #e5493e);\n --hx-button-color: var(--hx-color-text-on-error, #ffffff);\n --hx-button-border-color: transparent;\n }\n\n /* on-error tokens are tuned for error-500 (neutral-900 on #E5493E ≈ 4.59:1).\n error-600 (#C92A2A) drops that to 2.25:1 — AA fail. Hold fg at neutral-0\n directly so darker hover fills stay legible. Mirrors hx-toast precedent\n (commit 300e21ab0). */\n .button--danger:hover {\n --hx-button-bg: var(--hx-button-hover-bg, var(--hx-color-error-600, #c92a2a));\n --hx-button-color: var(--hx-color-neutral-0, #ffffff);\n }\n\n .button--ghost {\n --hx-button-bg: transparent;\n /* primary-500 (#429797) text on white surface = 3.43:1 — fails AA.\n primary-600 (#0F7078) on white = 6.06:1 — AA pass. */\n --hx-button-color: var(--hx-color-primary-600, #0f7078);\n --hx-button-border-color: transparent;\n }\n\n .button--ghost:hover {\n --hx-button-bg: var(--hx-button-hover-bg, var(--hx-color-surface-raised, #f5f8f3));\n }\n\n .button--outline {\n --hx-button-bg: transparent;\n --hx-button-color: var(--hx-color-text-primary, #0d1825);\n --hx-button-border-color: var(--hx-color-border-strong, #8e9c98);\n }\n\n .button--outline:hover {\n --hx-button-bg: var(--hx-button-hover-bg, var(--hx-color-surface-raised, #f5f8f3));\n }\n\n /* on-primary token resolves to neutral-900 (#0D1825) — tuned for primary-500.\n primary-600 (#0F7078) drops the pair to 3.07:1 — AA fail. Pin fg at\n neutral-0 for the darker hover fill. Mirrors hx-toast precedent\n (commit 300e21ab0). */\n .button--primary:hover {\n --hx-button-bg: var(--hx-button-hover-bg, var(--hx-color-primary-600, #0f7078));\n --hx-button-color: var(--hx-color-neutral-0, #ffffff);\n }\n\n /* ─── Disabled ─── */\n\n /* Note: opacity is applied on :host([disabled]) above — do NOT add opacity here.\n Stacking opacity on both :host and .button[disabled] would multiply to 0.25. */\n .button[disabled] {\n cursor: not-allowed;\n }\n\n /* ─── Loading State ─── */\n\n .button--loading {\n position: relative;\n cursor: wait;\n }\n\n .button__spinner {\n width: 1em;\n height: 1em;\n flex-shrink: 0;\n animation: hx-spin var(--hx-duration-spinner, 750ms) linear infinite;\n }\n\n @keyframes hx-spin {\n to {\n transform: rotate(360deg);\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n .button {\n transition: none;\n }\n\n .button__spinner {\n animation: none;\n opacity: var(--hx-opacity-muted, 0.6);\n }\n }\n\n /* ─── Inverted Mode ─── */\n\n /* Override text color and filter-based hover/active for all variants */\n :host([inverted]) .button {\n color: var(--hx-button-inverted-color, var(--hx-color-neutral-0, #ffffff));\n filter: none;\n }\n\n :host([inverted]) .button:hover {\n filter: none;\n }\n\n :host([inverted]) .button:active {\n filter: none;\n }\n\n :host([inverted]) .button:focus-visible {\n outline-color: var(\n --hx-button-inverted-focus-ring-color,\n var(--hx-overlay-white-50, rgba(255, 255, 255, 0.5))\n );\n }\n\n /* Primary inverted — slight transparent white overlay on hover */\n :host([inverted]) .button--primary:hover {\n --hx-button-bg: var(--hx-color-primary-400, #6ab1b1);\n }\n\n /* Secondary inverted — white border and text */\n :host([inverted]) .button--secondary {\n --hx-button-border-color: var(--hx-overlay-white-70, rgba(255, 255, 255, 0.7));\n }\n\n :host([inverted]) .button--secondary:hover {\n --hx-button-bg: var(--hx-overlay-white-15, rgba(255, 255, 255, 0.15));\n }\n\n /* Tertiary inverted */\n :host([inverted]) .button--tertiary {\n --hx-button-bg: var(--hx-overlay-white-15, rgba(255, 255, 255, 0.15));\n --hx-button-border-color: transparent;\n }\n\n :host([inverted]) .button--tertiary:hover {\n --hx-button-bg: var(--hx-overlay-white-25, rgba(255, 255, 255, 0.25));\n }\n\n /* Ghost inverted — transparent base, white hover bg */\n :host([inverted]) .button--ghost {\n --hx-button-bg: transparent;\n --hx-button-border-color: transparent;\n }\n\n :host([inverted]) .button--ghost:hover {\n --hx-button-bg: var(\n --hx-button-inverted-ghost-hover-bg,\n var(--hx-overlay-white-20, rgba(255, 255, 255, 0.2))\n );\n }\n\n /* Outline inverted — white border */\n :host([inverted]) .button--outline {\n --hx-button-border-color: var(--hx-overlay-white-70, rgba(255, 255, 255, 0.7));\n }\n\n :host([inverted]) .button--outline:hover {\n --hx-button-bg: var(--hx-overlay-white-15, rgba(255, 255, 255, 0.15));\n }\n\n /* ─── Prefix / Suffix / Label ─── */\n\n .button__prefix,\n .button__suffix {\n display: inline-flex;\n align-items: center;\n flex-shrink: 0;\n }\n\n .button__label {\n flex: 1 1 auto;\n }\n\n /* ─── High Contrast Mode (forced-colors) ─── */\n\n @media (forced-colors: active) {\n .button {\n /* Ensure button outline is visible in Windows High Contrast mode.\n ButtonText/ButtonFace are system colors recognized by the browser. */\n forced-color-adjust: none;\n background-color: ButtonFace;\n color: ButtonText;\n border: 2px solid ButtonText;\n }\n\n .button:focus-visible {\n outline: 3px solid Highlight;\n outline-offset: 2px;\n }\n\n .button[disabled] {\n background-color: ButtonFace;\n color: GrayText;\n border-color: GrayText;\n opacity: 1;\n }\n\n :host([disabled]) {\n opacity: 1;\n }\n\n .button--loading .button__spinner {\n /* Ensure spinner is visible in HCM */\n forced-color-adjust: auto;\n }\n }\n`;\n","import { html, nothing, type TemplateResult, type PropertyValues } from 'lit';\nimport '../../utilities/document-token-adoption.js';\nimport { customElement, property } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { HelixElement } from '../../base/index.js';\nimport { mixinDelegatesAria } from '../../mixins/index.js';\nimport { helixButtonStyles } from './hx-button.styles.js';\nimport { forcedColorsInteractive } from '../../styles/forced-colors.js';\nimport { devWarn } from '../../utils/dev-warn.js';\n\n/** Detail for the hx-click event dispatched by hx-button. */\nexport interface HxButtonClickDetail {\n originalEvent: MouseEvent;\n}\n\n/**\n * A production-grade button component for user interaction. Supports multiple\n * visual variants, sizes, loading state, prefix/suffix slots, anchor rendering,\n * and full ElementInternals form association.\n *\n * @summary Primary interactive element for triggering actions and form submission.\n *\n * @tag hx-button\n *\n * @slot - Default slot for button label text or content.\n * @slot prefix - Icon or content rendered before the label.\n * @slot suffix - Icon or content rendered after the label.\n *\n * @fires {CustomEvent<{originalEvent: MouseEvent}>} hx-click - Dispatched when\n * the button is clicked and is neither disabled nor loading.\n *\n * @csspart button - The native button or anchor element.\n * @csspart label - The label text wrapper span.\n * @csspart prefix - The prefix slot container span.\n * @csspart suffix - The suffix slot container span.\n * @csspart spinner - The loading spinner SVG element.\n *\n * @cssprop [--hx-button-bg=var(--hx-color-primary-500)] - Button background color.\n * @cssprop [--hx-button-hover-bg] - Hover background color override. When set, overrides the variant default hover background from outside the shadow DOM.\n * @cssprop [--hx-button-color=var(--hx-color-neutral-0)] - Button text color.\n * @cssprop [--hx-button-border-color=transparent] - Button border color.\n * @cssprop [--hx-button-border-radius=var(--hx-border-radius-md)] - Button border radius.\n * @cssprop [--hx-button-font-family=var(--hx-font-family-sans)] - Button font family.\n * @cssprop [--hx-button-font-weight=var(--hx-font-weight-semibold)] - Button font weight.\n * @cssprop [--hx-button-focus-ring-color=var(--hx-focus-ring-color)] - Focus ring color.\n *\n * @cssprop [--hx-button-inverted-color=#ffffff] - Text color when inverted.\n * @cssprop [--hx-button-inverted-ghost-hover-bg=rgba(255,255,255,0.15)] - Ghost hover bg when inverted.\n * @cssprop [--hx-button-inverted-focus-ring-color=rgba(255,255,255,0.5)] - Focus ring color when inverted.\n * @cssprop [--hx-opacity-disabled] - Opacity.\n * @cssprop [--hx-space-2] - Spacing token.\n * @cssprop [--hx-border-width-thin] - Width.\n * @cssprop [--hx-border-radius-md] - CSS custom property.\n * @cssprop [--hx-color-primary-500] - Color.\n * @cssprop [--hx-color-neutral-0] - Color.\n * @cssprop [--hx-font-family-sans] - Font family.\n * @cssprop [--hx-font-weight-semibold] - Font weight.\n * @cssprop [--hx-line-height-tight] - Line height.\n * @cssprop [--hx-transition-fast] - Transition timing.\n * @cssprop [--hx-focus-ring-width] - Width.\n * @cssprop [--hx-focus-ring-color] - Color.\n * @cssprop [--hx-focus-ring-offset] - CSS custom property.\n * @cssprop [--hx-filter-brightness-hover] - CSS filter.\n * @cssprop [--hx-filter-brightness-active] - CSS filter.\n * @cssprop [--hx-space-1] - Spacing token.\n * @cssprop [--hx-space-3] - Spacing token.\n * @cssprop [--hx-font-size-sm] - Font size.\n * @cssprop [--hx-touch-target-min] - Minimum touch target size.\n * @cssprop [--hx-space-4] - Spacing token.\n * @cssprop [--hx-font-size-md] - Font size.\n * @cssprop [--hx-size-10] - Size token.\n * @cssprop [--hx-space-6] - Spacing token.\n * @cssprop [--hx-font-size-lg] - Font size.\n * @cssprop [--hx-size-12] - Size token.\n * @cssprop [--hx-color-primary-50] - Color.\n * @cssprop [--hx-color-neutral-100] - Color.\n * @cssprop [--hx-color-neutral-900] - Color.\n * @cssprop [--hx-color-neutral-200] - Color.\n * @cssprop [--hx-color-error-500] - Color.\n * @cssprop [--hx-color-error-600] - Color.\n * @cssprop [--hx-color-neutral-300] - Color.\n * @cssprop [--hx-color-neutral-50] - Color.\n * @cssprop [--hx-color-primary-600] - Color.\n * @cssprop [--hx-duration-spinner] - Animation duration.\n * @cssprop [--hx-opacity-muted] - Opacity.\n * @cssprop [--hx-overlay-white-50] - Overlay color.\n * @cssprop [--hx-color-primary-400] - Color.\n * @cssprop [--hx-overlay-white-70] - Overlay color.\n * @cssprop [--hx-overlay-white-15] - Overlay color.\n * @cssprop [--hx-overlay-white-25] - Overlay color.\n * @cssprop [--hx-overlay-white-20] - Overlay color.\n */\n@customElement('hx-button')\nexport class HelixButton extends mixinDelegatesAria(HelixElement) {\n static override styles = [helixButtonStyles, forcedColorsInteractive];\n\n // ─── Form Association ───\n\n /** @internal */\n static override formAssociated = true;\n\n // ─── Public Properties ───\n\n /**\n * Visual style variant of the button.\n * @attr variant\n */\n @property({ type: String, reflect: true })\n variant: 'primary' | 'secondary' | 'tertiary' | 'danger' | 'ghost' | 'outline' = 'primary';\n\n /**\n * Size of the button.\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 button is disabled. Prevents all interaction and form actions.\n * @attr disabled\n */\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /**\n * Whether the button is in a loading state. Shows spinner, prevents interaction,\n * and sets aria-busy. Does not set the disabled attribute.\n * @attr loading\n */\n @property({ type: Boolean, reflect: true })\n loading = false;\n\n /**\n * The type attribute for the underlying button element. Ignored when href is set.\n * @attr type\n */\n @property({ type: String })\n type: 'button' | 'submit' | 'reset' = 'button';\n\n /**\n * When set, renders an anchor element instead of a button.\n * @attr href\n */\n @property({ type: String })\n href: string | undefined = undefined;\n\n /**\n * Anchor target attribute. Only used when href is set.\n * @attr target\n */\n @property({ type: String })\n target: string | undefined = undefined;\n\n /**\n * Form field name submitted via ElementInternals.setFormValue on submit.\n * @attr name\n */\n @property({ type: String })\n name: string | undefined = undefined;\n\n /**\n * Form field value submitted via ElementInternals.setFormValue on submit.\n * @attr value\n */\n @property({ type: String })\n value: string | undefined = undefined;\n\n /**\n * When true, the button stretches to fill its container width.\n * Sets the host to `display: block` and the inner element to `width: 100%`.\n * @attr full\n */\n @property({ type: Boolean, reflect: true })\n full = false;\n\n /**\n * When true, flips button colors for placement on dark or gradient backgrounds.\n * Forces text to white and adjusts hover/focus ring colors across all variants.\n * @attr inverted\n */\n @property({ type: Boolean, reflect: true })\n inverted = false;\n\n /**\n * Accessible label for icon-only or text-less buttons.\n * Required when the button has no visible text content.\n *\n * Accepts both `accessible-label` and the standard `aria-label` HTML attribute.\n * `accessible-label` takes precedence when both are set.\n *\n * @attr accessible-label\n */\n @property({ type: String, attribute: 'accessible-label' })\n accessibleLabel: string = '';\n\n /**\n * Returns the effective label for the button, checking accessible-label first,\n * then the aria-label attribute, falling back to empty string.\n * @internal\n */\n private get _effectiveLabel(): string {\n return this.accessibleLabel?.trim() || this.ariaLabel?.trim() || '';\n }\n\n // ─── Form API ───\n\n protected override _onFormDisabled(disabled: boolean): void {\n this.disabled = disabled;\n }\n\n // ─── Lifecycle ───\n\n /** @internal */\n private static readonly _VALID_VARIANTS = [\n 'primary',\n 'secondary',\n 'tertiary',\n 'danger',\n 'ghost',\n 'outline',\n ] as const;\n\n // Prevents double-warn on browsers that fire slotchange for empty initial slots.\n private _emptySlotWarnEmitted = false;\n\n override firstUpdated(changedProperties: PropertyValues<this>): void {\n super.firstUpdated(changedProperties);\n const slot = this.shadowRoot?.querySelector<HTMLSlotElement>('slot:not([name])');\n const hasContent = (slot?.assignedNodes({ flatten: true }) ?? []).some(\n (n) => n.nodeType !== Node.TEXT_NODE || (n.textContent?.trim().length ?? 0) > 0,\n );\n if (!hasContent && !this._effectiveLabel) {\n this._emptySlotWarnEmitted = true;\n devWarn(\n 'hx-button',\n 'hx-button has no slot content and no accessible-label — button will have no accessible name.',\n );\n }\n }\n\n override updated(changedProperties: PropertyValues<this>): void {\n super.updated(changedProperties);\n if (changedProperties.has('variant')) {\n const validVariants: string[] = [...HelixButton._VALID_VARIANTS];\n if (!validVariants.includes(this.variant)) {\n devWarn(\n 'hx-button',\n `Invalid variant \"${this.variant}\". Expected one of: ${validVariants.join(', ')}. Clamping to \"primary\".`,\n );\n this.variant = 'primary';\n }\n }\n }\n\n // ─── Slot Handlers ───\n\n /** @internal */\n private _handleDefaultSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n const hasContent = slot\n .assignedNodes({ flatten: true })\n .some((n) => n.nodeType !== Node.TEXT_NODE || (n.textContent?.trim().length ?? 0) > 0);\n if (!hasContent && !this._effectiveLabel && !this._emptySlotWarnEmitted) {\n devWarn(\n 'hx-button',\n 'hx-button has no slot content and no accessible-label — button will have no accessible name.',\n );\n }\n // Only reset once content arrives so the guard stays armed for browsers\n // that fire a second slotchange for the same empty initial slot.\n if (hasContent) {\n this._emptySlotWarnEmitted = false;\n }\n }\n\n // ─── Event Handling ───\n\n /**\n * @private\n * @internal\n */\n private _handleClick(e: MouseEvent): void {\n if (this.disabled || this.loading) {\n e.preventDefault();\n e.stopPropagation();\n return;\n }\n\n /**\n * Dispatched when the button is clicked.\n * @event hx-click\n */\n this.dispatchEvent(\n new CustomEvent<{ originalEvent: MouseEvent }>('hx-click', {\n bubbles: true,\n composed: true,\n detail: { originalEvent: e },\n }),\n );\n\n // Handle form submission/reset if form-associated and not in anchor mode\n if (this.href === undefined && this.type === 'submit' && this._internals.form) {\n if (this.name !== undefined && this.value !== undefined) {\n this._internals.setFormValue(this.value);\n }\n this._internals.form.requestSubmit();\n } else if (this.href === undefined && this.type === 'reset' && this._internals.form) {\n this._internals.form.reset();\n }\n }\n\n // ─── Render Helpers ───\n\n /**\n * @private\n * @internal\n */\n private _renderSpinner(): TemplateResult {\n return html`\n <svg\n class=\"button__spinner\"\n part=\"spinner\"\n aria-hidden=\"true\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n >\n <circle\n class=\"button__spinner-track\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n opacity=\"0.3\"\n />\n <path\n class=\"button__spinner-arc\"\n d=\"M12 2a10 10 0 0 1 10 10\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n />\n </svg>\n `;\n }\n\n /**\n * @private\n * @internal\n */\n private _renderInner(): TemplateResult {\n return html`\n ${this.loading ? this._renderSpinner() : nothing}\n <span part=\"prefix\" class=\"button__prefix\">\n <slot name=\"prefix\"></slot>\n </span>\n <span part=\"label\" class=\"button__label\">\n <slot @slotchange=${this._handleDefaultSlotChange}></slot>\n </span>\n <span part=\"suffix\" class=\"button__suffix\">\n <slot name=\"suffix\"></slot>\n </span>\n `;\n }\n\n // ─── Render ───\n\n override render() {\n const classes = {\n button: true,\n [`button--${this.variant}`]: true,\n [`button--${this.size}`]: true,\n 'button--loading': this.loading,\n };\n\n if (this.href !== undefined) {\n return html`\n <a\n part=\"button\"\n class=${classMap(classes)}\n href=${this.disabled || this.loading ? nothing : ifDefined(this.href)}\n target=${ifDefined(this.target)}\n rel=${this.target === '_blank' ? 'noopener noreferrer' : nothing}\n aria-label=${this._effectiveLabel || nothing}\n aria-disabled=${this.disabled ? 'true' : nothing}\n aria-busy=${this.loading ? 'true' : nothing}\n tabindex=${this.disabled ? '-1' : nothing}\n @click=${this._handleClick}\n >\n ${this._renderInner()}\n </a>\n `;\n }\n\n return html`\n <button\n part=\"button\"\n class=${classMap(classes)}\n ?disabled=${this.disabled}\n type=${this.type}\n aria-label=${this._effectiveLabel || nothing}\n aria-busy=${this.loading ? 'true' : nothing}\n @click=${this._handleClick}\n >\n ${this._renderInner()}\n </button>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-button': HelixButton;\n }\n interface HTMLElementEventMap {\n 'hx-click': CustomEvent<{ originalEvent: MouseEvent }>;\n }\n}\n"],"names":["helixButtonStyles","css","HelixButton","mixinDelegatesAria","HelixElement","_a","_b","disabled","changedProperties","slot","n","validVariants","devWarn","e","hasContent","html","nothing","classes","classMap","ifDefined","forcedColorsInteractive","__decorateClass","property","customElement"],"mappings":";;;;;;;;AAEO,MAAMA,IAAoBC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hx-card-CU1QnjNb.js","sources":["../../src/components/hx-card/hx-card.styles.ts","../../src/components/hx-card/hx-card.ts"],"sourcesContent":["import { css } from 'lit';\n\n/**\n * hx-card styles.\n *\n * Component-tier tokens with two-level var() fallback:\n * var(--hx-card-{prop}, var(--hx-color-{semantic}, #hex))\n * Inner hex fallbacks track the \"precision cool\" palette (3.2.0):\n * neutral-0 = #FFFFFF, neutral-200 = #D6DBD5, neutral-800 = #202B39,\n * neutral-600 = #4A5362, primary-500 = #429797.\n */\nexport const helixCardStyles = css`\n :host {\n display: block;\n color: var(--hx-card-color, inherit);\n background-color: var(--hx-card-bg, var(--hx-color-surface-default, #ffffff));\n }\n\n .card {\n display: flex;\n flex-direction: column;\n gap: var(--hx-card-gap, var(--hx-space-4, 1rem));\n background-color: var(--hx-card-bg, var(--hx-color-surface-default, #ffffff));\n color: var(--hx-card-color, var(--hx-color-text-strong, #202b39));\n border: var(--hx-border-width-thin, 1px) solid\n var(--hx-card-border-color, var(--hx-color-border-default, #d6dbd5));\n border-radius: var(--hx-card-border-radius, var(--hx-border-radius-lg, 0.5rem));\n overflow: hidden;\n font-family: var(--hx-card-font-family, var(--hx-font-family-sans, sans-serif));\n transition:\n box-shadow var(--hx-transition-normal, 250ms ease),\n transform var(--hx-transition-normal, 250ms ease);\n }\n\n /* ─── Elevation Variants ─── */\n\n .card--flat {\n box-shadow: none;\n }\n\n .card--raised {\n box-shadow: var(--hx-card-shadow, var(--hx-shadow-md, 0 4px 6px -1px rgb(0 0 0 / 0.1)));\n }\n\n .card--floating {\n box-shadow: var(\n --hx-card-shadow-floating,\n var(--hx-shadow-xl, 0 20px 25px -5px rgb(0 0 0 / 0.1))\n );\n }\n\n /* ─── Style Variants ─── */\n\n .card--default {\n /* Default styling — uses base styles */\n }\n\n .card--featured {\n border-color: var(--hx-card-featured-border-color, var(--hx-color-primary-500, #429797));\n border-width: var(--hx-card-featured-border-width, var(--hx-border-width-medium, 2px));\n }\n\n .card--compact .card__body {\n padding: var(--hx-space-3, 0.75rem);\n }\n\n .card--compact .card__heading {\n padding-top: var(--hx-space-3, 0.75rem);\n padding-inline-end: var(--hx-space-3, 0.75rem);\n padding-inline-start: var(--hx-space-3, 0.75rem);\n }\n\n .card--compact .card__footer {\n padding-inline-end: var(--hx-space-3, 0.75rem);\n padding-bottom: var(--hx-space-3, 0.75rem);\n padding-inline-start: var(--hx-space-3, 0.75rem);\n }\n\n .card--compact .card__actions {\n padding-inline-end: var(--hx-space-3, 0.75rem);\n padding-bottom: var(--hx-space-3, 0.75rem);\n padding-inline-start: var(--hx-space-3, 0.75rem);\n }\n\n /* ─── Interactive ─── */\n\n .card--interactive {\n cursor: pointer;\n }\n\n .card--interactive:hover {\n box-shadow: var(--hx-card-shadow-hover, var(--hx-shadow-lg, 0 10px 15px -3px rgb(0 0 0 / 0.1)));\n transform: translateY(var(--hx-transform-lift-md, -2px));\n }\n\n .card--interactive:focus-visible {\n outline: var(--hx-focus-ring-width, 2px) solid\n var(\n --hx-card-focus-ring-color,\n var(--hx-focus-ring-color, var(--hx-color-primary-500, #429797))\n );\n outline-offset: var(--hx-focus-ring-offset, 2px);\n }\n\n .card--interactive:active {\n transform: translateY(0);\n }\n\n @media (prefers-reduced-motion: reduce) {\n .card {\n transition: none;\n }\n\n .card--interactive:hover {\n transform: none;\n }\n\n .card--interactive:active {\n transform: none;\n }\n }\n\n /* ─── Hidden empty slot wrappers ─── */\n\n [hidden] {\n display: none !important;\n }\n\n /* ─── Sections ─── */\n\n .card__image {\n overflow: hidden;\n line-height: 0;\n }\n\n .card__image ::slotted(img) {\n width: 100%;\n aspect-ratio: var(--hx-card-image-aspect-ratio, 16 / 9);\n display: block;\n object-fit: cover;\n }\n\n .card__heading {\n padding-top: var(--hx-card-padding, var(--hx-space-6, 1.5rem));\n padding-inline-end: var(--hx-card-padding, var(--hx-space-6, 1.5rem));\n padding-bottom: 0;\n padding-inline-start: var(--hx-card-padding, var(--hx-space-6, 1.5rem));\n font-size: var(--hx-font-size-xl, 1.25rem);\n font-weight: var(--hx-font-weight-semibold, 600);\n line-height: var(--hx-line-height-tight, 1.25);\n }\n\n .card__body {\n padding: var(--hx-card-padding, var(--hx-space-6, 1.5rem));\n flex: 1;\n font-size: var(--hx-font-size-md, 1rem);\n line-height: var(--hx-line-height-normal, 1.5);\n /*\n * Body color cascades: component-tier --hx-card-body-color overrides\n * the host-tier --hx-card-color, which falls back to text-secondary.\n * Preserves the propagation contract: setting --hx-card-color on the\n * host flows into the body slot (and through to slotted light-DOM\n * descendants via flat-tree inheritance).\n */\n color: var(--hx-card-body-color, var(--hx-card-color, var(--hx-color-text-secondary, #313e4b)));\n }\n\n .card__footer {\n padding-top: 0;\n padding-inline-end: var(--hx-card-padding, var(--hx-space-6, 1.5rem));\n padding-bottom: var(--hx-card-padding, var(--hx-space-6, 1.5rem));\n padding-inline-start: var(--hx-card-padding, var(--hx-space-6, 1.5rem));\n }\n\n .card__actions {\n display: flex;\n gap: var(--hx-space-2, 0.5rem);\n padding-top: var(--hx-space-4, 1rem);\n padding-inline-end: var(--hx-card-padding, var(--hx-space-6, 1.5rem));\n padding-bottom: var(--hx-card-padding, var(--hx-space-6, 1.5rem));\n padding-inline-start: var(--hx-card-padding, var(--hx-space-6, 1.5rem));\n border-top: var(--hx-border-width-thin, 1px) solid\n var(--hx-card-border-color, var(--hx-color-border-default, #d6dbd5));\n margin-top: auto;\n }\n\n /* ─── Forced Colors (Windows High Contrast) ─── */\n /* Belt-and-suspenders: rich per-class HC overrides PLUS the forcedColorsSurface mixin. */\n\n @media (forced-colors: active) {\n .card {\n border-color: CanvasText;\n }\n\n .card__actions {\n border-top-color: CanvasText;\n }\n }\n`;\n","import { html, nothing, type PropertyValues } 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 { HelixElement, createIdCounter } from '../../base/index.js';\nimport { helixCardStyles } from './hx-card.styles.js';\nimport { forcedColorsSurface } from '../../styles/forced-colors.js';\nimport { devWarn } from '../../utils/dev-warn.js';\n\nconst _nextCardId = createIdCounter('hx-card');\n\n/**\n * A flexible card component for displaying grouped content.\n *\n * @summary Content container with image, heading, body, footer, and action slots.\n *\n * @tag hx-card\n *\n * @slot image - Optional image or media content at the top of the card.\n * @slot heading - The card heading/title content. Use a semantic heading element (h2, h3, etc.) for proper accessibility.\n * @slot - Default slot for the card body content.\n * @slot footer - Optional footer content below the body.\n * @slot actions - Optional action buttons, rendered with a top border separator. Do NOT use together with hx-href (interactive card + focusable actions is an ARIA anti-pattern).\n *\n * @fires {CustomEvent<{href: string, originalEvent: MouseEvent | KeyboardEvent}>} hx-click - Dispatched when an interactive card (with hx-href) is clicked.\n *\n * @csspart card - The outer card container element.\n * @csspart image - The image slot container.\n * @csspart heading - The heading slot container.\n * @csspart body - The body slot container.\n * @csspart footer - The footer slot container.\n * @csspart actions - The actions slot container.\n *\n * @cssprop [--hx-card-bg=var(--hx-color-neutral-0)] - Card background color.\n * @cssprop [--hx-card-color=var(--hx-color-neutral-800)] - Card text color.\n * @cssprop [--hx-card-border-color=var(--hx-color-neutral-200)] - Card border color.\n * @cssprop [--hx-card-border-radius=var(--hx-border-radius-lg)] - Card border radius.\n * @cssprop [--hx-card-padding=var(--hx-space-6)] - Internal padding for card sections.\n * @cssprop [--hx-card-gap=var(--hx-space-4)] - Gap between card sections.\n * @cssprop [--hx-card-image-aspect-ratio=16/9] - Aspect ratio for the image slot.\n * @cssprop [--hx-border-radius-lg] - CSS custom property.\n * @cssprop [--hx-border-width-medium] - Width.\n * @cssprop [--hx-border-width-thin] - Width.\n * @cssprop [--hx-card-focus-ring-color=var(--hx-focus-ring-color)] - Color.\n * @cssprop [--hx-card-font-family=var(--hx-font-family-sans)] - Font family for card text content.\n * @cssprop [--hx-color-neutral-0] - Color.\n * @cssprop [--hx-color-neutral-200] - Color.\n * @cssprop [--hx-color-neutral-600] - Color.\n * @cssprop [--hx-color-neutral-800] - Color.\n * @cssprop [--hx-color-primary-500] - Color.\n * @cssprop [--hx-focus-ring-color] - Color.\n * @cssprop [--hx-focus-ring-offset] - CSS custom property.\n * @cssprop [--hx-focus-ring-width] - Width.\n * @cssprop [--hx-font-family-sans] - Font family.\n * @cssprop [--hx-font-size-md] - Font size.\n * @cssprop [--hx-font-size-xl] - Font size.\n * @cssprop [--hx-font-weight-semibold] - Font weight.\n * @cssprop [--hx-line-height-normal] - Line height.\n * @cssprop [--hx-line-height-tight] - Line height.\n * @cssprop [--hx-shadow-lg] - Box shadow.\n * @cssprop [--hx-shadow-md] - Box shadow.\n * @cssprop [--hx-shadow-xl] - Box shadow.\n * @cssprop [--hx-space-2] - Spacing token.\n * @cssprop [--hx-space-3] - Spacing token.\n * @cssprop [--hx-space-4] - Spacing token.\n * @cssprop [--hx-space-6] - Spacing token.\n * @cssprop [--hx-transform-lift-md] - Transform applied on hover to lift the card.\n * @cssprop [--hx-transition-normal] - Transition timing.\n */\n@customElement('hx-card')\nexport class HelixCard extends HelixElement {\n /** @internal */\n static override shadowRootOptions = {\n ...HelixElement.shadowRootOptions,\n delegatesFocus: true,\n };\n\n static override styles = [helixCardStyles, forcedColorsSurface];\n\n /**\n * Visual style variant of the card.\n * @attr variant\n */\n @property({ type: String, reflect: true })\n variant: 'default' | 'featured' | 'compact' = 'default';\n\n /**\n * Elevation (shadow depth) of the card.\n * @attr elevation\n */\n @property({ type: String, reflect: true })\n elevation: 'flat' | 'raised' | 'floating' = 'flat';\n\n /**\n * Optional URL. When set, the card becomes interactive (clickable)\n * and navigates to this URL on click.\n * Uses the hx-href attribute to avoid conflicting with the native HTML href attribute.\n * @attr hx-href\n */\n @property({ type: String, attribute: 'hx-href' })\n href: string | undefined = undefined;\n\n /**\n * Accessible label for interactive cards. Use this to provide a meaningful\n * description of the card's purpose rather than exposing the raw URL.\n * Only applies when hx-href is set.\n * @attr hx-label\n */\n @property({ type: String, attribute: 'hx-label' })\n label: string | undefined = undefined;\n\n // ─── Slot Detection ───\n\n /**\n * Tracks whether any content is assigned to the image slot, controlling slot container visibility.\n * @internal\n */\n @state() private _hasImage = false;\n\n /**\n * Tracks whether any content is assigned to the heading slot, controlling slot container visibility.\n * @internal\n */\n @state() private _hasHeading = false;\n\n /**\n * Tracks whether any content is assigned to the footer slot, controlling slot container visibility.\n * @internal\n */\n @state() private _hasFooter = false;\n\n /**\n * Tracks whether any content is assigned to the actions slot, controlling slot container visibility.\n * @internal\n */\n @state() private _hasActions = false;\n\n /**\n * Text content extracted from the heading slot, used as a fallback accessible\n * name for interactive cards when no explicit `hx-label` is provided.\n * @internal\n */\n @state() private _headingText = '';\n\n /**\n * Unique identifier for this card instance, used in ARIA attributes.\n * @internal\n */\n private _cardId = _nextCardId();\n /**\n * Unique identifier for the heading element, used in aria-labelledby.\n * @internal\n */\n private _headingId = `${this._cardId}-heading`;\n\n /** @internal */\n private _onImageSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n this._hasImage = slot.assignedNodes({ flatten: true }).length > 0;\n }\n\n /** @internal */\n private _onHeadingSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n const nodes = slot.assignedNodes({ flatten: true });\n this._hasHeading = nodes.length > 0;\n this._headingText = nodes\n .map((n) => n.textContent?.trim() ?? '')\n .join(' ')\n .trim();\n }\n\n /** @internal */\n private _onFooterSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n this._hasFooter = slot.assignedNodes({ flatten: true }).length > 0;\n }\n\n /** @internal */\n private _onActionsSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n this._hasActions = slot.assignedNodes({ flatten: true }).length > 0;\n if (this._hasActions && this.href) {\n devWarn(\n 'hx-card',\n 'Using hx-href (interactive card) together with the actions slot is an ARIA anti-pattern: ' +\n 'interactive controls cannot be nested inside role=\"link\". ' +\n 'Use either hx-href or the actions slot, not both.',\n );\n }\n }\n\n override updated(changedProperties: PropertyValues<this>): void {\n super.updated(changedProperties);\n // WCAG 4.1.2: interactive cards (with hx-href) must have an accessible name\n if (\n (changedProperties.has('href') || changedProperties.has('label')) &&\n this.href &&\n !this.label &&\n !this._headingText\n ) {\n devWarn(\n 'hx-card',\n \"Interactive card (hx-href is set) is missing an accessible name. Set `hx-label` or provide heading slot content to describe the card's destination or purpose (WCAG 4.1.2).\",\n );\n }\n }\n\n // ─── Event Handling ───\n\n /** @internal */\n private _dispatchCardClick(originalEvent: MouseEvent | KeyboardEvent): void {\n if (!this.href) return;\n\n /**\n * Dispatched when an interactive card is clicked.\n * Includes the target href in the detail.\n * @event hx-click\n */\n this.dispatchEvent(\n new CustomEvent<{ href: string; originalEvent: MouseEvent | KeyboardEvent }>('hx-click', {\n bubbles: true,\n composed: true,\n detail: { href: this.href, originalEvent },\n }),\n );\n }\n\n /** @internal */\n private _handleClick(e: MouseEvent): void {\n this._dispatchCardClick(e);\n }\n\n /** @internal */\n private _handleKeyDown(e: KeyboardEvent): void {\n if (!this.href) return;\n\n // WCAG 2.1.1 / ARIA APG: role=\"link\" activates on Enter only.\n // Space is reserved for scrolling and must not activate links.\n if (e.key === 'Enter') {\n e.preventDefault();\n this._dispatchCardClick(e);\n }\n }\n\n // ─── Render ───\n\n override render() {\n const isInteractive = !!this.href;\n\n const classes = {\n card: true,\n [`card--${this.variant}`]: true,\n [`card--${this.elevation}`]: true,\n 'card--interactive': isInteractive,\n };\n\n return html`\n <div\n part=\"card\"\n class=${classMap(classes)}\n role=${isInteractive ? 'link' : nothing}\n tabindex=${isInteractive ? '0' : nothing}\n aria-label=${isInteractive && this.label ? this.label : nothing}\n aria-labelledby=${this._hasHeading && !this.label ? this._headingId : nothing}\n @click=${this._handleClick}\n @keydown=${this._handleKeyDown}\n >\n <div class=\"card__image\" part=\"image\" ?hidden=${!this._hasImage}>\n <slot name=\"image\" @slotchange=${this._onImageSlotChange}></slot>\n </div>\n\n <div\n class=\"card__heading\"\n part=\"heading\"\n id=${this._headingId}\n ?hidden=${!this._hasHeading}\n >\n <slot name=\"heading\" @slotchange=${this._onHeadingSlotChange}></slot>\n </div>\n\n <div class=\"card__body\" part=\"body\">\n <slot></slot>\n </div>\n\n <div class=\"card__footer\" part=\"footer\" ?hidden=${!this._hasFooter}>\n <slot name=\"footer\" @slotchange=${this._onFooterSlotChange}></slot>\n </div>\n\n <div class=\"card__actions\" part=\"actions\" ?hidden=${!this._hasActions}>\n <slot name=\"actions\" @slotchange=${this._onActionsSlotChange}></slot>\n </div>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-card': HelixCard;\n }\n}\n"],"names":["helixCardStyles","css","_nextCardId","createIdCounter","HelixCard","HelixElement","e","slot","nodes","n","_a","changedProperties","originalEvent","isInteractive","classes","html","classMap","nothing","forcedColorsSurface","__decorateClass","property","state","customElement"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hx-carousel-item-BaE4hpLl.js","sources":["../../src/components/hx-carousel/hx-carousel.styles.ts","../../src/components/hx-carousel/hx-carousel.ts","../../src/components/hx-carousel/hx-carousel-item.styles.ts","../../src/components/hx-carousel/hx-carousel-item.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixCarouselStyles = css`\n :host {\n display: block;\n position: relative;\n }\n\n /* ─── Base ─── */\n\n .base {\n display: flex;\n flex-direction: column;\n gap: var(--hx-space-3, 0.75rem);\n }\n\n :host([orientation='vertical']) .base {\n flex-direction: row;\n }\n\n /* ─── Navigation ─── */\n\n .navigation {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: var(--hx-space-2, 0.5rem);\n }\n\n :host([orientation='vertical']) .navigation {\n flex-direction: column;\n }\n\n .nav-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--hx-carousel-nav-btn-size, var(--hx-size-10, 2.5rem));\n height: var(--hx-carousel-nav-btn-size, var(--hx-size-10, 2.5rem));\n /* WCAG 2.5.5 (healthcare mandate): minimum 44x44px touch target */\n min-width: var(--hx-touch-target-min, 2.75rem);\n min-height: var(--hx-touch-target-min, 2.75rem);\n border: var(--hx-border-width-thin, 1px) solid\n var(--hx-carousel-nav-btn-border-color, var(--hx-color-neutral-200, #d6dbd5));\n border-radius: var(--hx-border-radius-full, 9999px);\n background: var(--hx-carousel-nav-btn-bg, var(--hx-color-neutral-0, #ffffff));\n color: var(--hx-carousel-nav-btn-color, var(--hx-color-neutral-700, #313e4b));\n cursor: pointer;\n padding: 0;\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 flex-shrink: 0;\n }\n\n .nav-btn:hover:not([disabled]) {\n background: var(--hx-carousel-nav-btn-hover-bg, var(--hx-color-neutral-50, #f5f8f3));\n border-color: var(\n --hx-carousel-nav-btn-hover-border-color,\n var(--hx-color-neutral-400, #8e9c98)\n );\n }\n\n .nav-btn:focus-visible {\n outline: var(--hx-focus-ring-width, 2px) solid\n var(--hx-carousel-focus-ring-color, var(--hx-focus-ring-color, var(--hx-color-primary-500)));\n outline-offset: var(--hx-focus-ring-offset, 2px);\n }\n\n .nav-btn[disabled] {\n opacity: var(--hx-opacity-disabled, 0.5);\n cursor: not-allowed;\n }\n\n .nav-btn svg {\n width: 1.25em;\n height: 1.25em;\n }\n\n /* ─── Play/Pause ─── */\n\n .play-pause-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n /* WCAG 2.5.5 (healthcare mandate): minimum 44x44px touch target */\n min-width: var(--hx-touch-target-min, 2.75rem);\n min-height: var(--hx-touch-target-min, 2.75rem);\n width: var(--hx-touch-target-min, 2.75rem);\n height: var(--hx-touch-target-min, 2.75rem);\n border: var(--hx-border-width-thin, 1px) solid transparent;\n border-radius: var(--hx-border-radius-md, 0.375rem);\n background: transparent;\n color: var(--hx-carousel-play-pause-color, var(--hx-color-neutral-500, #66787b));\n cursor: pointer;\n padding: 0;\n font-size: var(--hx-font-size-sm, 0.875rem);\n transition: background-color var(--hx-transition-fast, 150ms ease);\n flex-shrink: 0;\n }\n\n .play-pause-btn:hover {\n background: var(--hx-carousel-play-pause-hover-bg, var(--hx-color-neutral-100, #ebeee9));\n }\n\n .play-pause-btn:focus-visible {\n outline: var(--hx-focus-ring-width, 2px) solid\n var(--hx-carousel-focus-ring-color, var(--hx-focus-ring-color, var(--hx-color-primary-500)));\n outline-offset: var(--hx-focus-ring-offset, 2px);\n }\n\n /* ─── Scroll Container ─── */\n\n .scroll-container-wrapper {\n flex: 1;\n overflow: hidden;\n }\n\n .slide-viewport {\n overflow: hidden;\n border-radius: var(--hx-border-radius-md, 0.375rem);\n }\n\n .track {\n display: flex;\n transition: transform var(--hx-transition-base, 0.3s ease);\n }\n\n :host([orientation='vertical']) .track {\n flex-direction: column;\n }\n\n /* ─── Pagination ─── */\n\n .pagination {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: var(--hx-space-2, 0.5rem);\n flex-wrap: wrap;\n }\n\n :host([orientation='vertical']) .pagination {\n flex-direction: column;\n }\n\n .pagination-item {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n /* WCAG 2.5.5 (healthcare mandate): minimum 44x44px touch target */\n min-width: var(--hx-touch-target-min, 2.75rem);\n min-height: var(--hx-touch-target-min, 2.75rem);\n padding: 0;\n border: none;\n cursor: pointer;\n background: transparent;\n border-radius: var(--hx-border-radius-full, 9999px);\n }\n\n .pagination-dot {\n display: block;\n width: var(--hx-carousel-pagination-dot-size, 0.5rem);\n height: var(--hx-carousel-pagination-dot-size, 0.5rem);\n border-radius: var(--hx-border-radius-full, 9999px);\n background: var(--hx-carousel-pagination-dot-bg, var(--hx-color-neutral-300, #b6bfb9));\n transition:\n background-color var(--hx-transition-fast, 150ms ease),\n transform var(--hx-transition-fast, 150ms ease);\n }\n\n .pagination-item[aria-current='true'] .pagination-dot,\n .pagination-item.is-active .pagination-dot {\n background: var(--hx-carousel-pagination-dot-active-bg, var(--hx-color-primary-600, #0f7078));\n transform: scale(1.25);\n }\n\n .pagination-item:focus-visible {\n outline: var(--hx-focus-ring-width, 2px) solid\n var(--hx-carousel-focus-ring-color, var(--hx-focus-ring-color, var(--hx-color-primary-500)));\n outline-offset: var(--hx-focus-ring-offset, 2px);\n border-radius: var(--hx-border-radius-full, 9999px);\n }\n\n /* ─── Controls row ─── */\n\n .controls {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: var(--hx-space-3, 0.75rem);\n }\n\n /* ─── Live Region ─── */\n\n .live-region {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n }\n\n /* ─── Reduced Motion ─── */\n\n @media (prefers-reduced-motion: reduce) {\n .track,\n .nav-btn,\n .pagination-dot,\n .play-pause-btn {\n transition: none;\n }\n }\n\n /* ─── Forced Colors (Windows High Contrast) ─── */\n\n @media (forced-colors: active) {\n .nav-btn {\n border-color: ButtonText;\n color: ButtonText;\n }\n\n .play-pause-btn {\n border-color: ButtonText;\n color: ButtonText;\n }\n\n .pagination-dot {\n border: 1px solid CanvasText;\n }\n\n .pagination-item[aria-current='true'] .pagination-dot,\n .pagination-item.is-active .pagination-dot {\n background: Highlight;\n border-color: Highlight;\n }\n }\n`;\n","import { 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 { HelixElement } from '../../base/index.js';\nimport { helixCarouselStyles } from './hx-carousel.styles.js';\nimport { forcedColorsInteractive } from '../../styles/forced-colors.js';\nimport type { HelixCarouselItem } from './hx-carousel-item.js';\n\n// ─── Module-level SVG icon constants ───\n\nconst _svgChevronLeft = html`<svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n>\n <polyline points=\"15 18 9 12 15 6\"></polyline>\n</svg>`;\n\nconst _svgChevronUp = html`<svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n>\n <polyline points=\"18 15 12 9 6 15\"></polyline>\n</svg>`;\n\nconst _svgChevronRight = html`<svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n>\n <polyline points=\"9 18 15 12 9 6\"></polyline>\n</svg>`;\n\nconst _svgChevronDown = html`<svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n>\n <polyline points=\"6 9 12 15 18 9\"></polyline>\n</svg>`;\n\nconst _svgPlay = html`<svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n width=\"1em\"\n height=\"1em\"\n>\n <polygon points=\"5 3 19 12 5 21 5 3\"></polygon>\n</svg>`;\n\nconst _svgPause = html`<svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n width=\"1em\"\n height=\"1em\"\n>\n <rect x=\"6\" y=\"4\" width=\"4\" height=\"16\"></rect>\n <rect x=\"14\" y=\"4\" width=\"4\" height=\"16\"></rect>\n</svg>`;\n\n/**\n * A scrollable carousel/slider for images or content slides.\n *\n * @summary Scrollable carousel with navigation, pagination, autoplay, and an accessible label.\n *\n * @tag hx-carousel\n *\n * @slot - `hx-carousel-item` elements (the slides).\n * @slot next-button - Custom next navigation button.\n * @slot previous-button - Custom previous navigation button.\n *\n * @fires {CustomEvent<{index: number, slide: HelixCarouselItem}>} hx-slide-change - Dispatched when the active slide changes.\n *\n * @csspart base - The outer wrapper element.\n * @csspart slide-viewport - The slide viewport/overflow container.\n * @csspart pagination - The pagination dot container.\n * @csspart pagination-item - Individual pagination dot button.\n * @csspart navigation - The previous/next button wrapper.\n * @csspart prev-button - The previous navigation button.\n * @csspart next-button - The next navigation button.\n * @csspart play-pause-btn - The autoplay play/pause toggle button.\n *\n * @cssprop [--hx-carousel-gap=0px] - Gap between slides.\n * @cssprop [--hx-carousel-slide-width=100%] - Width override for each slide.\n * @cssprop [--hx-carousel-nav-btn-size=2.5rem] - Size of previous/next navigation buttons.\n * @cssprop [--hx-carousel-pagination-dot-size=0.5rem] - Size of pagination dots.\n * @cssprop [--hx-space-3] - Spacing token.\n * @cssprop [--hx-space-2] - Spacing token.\n * @cssprop [--hx-size-10] - Size token.\n * @cssprop [--hx-touch-target-min] - Minimum touch target size.\n * @cssprop [--hx-border-width-thin] - Width.\n * @cssprop [--hx-color-neutral-200] - Color.\n * @cssprop [--hx-border-radius-full] - CSS custom property.\n * @cssprop [--hx-color-neutral-0] - Color.\n * @cssprop [--hx-color-neutral-700] - Color.\n * @cssprop [--hx-transition-fast] - Transition timing.\n * @cssprop [--hx-color-neutral-50] - Color.\n * @cssprop [--hx-color-neutral-400] - Color.\n * @cssprop [--hx-focus-ring-width] - Width.\n * @cssprop [--hx-carousel-focus-ring-color=var(--hx-focus-ring-color)] - Color.\n * @cssprop [--hx-focus-ring-color] - Color.\n * @cssprop [--hx-color-primary-500] - Color.\n * @cssprop [--hx-focus-ring-offset] - CSS custom property.\n * @cssprop [--hx-opacity-disabled] - Opacity.\n * @cssprop [--hx-border-radius-md] - CSS custom property.\n * @cssprop [--hx-color-neutral-500] - Color.\n * @cssprop [--hx-font-size-sm] - Font size.\n * @cssprop [--hx-color-neutral-100] - Color.\n * @cssprop [--hx-transition-base] - Transition timing.\n * @cssprop [--hx-color-neutral-300] - Color.\n * @cssprop [--hx-color-primary-600] - Color.\n */\n@customElement('hx-carousel')\nexport class HelixCarousel extends HelixElement {\n static override styles = [helixCarouselStyles, forcedColorsInteractive];\n\n /**\n * Accessible label identifying this carousel to assistive technology.\n * When multiple carousels appear on the same page, each must have a unique label.\n * @attr label\n */\n @property({ type: String, reflect: true })\n label = 'Carousel';\n\n /**\n * Whether the carousel wraps around from last to first slide and vice-versa.\n * @attr loop\n */\n @property({ type: Boolean, reflect: true })\n loop = false;\n\n /**\n * Whether the carousel auto-advances slides.\n * Automatically pauses on hover, focus, and when prefers-reduced-motion is active.\n * @attr autoplay\n */\n @property({ type: Boolean, reflect: true })\n autoplay = false;\n\n /**\n * Milliseconds between auto-advance transitions.\n * @attr autoplay-interval\n */\n @property({ type: Number, attribute: 'autoplay-interval' })\n autoplayInterval = 3000;\n\n /**\n * Number of slides visible at once.\n * @attr slides-per-page\n */\n @property({ type: Number, attribute: 'slides-per-page' })\n slidesPerPage = 1;\n\n /**\n * Number of slides to advance per navigation action.\n * @attr slides-per-move\n */\n @property({ type: Number, attribute: 'slides-per-move' })\n slidesPerMove = 1;\n\n /**\n * Scroll axis of the carousel.\n * @attr orientation\n */\n @property({ type: String, reflect: true })\n orientation: 'horizontal' | 'vertical' = 'horizontal';\n\n /**\n * Whether click-drag scrolling is enabled.\n * @attr mouse-dragging\n */\n @property({ type: Boolean, attribute: 'mouse-dragging', reflect: true })\n mouseDragging = false;\n\n /**\n * Accessible label for the previous slide button.\n * @attr label-prev-slide\n */\n @property({ type: String, attribute: 'label-prev-slide' })\n labelPrevSlide = 'Previous slide';\n\n /**\n * Accessible label for the next slide button.\n * @attr label-next-slide\n */\n @property({ type: String, attribute: 'label-next-slide' })\n labelNextSlide = 'Next slide';\n\n /**\n * Accessible label for the autoplay pause button.\n * @attr label-pause-autoplay\n */\n @property({ type: String, attribute: 'label-pause-autoplay' })\n labelPauseAutoplay = 'Pause autoplay';\n\n /**\n * Accessible label for the autoplay play button.\n * @attr label-play-autoplay\n */\n @property({ type: String, attribute: 'label-play-autoplay' })\n labelPlayAutoplay = 'Play autoplay';\n\n /**\n * Generates the live-region text for a slide position.\n * @param index - 1-based slide index\n * @param total - total slide count\n */\n @property({ attribute: false })\n labelSlideOf: (index: number, total: number) => string = (index, total) =>\n `Slide ${index} of ${total}`;\n\n /**\n * Index of the currently visible slide.\n * @internal\n */\n @state() private _currentIndex = 0;\n /**\n * Array of carousel item elements assigned to the default slot.\n * @internal\n */\n @state() private _slides: HelixCarouselItem[] = [];\n /**\n * Whether the autoplay is currently active and advancing slides.\n * @internal\n */\n @state() private _isPlaying = false;\n /**\n * Text content for the ARIA live region announcing slide changes.\n * @internal\n */\n @state() private _liveText = '';\n /** @internal */\n @state() private _livePolite = true;\n\n /**\n * Reference to the active autoplay interval timer, or null when stopped.\n * @internal\n */\n private _autoplayTimer: ReturnType<typeof setInterval> | null = null;\n /**\n * Whether the user has requested reduced motion via the OS media preference.\n * @internal\n */\n private _reducedMotion = false;\n /**\n * MediaQueryList instance for monitoring the prefers-reduced-motion media feature.\n * @internal\n */\n private _mql: MediaQueryList | null = null;\n /**\n * Whether the carousel is currently being hovered, used to pause autoplay on hover.\n * @internal\n */\n private _isHovered = false;\n /**\n * Whether a descendant of the carousel currently has focus, used to pause autoplay on focus.\n * @internal\n */\n private _isFocused = false;\n\n // ─── Drag state ───\n /**\n * Pointer coordinate at the start of a mouse drag gesture.\n * @internal\n */\n private _dragStartCoord = 0;\n /**\n * Whether a mouse drag gesture is currently in progress.\n * @internal\n */\n private _isDragging = false;\n /**\n * Whether the pointer has moved beyond the drag threshold during the current drag gesture.\n * @internal\n */\n private _dragMoved = false;\n /**\n * Touch coordinate at the start of a touch swipe gesture.\n * @internal\n */\n private _touchStartCoord = 0;\n /**\n * Whether the touch has moved beyond the swipe threshold during the current touch gesture.\n * @internal\n */\n private _touchMoved = false;\n\n // ─── Lifecycle ───\n\n override connectedCallback(): void {\n super.connectedCallback();\n\n // Guard for SSR — window.matchMedia is unavailable server-side\n if (typeof window !== 'undefined') {\n this._mql = window.matchMedia('(prefers-reduced-motion: reduce)');\n this._reducedMotion = this._mql.matches;\n this._mql.addEventListener('change', this._handleMotionChange);\n }\n\n this.addEventListener('mouseenter', this._handleMouseEnter);\n this.addEventListener('mouseleave', this._handleMouseLeave);\n this.addEventListener('focusin', this._handleFocusIn);\n this.addEventListener('focusout', this._handleFocusOut);\n this.addEventListener('keydown', this._handleKeydown);\n // Touch events are registered directly on the scroll-container in the template\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this._mql?.removeEventListener('change', this._handleMotionChange);\n this._stopAutoplay();\n this.removeEventListener('mouseenter', this._handleMouseEnter);\n this.removeEventListener('mouseleave', this._handleMouseLeave);\n this.removeEventListener('focusin', this._handleFocusIn);\n this.removeEventListener('focusout', this._handleFocusOut);\n this.removeEventListener('keydown', this._handleKeydown);\n }\n\n override firstUpdated(): void {\n this._syncSlides();\n if (this.autoplay && !this._reducedMotion) {\n this._startAutoplay();\n }\n }\n\n // ─── Slide Management ───\n\n /** @internal */\n private _syncSlides(): void {\n const slot = this.shadowRoot?.querySelector<HTMLSlotElement>('slot:not([name])');\n if (!slot) return;\n\n const items = slot\n .assignedElements({ flatten: true })\n .filter((el) => el.tagName.toLowerCase() === 'hx-carousel-item') as HelixCarouselItem[];\n\n this._slides = items;\n\n // Update aria labels on each item\n items.forEach((item, i) => {\n item.slideIndex = i;\n item.totalSlides = items.length;\n const slideWidth = `${100 / this.slidesPerPage}%`;\n (item as HTMLElement).style.setProperty('--_hx-carousel-slide-width', slideWidth);\n });\n\n // Clamp currentIndex if slides changed\n if (this._currentIndex >= items.length) {\n this._currentIndex = Math.max(0, items.length - 1);\n }\n }\n\n /** @internal */\n private _handleSlotChange(): void {\n this._syncSlides();\n }\n\n // ─── Navigation ───\n\n /**\n * Maximum valid slide index accounting for the number of slides visible per page.\n * @internal\n */\n private get _maxIndex(): number {\n return Math.max(0, this._slides.length - this.slidesPerPage);\n }\n\n goTo(index: number): void {\n if (this._slides.length === 0) return;\n\n let next = index;\n if (this.loop) {\n next = ((index % this._slides.length) + this._slides.length) % this._slides.length;\n } else {\n next = Math.max(0, Math.min(index, this._maxIndex));\n }\n\n if (next === this._currentIndex) return;\n\n this._currentIndex = next;\n this._liveText = this.labelSlideOf(next + 1, this._slides.length);\n const slide = this._slides[next];\n if (!slide) return;\n this.dispatchEvent(\n new CustomEvent<{ index: number; slide: HelixCarouselItem | undefined }>('hx-slide-change', {\n bubbles: true,\n composed: true,\n detail: { index: next, slide },\n }),\n );\n }\n\n next(): void {\n const nextIndex = this._currentIndex + this.slidesPerMove;\n if (!this.loop && nextIndex > this._maxIndex) {\n return;\n }\n this._livePolite = true;\n this.goTo(nextIndex);\n }\n\n previous(): void {\n const prevIndex = this._currentIndex - this.slidesPerMove;\n if (!this.loop && prevIndex < 0) {\n return;\n }\n this._livePolite = true;\n this.goTo(prevIndex);\n }\n\n // ─── Autoplay ───\n\n /**\n * Callback invoked on each autoplay interval tick to advance to the next slide.\n * @internal\n */\n private _autoplayTick = (): void => {\n this._livePolite = false;\n if (this.loop) {\n this.goTo(this._currentIndex + this.slidesPerMove);\n } else if (this._currentIndex < this._maxIndex) {\n this.goTo(this._currentIndex + this.slidesPerMove);\n } else {\n this.goTo(0);\n }\n };\n\n /** @internal */\n private _startAutoplay(): void {\n if (this._autoplayTimer !== null) return;\n this._isPlaying = true;\n this._autoplayTimer = setInterval(this._autoplayTick, this.autoplayInterval);\n }\n\n /** @internal */\n private _stopAutoplay(): void {\n if (this._autoplayTimer !== null) {\n clearInterval(this._autoplayTimer);\n this._autoplayTimer = null;\n }\n this._isPlaying = false;\n }\n\n /** @internal */\n private _toggleAutoplay(): void {\n if (this._isPlaying) {\n this._stopAutoplay();\n } else if (!this._reducedMotion) {\n this._startAutoplay();\n }\n }\n\n /** @internal */\n private _pauseAutoplay(): void {\n if (!this._isPlaying || this._autoplayTimer === null) return;\n clearInterval(this._autoplayTimer);\n this._autoplayTimer = null;\n }\n\n /** @internal */\n private _resumeAutoplay(): void {\n if (!this.autoplay || !this._isPlaying || this._reducedMotion) return;\n if (this._autoplayTimer !== null) return;\n this._autoplayTimer = setInterval(this._autoplayTick, this.autoplayInterval);\n }\n\n // ─── Event Handlers ───\n\n /**\n * Handles changes to the prefers-reduced-motion media query, stopping or resuming autoplay accordingly.\n * @internal\n */\n private _handleMotionChange = (e: MediaQueryListEvent): void => {\n this._reducedMotion = e.matches;\n if (this._reducedMotion) {\n this._stopAutoplay();\n } else if (this.autoplay && !this._isHovered && !this._isFocused) {\n this._startAutoplay();\n }\n };\n\n /**\n * Handles the mouseenter event to pause autoplay while the user hovers over the carousel.\n * @internal\n */\n private _handleMouseEnter = (): void => {\n this._isHovered = true;\n this._pauseAutoplay();\n };\n\n /**\n * Handles the mouseleave event to resume autoplay when the user stops hovering.\n * @internal\n */\n private _handleMouseLeave = (): void => {\n this._isHovered = false;\n if (!this._isFocused) {\n this._resumeAutoplay();\n }\n };\n\n /**\n * Handles the focusin event to pause autoplay while a descendant has focus.\n * @internal\n */\n private _handleFocusIn = (): void => {\n this._isFocused = true;\n this._pauseAutoplay();\n };\n\n /**\n * Handles the focusout event to resume autoplay when focus leaves the carousel.\n * @internal\n */\n private _handleFocusOut = (): void => {\n this._isFocused = false;\n if (!this._isHovered) {\n this._resumeAutoplay();\n }\n };\n\n /**\n * Handles keyboard navigation to move between slides using arrow, Home, and End keys.\n * @internal\n */\n private _handleKeydown = (e: KeyboardEvent): void => {\n if (this.orientation === 'horizontal') {\n if (e.key === 'ArrowLeft') {\n e.preventDefault();\n this.previous();\n } else if (e.key === 'ArrowRight') {\n e.preventDefault();\n this.next();\n }\n } else {\n if (e.key === 'ArrowUp') {\n e.preventDefault();\n this.previous();\n } else if (e.key === 'ArrowDown') {\n e.preventDefault();\n this.next();\n }\n }\n\n if (e.key === 'Home') {\n e.preventDefault();\n this.goTo(0);\n } else if (e.key === 'End') {\n e.preventDefault();\n this.goTo(this._slides.length - 1);\n }\n };\n\n // ─── Drag Handlers ───\n\n /** @internal */\n private _handleDragStart(e: MouseEvent): void {\n if (!this.mouseDragging) return;\n this._isDragging = true;\n this._dragMoved = false;\n this._dragStartCoord = this.orientation === 'horizontal' ? e.clientX : e.clientY;\n (e.currentTarget as HTMLElement).style.cursor = 'grabbing';\n e.preventDefault();\n }\n\n /** @internal */\n private _handleDragMove(e: MouseEvent): void {\n if (!this._isDragging) return;\n const current = this.orientation === 'horizontal' ? e.clientX : e.clientY;\n const diff = current - this._dragStartCoord;\n if (Math.abs(diff) > 5) {\n this._dragMoved = true;\n }\n }\n\n /** @internal */\n private _handleDragEnd(e: MouseEvent): void {\n if (!this._isDragging) return;\n const current = this.orientation === 'horizontal' ? e.clientX : e.clientY;\n const diff = current - this._dragStartCoord;\n const threshold = 50;\n if (this._dragMoved) {\n if (diff > threshold) {\n this.previous();\n } else if (diff < -threshold) {\n this.next();\n }\n }\n this._isDragging = false;\n this._dragMoved = false;\n (e.currentTarget as HTMLElement).style.cursor = '';\n }\n\n // ─── Touch Handlers ───\n\n /** @internal */\n private _handleTouchStart(e: TouchEvent): void {\n if (!this.mouseDragging) return;\n const touch = e.touches[0];\n if (!touch) return;\n this._isDragging = true;\n this._touchMoved = false;\n this._touchStartCoord = this.orientation === 'horizontal' ? touch.clientX : touch.clientY;\n }\n\n /** @internal */\n private _handleTouchMove(e: TouchEvent): void {\n if (!this._isDragging) return;\n const touch = e.touches[0];\n if (!touch) return;\n const current = this.orientation === 'horizontal' ? touch.clientX : touch.clientY;\n const diff = current - this._touchStartCoord;\n if (Math.abs(diff) > 5) {\n this._touchMoved = true;\n }\n }\n\n /** @internal */\n private _handleTouchEnd(e: TouchEvent): void {\n if (!this._isDragging) return;\n const touch = e.changedTouches[0];\n if (!touch) return;\n const current = this.orientation === 'horizontal' ? touch.clientX : touch.clientY;\n const diff = current - this._touchStartCoord;\n const threshold = 50;\n if (this._touchMoved) {\n if (diff > threshold) {\n this.previous();\n } else if (diff < -threshold) {\n this.next();\n }\n }\n this._isDragging = false;\n this._touchMoved = false;\n }\n\n /** @internal */\n private _goToManual(index: number): void {\n this._livePolite = true;\n this.goTo(index);\n }\n\n // ─── Computed ───\n\n /**\n * CSS transform value applied to the slide track to scroll to the current index.\n * @internal\n */\n private get _trackTransform(): string {\n const slideSize = 100 / this.slidesPerPage;\n const offset = this._currentIndex * slideSize;\n return this.orientation === 'horizontal'\n ? `translateX(-${offset}%)`\n : `translateY(-${offset}%)`;\n }\n\n /**\n * Whether the previous navigation button should be enabled.\n * @internal\n */\n private get _canGoPrev(): boolean {\n return this.loop || this._currentIndex > 0;\n }\n\n /**\n * Whether the next navigation button should be enabled.\n * @internal\n */\n private get _canGoNext(): boolean {\n return this.loop || this._currentIndex < this._maxIndex;\n }\n\n // ─── Render Helpers ───\n\n /** @internal */\n private _renderNavigation() {\n return html`\n <div class=\"navigation\" part=\"navigation\">\n <slot name=\"previous-button\">\n <button\n class=\"nav-btn\"\n part=\"prev-button\"\n type=\"button\"\n aria-label=${this.labelPrevSlide}\n ?disabled=${!this._canGoPrev}\n @click=${() => this.previous()}\n >\n ${this._renderPrevIcon()}\n </button>\n </slot>\n ${this.autoplay\n ? html`\n <button\n class=\"play-pause-btn\"\n part=\"play-pause-btn\"\n type=\"button\"\n aria-label=${this._isPlaying ? this.labelPauseAutoplay : this.labelPlayAutoplay}\n @click=${() => this._toggleAutoplay()}\n >\n ${this._isPlaying ? this._renderPauseIcon() : this._renderPlayIcon()}\n </button>\n `\n : nothing}\n <slot name=\"next-button\">\n <button\n class=\"nav-btn\"\n part=\"next-button\"\n type=\"button\"\n aria-label=${this.labelNextSlide}\n ?disabled=${!this._canGoNext}\n @click=${() => this.next()}\n >\n ${this._renderNextIcon()}\n </button>\n </slot>\n </div>\n `;\n }\n\n /** @internal */\n private _renderPagination() {\n const count = this._slides.length;\n if (count <= 1) return nothing;\n const dots = Array.from({ length: count }, (_, i) => i);\n return html`\n <div class=\"controls\">\n <div class=\"pagination\" part=\"pagination\">\n ${dots.map(\n (i) => html`\n <button\n class=${classMap({\n 'pagination-item': true,\n 'is-active': i === this._currentIndex,\n })}\n part=\"pagination-item\"\n type=\"button\"\n aria-label=${this.labelSlideOf(i + 1, count)}\n aria-current=${i === this._currentIndex ? 'true' : nothing}\n @click=${() => this._goToManual(i)}\n >\n <span class=\"pagination-dot\"></span>\n </button>\n `,\n )}\n </div>\n </div>\n `;\n }\n\n /** @internal */\n private _renderPrevIcon() {\n return this.orientation === 'horizontal' ? _svgChevronLeft : _svgChevronUp;\n }\n\n /** @internal */\n private _renderNextIcon() {\n return this.orientation === 'horizontal' ? _svgChevronRight : _svgChevronDown;\n }\n\n /** @internal */\n private _renderPlayIcon() {\n return _svgPlay;\n }\n\n /** @internal */\n private _renderPauseIcon() {\n return _svgPause;\n }\n\n // ─── Render ───\n\n override render() {\n return html`\n <div\n class=\"base\"\n part=\"base\"\n role=\"region\"\n aria-label=${this.label}\n aria-roledescription=\"carousel\"\n >\n <div\n class=\"live-region\"\n role=\"status\"\n aria-live=${this._livePolite ? 'polite' : 'off'}\n aria-atomic=\"true\"\n >\n ${this._liveText}\n </div>\n ${this._renderNavigation()}\n <div class=\"scroll-container-wrapper\">\n <div\n class=\"slide-viewport\"\n part=\"slide-viewport\"\n aria-live=\"polite\"\n aria-atomic=\"false\"\n @mousedown=${this._handleDragStart}\n @mousemove=${this._handleDragMove}\n @mouseup=${this._handleDragEnd}\n @mouseleave=${this._handleDragEnd}\n @touchstart=${this._handleTouchStart}\n @touchmove=${this._handleTouchMove}\n @touchend=${this._handleTouchEnd}\n >\n <div class=\"track\" style=\"transform: ${this._trackTransform};\">\n <slot @slotchange=${this._handleSlotChange}></slot>\n </div>\n </div>\n </div>\n ${this._renderPagination()}\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-carousel': HelixCarousel;\n }\n}\n","import { css } from 'lit';\n\nexport const helixCarouselItemStyles = css`\n :host {\n display: block;\n flex-shrink: 0;\n width: var(--_hx-carousel-slide-width, 100%);\n box-sizing: border-box;\n }\n\n .slide-group {\n height: 100%;\n outline: none;\n }\n\n .slide-group:focus-visible {\n outline: var(--hx-focus-ring-width) solid var(--hx-focus-ring-color);\n outline-offset: var(--hx-focus-ring-offset);\n }\n\n /* ─── High Contrast Mode (forced-colors) ─── */\n\n @media (forced-colors: active) {\n .slide-group:focus-visible {\n outline: 3px solid Highlight;\n outline-offset: 2px;\n }\n }\n`;\n","import { html } from 'lit';\nimport '../../utilities/document-token-adoption.js';\nimport { customElement, property } from 'lit/decorators.js';\nimport { HelixElement } from '../../base/index.js';\nimport { helixCarouselItemStyles } from './hx-carousel-item.styles.js';\n\n/**\n * A wrapper for individual carousel slides.\n *\n * @summary Individual slide wrapper for use inside hx-carousel.\n *\n * @tag hx-carousel-item\n *\n * @slot - Slide content.\n *\n * @csspart slide - The slide wrapper element.\n */\n@customElement('hx-carousel-item')\nexport class HelixCarouselItem extends HelixElement {\n static override styles = [helixCarouselItemStyles];\n\n /**\n * The 0-based index of this slide within the carousel. Set by hx-carousel.\n * @attr slide-index\n */\n @property({ type: Number, attribute: 'slide-index' })\n slideIndex = 0;\n\n /**\n * Total number of slides in the carousel. Set by hx-carousel.\n * @attr total-slides\n */\n @property({ type: Number, attribute: 'total-slides' })\n totalSlides = 0;\n\n override render() {\n const label = `Slide ${this.slideIndex + 1} of ${this.totalSlides}`;\n return html`\n <div class=\"slide-group\" part=\"slide\" role=\"group\" aria-label=${label} tabindex=\"-1\">\n <slot></slot>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-carousel-item': HelixCarouselItem;\n }\n}\n"],"names":["helixCarouselStyles","css","_svgChevronLeft","html","_svgChevronUp","_svgChevronRight","_svgChevronDown","_svgPlay","_svgPause","HelixCarousel","HelixElement","index","total","e","_a","slot","items","el","item","i","slideWidth","next","slide","nextIndex","prevIndex","diff","threshold","touch","slideSize","offset","nothing","count","dots","_","classMap","forcedColorsInteractive","__decorateClass","property","state","customElement","helixCarouselItemStyles","HelixCarouselItem","label"],"mappings":";;;;;AAEO,MAAMA,IAAsBC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hx-checkbox-C46TyXhM.js","sources":["../../src/components/hx-checkbox/hx-checkbox.styles.ts","../../src/components/hx-checkbox/hx-checkbox.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixCheckboxStyles = css`\n :host {\n display: block;\n }\n\n :host([disabled]) {\n opacity: var(--hx-opacity-disabled, 0.5);\n pointer-events: none;\n }\n\n * {\n box-sizing: border-box;\n }\n\n .checkbox {\n display: flex;\n flex-direction: column;\n gap: var(--hx-space-1, 0.25rem);\n font-family: var(--hx-checkbox-font-family, var(--hx-font-family-sans, sans-serif));\n }\n\n /* ─── Control (checkbox + label row) ─── */\n\n .checkbox__control {\n display: inline-flex;\n align-items: flex-start;\n gap: var(--hx-space-2, 0.5rem);\n /* WCAG 2.5.5 (healthcare mandate): minimum 44px touch target height */\n min-height: var(--hx-touch-target-min, 2.75rem);\n cursor: pointer;\n }\n\n :host([disabled]) .checkbox__control {\n cursor: not-allowed;\n }\n\n /* ─── Hidden Native Input ─── */\n\n .checkbox__input {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n border: 0;\n }\n\n /* ─── Visual Checkbox ─── */\n\n .checkbox__box {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n width: var(--hx-checkbox-size, var(--hx-size-5, 1.25rem));\n height: var(--hx-checkbox-size, var(--hx-size-5, 1.25rem));\n border: var(--hx-border-width-medium, 2px) solid\n var(--hx-checkbox-border-color, var(--hx-color-border-strong, #8e9c98));\n border-radius: var(--hx-checkbox-border-radius, var(--hx-border-radius-sm, 0.25rem));\n background-color: var(--hx-checkbox-bg, var(--hx-color-surface-default, #ffffff));\n transition:\n background-color var(--hx-transition-fast, 150ms ease),\n border-color var(--hx-transition-fast, 150ms ease),\n box-shadow var(--hx-transition-fast, 150ms ease);\n margin-top: var(--hx-space-px, 1px);\n }\n\n /* ─── Focus Ring ─── */\n\n .checkbox__input:focus-visible ~ .checkbox__box {\n outline: var(--hx-checkbox-focus-ring-width, var(--hx-focus-ring-width, 2px)) solid\n var(\n --hx-checkbox-focus-ring-color,\n var(--hx-focus-ring-color, var(--hx-color-primary-400, #6ab1b1))\n );\n outline-offset: var(--hx-checkbox-focus-ring-offset, var(--hx-focus-ring-offset, 2px));\n }\n\n /* ─── Checked State ─── */\n\n .checkbox--checked .checkbox__box {\n background-color: var(--hx-checkbox-checked-bg, var(--hx-color-primary-500, #429797));\n border-color: var(--hx-checkbox-checked-border-color, var(--hx-color-primary-500, #429797));\n }\n\n /* ─── Indeterminate State ─── */\n\n .checkbox--indeterminate .checkbox__box {\n background-color: var(--hx-checkbox-checked-bg, var(--hx-color-primary-500, #429797));\n border-color: var(--hx-checkbox-checked-border-color, var(--hx-color-primary-500, #429797));\n }\n\n /* ─── Error State ─── */\n\n .checkbox--error .checkbox__box {\n border-color: var(--hx-checkbox-error-color, var(--hx-color-error-500, #e5493e));\n }\n\n .checkbox--error.checkbox--checked .checkbox__box,\n .checkbox--error.checkbox--indeterminate .checkbox__box {\n background-color: var(--hx-checkbox-error-color, var(--hx-color-error-500, #e5493e));\n border-color: var(--hx-checkbox-error-color, var(--hx-color-error-500, #e5493e));\n }\n\n /* ─── Hover ─── */\n\n /* P1-03: use component token so consumer overrides of --hx-checkbox-border-color work on hover */\n .checkbox__control:hover .checkbox__box {\n border-color: var(\n --hx-checkbox-hover-border-color,\n var(--hx-checkbox-border-color, var(--hx-color-primary-500, #429797))\n );\n }\n\n .checkbox--checked .checkbox__control:hover .checkbox__box {\n filter: brightness(var(--hx-filter-brightness-hover, 0.9));\n }\n\n .checkbox--error .checkbox__control:hover .checkbox__box {\n border-color: var(--hx-checkbox-error-color, var(--hx-color-error-500, #e5493e));\n }\n\n /* ─── Checkmark Icon ─── */\n\n .checkbox__icon {\n display: none;\n width: calc(var(--hx-checkbox-size, var(--hx-size-5, 1.25rem)) * 0.65);\n height: calc(var(--hx-checkbox-size, var(--hx-size-5, 1.25rem)) * 0.65);\n fill: none;\n stroke: var(--hx-checkbox-checkmark-color, var(--hx-color-text-on-primary, #ffffff));\n stroke-width: 2.5;\n stroke-linecap: round;\n stroke-linejoin: round;\n }\n\n .checkbox--checked .checkbox__icon--check {\n display: block;\n }\n\n .checkbox--indeterminate .checkbox__icon--indeterminate {\n display: block;\n }\n\n /* ─── Label ─── */\n\n .checkbox__label {\n font-size: var(--hx-font-size-sm, 0.875rem);\n font-weight: var(--hx-font-weight-medium, 500);\n color: var(--hx-checkbox-label-color, var(--hx-color-text-strong, #202b39));\n line-height: var(--hx-line-height-normal, 1.5);\n user-select: none;\n -webkit-user-select: none;\n }\n\n .checkbox__required-marker {\n color: var(--hx-checkbox-error-color, var(--hx-color-error-text, #c92a2a));\n font-weight: var(--hx-font-weight-bold, 700);\n }\n\n /* ─── Help Text & Error Messages ─── */\n\n .checkbox__help-text {\n font-size: var(--hx-font-size-xs, 0.75rem);\n color: var(--hx-checkbox-help-text-color, var(--hx-color-text-muted, #4a5362));\n line-height: var(--hx-line-height-normal, 1.5);\n padding-inline-start: calc(\n var(--hx-checkbox-size, var(--hx-size-5, 1.25rem)) + var(--hx-space-2, 0.5rem)\n );\n }\n\n .checkbox__error {\n font-size: var(--hx-font-size-xs, 0.75rem);\n color: var(--hx-checkbox-error-color, var(--hx-color-error-text, #c92a2a));\n line-height: var(--hx-line-height-normal, 1.5);\n padding-inline-start: calc(\n var(--hx-checkbox-size, var(--hx-size-5, 1.25rem)) + var(--hx-space-2, 0.5rem)\n );\n }\n\n /* ─── Size Variants ─── */\n\n :host([hx-size='sm']) {\n --hx-checkbox-size: var(--hx-size-4, 1rem);\n }\n\n :host([hx-size='sm']) .checkbox__label {\n font-size: var(--hx-font-size-xs, 0.75rem);\n }\n\n :host([hx-size='sm']) .checkbox__help-text,\n :host([hx-size='sm']) .checkbox__error {\n font-size: var(--hx-font-size-xs, 0.75rem);\n padding-inline-start: calc(var(--hx-size-4, 1rem) + var(--hx-space-2, 0.5rem));\n }\n\n :host([hx-size='lg']) {\n --hx-checkbox-size: var(--hx-size-6, 1.5rem);\n }\n\n :host([hx-size='lg']) .checkbox__label {\n font-size: var(--hx-font-size-md, 1rem);\n }\n\n :host([hx-size='lg']) .checkbox__help-text,\n :host([hx-size='lg']) .checkbox__error {\n font-size: var(--hx-font-size-sm, 0.875rem);\n padding-inline-start: calc(var(--hx-size-6, 1.5rem) + var(--hx-space-2, 0.5rem));\n }\n\n /* ─── Reduced Motion ─── */\n\n @media (prefers-reduced-motion: reduce) {\n .checkbox__box {\n transition: none;\n }\n }\n\n /* ─── High Contrast Mode (forced-colors) ─── */\n\n @media (forced-colors: active) {\n .checkbox__box {\n forced-color-adjust: none;\n background-color: ButtonFace;\n border: 2px solid ButtonText;\n }\n\n .checkbox__input:focus-visible ~ .checkbox__box {\n outline: 3px solid Highlight;\n outline-offset: 2px;\n }\n\n .checkbox--checked .checkbox__box,\n .checkbox--indeterminate .checkbox__box {\n background-color: Highlight;\n border-color: Highlight;\n }\n\n .checkbox__icon {\n stroke: HighlightText;\n }\n\n .checkbox--error .checkbox__box {\n border-color: LinkText;\n }\n\n .checkbox--error.checkbox--checked .checkbox__box,\n .checkbox--error.checkbox--indeterminate .checkbox__box {\n background-color: LinkText;\n border-color: LinkText;\n }\n\n :host([disabled]) {\n opacity: 1;\n }\n\n :host([disabled]) .checkbox__box {\n border-color: GrayText;\n background-color: ButtonFace;\n }\n\n :host([disabled]) .checkbox--checked .checkbox__box,\n :host([disabled]) .checkbox--indeterminate .checkbox__box {\n background-color: GrayText;\n border-color: GrayText;\n }\n\n :host([disabled]) .checkbox__label {\n color: GrayText;\n }\n\n .checkbox__label {\n color: CanvasText;\n }\n\n .checkbox__help-text {\n color: GrayText;\n }\n\n .checkbox__error {\n color: LinkText;\n }\n }\n`;\n","import { html, nothing, type PropertyValues } from 'lit';\nimport '../../utilities/document-token-adoption.js';\nimport { customElement, property, query, state } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { live } from 'lit/directives/live.js';\nimport { HelixElement, createIdCounter } from '../../base/index.js';\nimport { mixinDelegatesAria } from '../../mixins/index.js';\nimport { FormMixin } from '../../mixins/FormMixin.js';\nimport { helixCheckboxStyles } from './hx-checkbox.styles.js';\nimport { forcedColorsField } from '../../styles/forced-colors.js';\nimport { devWarn } from '../../utils/dev-warn.js';\n\n// P2-05: monotonic counter — collision-free, deterministic, SSR-safe\nconst _nextCheckboxId = createIdCounter('hx-checkbox');\n\n/** Detail for the hx-change event dispatched by hx-checkbox. */\nexport interface HxCheckboxChangeDetail {\n checked: boolean;\n value: string;\n}\n\n/**\n * A checkbox component with label, validation, and form association.\n *\n * @summary Form-associated checkbox with built-in label, error, and help text.\n *\n * @tag hx-checkbox\n *\n * @slot - Custom label content (overrides the label property). Rich HTML allowed — Drupal can include links in consent labels.\n * @slot error - Custom error content (overrides the error property).\n * @slot help-text - Custom help text content (overrides the helpText property).\n *\n * @fires {CustomEvent<{checked: boolean, value: string}>} hx-change - Dispatched when the checkbox is toggled. Boolean-selection controls (`hx-switch`, `hx-checkbox`) include both `checked` (boolean state) and `value` (form value) in the detail; text-value controls (`hx-text-input`, `hx-combobox`, `hx-select`) emit only `{value}`.\n *\n * @csspart checkbox - The visual checkbox element.\n * @csspart checkmark - The SVG checkmark icon inside the checkbox.\n * @csspart label - The label element.\n * @csspart help-text - The help text container.\n * @csspart error - The error message container.\n * @csspart control - The wrapper around checkbox and label.\n *\n * @cssprop [--hx-checkbox-size=var(--hx-size-5, 1.25rem)] - Checkbox dimensions.\n * @cssprop [--hx-checkbox-bg=var(--hx-color-neutral-0, #ffffff)] - Unchecked background color.\n * @cssprop [--hx-checkbox-border-color=var(--hx-color-neutral-300, #B6BFB9)] - Checkbox border color.\n * @cssprop [--hx-checkbox-border-radius=var(--hx-border-radius-sm, 0.25rem)] - Checkbox border radius.\n * @cssprop [--hx-checkbox-checked-bg=var(--hx-color-primary-500, #429797)] - Checked background color.\n * @cssprop [--hx-checkbox-checked-border-color=var(--hx-color-primary-500, #429797)] - Checked border color.\n * @cssprop [--hx-checkbox-checkmark-color=var(--hx-color-neutral-0, #ffffff)] - Checkmark color.\n * @cssprop [--hx-checkbox-focus-ring-color=var(--hx-focus-ring-color, #6AB1B1)] - Focus ring color.\n * @cssprop [--hx-checkbox-label-color=var(--hx-color-neutral-700, #313E4B)] - Label text color.\n * @cssprop [--hx-checkbox-help-text-color=var(--hx-color-neutral-500, #66787B)] - Help text color.\n * @cssprop [--hx-checkbox-hover-border-color=var(--hx-checkbox-border-color)] - Border color on hover.\n * @cssprop [--hx-checkbox-error-color=var(--hx-color-error-500, #E5493E)] - Error state color.\n * @cssprop [--hx-opacity-disabled] - Opacity.\n * @cssprop [--hx-space-1] - Spacing token.\n * @cssprop [--hx-checkbox-font-family=var(--hx-font-family-sans)] - Font family for checkbox label and help text.\n * @cssprop [--hx-font-family-sans] - Font family.\n * @cssprop [--hx-space-2] - Spacing token.\n * @cssprop [--hx-touch-target-min] - Minimum touch target size.\n * @cssprop [--hx-size-5] - Size token.\n * @cssprop [--hx-border-width-medium] - Width.\n * @cssprop [--hx-color-neutral-300] - Color.\n * @cssprop [--hx-border-radius-sm] - CSS custom property.\n * @cssprop [--hx-color-neutral-0] - Color.\n * @cssprop [--hx-transition-fast] - Transition timing.\n * @cssprop [--hx-space-px] - Spacing token.\n * @cssprop [--hx-focus-ring-width] - Width.\n * @cssprop [--hx-focus-ring-color] - Color.\n * @cssprop [--hx-color-primary-400] - Color.\n * @cssprop [--hx-focus-ring-offset] - CSS custom property.\n * @cssprop [--hx-color-primary-500] - Color.\n * @cssprop [--hx-filter-brightness-hover] - CSS filter.\n * @cssprop [--hx-font-size-sm] - Font size.\n * @cssprop [--hx-font-weight-medium] - Font weight.\n * @cssprop [--hx-color-neutral-700] - Color.\n * @cssprop [--hx-line-height-normal] - Line height.\n * @cssprop [--hx-color-error-text] - Color.\n * @cssprop [--hx-font-weight-bold] - Font weight.\n * @cssprop [--hx-font-size-xs] - Font size.\n * @cssprop [--hx-color-neutral-500] - Color.\n * @cssprop [--hx-size-4] - Size token.\n * @cssprop [--hx-size-6] - Size token.\n * @cssprop [--hx-font-size-md] - Font size.\n * @cssprop [--hx-color-error-500] - Color.\n */\n@customElement('hx-checkbox')\nexport class HelixCheckbox extends mixinDelegatesAria(FormMixin(HelixElement)) {\n static override styles = [helixCheckboxStyles, forcedColorsField];\n\n // ─── Form Association ───\n\n /** @internal */\n static override formAssociated = true;\n\n // ─── Properties ───\n\n /**\n * Whether the checkbox is checked.\n * @attr checked\n */\n @property({ type: Boolean, reflect: true })\n checked = false;\n\n /**\n * Whether the checkbox is in an indeterminate state (e.g., for \"select all\" patterns).\n * @attr indeterminate\n */\n @property({ type: Boolean, reflect: true })\n indeterminate = false;\n\n /**\n * Whether the checkbox is disabled.\n * @attr disabled\n */\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /**\n * Whether the checkbox is required for form submission.\n * @attr required\n */\n @property({ type: Boolean, reflect: true })\n required = false;\n\n /**\n * The name of the checkbox, used for form submission.\n * @attr name\n */\n @property({ type: String, reflect: true })\n name = '';\n\n /**\n * The value submitted when the checkbox is checked.\n * @attr value\n */\n @property({ type: String, reflect: true })\n value = 'on';\n\n /**\n * The visible label text for the checkbox.\n * @attr label\n */\n @property({ type: String })\n label = '';\n\n /**\n * Error message to display. When set, the checkbox enters an error state.\n * @attr error\n */\n @property({ type: String })\n error = '';\n\n /**\n * Help text displayed below the checkbox for guidance.\n * @attr help-text\n */\n @property({ type: String, attribute: 'help-text' })\n helpText = '';\n\n /**\n * Validation message shown when the field is required but empty.\n * @attr required-message\n */\n @property({ attribute: 'required-message' })\n requiredMessage = 'This field is required.';\n\n /**\n * The size of the checkbox.\n * @attr hx-size\n */\n @property({ type: String, attribute: 'hx-size', reflect: true })\n size: 'sm' | 'md' | 'lg' = 'md';\n\n /**\n * Accessible label for the checkbox when no visible label text is provided.\n * Use when embedding a checkbox in a context where a label element is not practical.\n *\n * Accepts both `accessible-label` and the standard `aria-label` HTML attribute.\n * `accessible-label` takes precedence when both are set.\n * When set, replaces the visible label as the input's accessible name. Cannot be combined\n * with a visible label — set either `accessible-label` or the `label` slot, not both.\n *\n * @attr accessible-label\n */\n @property({ type: String, attribute: 'accessible-label' })\n accessibleLabel: string = '';\n\n /**\n * Returns the effective label for the checkbox, checking accessible-label first,\n * then the aria-label attribute, falling back to empty string.\n * @internal\n */\n private get _effectiveLabel(): string {\n return this.accessibleLabel?.trim() || this.ariaLabel?.trim() || '';\n }\n\n /** @internal */\n @query('.checkbox__input')\n private _inputEl: HTMLInputElement | undefined;\n\n /** @internal */\n @state() private _hasErrorSlot = false;\n\n /**\n * Deferred copy of this.error used inside the live region. Injected after\n * the region is visible (via requestAnimationFrame) so screen readers\n * re-announce the message even if it was set before the region became\n * visible — see WCAG 4.1.3.\n * @internal\n */\n @state() private _announcedError = '';\n\n /** @internal */\n private _hasWarnedLabelConflict = false;\n\n // ─── Slot Handlers ───\n\n /** @internal */\n private _handleErrorSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n this._hasErrorSlot = slot.assignedNodes({ flatten: true }).length > 0;\n }\n\n // ─── Lifecycle ───\n\n override updated(changedProperties: PropertyValues<this>): void {\n super.updated(changedProperties);\n if (changedProperties.has('checked') || changedProperties.has('value')) {\n this._internals.setFormValue(this.checked ? this.value : null);\n }\n // Warn when accessible-label is set alongside a visible label — they are mutually exclusive.\n // Checked unconditionally (not gated on changedProperties) because ariaLabel is provided by\n // mixinDelegatesAria via Object.defineProperty and never appears in changedProperties.\n {\n const hasAccessibleLabel = !!(this.accessibleLabel?.trim() || this.ariaLabel?.trim());\n const hasVisibleLabel =\n !!this.label ||\n (this.shadowRoot\n ?.querySelector<HTMLSlotElement>('.checkbox__label slot')\n ?.assignedNodes({ flatten: true }).length ?? 0) > 0;\n if (hasAccessibleLabel && hasVisibleLabel && !this._hasWarnedLabelConflict) {\n this._hasWarnedLabelConflict = true;\n devWarn(\n 'hx-checkbox',\n 'accessible-label is set alongside a visible label. Use either accessible-label or the label slot, not both.',\n );\n } else if (!hasAccessibleLabel || !hasVisibleLabel) {\n this._hasWarnedLabelConflict = false;\n }\n }\n // WCAG 4.1.3: Keep _announcedError in sync with the error property.\n // When error changes from one non-empty value to another, clear the live region\n // first then re-inject after a rAF tick so screen readers re-announce the updated\n // message (clearing content before the region is re-populated triggers a new event).\n // When transitioning from empty to non-empty (initial display), set directly so\n // the text is immediately available for synchronous DOM assertions.\n if (changedProperties.has('error')) {\n const previousError = changedProperties.get('error') as string;\n if (previousError && this.error) {\n // Changing from one error message to another: defer to trigger re-announcement.\n this._announcedError = '';\n requestAnimationFrame(() => {\n this._announcedError = this.error;\n });\n } else {\n // Transitioning from empty→error or error→empty: set directly.\n this._announcedError = this.error;\n }\n }\n }\n\n // ─── Form Integration ───\n\n /** Returns the associated form element, if any. */\n override get form(): HTMLFormElement | null {\n return this._internals.form;\n }\n\n /** Returns the validation message. */\n override get validationMessage(): string {\n return this._internals.validationMessage;\n }\n\n /** Returns the ValidityState object. */\n override get validity(): ValidityState {\n return this._internals.validity;\n }\n\n /** @internal */\n _updateValidity(): void {\n if (this.required && !this.checked) {\n this._internals.setValidity(\n { valueMissing: true },\n this.error || this.requiredMessage,\n this._inputEl ?? undefined,\n );\n } else {\n this._internals.setValidity({});\n }\n }\n\n // ─── Form Lifecycle Hooks ───\n\n protected override _onFormReset(): void {\n this.checked = false;\n this.indeterminate = false;\n this._internals.setFormValue(null);\n this._resetInteractionState();\n }\n\n protected override _onFormStateRestore(\n state: File | string | FormData | null,\n _mode: 'restore' | 'autocomplete',\n ): void {\n this.checked = typeof state === 'string' && state === this.value;\n }\n\n protected override _onFormDisabled(disabled: boolean): void {\n this.disabled = disabled;\n }\n\n // ─── Event Handling ───\n\n /** @internal */\n private _handleChange(): void {\n if (this.disabled) return;\n\n this.indeterminate = false;\n this.checked = !this.checked;\n\n this._internals.setFormValue(this.checked ? this.value : null);\n this._handleInteractionInput();\n\n /**\n * Dispatched when the checkbox is toggled.\n * @event hx-change\n */\n this.dispatchEvent(\n new CustomEvent<{ checked: boolean; value: string }>('hx-change', {\n bubbles: true,\n composed: true,\n detail: { checked: this.checked, value: this.value },\n }),\n );\n }\n\n /** @internal */\n private _handleKeyDown(e: KeyboardEvent): void {\n if (e.key === ' ') {\n e.preventDefault();\n e.stopPropagation();\n this._handleChange();\n }\n }\n\n // ─── Public Methods ───\n\n /** Moves focus to the checkbox input element. */\n override focus(options?: FocusOptions): void {\n this._inputEl?.focus(options);\n }\n\n // ─── Render ───\n\n // P2-05: monotonic counter — collision-free and deterministic\n /** @internal */\n private _id = _nextCheckboxId();\n /** @internal */\n private _helpTextId = `${this._id}-help`;\n /** @internal */\n private _errorId = `${this._id}-error`;\n /** @internal */\n private _labelId = `${this._id}-label`;\n\n override render() {\n const hasError = !!this.error || this._hasErrorSlot;\n\n const containerClasses = {\n checkbox: true,\n 'checkbox--checked': this.checked,\n 'checkbox--indeterminate': this.indeterminate,\n 'checkbox--error': hasError,\n 'checkbox--disabled': this.disabled,\n 'checkbox--required': this.required,\n 'checkbox--sm': this.size === 'sm',\n 'checkbox--md': this.size === 'md',\n 'checkbox--lg': this.size === 'lg',\n };\n\n // P2-06: simplified — hasError already includes _hasErrorSlot\n const describedBy =\n [hasError ? this._errorId : null, this.helpText && !hasError ? this._helpTextId : null]\n .filter(Boolean)\n .join(' ') || undefined;\n\n const hostAriaLabel = this._effectiveLabel || undefined;\n\n return html`\n <div class=${classMap(containerClasses)}>\n <label part=\"control\" class=\"checkbox__control\" @click=${this._handleChange}>\n <input\n class=\"checkbox__input\"\n type=\"checkbox\"\n id=${this._id}\n .checked=${live(this.checked)}\n .indeterminate=${live(this.indeterminate)}\n ?disabled=${this.disabled}\n ?required=${this.required}\n name=${ifDefined(this.name || undefined)}\n .value=${this.value}\n aria-checked=${this.indeterminate ? 'mixed' : nothing}\n aria-invalid=${hasError ? 'true' : nothing}\n aria-describedby=${ifDefined(describedBy)}\n aria-label=${ifDefined(hostAriaLabel)}\n aria-labelledby=${ifDefined(!hostAriaLabel ? this._labelId : undefined)}\n @keydown=${this._handleKeyDown}\n @click=${(e: Event) => {\n e.preventDefault();\n e.stopPropagation();\n }}\n @change=${(e: Event) => e.stopPropagation()}\n />\n\n <span part=\"checkbox\" class=\"checkbox__box\">\n <svg\n part=\"checkmark\"\n class=\"checkbox__icon checkbox__icon--check\"\n viewBox=\"0 0 16 16\"\n aria-hidden=\"true\"\n >\n <polyline points=\"3.5 8 6.5 11 12.5 5\"></polyline>\n </svg>\n <svg\n class=\"checkbox__icon checkbox__icon--indeterminate\"\n viewBox=\"0 0 16 16\"\n aria-hidden=\"true\"\n >\n <line x1=\"4\" y1=\"8\" x2=\"12\" y2=\"8\"></line>\n </svg>\n </span>\n\n <span part=\"label\" class=\"checkbox__label\" id=${this._labelId}>\n <slot>${this.label}</slot>\n ${this.required\n ? html`<span class=\"checkbox__required-marker\" aria-hidden=\"true\">*</span>`\n : nothing}\n </span>\n </label>\n\n <!--\n P0-01: wrapper div always owns _errorId so aria-describedby works regardless\n of whether error content comes from the .error property or the named slot.\n P1-02: role=\"status\" (implicit aria-live=\"polite\") replaces role=\"alert\" +\n aria-live=\"polite\" which was semantically contradictory.\n -->\n <div\n part=\"error\"\n class=\"checkbox__error\"\n id=${this._errorId}\n role=\"status\"\n ?hidden=${!hasError}\n >\n <slot name=\"error\" @slotchange=${this._handleErrorSlotChange}>\n ${this._announcedError}\n </slot>\n </div>\n\n ${this.helpText && !hasError\n ? html`\n <div part=\"help-text\" class=\"checkbox__help-text\" id=${this._helpTextId}>\n <slot name=\"help-text\">${this.helpText}</slot>\n </div>\n `\n : nothing}\n </div>\n `;\n }\n}\n\n/** Canonical type alias for the hx-checkbox component. */\nexport type HxCheckbox = HelixCheckbox;\n\n/**\n * Per-component event map for type-safe addEventListener on hx-checkbox.\n * The `hx-change` detail always includes both `checked` and `value` for this component.\n */\nexport interface HxCheckboxEventMap {\n 'hx-change': CustomEvent<{ checked: boolean; value: string }>;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-checkbox': HelixCheckbox;\n }\n /**\n * Global hx-change event type. The detail shape is a union because hx-change is dispatched\n * by multiple components: form-field components (value only) and toggle components\n * (checked + value). Use per-component EventMap types (e.g. HxCheckboxEventMap) for\n * narrowed addEventListener calls.\n */\n interface HTMLElementEventMap {\n 'hx-change': CustomEvent<{ value: string } | { checked: boolean; value: string }>;\n }\n}\n"],"names":["helixCheckboxStyles","css","_nextCheckboxId","createIdCounter","HelixCheckbox","mixinDelegatesAria","FormMixin","HelixElement","_a","_b","slot","changedProperties","hasAccessibleLabel","hasVisibleLabel","_d","_c","state","_mode","disabled","options","hasError","containerClasses","describedBy","hostAriaLabel","html","classMap","live","ifDefined","nothing","e","forcedColorsField","__decorateClass","property","query","customElement"],"mappings":";;;;;;;;;;AAEO,MAAMA,IAAsBC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA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"}
|