@helixui/library 0.1.0 → 0.1.1
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/README.md +174 -0
- package/custom-elements.json +11874 -11838
- package/dist/components/hx-accordion/hx-accordion.d.ts +1 -0
- package/dist/components/hx-accordion/hx-accordion.d.ts.map +1 -1
- package/dist/components/hx-accordion/index.js +1 -1
- package/dist/components/hx-action-bar/index.js +1 -1
- package/dist/components/hx-alert/index.js +1 -1
- package/dist/components/hx-avatar/index.js +1 -1
- package/dist/components/hx-badge/index.js +1 -1
- package/dist/components/hx-breadcrumb/index.js +1 -1
- package/dist/components/hx-button/index.js +1 -1
- package/dist/components/hx-button-group/index.js +1 -1
- package/dist/components/hx-card/index.js +1 -1
- package/dist/components/hx-carousel/hx-carousel-item.d.ts.map +1 -1
- package/dist/components/hx-carousel/index.js +1 -1
- package/dist/components/hx-checkbox/hx-checkbox.d.ts.map +1 -1
- package/dist/components/hx-checkbox/index.js +1 -1
- package/dist/components/hx-checkbox-group/index.js +1 -1
- package/dist/components/hx-code-snippet/index.js +1 -1
- package/dist/components/hx-color-picker/index.js +1 -1
- package/dist/components/hx-combobox/index.js +1 -1
- package/dist/components/hx-container/index.js +1 -1
- package/dist/components/hx-copy-button/index.js +1 -1
- package/dist/components/hx-data-table/index.js +1 -1
- package/dist/components/hx-date-picker/index.js +1 -1
- package/dist/components/hx-dialog/index.js +1 -1
- package/dist/components/hx-divider/index.js +1 -1
- package/dist/components/hx-drawer/index.js +1 -1
- package/dist/components/hx-dropdown/hx-dropdown.d.ts.map +1 -1
- package/dist/components/hx-dropdown/index.js +1 -1
- package/dist/components/hx-field/index.js +1 -1
- package/dist/components/hx-field-label/index.js +1 -1
- package/dist/components/hx-file-upload/index.js +1 -1
- package/dist/components/hx-format-date/index.js +1 -1
- package/dist/components/hx-grid/index.js +1 -1
- package/dist/components/hx-help-text/index.js +1 -1
- package/dist/components/hx-icon/index.js +1 -1
- package/dist/components/hx-image/index.js +1 -1
- package/dist/components/hx-link/index.js +1 -1
- package/dist/components/hx-list/index.js +1 -1
- package/dist/components/hx-menu/hx-menu.d.ts +1 -0
- package/dist/components/hx-menu/hx-menu.d.ts.map +1 -1
- package/dist/components/hx-menu/index.js +1 -1
- package/dist/components/hx-meter/index.js +1 -1
- package/dist/components/hx-nav/hx-nav.d.ts.map +1 -1
- package/dist/components/hx-nav/index.js +1 -1
- package/dist/components/hx-number-input/hx-number-input.d.ts.map +1 -1
- package/dist/components/hx-number-input/index.js +1 -1
- package/dist/components/hx-overflow-menu/index.js +1 -1
- package/dist/components/hx-pagination/index.js +1 -1
- package/dist/components/hx-popover/index.js +1 -1
- package/dist/components/hx-popup/index.js +1 -1
- package/dist/components/hx-progress-bar/index.js +1 -1
- package/dist/components/hx-progress-ring/index.js +1 -1
- package/dist/components/hx-radio-group/index.js +1 -1
- package/dist/components/hx-rating/index.js +1 -1
- package/dist/components/hx-select/index.js +1 -1
- package/dist/components/hx-side-nav/index.js +1 -1
- package/dist/components/hx-skeleton/index.js +1 -1
- package/dist/components/hx-slider/index.js +1 -1
- package/dist/components/hx-spinner/index.js +1 -1
- package/dist/components/hx-split-button/index.js +1 -1
- package/dist/components/hx-split-panel/index.js +1 -1
- package/dist/components/hx-stack/index.js +1 -1
- package/dist/components/hx-status-indicator/index.js +1 -1
- package/dist/components/hx-steps/index.js +1 -1
- package/dist/components/hx-structured-list/index.js +1 -1
- package/dist/components/hx-switch/index.js +1 -1
- package/dist/components/hx-tabs/hx-tabs.d.ts +2 -0
- package/dist/components/hx-tabs/hx-tabs.d.ts.map +1 -1
- package/dist/components/hx-tabs/index.js +1 -1
- package/dist/components/hx-tag/index.js +1 -1
- package/dist/components/hx-text/index.js +1 -1
- package/dist/components/hx-text-input/index.js +1 -1
- package/dist/components/hx-textarea/hx-textarea.d.ts.map +1 -1
- package/dist/components/hx-textarea/index.js +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 +1 -1
- package/dist/components/hx-toast/index.js +1 -1
- package/dist/components/hx-toggle-button/index.js +1 -1
- package/dist/components/hx-tooltip/index.js +1 -1
- package/dist/components/hx-top-nav/hx-top-nav.d.ts.map +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/index.js +1 -1
- package/dist/components/hx-visually-hidden/index.js +1 -1
- package/dist/index.js +70 -70
- package/dist/shared/{hx-accordion-DUkYS5rZ.js → hx-accordion-C84oGPj7.js} +37 -28
- package/dist/shared/{hx-accordion-DUkYS5rZ.js.map → hx-accordion-C84oGPj7.js.map} +1 -1
- package/dist/shared/{hx-action-bar-CwIRFzBx.js → hx-action-bar-DxpGLABm.js} +2 -2
- package/dist/shared/{hx-action-bar-CwIRFzBx.js.map → hx-action-bar-DxpGLABm.js.map} +1 -1
- package/dist/shared/{hx-alert-C3Papw22.js → hx-alert-BQpT4gL3.js} +2 -2
- package/dist/shared/{hx-alert-C3Papw22.js.map → hx-alert-BQpT4gL3.js.map} +1 -1
- package/dist/shared/{hx-avatar-DoHGMrj7.js → hx-avatar-ekyZvOCm.js} +2 -2
- package/dist/shared/{hx-avatar-DoHGMrj7.js.map → hx-avatar-ekyZvOCm.js.map} +1 -1
- package/dist/shared/{hx-badge-BeCmOPr1.js → hx-badge-DYB1Pnym.js} +10 -10
- package/dist/shared/{hx-badge-BeCmOPr1.js.map → hx-badge-DYB1Pnym.js.map} +1 -1
- package/dist/shared/{hx-breadcrumb-item-BSBMWQHz.js → hx-breadcrumb-item-TKRcrMYc.js} +2 -2
- package/dist/shared/{hx-breadcrumb-item-BSBMWQHz.js.map → hx-breadcrumb-item-TKRcrMYc.js.map} +1 -1
- package/dist/shared/{hx-button-p_YAY9Nv.js → hx-button-DpFW7PO3.js} +2 -2
- package/dist/shared/{hx-button-p_YAY9Nv.js.map → hx-button-DpFW7PO3.js.map} +1 -1
- package/dist/shared/{hx-button-group-BbWEDMPb.js → hx-button-group-DxCwaWnu.js} +2 -2
- package/dist/shared/{hx-button-group-BbWEDMPb.js.map → hx-button-group-DxCwaWnu.js.map} +1 -1
- package/dist/shared/{hx-card-DfEGlbZR.js → hx-card-VdiB2Pc4.js} +2 -2
- package/dist/shared/{hx-card-DfEGlbZR.js.map → hx-card-VdiB2Pc4.js.map} +1 -1
- package/dist/shared/{hx-carousel-item-CymJHv1m.js → hx-carousel-item-C2yBnM0r.js} +12 -5
- package/dist/shared/{hx-carousel-item-CymJHv1m.js.map → hx-carousel-item-C2yBnM0r.js.map} +1 -1
- package/dist/shared/{hx-checkbox-CV5c6AE8.js → hx-checkbox-Dq2xXIvl.js} +14 -13
- package/dist/shared/{hx-checkbox-CV5c6AE8.js.map → hx-checkbox-Dq2xXIvl.js.map} +1 -1
- package/dist/shared/{hx-checkbox-group-ClGxYUi0.js → hx-checkbox-group-BLePVahw.js} +15 -15
- package/dist/shared/{hx-checkbox-group-ClGxYUi0.js.map → hx-checkbox-group-BLePVahw.js.map} +1 -1
- package/dist/shared/{hx-code-snippet-CoFaSyuB.js → hx-code-snippet-DjY96OY8.js} +2 -2
- package/dist/shared/{hx-code-snippet-CoFaSyuB.js.map → hx-code-snippet-DjY96OY8.js.map} +1 -1
- package/dist/shared/{hx-color-picker-BF7PA7zf.js → hx-color-picker-O4b_6QXT.js} +2 -2
- package/dist/shared/{hx-color-picker-BF7PA7zf.js.map → hx-color-picker-O4b_6QXT.js.map} +1 -1
- package/dist/shared/{hx-combobox-De4-pDn0.js → hx-combobox-DjMigccw.js} +2 -2
- package/dist/shared/{hx-combobox-De4-pDn0.js.map → hx-combobox-DjMigccw.js.map} +1 -1
- package/dist/shared/{hx-container-DWBtruk3.js → hx-container-COinHjxn.js} +2 -2
- package/dist/shared/{hx-container-DWBtruk3.js.map → hx-container-COinHjxn.js.map} +1 -1
- package/dist/shared/{hx-copy-button-BCy6VMwN.js → hx-copy-button-BXL1xkxb.js} +2 -2
- package/dist/shared/{hx-copy-button-BCy6VMwN.js.map → hx-copy-button-BXL1xkxb.js.map} +1 -1
- package/dist/shared/{hx-data-table-D5huonFo.js → hx-data-table-D3NZvc3P.js} +2 -2
- package/dist/shared/{hx-data-table-D5huonFo.js.map → hx-data-table-D3NZvc3P.js.map} +1 -1
- package/dist/shared/{hx-date-picker-Ckvm0yi9.js → hx-date-picker-CIHwx9b3.js} +2 -2
- package/dist/shared/{hx-date-picker-Ckvm0yi9.js.map → hx-date-picker-CIHwx9b3.js.map} +1 -1
- package/dist/shared/{hx-dialog-D_NXy5rB.js → hx-dialog-1VegS0l1.js} +2 -2
- package/dist/shared/{hx-dialog-D_NXy5rB.js.map → hx-dialog-1VegS0l1.js.map} +1 -1
- package/dist/shared/{hx-divider-BDMW3H-1.js → hx-divider-UdSFzALX.js} +2 -2
- package/dist/shared/{hx-divider-BDMW3H-1.js.map → hx-divider-UdSFzALX.js.map} +1 -1
- package/dist/shared/{hx-drawer-CESgUmre.js → hx-drawer-CenIAGuR.js} +2 -2
- package/dist/shared/{hx-drawer-CESgUmre.js.map → hx-drawer-CenIAGuR.js.map} +1 -1
- package/dist/shared/{hx-dropdown-AZLF-5t6.js → hx-dropdown-DnjLnkTj.js} +31 -31
- package/dist/shared/{hx-dropdown-AZLF-5t6.js.map → hx-dropdown-DnjLnkTj.js.map} +1 -1
- package/dist/shared/{hx-field-vWiKgWIy.js → hx-field-BMyp6hBx.js} +2 -2
- package/dist/shared/{hx-field-vWiKgWIy.js.map → hx-field-BMyp6hBx.js.map} +1 -1
- package/dist/shared/{hx-field-label-CPBvSn_r.js → hx-field-label-Bg-EWvqF.js} +2 -2
- package/dist/shared/{hx-field-label-CPBvSn_r.js.map → hx-field-label-Bg-EWvqF.js.map} +1 -1
- package/dist/shared/{hx-file-upload-Px6kRzAZ.js → hx-file-upload-DnYiIhyN.js} +2 -2
- package/dist/shared/{hx-file-upload-Px6kRzAZ.js.map → hx-file-upload-DnYiIhyN.js.map} +1 -1
- package/dist/shared/{hx-format-date-BIR66MeC.js → hx-format-date-BsVr8gpD.js} +2 -2
- package/dist/shared/{hx-format-date-BIR66MeC.js.map → hx-format-date-BsVr8gpD.js.map} +1 -1
- package/dist/shared/{hx-grid-Dgo7fnWu.js → hx-grid-BsDBCTbt.js} +2 -2
- package/dist/shared/{hx-grid-Dgo7fnWu.js.map → hx-grid-BsDBCTbt.js.map} +1 -1
- package/dist/shared/{hx-help-text-C3WCP11-.js → hx-help-text-DaOPN1iB.js} +2 -2
- package/dist/shared/{hx-help-text-C3WCP11-.js.map → hx-help-text-DaOPN1iB.js.map} +1 -1
- package/dist/shared/{hx-icon-CxOk7jZe.js → hx-icon--xsJztDh.js} +2 -2
- package/dist/shared/{hx-icon-CxOk7jZe.js.map → hx-icon--xsJztDh.js.map} +1 -1
- package/dist/shared/{hx-image-CZPw1AiF.js → hx-image-CzkOEeO4.js} +2 -2
- package/dist/shared/{hx-image-CZPw1AiF.js.map → hx-image-CzkOEeO4.js.map} +1 -1
- package/dist/shared/{hx-link-DObQ7eS4.js → hx-link-D73HP4Lq.js} +2 -2
- package/dist/shared/{hx-link-DObQ7eS4.js.map → hx-link-D73HP4Lq.js.map} +1 -1
- package/dist/shared/{hx-list-B6yPCAAW.js → hx-list-CF-AAnp-.js} +2 -2
- package/dist/shared/{hx-list-B6yPCAAW.js.map → hx-list-CF-AAnp-.js.map} +1 -1
- package/dist/shared/{hx-menu-divider-BgVoqte4.js → hx-menu-divider-Bds6Gn6b.js} +44 -36
- package/dist/shared/hx-menu-divider-Bds6Gn6b.js.map +1 -0
- package/dist/shared/{hx-meter-B5LOo0zD.js → hx-meter-qcXl0zCL.js} +2 -2
- package/dist/shared/{hx-meter-B5LOo0zD.js.map → hx-meter-qcXl0zCL.js.map} +1 -1
- package/dist/shared/{hx-nav-BhtMZCze.js → hx-nav-TK0mPfU6.js} +19 -19
- package/dist/shared/hx-nav-TK0mPfU6.js.map +1 -0
- package/dist/shared/{hx-nav-item-CbNibLuK.js → hx-nav-item-XvXQzMwc.js} +2 -2
- package/dist/shared/{hx-nav-item-CbNibLuK.js.map → hx-nav-item-XvXQzMwc.js.map} +1 -1
- package/dist/shared/{hx-number-input-DgHt4ggr.js → hx-number-input-BJ5XSvjL.js} +22 -19
- package/dist/shared/{hx-number-input-DgHt4ggr.js.map → hx-number-input-BJ5XSvjL.js.map} +1 -1
- package/dist/shared/{hx-overflow-menu-DkbrRDmB.js → hx-overflow-menu-CAS1Mlus.js} +2 -2
- package/dist/shared/{hx-overflow-menu-DkbrRDmB.js.map → hx-overflow-menu-CAS1Mlus.js.map} +1 -1
- package/dist/shared/{hx-pagination-VMEpaOXX.js → hx-pagination-DNFgXQm3.js} +2 -2
- package/dist/shared/{hx-pagination-VMEpaOXX.js.map → hx-pagination-DNFgXQm3.js.map} +1 -1
- package/dist/shared/{hx-popover-DTe00Q46.js → hx-popover-BjAyLbzp.js} +2 -2
- package/dist/shared/{hx-popover-DTe00Q46.js.map → hx-popover-BjAyLbzp.js.map} +1 -1
- package/dist/shared/{hx-popup-5O6q0jf1.js → hx-popup-CYf9Q5sj.js} +2 -2
- package/dist/shared/{hx-popup-5O6q0jf1.js.map → hx-popup-CYf9Q5sj.js.map} +1 -1
- package/dist/shared/{hx-progress-bar-vQnpJ-9N.js → hx-progress-bar-b3_m1hna.js} +2 -2
- package/dist/shared/{hx-progress-bar-vQnpJ-9N.js.map → hx-progress-bar-b3_m1hna.js.map} +1 -1
- package/dist/shared/{hx-progress-ring-DDSW677s.js → hx-progress-ring-QGg5fdis.js} +2 -2
- package/dist/shared/{hx-progress-ring-DDSW677s.js.map → hx-progress-ring-QGg5fdis.js.map} +1 -1
- package/dist/shared/{hx-radio-93uKku6B.js → hx-radio-CWzYFy-I.js} +2 -2
- package/dist/shared/{hx-radio-93uKku6B.js.map → hx-radio-CWzYFy-I.js.map} +1 -1
- package/dist/shared/{hx-rating-t4o150-R.js → hx-rating-C4kTOyHF.js} +2 -2
- package/dist/shared/{hx-rating-t4o150-R.js.map → hx-rating-C4kTOyHF.js.map} +1 -1
- package/dist/shared/{hx-select-DQks1zLJ.js → hx-select-D9bYJcDv.js} +2 -2
- package/dist/shared/{hx-select-DQks1zLJ.js.map → hx-select-D9bYJcDv.js.map} +1 -1
- package/dist/shared/{hx-skeleton-DQQ2SYxF.js → hx-skeleton-BHvALyd7.js} +2 -2
- package/dist/shared/{hx-skeleton-DQQ2SYxF.js.map → hx-skeleton-BHvALyd7.js.map} +1 -1
- package/dist/shared/{hx-slider-BRMWoKZk.js → hx-slider-BMofa55D.js} +2 -2
- package/dist/shared/{hx-slider-BRMWoKZk.js.map → hx-slider-BMofa55D.js.map} +1 -1
- package/dist/shared/{hx-spinner-CcbmN-u_.js → hx-spinner-BOApJ-g9.js} +2 -2
- package/dist/shared/{hx-spinner-CcbmN-u_.js.map → hx-spinner-BOApJ-g9.js.map} +1 -1
- package/dist/shared/{hx-split-button-hBPl-zRv.js → hx-split-button-DhncgAtZ.js} +2 -2
- package/dist/shared/{hx-split-button-hBPl-zRv.js.map → hx-split-button-DhncgAtZ.js.map} +1 -1
- package/dist/shared/{hx-split-panel-C9Sy7XVW.js → hx-split-panel-D9Jg5qKO.js} +2 -2
- package/dist/shared/{hx-split-panel-C9Sy7XVW.js.map → hx-split-panel-D9Jg5qKO.js.map} +1 -1
- package/dist/shared/{hx-stack-B_wODjQX.js → hx-stack-C3xUwi6-.js} +2 -2
- package/dist/shared/{hx-stack-B_wODjQX.js.map → hx-stack-C3xUwi6-.js.map} +1 -1
- package/dist/shared/{hx-status-indicator-CiTQuO5V.js → hx-status-indicator-Mv44COA-.js} +16 -16
- package/dist/shared/{hx-status-indicator-CiTQuO5V.js.map → hx-status-indicator-Mv44COA-.js.map} +1 -1
- package/dist/shared/{hx-step-m5RcyZ61.js → hx-step-nMT0fHEn.js} +2 -2
- package/dist/shared/{hx-step-m5RcyZ61.js.map → hx-step-nMT0fHEn.js.map} +1 -1
- package/dist/shared/{hx-structured-list-ClvSFleR.js → hx-structured-list-DKborM60.js} +2 -2
- package/dist/shared/{hx-structured-list-ClvSFleR.js.map → hx-structured-list-DKborM60.js.map} +1 -1
- package/dist/shared/{hx-switch-BFxgxal8.js → hx-switch-BPvIcDpM.js} +2 -2
- package/dist/shared/{hx-switch-BFxgxal8.js.map → hx-switch-BPvIcDpM.js.map} +1 -1
- package/dist/shared/{hx-tab-panel-8p6KfVzz.js → hx-tab-panel-C7h5lRpw.js} +97 -80
- package/dist/shared/hx-tab-panel-C7h5lRpw.js.map +1 -0
- package/dist/shared/{hx-tag-BP7HJ6_0.js → hx-tag-SJJtMlOS.js} +2 -2
- package/dist/shared/{hx-tag-BP7HJ6_0.js.map → hx-tag-SJJtMlOS.js.map} +1 -1
- package/dist/shared/{hx-text-DDSH1alC.js → hx-text-NjKoQATI.js} +2 -2
- package/dist/shared/{hx-text-DDSH1alC.js.map → hx-text-NjKoQATI.js.map} +1 -1
- package/dist/shared/{hx-text-input-Dv458950.js → hx-text-input-BUMgOQHX.js} +2 -2
- package/dist/shared/{hx-text-input-Dv458950.js.map → hx-text-input-BUMgOQHX.js.map} +1 -1
- package/dist/shared/{hx-textarea-BX8nCfDJ.js → hx-textarea-Bsq5aJf8.js} +14 -14
- package/dist/shared/hx-textarea-Bsq5aJf8.js.map +1 -0
- package/dist/shared/{hx-theme-Dc0nKH7V.js → hx-theme-6GDoUG8j.js} +19 -19
- package/dist/shared/{hx-theme-Dc0nKH7V.js.map → hx-theme-6GDoUG8j.js.map} +1 -1
- package/dist/shared/{hx-time-picker-CA58UCqx.js → hx-time-picker-a-BCkecJ.js} +2 -2
- package/dist/shared/{hx-time-picker-CA58UCqx.js.map → hx-time-picker-a-BCkecJ.js.map} +1 -1
- package/dist/shared/{hx-toast-BTqzF2VV.js → hx-toast-ikwh9Y03.js} +2 -2
- package/dist/shared/{hx-toast-BTqzF2VV.js.map → hx-toast-ikwh9Y03.js.map} +1 -1
- package/dist/shared/{hx-toggle-button-BkDaJgRS.js → hx-toggle-button---Z4zvmn.js} +2 -2
- package/dist/shared/{hx-toggle-button-BkDaJgRS.js.map → hx-toggle-button---Z4zvmn.js.map} +1 -1
- package/dist/shared/{hx-tooltip-wAQWzjlr.js → hx-tooltip-DN6lMlP5.js} +2 -2
- package/dist/shared/{hx-tooltip-wAQWzjlr.js.map → hx-tooltip-DN6lMlP5.js.map} +1 -1
- package/dist/shared/{hx-top-nav-CBxdfPqY.js → hx-top-nav-8lDKNZUj.js} +47 -40
- package/dist/shared/hx-top-nav-8lDKNZUj.js.map +1 -0
- package/dist/shared/{hx-tree-item-BySNNlrw.js → hx-tree-item-CIo3ek2M.js} +2 -2
- package/dist/shared/{hx-tree-item-BySNNlrw.js.map → hx-tree-item-CIo3ek2M.js.map} +1 -1
- package/dist/shared/{hx-visually-hidden-8ycpz6oY.js → hx-visually-hidden-CCTQTjbR.js} +2 -2
- package/dist/shared/{hx-visually-hidden-8ycpz6oY.js.map → hx-visually-hidden-CCTQTjbR.js.map} +1 -1
- package/package.json +20 -3
- package/dist/shared/hx-menu-divider-BgVoqte4.js.map +0 -1
- package/dist/shared/hx-nav-BhtMZCze.js.map +0 -1
- package/dist/shared/hx-tab-panel-8p6KfVzz.js.map +0 -1
- package/dist/shared/hx-textarea-BX8nCfDJ.js.map +0 -1
- package/dist/shared/hx-top-nav-CBxdfPqY.js.map +0 -1
- package/dist/shared/index-nHBAh0Cr.js +0 -74
- package/dist/shared/index-nHBAh0Cr.js.map +0 -1
- package/dist/shared/lit-Dpo7RLp4.js +0 -24
- package/dist/shared/lit-Dpo7RLp4.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hx-slider-BRMWoKZk.js","sources":["../../src/components/hx-slider/hx-slider.styles.ts","../../src/components/hx-slider/hx-slider.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixSliderStyles = 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 /* ─── Container ─── */\n\n .slider {\n display: flex;\n flex-direction: column;\n gap: var(--hx-space-1, 0.25rem);\n font-family: var(--hx-font-family-sans, sans-serif);\n }\n\n /* ─── Label Row ─── */\n\n .slider__label-row {\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n gap: var(--hx-space-2, 0.5rem);\n }\n\n .slider__label {\n font-size: var(--hx-font-size-sm, 0.875rem);\n font-weight: var(--hx-font-weight-medium, 500);\n color: var(--hx-slider-label-color, var(--hx-color-neutral-700, #343a40));\n line-height: var(--hx-line-height-normal, 1.5);\n }\n\n .slider__value-display {\n font-size: var(--hx-font-size-sm, 0.875rem);\n font-weight: var(--hx-font-weight-medium, 500);\n color: var(--hx-slider-value-color, var(--hx-color-neutral-600, #6c757d));\n line-height: var(--hx-line-height-normal, 1.5);\n font-variant-numeric: tabular-nums;\n min-width: var(--hx-size-8, 2rem);\n text-align: right;\n }\n\n /* ─── Track Container ─── */\n\n .slider__track-container {\n position: relative;\n width: 100%;\n }\n\n .slider__track {\n position: relative;\n width: 100%;\n border-radius: var(--hx-border-radius-full, 9999px);\n background-color: var(--hx-slider-track-bg, var(--hx-color-neutral-200, #e9ecef));\n overflow: visible;\n }\n\n /* ─── Size: sm ─── */\n\n .slider--sm .slider__track {\n height: var(--hx-slider-track-height-sm, var(--hx-size-1, 0.25rem));\n }\n\n .slider--sm .slider__input {\n height: var(--hx-slider-track-height-sm, var(--hx-size-1, 0.25rem));\n }\n\n /* ─── Size: md ─── */\n\n .slider--md .slider__track {\n height: var(--hx-slider-track-height-md, var(--hx-size-1-5, 0.375rem));\n }\n\n .slider--md .slider__input {\n height: var(--hx-slider-track-height-md, var(--hx-size-1-5, 0.375rem));\n }\n\n /* ─── Size: lg ─── */\n\n .slider--lg .slider__track {\n height: var(--hx-slider-track-height-lg, var(--hx-size-2, 0.5rem));\n }\n\n .slider--lg .slider__input {\n height: var(--hx-slider-track-height-lg, var(--hx-size-2, 0.5rem));\n }\n\n /* ─── Fill ─── */\n\n .slider__fill {\n position: absolute;\n top: 0;\n left: 0;\n height: 100%;\n border-radius: var(--hx-border-radius-full, 9999px);\n background-color: var(--hx-slider-fill-bg, var(--hx-color-primary-500, #2563eb));\n pointer-events: none;\n transition: width var(--hx-transition-fast, 150ms ease);\n }\n\n @media (prefers-reduced-motion: reduce) {\n .slider__fill {\n transition: none;\n }\n }\n\n /* ─── Native Range Input ─── */\n\n .slider__input {\n position: absolute;\n top: 50%;\n left: 0;\n transform: translateY(-50%);\n width: 100%;\n margin: 0;\n padding: 0;\n opacity: 0;\n cursor: pointer;\n -webkit-appearance: none;\n appearance: none;\n background: transparent;\n border: none;\n outline: none;\n /* Expand the hit area so the thumb is easy to grab */\n padding-block: var(--hx-slider-input-padding-block, 0.75rem);\n }\n\n /* In forced-color mode, restore native outline so the input remains focusable */\n @media (forced-colors: active) {\n .slider__input {\n outline: revert;\n opacity: 1;\n }\n .slider__input:focus-visible {\n outline: 2px solid ButtonText;\n }\n }\n\n .slider__input:disabled {\n cursor: not-allowed;\n }\n\n /* ─── Thumb (visual, :before on a wrapper or via ::after on track) ─── */\n /*\n * The native thumb is hidden (opacity 0 on the input). We render a visible\n * thumb element positioned by --fill-pct (a raw 0–100 number set in JS).\n *\n * Correct alignment formula keeps the thumb centered within the track at\n * both extremes, preventing the left/right halves from clipping outside:\n * left = fillPct% * (1 – thumbSize/100%) + thumbSize * (1 – fillPct/100)\n * Simplified: left = calc(var(--fill-pct,0)*1% + var(--_thumb-size)*(1 - var(--fill-pct,0)/100))\n * Combined with translate(-50%,-50%) this places the thumb center correctly\n * at every position from min to max.\n */\n\n .slider__thumb-visual {\n position: absolute;\n top: 50%;\n /* Corrected position: thumb stays within track at all fill values */\n left: calc(var(--fill-pct, 0) * 1% + var(--_thumb-size, 1rem) * (1 - var(--fill-pct, 0) / 100));\n transform: translate(-50%, -50%);\n border-radius: var(--hx-border-radius-full, 9999px);\n background-color: var(--hx-slider-thumb-bg, var(--hx-color-neutral-0, #ffffff));\n border: 2px solid var(--hx-slider-thumb-border-color, var(--hx-color-primary-500, #2563eb));\n box-shadow: var(--hx-slider-thumb-shadow, var(--hx-shadow-sm, 0 1px 2px 0 rgb(0 0 0 / 0.05)));\n pointer-events: none;\n transition:\n box-shadow var(--hx-transition-fast, 150ms ease),\n transform var(--hx-transition-fast, 150ms ease);\n }\n\n @media (prefers-reduced-motion: reduce) {\n .slider__thumb-visual {\n transition: none;\n }\n }\n\n .slider__input:focus-visible ~ .slider__thumb-visual {\n box-shadow:\n 0 0 0 var(--hx-focus-ring-width, 2px)\n var(--hx-slider-focus-ring-color, var(--hx-focus-ring-color, #2563eb)),\n var(--hx-slider-thumb-shadow, var(--hx-shadow-sm, 0 1px 2px 0 rgb(0 0 0 / 0.05)));\n }\n\n /* ─── Thumb sizes ─── */\n\n .slider--sm .slider__thumb-visual {\n --_thumb-size: var(--hx-slider-thumb-size-sm, var(--hx-size-3, 0.75rem));\n width: var(--_thumb-size);\n height: var(--_thumb-size);\n }\n\n .slider--md .slider__thumb-visual {\n --_thumb-size: var(--hx-slider-thumb-size-md, var(--hx-size-4, 1rem));\n width: var(--_thumb-size);\n height: var(--_thumb-size);\n }\n\n .slider--lg .slider__thumb-visual {\n --_thumb-size: var(--hx-slider-thumb-size-lg, var(--hx-size-5, 1.25rem));\n width: var(--_thumb-size);\n height: var(--_thumb-size);\n }\n\n /* ─── Forced colors (Windows High Contrast) ─── */\n @media (forced-colors: active) {\n .slider__fill {\n background-color: Highlight;\n }\n .slider__track {\n background-color: ButtonFace;\n border: 1px solid ButtonText;\n }\n .slider__thumb-visual {\n background-color: ButtonText;\n border-color: ButtonText;\n }\n .slider__input:focus-visible ~ .slider__thumb-visual {\n outline: 2px solid Highlight;\n }\n }\n\n /* ─── Ticks ─── */\n\n .slider__ticks {\n position: relative;\n width: 100%;\n height: var(--hx-size-2, 0.5rem);\n margin-top: var(--hx-space-1, 0.25rem);\n }\n\n .slider__tick {\n position: absolute;\n top: 0;\n width: var(--hx-border-width-thin, 1px);\n height: 100%;\n background-color: var(--hx-slider-tick-color, var(--hx-color-neutral-400, #adb5bd));\n transform: translateX(-50%);\n }\n\n /* ─── Range Labels ─── */\n\n .slider__range-labels {\n display: flex;\n justify-content: space-between;\n font-size: var(--hx-font-size-xs, 0.75rem);\n color: var(--hx-slider-range-label-color, var(--hx-color-neutral-500, #6c757d));\n line-height: var(--hx-line-height-normal, 1.5);\n margin-top: var(--hx-space-0-5, 0.125rem);\n }\n\n /* ─── Help Text ─── */\n\n .slider__help-text {\n font-size: var(--hx-font-size-xs, 0.75rem);\n color: var(--hx-slider-help-text-color, var(--hx-color-neutral-500, #6c757d));\n line-height: var(--hx-line-height-normal, 1.5);\n }\n\n /* ─── Disabled state ─── */\n\n .slider--disabled .slider__fill {\n background-color: var(--hx-color-neutral-400, #adb5bd);\n }\n\n .slider--disabled .slider__thumb-visual {\n border-color: var(--hx-color-neutral-400, #adb5bd);\n }\n`;\n","import { LitElement, TemplateResult, html, nothing } from 'lit';\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 { styleMap } from 'lit/directives/style-map.js';\nimport { tokenStyles } from '@helixui/tokens/lit';\nimport { helixSliderStyles } from './hx-slider.styles.js';\n\n// Module-level counter for stable, SSR-safe IDs (avoids Math.random() hydration mismatch)\nlet _hxSliderIdCounter = 0;\n\n/**\n * A range slider component for selecting a numeric value within a min/max boundary.\n * Supports tick marks, value display, range labels, and native form participation\n * via ElementInternals.\n *\n * The native `<input type=\"range\">` receives `role=\"slider\"` with `aria-valuenow`,\n * `aria-valuemin`, and `aria-valuemax`. Label association uses `aria-labelledby`\n * when a label is present, or `aria-label` as a fallback. Help text is linked via\n * `aria-describedby`. Keyboard navigation follows the native range behavior:\n * Arrow keys increment/decrement by step, Home jumps to min, End jumps to max.\n *\n * @summary Form-associated range slider with label, ticks, and value display.\n *\n * @tag hx-slider\n *\n * @slot label - Custom label content (overrides the label property).\n * @slot help-text - Custom help text content (overrides the helpText property).\n * @slot min-label - Label rendered at the minimum end of the slider.\n * @slot max-label - Label rendered at the maximum end of the slider.\n *\n * @fires {CustomEvent<{value: number}>} hx-input - Dispatched continuously while the user drags.\n * @fires {CustomEvent<{value: number}>} hx-change - Dispatched when the user releases the thumb.\n *\n * @csspart slider - The outer container element.\n * @csspart track - The track background element.\n * @csspart fill - The filled portion of the track showing progress.\n * @csspart thumb - The draggable thumb overlay element.\n * @csspart label - The label element.\n * @csspart value-display - The element displaying the current numeric value.\n * @csspart tick - Each individual tick mark element.\n *\n * @cssprop [--hx-slider-track-bg=var(--hx-color-neutral-200)] - Track background color.\n * @cssprop [--hx-slider-fill-bg=var(--hx-color-primary-500)] - Fill/progress color.\n * @cssprop [--hx-slider-thumb-bg=var(--hx-color-neutral-0)] - Thumb background color.\n * @cssprop [--hx-slider-thumb-border-color=var(--hx-color-primary-500)] - Thumb border color.\n * @cssprop [--hx-slider-thumb-shadow=var(--hx-shadow-sm)] - Thumb box shadow.\n * @cssprop [--hx-slider-focus-ring-color=var(--hx-focus-ring-color)] - Focus ring color.\n * @cssprop [--hx-slider-label-color=var(--hx-color-neutral-700)] - Label text color.\n * @cssprop [--hx-slider-value-color=var(--hx-color-neutral-600)] - Value display text color.\n * @cssprop [--hx-slider-tick-color=var(--hx-color-neutral-400)] - Tick mark color.\n * @cssprop [--hx-slider-range-label-color=var(--hx-color-neutral-500)] - Range label text color.\n * @cssprop [--hx-slider-help-text-color=var(--hx-color-neutral-500)] - Help text color.\n */\n@customElement('hx-slider')\nexport class HelixSlider extends LitElement {\n static override styles = [tokenStyles, helixSliderStyles];\n\n // ─── Form Association ───\n\n /** Enables native form participation via ElementInternals. */\n static formAssociated = true;\n\n /** ElementInternals instance for form value, validity, and label association. */\n private _internals: ElementInternals;\n\n constructor() {\n super();\n this._internals = this.attachInternals();\n }\n\n // ─── Properties ───\n\n /**\n * The name submitted with the form.\n * @attr name\n */\n @property({ type: String })\n name = '';\n\n /**\n * The current numeric value of the slider.\n * @attr value\n */\n @property({ type: Number })\n value = 0;\n\n /**\n * The minimum allowed value.\n * @attr min\n */\n @property({ type: Number })\n min = 0;\n\n /**\n * The maximum allowed value.\n * @attr max\n */\n @property({ type: Number })\n max = 100;\n\n /**\n * The stepping interval between values.\n * @attr step\n */\n @property({ type: Number })\n step = 1;\n\n /**\n * Whether the slider is disabled.\n * @attr disabled\n */\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /**\n * The visible label text for the slider.\n * @attr label\n */\n @property({ type: String })\n label = '';\n\n /**\n * Help text displayed below the slider for guidance.\n * @attr help-text\n */\n @property({ type: String, attribute: 'help-text' })\n helpText = '';\n\n /**\n * When true, the current value is shown next to the label.\n * @attr show-value\n */\n @property({ type: Boolean, attribute: 'show-value' })\n showValue = false;\n\n /**\n * When true, tick marks are rendered at each step interval.\n * @attr show-ticks\n */\n @property({ type: Boolean, attribute: 'show-ticks' })\n showTicks = false;\n\n /**\n * The size variant of the slider.\n * @attr hx-size\n */\n @property({ type: String, reflect: true, attribute: 'hx-size' })\n size: 'sm' | 'md' | 'lg' = 'md';\n\n /**\n * Human-readable text alternative for the current value, announced by screen readers\n * instead of the numeric value. For example, on a pain scale: \"7 — Moderate-Severe\".\n * @attr aria-valuetext\n */\n @property({ type: String, attribute: 'aria-valuetext' })\n valueText = '';\n\n // ─── Internal State ───\n\n /** Whether the label slot has assigned content. */\n @state() private _hasLabelSlot = false;\n /** Whether the min-label slot has assigned content. */\n @state() private _hasMinLabelSlot = false;\n /** Whether the max-label slot has assigned content. */\n @state() private _hasMaxLabelSlot = false;\n /** Whether the help slot has assigned content. */\n @state() private _hasHelpSlot = false;\n\n // ─── Internal References ───\n\n /** Reference to the native range `<input>` inside shadow DOM. */\n @query('.slider__input')\n private _input!: HTMLInputElement;\n\n // ─── Unique IDs ───\n\n /** Unique ID for the native range input element. */\n private readonly _sliderId = `hx-slider-${++_hxSliderIdCounter}`;\n /** Unique ID for the label element, derived from _sliderId. */\n private readonly _labelId = `${this._sliderId}-label`;\n /** Unique ID for the help text element, derived from _sliderId. */\n private readonly _helpId = `${this._sliderId}-help`;\n\n // ─── Computed Values ───\n\n private _clamp(v: number): number {\n return Math.min(Math.max(v, this.min), this.max);\n }\n\n private _fillPercent(): number {\n const clamped = this._clamp(this.value);\n const range = this.max - this.min;\n if (range === 0) return 0;\n return ((clamped - this.min) / range) * 100;\n }\n\n private _ticks(): number[] {\n if (!this.showTicks) return [];\n const ticks: number[] = [];\n const range = this.max - this.min;\n if (range <= 0 || this.step <= 0) return ticks;\n const count = Math.round(range / this.step);\n for (let i = 0; i <= count; i++) {\n ticks.push((i / count) * 100);\n }\n return ticks;\n }\n\n // ─── Lifecycle ───\n\n override updated(changedProperties: Map<string, unknown>): void {\n super.updated(changedProperties);\n // Clamp value to [min, max] after any relevant property change\n if (\n changedProperties.has('value') ||\n changedProperties.has('min') ||\n changedProperties.has('max')\n ) {\n const clamped = this._clamp(this.value);\n if (clamped !== this.value) {\n this.value = clamped;\n return;\n }\n this._internals.setFormValue(String(this.value));\n } else if (changedProperties.has('name')) {\n this._internals.setFormValue(String(this.value));\n }\n // Reflect aria-disabled on host for AT traversal\n if (changedProperties.has('disabled')) {\n if (this.disabled) {\n this.setAttribute('aria-disabled', 'true');\n } else {\n this.removeAttribute('aria-disabled');\n }\n }\n }\n\n // ─── Form Integration ───\n\n /** Returns the associated form element, if any. */\n get form(): HTMLFormElement | null {\n return this._internals.form;\n }\n\n /** Returns the validation message. */\n get validationMessage(): string {\n return this._internals.validationMessage;\n }\n\n /** Returns the ValidityState object. */\n get validity(): ValidityState {\n return this._internals.validity;\n }\n\n /** Checks whether the slider satisfies its constraints. */\n checkValidity(): boolean {\n return this._internals.checkValidity();\n }\n\n /** Reports validity and shows the browser's constraint validation UI. */\n reportValidity(): boolean {\n return this._internals.reportValidity();\n }\n\n /** Called by the form when it resets. Restores to the declared `value` attribute (default value). */\n formResetCallback(): void {\n const attrValue = this.getAttribute('value');\n const defaultValue = attrValue !== null ? parseFloat(attrValue) : this.min;\n const resetTo = this._clamp(!isNaN(defaultValue) ? defaultValue : this.min);\n this.value = resetTo;\n this._internals.setFormValue(String(resetTo));\n }\n\n /**\n * Called when the form restores state (e.g., back/forward navigation or autofill).\n * @param state - The serialized value to restore.\n * @param _reason - Either \"restore\" (back/forward) or \"autocomplete\".\n */\n formStateRestoreCallback(state: string, _reason: string): void {\n const parsed = parseFloat(state);\n if (!isNaN(parsed)) {\n this.value = this._clamp(parsed);\n }\n }\n\n // ─── Public Methods ───\n\n /** Moves focus to the native range input. */\n override focus(options?: FocusOptions): void {\n this._input?.focus(options);\n }\n\n // ─── Slot Handlers ───\n\n private _handleLabelSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n this._hasLabelSlot = slot.assignedNodes({ flatten: true }).length > 0;\n }\n\n private _handleHelpSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n this._hasHelpSlot = slot.assignedNodes({ flatten: true }).length > 0;\n }\n\n private _handleMinLabelSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n this._hasMinLabelSlot = slot.assignedNodes({ flatten: true }).length > 0;\n }\n\n private _handleMaxLabelSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n this._hasMaxLabelSlot = slot.assignedNodes({ flatten: true }).length > 0;\n }\n\n // ─── Event Handling ───\n\n private _handleInput(e: Event): void {\n if (this.disabled) return;\n const target = e.target as HTMLInputElement;\n this.value = parseFloat(target.value);\n this._internals.setFormValue(String(this.value));\n\n /**\n * Dispatched continuously while the user drags the thumb.\n * @event hx-input\n */\n this.dispatchEvent(\n new CustomEvent('hx-input', {\n bubbles: true,\n composed: true,\n detail: { value: this.value },\n }),\n );\n }\n\n private _handleChange(e: Event): void {\n if (this.disabled) return;\n const target = e.target as HTMLInputElement;\n this.value = parseFloat(target.value);\n this._internals.setFormValue(String(this.value));\n\n /**\n * Dispatched when the user releases the thumb after dragging.\n * @event hx-change\n */\n this.dispatchEvent(\n new CustomEvent('hx-change', {\n bubbles: true,\n composed: true,\n detail: { value: this.value },\n }),\n );\n }\n\n // ─── Render ───\n\n override render(): TemplateResult {\n const fillPct = this._fillPercent();\n const ticks = this._ticks();\n const hasLabel = !!this.label || this._hasLabelSlot;\n const showRangeLabels = this._hasMinLabelSlot || this._hasMaxLabelSlot;\n\n const containerClasses = {\n slider: true,\n [`slider--${this.size}`]: true,\n 'slider--disabled': this.disabled,\n 'slider--has-ticks': this.showTicks,\n };\n\n const describedBy =\n [this.helpText || this._hasHelpSlot ? this._helpId : null].filter(Boolean).join(' ') ||\n undefined;\n\n return html`\n <div part=\"slider\" class=${classMap(containerClasses)}>\n <!-- Label row -->\n <div class=\"slider__label-row\">\n ${hasLabel\n ? html`<label\n part=\"label\"\n class=\"slider__label\"\n id=${this._labelId}\n for=${this._sliderId}\n >\n <slot name=\"label\" @slotchange=${this._handleLabelSlotChange}>${this.label}</slot>\n </label>`\n : html`<slot name=\"label\" @slotchange=${this._handleLabelSlotChange}></slot>`}\n ${this.showValue\n ? html`<span part=\"value-display\" class=\"slider__value-display\"> ${this.value} </span>`\n : nothing}\n </div>\n\n <!-- Track -->\n <div class=\"slider__track-container\">\n <div part=\"track\" class=\"slider__track\">\n <div part=\"fill\" class=\"slider__fill\" style=${styleMap({ width: `${fillPct}%` })}></div>\n\n <input\n class=\"slider__input\"\n id=${this._sliderId}\n type=\"range\"\n .value=${live(String(this.value))}\n min=${this.min}\n max=${this.max}\n step=${this.step}\n ?disabled=${this.disabled}\n name=${ifDefined(this.name || undefined)}\n aria-labelledby=${ifDefined(hasLabel ? this._labelId : undefined)}\n aria-valuetext=${ifDefined(this.valueText || undefined)}\n aria-describedby=${ifDefined(describedBy)}\n @input=${this._handleInput}\n @change=${this._handleChange}\n />\n\n <!-- Visual thumb positioned by fill percentage (--fill-pct drives CSS calc) -->\n <span\n part=\"thumb\"\n class=\"slider__thumb-visual\"\n style=${styleMap({ '--fill-pct': String(fillPct) })}\n aria-hidden=\"true\"\n ></span>\n </div>\n </div>\n\n <!-- Tick marks -->\n ${this.showTicks && ticks.length > 0\n ? html`<div class=\"slider__ticks\">\n ${ticks.map(\n (pct) =>\n html`<span\n part=\"tick\"\n class=\"slider__tick\"\n style=${styleMap({ left: `${pct}%` })}\n ></span>`,\n )}\n </div>`\n : nothing}\n\n <!-- Range labels -->\n ${showRangeLabels\n ? html`<div class=\"slider__range-labels\">\n <slot name=\"min-label\" @slotchange=${this._handleMinLabelSlotChange}></slot>\n <slot name=\"max-label\" @slotchange=${this._handleMaxLabelSlotChange}></slot>\n </div>`\n : html`\n <!-- Always observe slot changes even when not rendered -->\n <slot name=\"min-label\" hidden @slotchange=${this._handleMinLabelSlotChange}></slot>\n <slot name=\"max-label\" hidden @slotchange=${this._handleMaxLabelSlotChange}></slot>\n `}\n\n <!-- Help text -->\n <slot name=\"help-text\" @slotchange=${this._handleHelpSlotChange}>\n ${this.helpText\n ? html`<div part=\"help-text\" class=\"slider__help-text\" id=${this._helpId}>\n ${this.helpText}\n </div>`\n : nothing}\n </slot>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-slider': HelixSlider;\n }\n}\n"],"names":["helixSliderStyles","css","_hxSliderIdCounter","HelixSlider","LitElement","v","clamped","range","ticks","count","i","changedProperties","attrValue","defaultValue","resetTo","state","_reason","parsed","options","_a","slot","target","fillPct","hasLabel","showRangeLabels","containerClasses","describedBy","html","classMap","nothing","styleMap","live","ifDefined","pct","tokenStyles","__decorateClass","property","query","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
|
+
{"version":3,"file":"hx-slider-BMofa55D.js","sources":["../../src/components/hx-slider/hx-slider.styles.ts","../../src/components/hx-slider/hx-slider.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixSliderStyles = 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 /* ─── Container ─── */\n\n .slider {\n display: flex;\n flex-direction: column;\n gap: var(--hx-space-1, 0.25rem);\n font-family: var(--hx-font-family-sans, sans-serif);\n }\n\n /* ─── Label Row ─── */\n\n .slider__label-row {\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n gap: var(--hx-space-2, 0.5rem);\n }\n\n .slider__label {\n font-size: var(--hx-font-size-sm, 0.875rem);\n font-weight: var(--hx-font-weight-medium, 500);\n color: var(--hx-slider-label-color, var(--hx-color-neutral-700, #343a40));\n line-height: var(--hx-line-height-normal, 1.5);\n }\n\n .slider__value-display {\n font-size: var(--hx-font-size-sm, 0.875rem);\n font-weight: var(--hx-font-weight-medium, 500);\n color: var(--hx-slider-value-color, var(--hx-color-neutral-600, #6c757d));\n line-height: var(--hx-line-height-normal, 1.5);\n font-variant-numeric: tabular-nums;\n min-width: var(--hx-size-8, 2rem);\n text-align: right;\n }\n\n /* ─── Track Container ─── */\n\n .slider__track-container {\n position: relative;\n width: 100%;\n }\n\n .slider__track {\n position: relative;\n width: 100%;\n border-radius: var(--hx-border-radius-full, 9999px);\n background-color: var(--hx-slider-track-bg, var(--hx-color-neutral-200, #e9ecef));\n overflow: visible;\n }\n\n /* ─── Size: sm ─── */\n\n .slider--sm .slider__track {\n height: var(--hx-slider-track-height-sm, var(--hx-size-1, 0.25rem));\n }\n\n .slider--sm .slider__input {\n height: var(--hx-slider-track-height-sm, var(--hx-size-1, 0.25rem));\n }\n\n /* ─── Size: md ─── */\n\n .slider--md .slider__track {\n height: var(--hx-slider-track-height-md, var(--hx-size-1-5, 0.375rem));\n }\n\n .slider--md .slider__input {\n height: var(--hx-slider-track-height-md, var(--hx-size-1-5, 0.375rem));\n }\n\n /* ─── Size: lg ─── */\n\n .slider--lg .slider__track {\n height: var(--hx-slider-track-height-lg, var(--hx-size-2, 0.5rem));\n }\n\n .slider--lg .slider__input {\n height: var(--hx-slider-track-height-lg, var(--hx-size-2, 0.5rem));\n }\n\n /* ─── Fill ─── */\n\n .slider__fill {\n position: absolute;\n top: 0;\n left: 0;\n height: 100%;\n border-radius: var(--hx-border-radius-full, 9999px);\n background-color: var(--hx-slider-fill-bg, var(--hx-color-primary-500, #2563eb));\n pointer-events: none;\n transition: width var(--hx-transition-fast, 150ms ease);\n }\n\n @media (prefers-reduced-motion: reduce) {\n .slider__fill {\n transition: none;\n }\n }\n\n /* ─── Native Range Input ─── */\n\n .slider__input {\n position: absolute;\n top: 50%;\n left: 0;\n transform: translateY(-50%);\n width: 100%;\n margin: 0;\n padding: 0;\n opacity: 0;\n cursor: pointer;\n -webkit-appearance: none;\n appearance: none;\n background: transparent;\n border: none;\n outline: none;\n /* Expand the hit area so the thumb is easy to grab */\n padding-block: var(--hx-slider-input-padding-block, 0.75rem);\n }\n\n /* In forced-color mode, restore native outline so the input remains focusable */\n @media (forced-colors: active) {\n .slider__input {\n outline: revert;\n opacity: 1;\n }\n .slider__input:focus-visible {\n outline: 2px solid ButtonText;\n }\n }\n\n .slider__input:disabled {\n cursor: not-allowed;\n }\n\n /* ─── Thumb (visual, :before on a wrapper or via ::after on track) ─── */\n /*\n * The native thumb is hidden (opacity 0 on the input). We render a visible\n * thumb element positioned by --fill-pct (a raw 0–100 number set in JS).\n *\n * Correct alignment formula keeps the thumb centered within the track at\n * both extremes, preventing the left/right halves from clipping outside:\n * left = fillPct% * (1 – thumbSize/100%) + thumbSize * (1 – fillPct/100)\n * Simplified: left = calc(var(--fill-pct,0)*1% + var(--_thumb-size)*(1 - var(--fill-pct,0)/100))\n * Combined with translate(-50%,-50%) this places the thumb center correctly\n * at every position from min to max.\n */\n\n .slider__thumb-visual {\n position: absolute;\n top: 50%;\n /* Corrected position: thumb stays within track at all fill values */\n left: calc(var(--fill-pct, 0) * 1% + var(--_thumb-size, 1rem) * (1 - var(--fill-pct, 0) / 100));\n transform: translate(-50%, -50%);\n border-radius: var(--hx-border-radius-full, 9999px);\n background-color: var(--hx-slider-thumb-bg, var(--hx-color-neutral-0, #ffffff));\n border: 2px solid var(--hx-slider-thumb-border-color, var(--hx-color-primary-500, #2563eb));\n box-shadow: var(--hx-slider-thumb-shadow, var(--hx-shadow-sm, 0 1px 2px 0 rgb(0 0 0 / 0.05)));\n pointer-events: none;\n transition:\n box-shadow var(--hx-transition-fast, 150ms ease),\n transform var(--hx-transition-fast, 150ms ease);\n }\n\n @media (prefers-reduced-motion: reduce) {\n .slider__thumb-visual {\n transition: none;\n }\n }\n\n .slider__input:focus-visible ~ .slider__thumb-visual {\n box-shadow:\n 0 0 0 var(--hx-focus-ring-width, 2px)\n var(--hx-slider-focus-ring-color, var(--hx-focus-ring-color, #2563eb)),\n var(--hx-slider-thumb-shadow, var(--hx-shadow-sm, 0 1px 2px 0 rgb(0 0 0 / 0.05)));\n }\n\n /* ─── Thumb sizes ─── */\n\n .slider--sm .slider__thumb-visual {\n --_thumb-size: var(--hx-slider-thumb-size-sm, var(--hx-size-3, 0.75rem));\n width: var(--_thumb-size);\n height: var(--_thumb-size);\n }\n\n .slider--md .slider__thumb-visual {\n --_thumb-size: var(--hx-slider-thumb-size-md, var(--hx-size-4, 1rem));\n width: var(--_thumb-size);\n height: var(--_thumb-size);\n }\n\n .slider--lg .slider__thumb-visual {\n --_thumb-size: var(--hx-slider-thumb-size-lg, var(--hx-size-5, 1.25rem));\n width: var(--_thumb-size);\n height: var(--_thumb-size);\n }\n\n /* ─── Forced colors (Windows High Contrast) ─── */\n @media (forced-colors: active) {\n .slider__fill {\n background-color: Highlight;\n }\n .slider__track {\n background-color: ButtonFace;\n border: 1px solid ButtonText;\n }\n .slider__thumb-visual {\n background-color: ButtonText;\n border-color: ButtonText;\n }\n .slider__input:focus-visible ~ .slider__thumb-visual {\n outline: 2px solid Highlight;\n }\n }\n\n /* ─── Ticks ─── */\n\n .slider__ticks {\n position: relative;\n width: 100%;\n height: var(--hx-size-2, 0.5rem);\n margin-top: var(--hx-space-1, 0.25rem);\n }\n\n .slider__tick {\n position: absolute;\n top: 0;\n width: var(--hx-border-width-thin, 1px);\n height: 100%;\n background-color: var(--hx-slider-tick-color, var(--hx-color-neutral-400, #adb5bd));\n transform: translateX(-50%);\n }\n\n /* ─── Range Labels ─── */\n\n .slider__range-labels {\n display: flex;\n justify-content: space-between;\n font-size: var(--hx-font-size-xs, 0.75rem);\n color: var(--hx-slider-range-label-color, var(--hx-color-neutral-500, #6c757d));\n line-height: var(--hx-line-height-normal, 1.5);\n margin-top: var(--hx-space-0-5, 0.125rem);\n }\n\n /* ─── Help Text ─── */\n\n .slider__help-text {\n font-size: var(--hx-font-size-xs, 0.75rem);\n color: var(--hx-slider-help-text-color, var(--hx-color-neutral-500, #6c757d));\n line-height: var(--hx-line-height-normal, 1.5);\n }\n\n /* ─── Disabled state ─── */\n\n .slider--disabled .slider__fill {\n background-color: var(--hx-color-neutral-400, #adb5bd);\n }\n\n .slider--disabled .slider__thumb-visual {\n border-color: var(--hx-color-neutral-400, #adb5bd);\n }\n`;\n","import { LitElement, TemplateResult, html, nothing } from 'lit';\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 { styleMap } from 'lit/directives/style-map.js';\nimport { tokenStyles } from '@helixui/tokens/lit';\nimport { helixSliderStyles } from './hx-slider.styles.js';\n\n// Module-level counter for stable, SSR-safe IDs (avoids Math.random() hydration mismatch)\nlet _hxSliderIdCounter = 0;\n\n/**\n * A range slider component for selecting a numeric value within a min/max boundary.\n * Supports tick marks, value display, range labels, and native form participation\n * via ElementInternals.\n *\n * The native `<input type=\"range\">` receives `role=\"slider\"` with `aria-valuenow`,\n * `aria-valuemin`, and `aria-valuemax`. Label association uses `aria-labelledby`\n * when a label is present, or `aria-label` as a fallback. Help text is linked via\n * `aria-describedby`. Keyboard navigation follows the native range behavior:\n * Arrow keys increment/decrement by step, Home jumps to min, End jumps to max.\n *\n * @summary Form-associated range slider with label, ticks, and value display.\n *\n * @tag hx-slider\n *\n * @slot label - Custom label content (overrides the label property).\n * @slot help-text - Custom help text content (overrides the helpText property).\n * @slot min-label - Label rendered at the minimum end of the slider.\n * @slot max-label - Label rendered at the maximum end of the slider.\n *\n * @fires {CustomEvent<{value: number}>} hx-input - Dispatched continuously while the user drags.\n * @fires {CustomEvent<{value: number}>} hx-change - Dispatched when the user releases the thumb.\n *\n * @csspart slider - The outer container element.\n * @csspart track - The track background element.\n * @csspart fill - The filled portion of the track showing progress.\n * @csspart thumb - The draggable thumb overlay element.\n * @csspart label - The label element.\n * @csspart value-display - The element displaying the current numeric value.\n * @csspart tick - Each individual tick mark element.\n *\n * @cssprop [--hx-slider-track-bg=var(--hx-color-neutral-200)] - Track background color.\n * @cssprop [--hx-slider-fill-bg=var(--hx-color-primary-500)] - Fill/progress color.\n * @cssprop [--hx-slider-thumb-bg=var(--hx-color-neutral-0)] - Thumb background color.\n * @cssprop [--hx-slider-thumb-border-color=var(--hx-color-primary-500)] - Thumb border color.\n * @cssprop [--hx-slider-thumb-shadow=var(--hx-shadow-sm)] - Thumb box shadow.\n * @cssprop [--hx-slider-focus-ring-color=var(--hx-focus-ring-color)] - Focus ring color.\n * @cssprop [--hx-slider-label-color=var(--hx-color-neutral-700)] - Label text color.\n * @cssprop [--hx-slider-value-color=var(--hx-color-neutral-600)] - Value display text color.\n * @cssprop [--hx-slider-tick-color=var(--hx-color-neutral-400)] - Tick mark color.\n * @cssprop [--hx-slider-range-label-color=var(--hx-color-neutral-500)] - Range label text color.\n * @cssprop [--hx-slider-help-text-color=var(--hx-color-neutral-500)] - Help text color.\n */\n@customElement('hx-slider')\nexport class HelixSlider extends LitElement {\n static override styles = [tokenStyles, helixSliderStyles];\n\n // ─── Form Association ───\n\n /** Enables native form participation via ElementInternals. */\n static formAssociated = true;\n\n /** ElementInternals instance for form value, validity, and label association. */\n private _internals: ElementInternals;\n\n constructor() {\n super();\n this._internals = this.attachInternals();\n }\n\n // ─── Properties ───\n\n /**\n * The name submitted with the form.\n * @attr name\n */\n @property({ type: String })\n name = '';\n\n /**\n * The current numeric value of the slider.\n * @attr value\n */\n @property({ type: Number })\n value = 0;\n\n /**\n * The minimum allowed value.\n * @attr min\n */\n @property({ type: Number })\n min = 0;\n\n /**\n * The maximum allowed value.\n * @attr max\n */\n @property({ type: Number })\n max = 100;\n\n /**\n * The stepping interval between values.\n * @attr step\n */\n @property({ type: Number })\n step = 1;\n\n /**\n * Whether the slider is disabled.\n * @attr disabled\n */\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /**\n * The visible label text for the slider.\n * @attr label\n */\n @property({ type: String })\n label = '';\n\n /**\n * Help text displayed below the slider for guidance.\n * @attr help-text\n */\n @property({ type: String, attribute: 'help-text' })\n helpText = '';\n\n /**\n * When true, the current value is shown next to the label.\n * @attr show-value\n */\n @property({ type: Boolean, attribute: 'show-value' })\n showValue = false;\n\n /**\n * When true, tick marks are rendered at each step interval.\n * @attr show-ticks\n */\n @property({ type: Boolean, attribute: 'show-ticks' })\n showTicks = false;\n\n /**\n * The size variant of the slider.\n * @attr hx-size\n */\n @property({ type: String, reflect: true, attribute: 'hx-size' })\n size: 'sm' | 'md' | 'lg' = 'md';\n\n /**\n * Human-readable text alternative for the current value, announced by screen readers\n * instead of the numeric value. For example, on a pain scale: \"7 — Moderate-Severe\".\n * @attr aria-valuetext\n */\n @property({ type: String, attribute: 'aria-valuetext' })\n valueText = '';\n\n // ─── Internal State ───\n\n /** Whether the label slot has assigned content. */\n @state() private _hasLabelSlot = false;\n /** Whether the min-label slot has assigned content. */\n @state() private _hasMinLabelSlot = false;\n /** Whether the max-label slot has assigned content. */\n @state() private _hasMaxLabelSlot = false;\n /** Whether the help slot has assigned content. */\n @state() private _hasHelpSlot = false;\n\n // ─── Internal References ───\n\n /** Reference to the native range `<input>` inside shadow DOM. */\n @query('.slider__input')\n private _input!: HTMLInputElement;\n\n // ─── Unique IDs ───\n\n /** Unique ID for the native range input element. */\n private readonly _sliderId = `hx-slider-${++_hxSliderIdCounter}`;\n /** Unique ID for the label element, derived from _sliderId. */\n private readonly _labelId = `${this._sliderId}-label`;\n /** Unique ID for the help text element, derived from _sliderId. */\n private readonly _helpId = `${this._sliderId}-help`;\n\n // ─── Computed Values ───\n\n private _clamp(v: number): number {\n return Math.min(Math.max(v, this.min), this.max);\n }\n\n private _fillPercent(): number {\n const clamped = this._clamp(this.value);\n const range = this.max - this.min;\n if (range === 0) return 0;\n return ((clamped - this.min) / range) * 100;\n }\n\n private _ticks(): number[] {\n if (!this.showTicks) return [];\n const ticks: number[] = [];\n const range = this.max - this.min;\n if (range <= 0 || this.step <= 0) return ticks;\n const count = Math.round(range / this.step);\n for (let i = 0; i <= count; i++) {\n ticks.push((i / count) * 100);\n }\n return ticks;\n }\n\n // ─── Lifecycle ───\n\n override updated(changedProperties: Map<string, unknown>): void {\n super.updated(changedProperties);\n // Clamp value to [min, max] after any relevant property change\n if (\n changedProperties.has('value') ||\n changedProperties.has('min') ||\n changedProperties.has('max')\n ) {\n const clamped = this._clamp(this.value);\n if (clamped !== this.value) {\n this.value = clamped;\n return;\n }\n this._internals.setFormValue(String(this.value));\n } else if (changedProperties.has('name')) {\n this._internals.setFormValue(String(this.value));\n }\n // Reflect aria-disabled on host for AT traversal\n if (changedProperties.has('disabled')) {\n if (this.disabled) {\n this.setAttribute('aria-disabled', 'true');\n } else {\n this.removeAttribute('aria-disabled');\n }\n }\n }\n\n // ─── Form Integration ───\n\n /** Returns the associated form element, if any. */\n get form(): HTMLFormElement | null {\n return this._internals.form;\n }\n\n /** Returns the validation message. */\n get validationMessage(): string {\n return this._internals.validationMessage;\n }\n\n /** Returns the ValidityState object. */\n get validity(): ValidityState {\n return this._internals.validity;\n }\n\n /** Checks whether the slider satisfies its constraints. */\n checkValidity(): boolean {\n return this._internals.checkValidity();\n }\n\n /** Reports validity and shows the browser's constraint validation UI. */\n reportValidity(): boolean {\n return this._internals.reportValidity();\n }\n\n /** Called by the form when it resets. Restores to the declared `value` attribute (default value). */\n formResetCallback(): void {\n const attrValue = this.getAttribute('value');\n const defaultValue = attrValue !== null ? parseFloat(attrValue) : this.min;\n const resetTo = this._clamp(!isNaN(defaultValue) ? defaultValue : this.min);\n this.value = resetTo;\n this._internals.setFormValue(String(resetTo));\n }\n\n /**\n * Called when the form restores state (e.g., back/forward navigation or autofill).\n * @param state - The serialized value to restore.\n * @param _reason - Either \"restore\" (back/forward) or \"autocomplete\".\n */\n formStateRestoreCallback(state: string, _reason: string): void {\n const parsed = parseFloat(state);\n if (!isNaN(parsed)) {\n this.value = this._clamp(parsed);\n }\n }\n\n // ─── Public Methods ───\n\n /** Moves focus to the native range input. */\n override focus(options?: FocusOptions): void {\n this._input?.focus(options);\n }\n\n // ─── Slot Handlers ───\n\n private _handleLabelSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n this._hasLabelSlot = slot.assignedNodes({ flatten: true }).length > 0;\n }\n\n private _handleHelpSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n this._hasHelpSlot = slot.assignedNodes({ flatten: true }).length > 0;\n }\n\n private _handleMinLabelSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n this._hasMinLabelSlot = slot.assignedNodes({ flatten: true }).length > 0;\n }\n\n private _handleMaxLabelSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n this._hasMaxLabelSlot = slot.assignedNodes({ flatten: true }).length > 0;\n }\n\n // ─── Event Handling ───\n\n private _handleInput(e: Event): void {\n if (this.disabled) return;\n const target = e.target as HTMLInputElement;\n this.value = parseFloat(target.value);\n this._internals.setFormValue(String(this.value));\n\n /**\n * Dispatched continuously while the user drags the thumb.\n * @event hx-input\n */\n this.dispatchEvent(\n new CustomEvent('hx-input', {\n bubbles: true,\n composed: true,\n detail: { value: this.value },\n }),\n );\n }\n\n private _handleChange(e: Event): void {\n if (this.disabled) return;\n const target = e.target as HTMLInputElement;\n this.value = parseFloat(target.value);\n this._internals.setFormValue(String(this.value));\n\n /**\n * Dispatched when the user releases the thumb after dragging.\n * @event hx-change\n */\n this.dispatchEvent(\n new CustomEvent('hx-change', {\n bubbles: true,\n composed: true,\n detail: { value: this.value },\n }),\n );\n }\n\n // ─── Render ───\n\n override render(): TemplateResult {\n const fillPct = this._fillPercent();\n const ticks = this._ticks();\n const hasLabel = !!this.label || this._hasLabelSlot;\n const showRangeLabels = this._hasMinLabelSlot || this._hasMaxLabelSlot;\n\n const containerClasses = {\n slider: true,\n [`slider--${this.size}`]: true,\n 'slider--disabled': this.disabled,\n 'slider--has-ticks': this.showTicks,\n };\n\n const describedBy =\n [this.helpText || this._hasHelpSlot ? this._helpId : null].filter(Boolean).join(' ') ||\n undefined;\n\n return html`\n <div part=\"slider\" class=${classMap(containerClasses)}>\n <!-- Label row -->\n <div class=\"slider__label-row\">\n ${hasLabel\n ? html`<label\n part=\"label\"\n class=\"slider__label\"\n id=${this._labelId}\n for=${this._sliderId}\n >\n <slot name=\"label\" @slotchange=${this._handleLabelSlotChange}>${this.label}</slot>\n </label>`\n : html`<slot name=\"label\" @slotchange=${this._handleLabelSlotChange}></slot>`}\n ${this.showValue\n ? html`<span part=\"value-display\" class=\"slider__value-display\"> ${this.value} </span>`\n : nothing}\n </div>\n\n <!-- Track -->\n <div class=\"slider__track-container\">\n <div part=\"track\" class=\"slider__track\">\n <div part=\"fill\" class=\"slider__fill\" style=${styleMap({ width: `${fillPct}%` })}></div>\n\n <input\n class=\"slider__input\"\n id=${this._sliderId}\n type=\"range\"\n .value=${live(String(this.value))}\n min=${this.min}\n max=${this.max}\n step=${this.step}\n ?disabled=${this.disabled}\n name=${ifDefined(this.name || undefined)}\n aria-labelledby=${ifDefined(hasLabel ? this._labelId : undefined)}\n aria-valuetext=${ifDefined(this.valueText || undefined)}\n aria-describedby=${ifDefined(describedBy)}\n @input=${this._handleInput}\n @change=${this._handleChange}\n />\n\n <!-- Visual thumb positioned by fill percentage (--fill-pct drives CSS calc) -->\n <span\n part=\"thumb\"\n class=\"slider__thumb-visual\"\n style=${styleMap({ '--fill-pct': String(fillPct) })}\n aria-hidden=\"true\"\n ></span>\n </div>\n </div>\n\n <!-- Tick marks -->\n ${this.showTicks && ticks.length > 0\n ? html`<div class=\"slider__ticks\">\n ${ticks.map(\n (pct) =>\n html`<span\n part=\"tick\"\n class=\"slider__tick\"\n style=${styleMap({ left: `${pct}%` })}\n ></span>`,\n )}\n </div>`\n : nothing}\n\n <!-- Range labels -->\n ${showRangeLabels\n ? html`<div class=\"slider__range-labels\">\n <slot name=\"min-label\" @slotchange=${this._handleMinLabelSlotChange}></slot>\n <slot name=\"max-label\" @slotchange=${this._handleMaxLabelSlotChange}></slot>\n </div>`\n : html`\n <!-- Always observe slot changes even when not rendered -->\n <slot name=\"min-label\" hidden @slotchange=${this._handleMinLabelSlotChange}></slot>\n <slot name=\"max-label\" hidden @slotchange=${this._handleMaxLabelSlotChange}></slot>\n `}\n\n <!-- Help text -->\n <slot name=\"help-text\" @slotchange=${this._handleHelpSlotChange}>\n ${this.helpText\n ? html`<div part=\"help-text\" class=\"slider__help-text\" id=${this._helpId}>\n ${this.helpText}\n </div>`\n : nothing}\n </slot>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-slider': HelixSlider;\n }\n}\n"],"names":["helixSliderStyles","css","_hxSliderIdCounter","HelixSlider","LitElement","v","clamped","range","ticks","count","i","changedProperties","attrValue","defaultValue","resetTo","state","_reason","parsed","options","_a","slot","target","fillPct","hasLabel","showRangeLabels","containerClasses","describedBy","html","classMap","nothing","styleMap","live","ifDefined","pct","tokenStyles","__decorateClass","property","query","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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;ACQjC,IAAIC,IAAqB,GA8CZC,IAAN,cAA0BC,EAAW;AAAA,EAW1C,cAAc;AACZ,UAAA,GAWF,KAAA,OAAO,IAOP,KAAA,QAAQ,GAOR,KAAA,MAAM,GAON,KAAA,MAAM,KAON,KAAA,OAAO,GAOP,KAAA,WAAW,IAOX,KAAA,QAAQ,IAOR,KAAA,WAAW,IAOX,KAAA,YAAY,IAOZ,KAAA,YAAY,IAOZ,KAAA,OAA2B,MAQ3B,KAAA,YAAY,IAKH,KAAQ,gBAAgB,IAExB,KAAQ,mBAAmB,IAE3B,KAAQ,mBAAmB,IAE3B,KAAQ,eAAe,IAWhC,KAAiB,YAAY,aAAa,EAAEF,CAAkB,IAE9D,KAAiB,WAAW,GAAG,KAAK,SAAS,UAE7C,KAAiB,UAAU,GAAG,KAAK,SAAS,SAlH1C,KAAK,aAAa,KAAK,gBAAA;AAAA,EACzB;AAAA;AAAA,EAqHQ,OAAOG,GAAmB;AAChC,WAAO,KAAK,IAAI,KAAK,IAAIA,GAAG,KAAK,GAAG,GAAG,KAAK,GAAG;AAAA,EACjD;AAAA,EAEQ,eAAuB;AAC7B,UAAMC,IAAU,KAAK,OAAO,KAAK,KAAK,GAChCC,IAAQ,KAAK,MAAM,KAAK;AAC9B,WAAIA,MAAU,IAAU,KACfD,IAAU,KAAK,OAAOC,IAAS;AAAA,EAC1C;AAAA,EAEQ,SAAmB;AACzB,QAAI,CAAC,KAAK,UAAW,QAAO,CAAA;AAC5B,UAAMC,IAAkB,CAAA,GAClBD,IAAQ,KAAK,MAAM,KAAK;AAC9B,QAAIA,KAAS,KAAK,KAAK,QAAQ,EAAG,QAAOC;AACzC,UAAMC,IAAQ,KAAK,MAAMF,IAAQ,KAAK,IAAI;AAC1C,aAASG,IAAI,GAAGA,KAAKD,GAAOC;AAC1B,MAAAF,EAAM,KAAME,IAAID,IAAS,GAAG;AAE9B,WAAOD;AAAA,EACT;AAAA;AAAA,EAIS,QAAQG,GAA+C;AAG9D,QAFA,MAAM,QAAQA,CAAiB,GAG7BA,EAAkB,IAAI,OAAO,KAC7BA,EAAkB,IAAI,KAAK,KAC3BA,EAAkB,IAAI,KAAK,GAC3B;AACA,YAAML,IAAU,KAAK,OAAO,KAAK,KAAK;AACtC,UAAIA,MAAY,KAAK,OAAO;AAC1B,aAAK,QAAQA;AACb;AAAA,MACF;AACA,WAAK,WAAW,aAAa,OAAO,KAAK,KAAK,CAAC;AAAA,IACjD,MAAA,CAAWK,EAAkB,IAAI,MAAM,KACrC,KAAK,WAAW,aAAa,OAAO,KAAK,KAAK,CAAC;AAGjD,IAAIA,EAAkB,IAAI,UAAU,MAC9B,KAAK,WACP,KAAK,aAAa,iBAAiB,MAAM,IAEzC,KAAK,gBAAgB,eAAe;AAAA,EAG1C;AAAA;AAAA;AAAA,EAKA,IAAI,OAA+B;AACjC,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA;AAAA,EAGA,IAAI,oBAA4B;AAC9B,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA;AAAA,EAGA,IAAI,WAA0B;AAC5B,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA;AAAA,EAGA,gBAAyB;AACvB,WAAO,KAAK,WAAW,cAAA;AAAA,EACzB;AAAA;AAAA,EAGA,iBAA0B;AACxB,WAAO,KAAK,WAAW,eAAA;AAAA,EACzB;AAAA;AAAA,EAGA,oBAA0B;AACxB,UAAMC,IAAY,KAAK,aAAa,OAAO,GACrCC,IAAeD,MAAc,OAAO,WAAWA,CAAS,IAAI,KAAK,KACjEE,IAAU,KAAK,OAAQ,MAAMD,CAAY,IAAmB,KAAK,MAApBA,CAAuB;AAC1E,SAAK,QAAQC,GACb,KAAK,WAAW,aAAa,OAAOA,CAAO,CAAC;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,yBAAyBC,GAAeC,GAAuB;AAC7D,UAAMC,IAAS,WAAWF,CAAK;AAC/B,IAAK,MAAME,CAAM,MACf,KAAK,QAAQ,KAAK,OAAOA,CAAM;AAAA,EAEnC;AAAA;AAAA;AAAA,EAKS,MAAMC,GAA8B;;AAC3C,KAAAC,IAAA,KAAK,WAAL,QAAAA,EAAa,MAAMD;AAAA,EACrB;AAAA;AAAA,EAIQ,uBAAuB,GAAgB;AAC7C,UAAME,IAAO,EAAE;AACf,SAAK,gBAAgBA,EAAK,cAAc,EAAE,SAAS,GAAA,CAAM,EAAE,SAAS;AAAA,EACtE;AAAA,EAEQ,sBAAsB,GAAgB;AAC5C,UAAMA,IAAO,EAAE;AACf,SAAK,eAAeA,EAAK,cAAc,EAAE,SAAS,GAAA,CAAM,EAAE,SAAS;AAAA,EACrE;AAAA,EAEQ,0BAA0B,GAAgB;AAChD,UAAMA,IAAO,EAAE;AACf,SAAK,mBAAmBA,EAAK,cAAc,EAAE,SAAS,GAAA,CAAM,EAAE,SAAS;AAAA,EACzE;AAAA,EAEQ,0BAA0B,GAAgB;AAChD,UAAMA,IAAO,EAAE;AACf,SAAK,mBAAmBA,EAAK,cAAc,EAAE,SAAS,GAAA,CAAM,EAAE,SAAS;AAAA,EACzE;AAAA;AAAA,EAIQ,aAAa,GAAgB;AACnC,QAAI,KAAK,SAAU;AACnB,UAAMC,IAAS,EAAE;AACjB,SAAK,QAAQ,WAAWA,EAAO,KAAK,GACpC,KAAK,WAAW,aAAa,OAAO,KAAK,KAAK,CAAC,GAM/C,KAAK;AAAA,MACH,IAAI,YAAY,YAAY;AAAA,QAC1B,SAAS;AAAA,QACT,UAAU;AAAA,QACV,QAAQ,EAAE,OAAO,KAAK,MAAA;AAAA,MAAM,CAC7B;AAAA,IAAA;AAAA,EAEL;AAAA,EAEQ,cAAc,GAAgB;AACpC,QAAI,KAAK,SAAU;AACnB,UAAMA,IAAS,EAAE;AACjB,SAAK,QAAQ,WAAWA,EAAO,KAAK,GACpC,KAAK,WAAW,aAAa,OAAO,KAAK,KAAK,CAAC,GAM/C,KAAK;AAAA,MACH,IAAI,YAAY,aAAa;AAAA,QAC3B,SAAS;AAAA,QACT,UAAU;AAAA,QACV,QAAQ,EAAE,OAAO,KAAK,MAAA;AAAA,MAAM,CAC7B;AAAA,IAAA;AAAA,EAEL;AAAA;AAAA,EAIS,SAAyB;AAChC,UAAMC,IAAU,KAAK,aAAA,GACfd,IAAQ,KAAK,OAAA,GACbe,IAAW,CAAC,CAAC,KAAK,SAAS,KAAK,eAChCC,IAAkB,KAAK,oBAAoB,KAAK,kBAEhDC,IAAmB;AAAA,MACvB,QAAQ;AAAA,MACR,CAAC,WAAW,KAAK,IAAI,EAAE,GAAG;AAAA,MAC1B,oBAAoB,KAAK;AAAA,MACzB,qBAAqB,KAAK;AAAA,IAAA,GAGtBC,IACJ,CAAC,KAAK,YAAY,KAAK,eAAe,KAAK,UAAU,IAAI,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,KACnF;AAEF,WAAOC;AAAA,iCACsBC,EAASH,CAAgB,CAAC;AAAA;AAAA;AAAA,YAG/CF,IACEI;AAAA;AAAA;AAAA,qBAGO,KAAK,QAAQ;AAAA,sBACZ,KAAK,SAAS;AAAA;AAAA,iDAEa,KAAK,sBAAsB,IAAI,KAAK,KAAK;AAAA,0BAE5EA,mCAAsC,KAAK,sBAAsB,UAAU;AAAA,YAC7E,KAAK,YACHA,8DAAiE,KAAK,KAAK,aAC3EE,CAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0DAMqCC,EAAS,EAAE,OAAO,GAAGR,CAAO,IAAA,CAAK,CAAC;AAAA;AAAA;AAAA;AAAA,mBAIzE,KAAK,SAAS;AAAA;AAAA,uBAEVS,EAAK,OAAO,KAAK,KAAK,CAAC,CAAC;AAAA,oBAC3B,KAAK,GAAG;AAAA,oBACR,KAAK,GAAG;AAAA,qBACP,KAAK,IAAI;AAAA,0BACJ,KAAK,QAAQ;AAAA,qBAClBC,EAAU,KAAK,QAAQ,MAAS,CAAC;AAAA,gCACtBA,EAAUT,IAAW,KAAK,WAAW,MAAS,CAAC;AAAA,+BAChDS,EAAU,KAAK,aAAa,MAAS,CAAC;AAAA,iCACpCA,EAAUN,CAAW,CAAC;AAAA,uBAChC,KAAK,YAAY;AAAA,wBAChB,KAAK,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sBAOpBI,EAAS,EAAE,cAAc,OAAOR,CAAO,EAAA,CAAG,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAOvD,KAAK,aAAad,EAAM,SAAS,IAC/BmB;AAAA,gBACInB,EAAM;AAAA,MACN,CAACyB,MACCN;AAAA;AAAA;AAAA,4BAGUG,EAAS,EAAE,MAAM,GAAGG,CAAG,KAAK,CAAC;AAAA;AAAA,IAAA,CAE1C;AAAA,sBAEHJ,CAAO;AAAA;AAAA;AAAA,UAGTL,IACEG;AAAA,mDACuC,KAAK,yBAAyB;AAAA,mDAC9B,KAAK,yBAAyB;AAAA,sBAErEA;AAAA;AAAA,0DAE8C,KAAK,yBAAyB;AAAA,0DAC9B,KAAK,yBAAyB;AAAA,aAC3E;AAAA;AAAA;AAAA,6CAGgC,KAAK,qBAAqB;AAAA,YAC3D,KAAK,WACHA,uDAA0D,KAAK,OAAO;AAAA,kBAClE,KAAK,QAAQ;AAAA,wBAEjBE,CAAO;AAAA;AAAA;AAAA;AAAA,EAInB;AACF;AAvZa1B,EACK,SAAS,CAAC+B,GAAalC,CAAiB;AAD7CG,EAMJ,iBAAiB;AAiBxBgC,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GAtBfjC,EAuBX,WAAA,QAAA,CAAA;AAOAgC,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GA7BfjC,EA8BX,WAAA,SAAA,CAAA;AAOAgC,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GApCfjC,EAqCX,WAAA,OAAA,CAAA;AAOAgC,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GA3CfjC,EA4CX,WAAA,OAAA,CAAA;AAOAgC,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GAlDfjC,EAmDX,WAAA,QAAA,CAAA;AAOAgC,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,SAAS,SAAS,IAAM;AAAA,GAzD/BjC,EA0DX,WAAA,YAAA,CAAA;AAOAgC,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GAhEfjC,EAiEX,WAAA,SAAA,CAAA;AAOAgC,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,QAAQ,WAAW,aAAa;AAAA,GAvEvCjC,EAwEX,WAAA,YAAA,CAAA;AAOAgC,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,SAAS,WAAW,cAAc;AAAA,GA9EzCjC,EA+EX,WAAA,aAAA,CAAA;AAOAgC,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,SAAS,WAAW,cAAc;AAAA,GArFzCjC,EAsFX,WAAA,aAAA,CAAA;AAOAgC,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,QAAQ,SAAS,IAAM,WAAW,WAAW;AAAA,GA5FpDjC,EA6FX,WAAA,QAAA,CAAA;AAQAgC,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,QAAQ,WAAW,kBAAkB;AAAA,GApG5CjC,EAqGX,WAAA,aAAA,CAAA;AAKiBgC,EAAA;AAAA,EAAhBpB,EAAA;AAAM,GA1GIZ,EA0GM,WAAA,iBAAA,CAAA;AAEAgC,EAAA;AAAA,EAAhBpB,EAAA;AAAM,GA5GIZ,EA4GM,WAAA,oBAAA,CAAA;AAEAgC,EAAA;AAAA,EAAhBpB,EAAA;AAAM,GA9GIZ,EA8GM,WAAA,oBAAA,CAAA;AAEAgC,EAAA;AAAA,EAAhBpB,EAAA;AAAM,GAhHIZ,EAgHM,WAAA,gBAAA,CAAA;AAMTgC,EAAA;AAAA,EADPE,EAAM,gBAAgB;AAAA,GArHZlC,EAsHH,WAAA,UAAA,CAAA;AAtHGA,IAANgC,EAAA;AAAA,EADNG,EAAc,WAAW;AAAA,GACbnC,CAAA;"}
|
|
@@ -2,7 +2,7 @@ import { css as h, LitElement as f, html as v } from "lit";
|
|
|
2
2
|
import { property as a, customElement as d } from "lit/decorators.js";
|
|
3
3
|
import { styleMap as p } from "lit/directives/style-map.js";
|
|
4
4
|
import { ifDefined as m } from "lit/directives/if-defined.js";
|
|
5
|
-
import {
|
|
5
|
+
import { tokenStyles as u } from "@helixui/tokens/lit";
|
|
6
6
|
const x = h`
|
|
7
7
|
:host {
|
|
8
8
|
display: inline-flex;
|
|
@@ -180,4 +180,4 @@ r = s([
|
|
|
180
180
|
export {
|
|
181
181
|
r as H
|
|
182
182
|
};
|
|
183
|
-
//# sourceMappingURL=hx-spinner-
|
|
183
|
+
//# sourceMappingURL=hx-spinner-BOApJ-g9.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hx-spinner-
|
|
1
|
+
{"version":3,"file":"hx-spinner-BOApJ-g9.js","sources":["../../src/components/hx-spinner/hx-spinner.styles.ts","../../src/components/hx-spinner/hx-spinner.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixSpinnerStyles = css`\n :host {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n }\n\n .spinner {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--_spinner-size);\n height: var(--_spinner-size);\n flex-shrink: 0;\n }\n\n .spinner__svg {\n width: 100%;\n height: 100%;\n animation: hx-spinner-rotate var(--hx-duration-spinner, 750ms) linear infinite;\n }\n\n .spinner__track {\n stroke: var(--_spinner-track-color);\n }\n\n .spinner__arc {\n stroke: var(--_spinner-color);\n /* SVG arc math: viewBox is 24×24, r=10, circumference = 2π × 10 ≈ 62.83.\n stroke-dasharray: 56 creates a visible arc of ~89% of circumference.\n stroke-dashoffset: 14 shifts the arc start to produce the ~75% visible gap aesthetic.\n Adjust both proportionally if r or viewBox dimensions change. */\n stroke-dasharray: 56;\n stroke-dashoffset: 14;\n animation: hx-spinner-dash 1.5s ease-in-out infinite;\n transform-origin: center;\n }\n\n @keyframes hx-spinner-rotate {\n to {\n transform: rotate(360deg);\n }\n }\n\n @keyframes hx-spinner-dash {\n 0% {\n stroke-dashoffset: 50;\n }\n 50% {\n stroke-dashoffset: 14;\n }\n 100% {\n stroke-dashoffset: 50;\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n .spinner__svg {\n animation: none;\n }\n\n .spinner__arc {\n animation: none;\n /* Maintain the static partial arc at full opacity so the loading state remains\n clearly communicated without motion. A faded arc looks broken; full opacity\n alongside the track ring unambiguously signals \"in progress\". */\n stroke-dashoffset: 14;\n opacity: 1;\n }\n }\n\n /* ─── Size Variants ─── */\n\n :host([size='sm']) {\n --_spinner-size: var(--hx-size-4, 1rem);\n }\n\n :host([size='md']) {\n --_spinner-size: var(--hx-size-6, 1.5rem);\n }\n\n :host([size='lg']) {\n --_spinner-size: var(--hx-size-8, 2rem);\n }\n\n /* ─── Variant Colors ─── */\n\n :host([variant='default']) {\n --_spinner-color: var(--hx-spinner-color, var(--hx-color-neutral-600, #475569));\n --_spinner-track-color: var(--hx-spinner-track-color, var(--hx-color-neutral-200, #e2e8f0));\n }\n\n :host([variant='primary']) {\n --_spinner-color: var(--hx-spinner-color, var(--hx-color-primary-500, #2563eb));\n --_spinner-track-color: var(--hx-spinner-track-color, var(--hx-color-primary-100, #dbeafe));\n }\n\n :host([variant='inverted']) {\n --_spinner-color: var(--hx-spinner-color, var(--hx-color-neutral-0, #ffffff));\n /* Fallback for browsers without color-mix() support (Chrome < 111, Firefox < 113, Safari < 16.2).\n rgba(255, 255, 255, 0.3) approximates the intended 30% white track color. */\n --_spinner-track-color: var(\n --hx-spinner-track-color,\n var(--hx-overlay-white-30, rgba(255, 255, 255, 0.3))\n );\n }\n\n @supports (color: color-mix(in srgb, white 30%, transparent)) {\n :host([variant='inverted']) {\n --_spinner-track-color: var(\n --hx-spinner-track-color,\n color-mix(in srgb, var(--hx-color-neutral-0, #ffffff) 30%, transparent)\n );\n }\n }\n`;\n","import { LitElement, html } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { styleMap } from 'lit/directives/style-map.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { tokenStyles } from '@helixui/tokens/lit';\nimport { helixSpinnerStyles } from './hx-spinner.styles.js';\n\n/**\n * A circular loading indicator for inline and overlay loading states.\n * Purely visual — no slots. Announces loading state to screen readers via\n * `role=\"status\"` and an `aria-label` (customizable via the `label` prop).\n *\n * When used alongside visible loading text, set `decorative` to suppress\n * duplicate AT announcements.\n *\n * @summary Circular loading indicator component.\n *\n * @tag hx-spinner\n *\n * @csspart base - The SVG spinner element.\n *\n * @cssprop [--hx-spinner-color] - Spinner arc color. Defaults per variant.\n * @cssprop [--hx-spinner-track-color] - Spinner track color. Defaults per variant.\n * @cssprop [--hx-duration-spinner] - Duration of the rotation animation. Defaults to 750ms.\n */\n@customElement('hx-spinner')\nexport class HelixSpinner extends LitElement {\n static override styles = [tokenStyles, helixSpinnerStyles];\n\n /**\n * Size of the spinner. Accepts 'sm' | 'md' | 'lg' token values, or any\n * valid CSS size string (e.g. \"3rem\", \"48px\").\n *\n * Note: `'sm' | 'md' | 'lg' | string` intentionally degrades to `string`\n * at the TypeScript level to allow CSS size values as a convenience override.\n * This is a deliberate design choice — use token values for standard sizing.\n * @attr size\n */\n @property({ type: String, reflect: true })\n size: 'sm' | 'md' | 'lg' | string = 'md';\n\n /**\n * Visual variant of the spinner.\n * @attr variant\n */\n @property({ type: String, reflect: true })\n variant: 'default' | 'primary' | 'inverted' = 'default';\n\n /**\n * Accessible label announced to screen readers. Defaults to \"Loading\".\n * Reflected as an attribute for Drupal/Twig compatibility.\n * @attr label\n */\n @property({ type: String, reflect: true })\n label = 'Loading';\n\n /**\n * When true, the spinner is decorative and suppresses all ARIA announcements.\n * Use this when the spinner appears alongside visible loading text to prevent\n * duplicate announcements. Sets `role=\"presentation\"` and removes `aria-label`.\n * @attr decorative\n */\n @property({ type: Boolean, reflect: true })\n decorative = false;\n\n private _isTokenSize(): boolean {\n return this.size === 'sm' || this.size === 'md' || this.size === 'lg';\n }\n\n override render() {\n const customSizeStyle =\n !this._isTokenSize() && this.size ? styleMap({ '--_spinner-size': this.size }) : styleMap({});\n\n // Decorative spinners use role=\"presentation\" to suppress AT announcements.\n // Non-decorative spinners use role=\"status\" with aria-label for accessible naming.\n // Guard against empty label (aria-label=\"\" is a WCAG failure).\n const role = this.decorative ? 'presentation' : 'status';\n const ariaLabel = this.decorative ? undefined : this.label || undefined;\n\n return html`\n <div\n class=\"spinner\"\n part=\"base\"\n style=${customSizeStyle}\n role=${role}\n aria-label=${ifDefined(ariaLabel)}\n >\n <svg\n class=\"spinner__svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <circle class=\"spinner__track\" cx=\"12\" cy=\"12\" r=\"10\" stroke-width=\"2.5\" fill=\"none\" />\n <path\n class=\"spinner__arc\"\n d=\"M12 2a10 10 0 0 1 10 10\"\n stroke-width=\"2.5\"\n stroke-linecap=\"round\"\n fill=\"none\"\n />\n </svg>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-spinner': HelixSpinner;\n }\n}\n"],"names":["helixSpinnerStyles","css","HelixSpinner","LitElement","customSizeStyle","styleMap","role","ariaLabel","html","ifDefined","tokenStyles","__decorateClass","property","customElement"],"mappings":";;;;;AAEO,MAAMA,IAAqBC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;ACwB3B,IAAMC,IAAN,cAA2BC,EAAW;AAAA,EAAtC,cAAA;AAAA,UAAA,GAAA,SAAA,GAaL,KAAA,OAAoC,MAOpC,KAAA,UAA8C,WAQ9C,KAAA,QAAQ,WASR,KAAA,aAAa;AAAA,EAAA;AAAA,EAEL,eAAwB;AAC9B,WAAO,KAAK,SAAS,QAAQ,KAAK,SAAS,QAAQ,KAAK,SAAS;AAAA,EACnE;AAAA,EAES,SAAS;AAChB,UAAMC,IACJ,CAAC,KAAK,aAAA,KAAkB,KAAK,OAAOC,EAAS,EAAE,mBAAmB,KAAK,KAAA,CAAM,IAAIA,EAAS,CAAA,CAAE,GAKxFC,IAAO,KAAK,aAAa,iBAAiB,UAC1CC,IAAY,KAAK,aAAa,SAAY,KAAK,SAAS;AAE9D,WAAOC;AAAA;AAAA;AAAA;AAAA,gBAIKJ,CAAe;AAAA,eAChBE,CAAI;AAAA,qBACEG,EAAUF,CAAS,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoBvC;AACF;AAhFaL,EACK,SAAS,CAACQ,GAAaV,CAAkB;AAYzDW,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,QAAQ,SAAS,IAAM;AAAA,GAZ9BV,EAaX,WAAA,QAAA,CAAA;AAOAS,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,QAAQ,SAAS,IAAM;AAAA,GAnB9BV,EAoBX,WAAA,WAAA,CAAA;AAQAS,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,QAAQ,SAAS,IAAM;AAAA,GA3B9BV,EA4BX,WAAA,SAAA,CAAA;AASAS,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,SAAS,SAAS,IAAM;AAAA,GApC/BV,EAqCX,WAAA,cAAA,CAAA;AArCWA,IAANS,EAAA;AAAA,EADNE,EAAc,YAAY;AAAA,GACdX,CAAA;"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { css as m, LitElement as v, html as d } from "lit";
|
|
2
2
|
import { query as c, state as x, property as u, customElement as g } from "lit/decorators.js";
|
|
3
3
|
import { classMap as h } from "lit/directives/class-map.js";
|
|
4
|
-
import {
|
|
4
|
+
import { tokenStyles as f } from "@helixui/tokens/lit";
|
|
5
5
|
const _ = m`
|
|
6
6
|
:host {
|
|
7
7
|
display: inline-block;
|
|
@@ -539,4 +539,4 @@ i = n([
|
|
|
539
539
|
export {
|
|
540
540
|
i as H
|
|
541
541
|
};
|
|
542
|
-
//# sourceMappingURL=hx-split-button-
|
|
542
|
+
//# sourceMappingURL=hx-split-button-DhncgAtZ.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hx-split-button-hBPl-zRv.js","sources":["../../src/components/hx-split-button/hx-split-button.styles.ts","../../src/components/hx-split-button/hx-split-button.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixSplitButtonStyles = css`\n :host {\n display: inline-block;\n position: relative;\n }\n\n :host([disabled]) {\n pointer-events: none;\n opacity: var(--hx-opacity-disabled, 0.5);\n }\n\n /* ─── Container ─── */\n\n .split-button {\n display: inline-flex;\n align-items: stretch;\n position: relative;\n }\n\n /* ─── Primary Button ─── */\n\n .split-button__primary {\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-split-button-border-color, transparent);\n border-right: none;\n border-radius: var(--hx-split-button-border-radius, var(--hx-border-radius-md, 0.375rem)) 0 0\n var(--hx-split-button-border-radius, var(--hx-border-radius-md, 0.375rem));\n background-color: var(--hx-split-button-bg, var(--hx-color-primary-500, #2563eb));\n color: var(--hx-split-button-color, var(--hx-color-neutral-0, #ffffff));\n font-family: var(--hx-split-button-font-family, var(--hx-font-family-sans, sans-serif));\n font-weight: var(--hx-split-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 flex: 1 1 auto;\n }\n\n .split-button__primary:focus-visible {\n outline: var(--hx-focus-ring-width, 2px) solid\n var(--hx-split-button-focus-ring-color, var(--hx-focus-ring-color, #2563eb));\n outline-offset: var(--hx-focus-ring-offset, 2px);\n z-index: 1;\n position: relative;\n }\n\n .split-button__primary:hover {\n filter: brightness(var(--hx-filter-brightness-hover, 0.9));\n }\n\n .split-button__primary:active {\n filter: brightness(var(--hx-filter-brightness-active, 0.8));\n }\n\n .split-button__primary[disabled] {\n cursor: not-allowed;\n }\n\n /* ─── Trigger Button ─── */\n\n .split-button__trigger {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n border: var(--hx-border-width-thin, 1px) solid var(--hx-split-button-border-color, transparent);\n border-left: var(--hx-border-width-thin, 1px) solid\n var(--hx-split-button-divider-color, var(--hx-color-primary-400, #3b82f6));\n border-radius: 0 var(--hx-split-button-border-radius, var(--hx-border-radius-md, 0.375rem))\n var(--hx-split-button-border-radius, var(--hx-border-radius-md, 0.375rem)) 0;\n background-color: var(--hx-split-button-bg, var(--hx-color-primary-500, #2563eb));\n color: var(--hx-split-button-color, var(--hx-color-neutral-0, #ffffff));\n cursor: pointer;\n transition:\n background-color var(--hx-transition-fast, 150ms ease),\n box-shadow var(--hx-transition-fast, 150ms ease);\n user-select: none;\n -webkit-user-select: none;\n }\n\n .split-button__trigger:focus-visible {\n outline: var(--hx-focus-ring-width, 2px) solid\n var(--hx-split-button-focus-ring-color, var(--hx-focus-ring-color, #2563eb));\n outline-offset: var(--hx-focus-ring-offset, 2px);\n z-index: 1;\n position: relative;\n }\n\n .split-button__trigger:hover {\n filter: brightness(var(--hx-filter-brightness-hover, 0.9));\n }\n\n .split-button__trigger:active {\n filter: brightness(var(--hx-filter-brightness-active, 0.8));\n }\n\n .split-button__trigger[disabled] {\n cursor: not-allowed;\n }\n\n /* ─── Trigger Icon ─── */\n\n .split-button__chevron {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n transition: transform var(--hx-transition-fast, 150ms ease);\n }\n\n .split-button__chevron--open {\n transform: rotate(180deg);\n }\n\n /* ─── Size Variants ─── */\n\n /* sm */\n .split-button--sm .split-button__primary {\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-size-8, 2rem);\n }\n\n .split-button--sm .split-button__trigger {\n padding: var(--hx-space-1, 0.25rem) var(--hx-space-2, 0.5rem);\n min-height: var(--hx-size-8, 2rem);\n }\n\n /* md */\n .split-button--md .split-button__primary {\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 .split-button--md .split-button__trigger {\n padding: var(--hx-space-2, 0.5rem) var(--hx-space-3, 0.75rem);\n min-height: var(--hx-size-10, 2.5rem);\n }\n\n /* lg */\n .split-button--lg .split-button__primary {\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 .split-button--lg .split-button__trigger {\n padding: var(--hx-space-3, 0.75rem) var(--hx-space-4, 1rem);\n min-height: var(--hx-size-12, 3rem);\n }\n\n /* ─── Variant: primary ─── */\n\n .split-button--primary .split-button__primary,\n .split-button--primary .split-button__trigger {\n --hx-split-button-bg: var(--hx-color-primary-500, #2563eb);\n --hx-split-button-color: var(--hx-color-neutral-0, #ffffff);\n --hx-split-button-border-color: transparent;\n --hx-split-button-divider-color: var(--hx-color-primary-400, #3b82f6);\n }\n\n /* ─── Variant: secondary ─── */\n\n .split-button--secondary .split-button__primary,\n .split-button--secondary .split-button__trigger {\n --hx-split-button-bg: transparent;\n --hx-split-button-color: var(--hx-color-primary-500, #2563eb);\n --hx-split-button-border-color: var(--hx-color-primary-500, #2563eb);\n --hx-split-button-divider-color: var(--hx-color-primary-300, #93c5fd);\n }\n\n .split-button--secondary .split-button__primary:hover,\n .split-button--secondary .split-button__trigger:hover {\n --hx-split-button-bg: var(--hx-color-primary-50, #eff6ff);\n filter: none;\n }\n\n /* ─── Variant: tertiary ─── */\n\n .split-button--tertiary .split-button__primary,\n .split-button--tertiary .split-button__trigger {\n --hx-split-button-bg: var(--hx-color-neutral-100, #f1f5f9);\n --hx-split-button-color: var(--hx-color-neutral-900, #0f172a);\n --hx-split-button-border-color: transparent;\n --hx-split-button-divider-color: var(--hx-color-neutral-300, #cbd5e1);\n }\n\n .split-button--tertiary .split-button__primary:hover,\n .split-button--tertiary .split-button__trigger:hover {\n --hx-split-button-bg: var(--hx-color-neutral-200, #e2e8f0);\n filter: none;\n }\n\n /* ─── Variant: danger ─── */\n\n .split-button--danger .split-button__primary,\n .split-button--danger .split-button__trigger {\n --hx-split-button-bg: var(--hx-color-error-500, #dc2626);\n --hx-split-button-color: var(--hx-color-neutral-0, #ffffff);\n --hx-split-button-border-color: transparent;\n --hx-split-button-divider-color: var(--hx-color-error-400, #f87171);\n }\n\n .split-button--danger .split-button__primary:hover,\n .split-button--danger .split-button__trigger:hover {\n --hx-split-button-bg: var(--hx-color-error-600, #b91c1c);\n filter: none;\n }\n\n /* ─── Variant: ghost ─── */\n\n .split-button--ghost .split-button__primary,\n .split-button--ghost .split-button__trigger {\n --hx-split-button-bg: transparent;\n --hx-split-button-color: var(--hx-color-primary-500, #2563eb);\n --hx-split-button-border-color: transparent;\n --hx-split-button-divider-color: var(--hx-color-primary-200, #bfdbfe);\n }\n\n .split-button--ghost .split-button__primary:hover,\n .split-button--ghost .split-button__trigger:hover {\n --hx-split-button-bg: var(--hx-color-neutral-100, #f1f5f9);\n filter: none;\n }\n\n /* ─── Variant: outline ─── */\n\n .split-button--outline .split-button__primary,\n .split-button--outline .split-button__trigger {\n --hx-split-button-bg: transparent;\n --hx-split-button-color: var(--hx-color-neutral-900, #0f172a);\n --hx-split-button-border-color: var(--hx-color-neutral-300, #cbd5e1);\n --hx-split-button-divider-color: var(--hx-color-neutral-300, #cbd5e1);\n }\n\n .split-button--outline .split-button__primary:hover,\n .split-button--outline .split-button__trigger:hover {\n --hx-split-button-bg: var(--hx-color-neutral-50, #f8fafc);\n filter: none;\n }\n\n /* ─── Dropdown Menu Panel ─── */\n\n @keyframes hx-split-button-menu-open {\n from {\n opacity: 0;\n transform: translateY(-4px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n }\n\n .split-button__menu {\n display: none;\n position: absolute;\n top: calc(100% + var(--hx-space-1, 0.25rem));\n inset-inline-end: 0;\n min-width: 100%;\n max-height: var(--hx-split-button-menu-max-height, 18rem);\n overflow-y: auto;\n background-color: var(--hx-split-button-menu-bg, var(--hx-color-neutral-0, #ffffff));\n border: var(--hx-border-width-thin, 1px) solid\n var(--hx-split-button-menu-border-color, var(--hx-color-neutral-200, #e2e8f0));\n border-radius: var(--hx-split-button-menu-border-radius, var(--hx-border-radius-md, 0.375rem));\n box-shadow: var(\n --hx-split-button-menu-shadow,\n 0 4px 6px -1px var(--hx-overlay-black-10, rgba(0, 0, 0, 0.1)),\n 0 2px 4px -2px var(--hx-overlay-black-10, rgba(0, 0, 0, 0.1))\n );\n padding: var(--hx-space-1, 0.25rem);\n z-index: var(--hx-z-index-dropdown, 200);\n }\n\n .split-button__menu--open {\n display: block;\n animation: hx-split-button-menu-open var(--hx-transition-fast, 150ms ease);\n }\n\n /* ─── Reduced Motion ─── */\n\n @media (prefers-reduced-motion: reduce) {\n .split-button__primary,\n .split-button__trigger,\n .split-button__chevron {\n transition: none;\n }\n\n .split-button__menu--open {\n animation: none;\n }\n }\n`;\n","import { LitElement, html } from 'lit';\nimport { customElement, property, state, query } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { tokenStyles } from '@helixui/tokens/lit';\nimport { helixSplitButtonStyles } from './hx-split-button.styles.js';\nimport type { HelixMenuItem } from '../hx-menu/hx-menu-item.js';\n\n// Module-level counter for stable, SSR-safe IDs (avoids Math.random() hydration mismatch)\nlet _hxSplitButtonIdCounter = 0;\n\n/**\n * A split button combining a primary action button with an attached dropdown\n * menu for secondary actions. Implements the ARIA menu button pattern for\n * full keyboard and screen reader support.\n *\n * @summary Primary action button with attached dropdown menu for secondary actions.\n *\n * @tag hx-split-button\n *\n * @slot - Primary button label text.\n * @slot menu - `hx-menu-item` children rendered in the dropdown panel.\n *\n * @fires {CustomEvent<{originalEvent: MouseEvent}>} hx-click - Dispatched when\n * the primary button is clicked and is not disabled.\n * @fires {CustomEvent<{value: string; label: string}>} hx-select - Dispatched when\n * a menu item is selected from the dropdown.\n *\n * @csspart button - The primary action button element.\n * @csspart trigger - The dropdown trigger button element.\n * @csspart menu - The dropdown menu panel.\n *\n * @cssprop [--hx-split-button-menu-max-height=18rem] - Maximum height of the dropdown menu panel before scrolling.\n * @cssprop [--hx-split-button-bg=var(--hx-color-primary-500)] - Background color for both buttons.\n * @cssprop [--hx-split-button-color=var(--hx-color-neutral-0)] - Text/icon color for both buttons.\n * @cssprop [--hx-split-button-border-color=transparent] - Border color.\n * @cssprop [--hx-split-button-border-radius=var(--hx-border-radius-md)] - Border radius.\n * @cssprop [--hx-split-button-divider-color=var(--hx-color-primary-400)] - Color of the divider between primary and trigger.\n * @cssprop [--hx-split-button-font-family=var(--hx-font-family-sans)] - Font family.\n * @cssprop [--hx-split-button-font-weight=var(--hx-font-weight-semibold)] - Font weight.\n * @cssprop [--hx-split-button-focus-ring-color=var(--hx-focus-ring-color)] - Focus ring color.\n * @cssprop [--hx-split-button-menu-bg=var(--hx-color-neutral-0)] - Dropdown menu background.\n * @cssprop [--hx-split-button-menu-border-color=var(--hx-color-neutral-200)] - Dropdown menu border color.\n * @cssprop [--hx-split-button-menu-border-radius=var(--hx-border-radius-md)] - Dropdown menu border radius.\n * @cssprop [--hx-split-button-menu-shadow] - Dropdown menu box shadow.\n */\n@customElement('hx-split-button')\nexport class HelixSplitButton extends LitElement {\n static override styles = [tokenStyles, helixSplitButtonStyles];\n\n // ─── Internal References ───\n\n @query('.split-button__menu')\n private _menuPanel!: HTMLElement;\n\n @query('.split-button__trigger')\n private _triggerButton!: HTMLButtonElement;\n\n // ─── Internal State ───\n\n @state() private _open = false;\n\n // ─── Public Properties ───\n\n /**\n * Visual style variant of the split 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 split 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 split button is disabled. Both the primary button and the\n * trigger are disabled when this is true.\n * @attr disabled\n */\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /**\n * Primary button label text. When set, overrides the default slot content.\n * @attr label\n */\n @property({ type: String })\n label: string | undefined = undefined;\n\n /**\n * Accessible label for the dropdown trigger button. Override for localization.\n * @attr trigger-label\n */\n @property({ type: String, attribute: 'trigger-label' })\n triggerLabel = 'More actions';\n\n /**\n * Accessible label for the dropdown menu panel. Override for localization.\n * @attr menu-label\n */\n @property({ type: String, attribute: 'menu-label' })\n menuLabel = 'Secondary actions';\n\n // ─── Unique IDs ───\n\n private readonly _menuId = `hx-split-button-menu-${++_hxSplitButtonIdCounter}`;\n\n // ─── Lifecycle ───\n\n override connectedCallback(): void {\n super.connectedCallback();\n document.addEventListener('click', this._handleOutsideClick);\n document.addEventListener('keydown', this._handleDocumentKeydown);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n document.removeEventListener('click', this._handleOutsideClick);\n document.removeEventListener('keydown', this._handleDocumentKeydown);\n }\n\n // ─── Outside-click / document keydown ───\n\n private readonly _handleOutsideClick = (e: MouseEvent): void => {\n if (!this._open) return;\n const target = e.target as Node;\n if (!this.contains(target) && target !== this) {\n this._closeMenu();\n }\n };\n\n private readonly _handleDocumentKeydown = (e: KeyboardEvent): void => {\n if (!this._open) return;\n if (e.key === 'Tab') {\n this._closeMenu();\n }\n };\n\n // ─── Primary Button Handlers ───\n\n private _handlePrimaryClick(e: MouseEvent): void {\n if (this.disabled) {\n e.preventDefault();\n e.stopPropagation();\n return;\n }\n\n /**\n * Dispatched when the primary 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\n private _handlePrimaryKeydown(e: KeyboardEvent): void {\n if (this.disabled) return;\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n this._openMenu();\n }\n }\n\n // ─── Trigger Button Handlers ───\n\n private _handleTriggerClick(e: MouseEvent): void {\n if (this.disabled) {\n e.preventDefault();\n e.stopPropagation();\n return;\n }\n // Stop propagation so _handleOutsideClick does not immediately close.\n e.stopPropagation();\n this._toggleMenu();\n }\n\n private _handleTriggerKeydown(e: KeyboardEvent): void {\n if (this.disabled) return;\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n this._openMenu();\n }\n }\n\n // ─── Menu Key Navigation ───\n\n private _handleMenuKeydown(e: KeyboardEvent): void {\n const items = this._getMenuItems();\n if (items.length === 0) return;\n\n // document.activeElement returns the hx-menu-item host element when its\n // inner shadow DOM element has focus, which matches items[] directly.\n const currentIndex = items.findIndex((item) => item === document.activeElement);\n\n switch (e.key) {\n case 'ArrowDown': {\n e.preventDefault();\n const next = currentIndex < items.length - 1 ? currentIndex + 1 : 0;\n items[next]?.focus();\n break;\n }\n case 'ArrowUp': {\n e.preventDefault();\n const prev = currentIndex > 0 ? currentIndex - 1 : items.length - 1;\n items[prev]?.focus();\n break;\n }\n case 'Escape': {\n e.preventDefault();\n this._closeMenu();\n this._triggerButton?.focus();\n break;\n }\n case 'Home': {\n e.preventDefault();\n items[0]?.focus();\n break;\n }\n case 'End': {\n e.preventDefault();\n items[items.length - 1]?.focus();\n break;\n }\n }\n }\n\n // ─── Menu Item Selection ───\n\n private _handleMenuItemSelect(e: Event): void {\n const custom = e as CustomEvent<{ item: HelixMenuItem; value: string }>;\n this._closeMenu();\n this._triggerButton?.focus();\n\n const item = custom.detail.item;\n const label = item?.textContent?.trim() ?? '';\n\n /**\n * Dispatched when a menu item is selected.\n * @event hx-select\n */\n this.dispatchEvent(\n new CustomEvent<{ value: string; label: string }>('hx-select', {\n bubbles: true,\n composed: true,\n detail: { value: custom.detail.value, label },\n }),\n );\n }\n\n // ─── Menu Helpers ───\n\n private _openMenu(): void {\n if (this._open) return;\n this._open = true;\n // Focus the first enabled menu item after the panel renders\n this.updateComplete\n .then(() => {\n const items = this._getMenuItems();\n items[0]?.focus();\n })\n .catch(() => undefined);\n }\n\n private _closeMenu(): void {\n this._open = false;\n }\n\n private _toggleMenu(): void {\n if (this._open) {\n this._closeMenu();\n } else {\n this._openMenu();\n }\n }\n\n /**\n * Returns the enabled hx-menu-item host elements assigned to the `menu` slot.\n * HelixMenuItem overrides focus() to delegate to its inner element, so calling\n * .focus() on hosts works correctly. document.activeElement returns the host\n * element when the inner shadow element has focus, enabling correct index tracking.\n */\n private _getMenuItems(): HelixMenuItem[] {\n const slot = this.shadowRoot?.querySelector<HTMLSlotElement>('slot[name=\"menu\"]');\n if (!slot) return [];\n\n return slot\n .assignedElements({ flatten: true })\n .filter(\n (el): el is HelixMenuItem =>\n el.tagName.toLowerCase() === 'hx-menu-item' && !(el as HelixMenuItem).disabled,\n );\n }\n\n // ─── Render ───\n\n override render() {\n const containerClasses = {\n 'split-button': true,\n [`split-button--${this.variant}`]: true,\n [`split-button--${this.size}`]: true,\n };\n\n const menuClasses = {\n 'split-button__menu': true,\n 'split-button__menu--open': this._open,\n };\n\n const chevronClasses = {\n 'split-button__chevron': true,\n 'split-button__chevron--open': this._open,\n };\n\n return html`\n <div class=${classMap(containerClasses)}>\n <!-- Primary action button -->\n <button\n part=\"button\"\n class=\"split-button__primary\"\n ?disabled=${this.disabled}\n type=\"button\"\n @click=${this._handlePrimaryClick}\n @keydown=${this._handlePrimaryKeydown}\n >\n ${this.label !== undefined ? this.label : html`<slot></slot>`}\n </button>\n\n <!-- Dropdown trigger button -->\n <button\n part=\"trigger\"\n class=\"split-button__trigger\"\n ?disabled=${this.disabled}\n aria-haspopup=\"menu\"\n aria-expanded=${this._open ? 'true' : 'false'}\n aria-controls=${this._menuId}\n aria-label=${this.triggerLabel}\n type=\"button\"\n @click=${this._handleTriggerClick}\n @keydown=${this._handleTriggerKeydown}\n >\n <span class=${classMap(chevronClasses)} aria-hidden=\"true\">\n <svg\n width=\"12\"\n height=\"8\"\n viewBox=\"0 0 12 8\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M1 1.5L6 6.5L11 1.5\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </span>\n </button>\n\n <!-- Dropdown menu panel -->\n <div\n part=\"menu\"\n id=${this._menuId}\n class=${classMap(menuClasses)}\n role=\"menu\"\n aria-label=${this.menuLabel}\n @keydown=${this._handleMenuKeydown}\n @hx-item-select=${this._handleMenuItemSelect}\n >\n <slot name=\"menu\"></slot>\n </div>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-split-button': HelixSplitButton;\n }\n}\n"],"names":["helixSplitButtonStyles","css","_hxSplitButtonIdCounter","HelixSplitButton","LitElement","e","target","items","currentIndex","item","next","_a","prev","_b","_c","_d","_e","custom","label","slot","el","containerClasses","menuClasses","chevronClasses","html","classMap","tokenStyles","__decorateClass","query","state","property","customElement"],"mappings":";;;;AAEO,MAAMA,IAAyBC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAA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"}
|
|
1
|
+
{"version":3,"file":"hx-split-button-DhncgAtZ.js","sources":["../../src/components/hx-split-button/hx-split-button.styles.ts","../../src/components/hx-split-button/hx-split-button.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixSplitButtonStyles = css`\n :host {\n display: inline-block;\n position: relative;\n }\n\n :host([disabled]) {\n pointer-events: none;\n opacity: var(--hx-opacity-disabled, 0.5);\n }\n\n /* ─── Container ─── */\n\n .split-button {\n display: inline-flex;\n align-items: stretch;\n position: relative;\n }\n\n /* ─── Primary Button ─── */\n\n .split-button__primary {\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-split-button-border-color, transparent);\n border-right: none;\n border-radius: var(--hx-split-button-border-radius, var(--hx-border-radius-md, 0.375rem)) 0 0\n var(--hx-split-button-border-radius, var(--hx-border-radius-md, 0.375rem));\n background-color: var(--hx-split-button-bg, var(--hx-color-primary-500, #2563eb));\n color: var(--hx-split-button-color, var(--hx-color-neutral-0, #ffffff));\n font-family: var(--hx-split-button-font-family, var(--hx-font-family-sans, sans-serif));\n font-weight: var(--hx-split-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 flex: 1 1 auto;\n }\n\n .split-button__primary:focus-visible {\n outline: var(--hx-focus-ring-width, 2px) solid\n var(--hx-split-button-focus-ring-color, var(--hx-focus-ring-color, #2563eb));\n outline-offset: var(--hx-focus-ring-offset, 2px);\n z-index: 1;\n position: relative;\n }\n\n .split-button__primary:hover {\n filter: brightness(var(--hx-filter-brightness-hover, 0.9));\n }\n\n .split-button__primary:active {\n filter: brightness(var(--hx-filter-brightness-active, 0.8));\n }\n\n .split-button__primary[disabled] {\n cursor: not-allowed;\n }\n\n /* ─── Trigger Button ─── */\n\n .split-button__trigger {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n border: var(--hx-border-width-thin, 1px) solid var(--hx-split-button-border-color, transparent);\n border-left: var(--hx-border-width-thin, 1px) solid\n var(--hx-split-button-divider-color, var(--hx-color-primary-400, #3b82f6));\n border-radius: 0 var(--hx-split-button-border-radius, var(--hx-border-radius-md, 0.375rem))\n var(--hx-split-button-border-radius, var(--hx-border-radius-md, 0.375rem)) 0;\n background-color: var(--hx-split-button-bg, var(--hx-color-primary-500, #2563eb));\n color: var(--hx-split-button-color, var(--hx-color-neutral-0, #ffffff));\n cursor: pointer;\n transition:\n background-color var(--hx-transition-fast, 150ms ease),\n box-shadow var(--hx-transition-fast, 150ms ease);\n user-select: none;\n -webkit-user-select: none;\n }\n\n .split-button__trigger:focus-visible {\n outline: var(--hx-focus-ring-width, 2px) solid\n var(--hx-split-button-focus-ring-color, var(--hx-focus-ring-color, #2563eb));\n outline-offset: var(--hx-focus-ring-offset, 2px);\n z-index: 1;\n position: relative;\n }\n\n .split-button__trigger:hover {\n filter: brightness(var(--hx-filter-brightness-hover, 0.9));\n }\n\n .split-button__trigger:active {\n filter: brightness(var(--hx-filter-brightness-active, 0.8));\n }\n\n .split-button__trigger[disabled] {\n cursor: not-allowed;\n }\n\n /* ─── Trigger Icon ─── */\n\n .split-button__chevron {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n transition: transform var(--hx-transition-fast, 150ms ease);\n }\n\n .split-button__chevron--open {\n transform: rotate(180deg);\n }\n\n /* ─── Size Variants ─── */\n\n /* sm */\n .split-button--sm .split-button__primary {\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-size-8, 2rem);\n }\n\n .split-button--sm .split-button__trigger {\n padding: var(--hx-space-1, 0.25rem) var(--hx-space-2, 0.5rem);\n min-height: var(--hx-size-8, 2rem);\n }\n\n /* md */\n .split-button--md .split-button__primary {\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 .split-button--md .split-button__trigger {\n padding: var(--hx-space-2, 0.5rem) var(--hx-space-3, 0.75rem);\n min-height: var(--hx-size-10, 2.5rem);\n }\n\n /* lg */\n .split-button--lg .split-button__primary {\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 .split-button--lg .split-button__trigger {\n padding: var(--hx-space-3, 0.75rem) var(--hx-space-4, 1rem);\n min-height: var(--hx-size-12, 3rem);\n }\n\n /* ─── Variant: primary ─── */\n\n .split-button--primary .split-button__primary,\n .split-button--primary .split-button__trigger {\n --hx-split-button-bg: var(--hx-color-primary-500, #2563eb);\n --hx-split-button-color: var(--hx-color-neutral-0, #ffffff);\n --hx-split-button-border-color: transparent;\n --hx-split-button-divider-color: var(--hx-color-primary-400, #3b82f6);\n }\n\n /* ─── Variant: secondary ─── */\n\n .split-button--secondary .split-button__primary,\n .split-button--secondary .split-button__trigger {\n --hx-split-button-bg: transparent;\n --hx-split-button-color: var(--hx-color-primary-500, #2563eb);\n --hx-split-button-border-color: var(--hx-color-primary-500, #2563eb);\n --hx-split-button-divider-color: var(--hx-color-primary-300, #93c5fd);\n }\n\n .split-button--secondary .split-button__primary:hover,\n .split-button--secondary .split-button__trigger:hover {\n --hx-split-button-bg: var(--hx-color-primary-50, #eff6ff);\n filter: none;\n }\n\n /* ─── Variant: tertiary ─── */\n\n .split-button--tertiary .split-button__primary,\n .split-button--tertiary .split-button__trigger {\n --hx-split-button-bg: var(--hx-color-neutral-100, #f1f5f9);\n --hx-split-button-color: var(--hx-color-neutral-900, #0f172a);\n --hx-split-button-border-color: transparent;\n --hx-split-button-divider-color: var(--hx-color-neutral-300, #cbd5e1);\n }\n\n .split-button--tertiary .split-button__primary:hover,\n .split-button--tertiary .split-button__trigger:hover {\n --hx-split-button-bg: var(--hx-color-neutral-200, #e2e8f0);\n filter: none;\n }\n\n /* ─── Variant: danger ─── */\n\n .split-button--danger .split-button__primary,\n .split-button--danger .split-button__trigger {\n --hx-split-button-bg: var(--hx-color-error-500, #dc2626);\n --hx-split-button-color: var(--hx-color-neutral-0, #ffffff);\n --hx-split-button-border-color: transparent;\n --hx-split-button-divider-color: var(--hx-color-error-400, #f87171);\n }\n\n .split-button--danger .split-button__primary:hover,\n .split-button--danger .split-button__trigger:hover {\n --hx-split-button-bg: var(--hx-color-error-600, #b91c1c);\n filter: none;\n }\n\n /* ─── Variant: ghost ─── */\n\n .split-button--ghost .split-button__primary,\n .split-button--ghost .split-button__trigger {\n --hx-split-button-bg: transparent;\n --hx-split-button-color: var(--hx-color-primary-500, #2563eb);\n --hx-split-button-border-color: transparent;\n --hx-split-button-divider-color: var(--hx-color-primary-200, #bfdbfe);\n }\n\n .split-button--ghost .split-button__primary:hover,\n .split-button--ghost .split-button__trigger:hover {\n --hx-split-button-bg: var(--hx-color-neutral-100, #f1f5f9);\n filter: none;\n }\n\n /* ─── Variant: outline ─── */\n\n .split-button--outline .split-button__primary,\n .split-button--outline .split-button__trigger {\n --hx-split-button-bg: transparent;\n --hx-split-button-color: var(--hx-color-neutral-900, #0f172a);\n --hx-split-button-border-color: var(--hx-color-neutral-300, #cbd5e1);\n --hx-split-button-divider-color: var(--hx-color-neutral-300, #cbd5e1);\n }\n\n .split-button--outline .split-button__primary:hover,\n .split-button--outline .split-button__trigger:hover {\n --hx-split-button-bg: var(--hx-color-neutral-50, #f8fafc);\n filter: none;\n }\n\n /* ─── Dropdown Menu Panel ─── */\n\n @keyframes hx-split-button-menu-open {\n from {\n opacity: 0;\n transform: translateY(-4px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n }\n\n .split-button__menu {\n display: none;\n position: absolute;\n top: calc(100% + var(--hx-space-1, 0.25rem));\n inset-inline-end: 0;\n min-width: 100%;\n max-height: var(--hx-split-button-menu-max-height, 18rem);\n overflow-y: auto;\n background-color: var(--hx-split-button-menu-bg, var(--hx-color-neutral-0, #ffffff));\n border: var(--hx-border-width-thin, 1px) solid\n var(--hx-split-button-menu-border-color, var(--hx-color-neutral-200, #e2e8f0));\n border-radius: var(--hx-split-button-menu-border-radius, var(--hx-border-radius-md, 0.375rem));\n box-shadow: var(\n --hx-split-button-menu-shadow,\n 0 4px 6px -1px var(--hx-overlay-black-10, rgba(0, 0, 0, 0.1)),\n 0 2px 4px -2px var(--hx-overlay-black-10, rgba(0, 0, 0, 0.1))\n );\n padding: var(--hx-space-1, 0.25rem);\n z-index: var(--hx-z-index-dropdown, 200);\n }\n\n .split-button__menu--open {\n display: block;\n animation: hx-split-button-menu-open var(--hx-transition-fast, 150ms ease);\n }\n\n /* ─── Reduced Motion ─── */\n\n @media (prefers-reduced-motion: reduce) {\n .split-button__primary,\n .split-button__trigger,\n .split-button__chevron {\n transition: none;\n }\n\n .split-button__menu--open {\n animation: none;\n }\n }\n`;\n","import { LitElement, html } from 'lit';\nimport { customElement, property, state, query } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { tokenStyles } from '@helixui/tokens/lit';\nimport { helixSplitButtonStyles } from './hx-split-button.styles.js';\nimport type { HelixMenuItem } from '../hx-menu/hx-menu-item.js';\n\n// Module-level counter for stable, SSR-safe IDs (avoids Math.random() hydration mismatch)\nlet _hxSplitButtonIdCounter = 0;\n\n/**\n * A split button combining a primary action button with an attached dropdown\n * menu for secondary actions. Implements the ARIA menu button pattern for\n * full keyboard and screen reader support.\n *\n * @summary Primary action button with attached dropdown menu for secondary actions.\n *\n * @tag hx-split-button\n *\n * @slot - Primary button label text.\n * @slot menu - `hx-menu-item` children rendered in the dropdown panel.\n *\n * @fires {CustomEvent<{originalEvent: MouseEvent}>} hx-click - Dispatched when\n * the primary button is clicked and is not disabled.\n * @fires {CustomEvent<{value: string; label: string}>} hx-select - Dispatched when\n * a menu item is selected from the dropdown.\n *\n * @csspart button - The primary action button element.\n * @csspart trigger - The dropdown trigger button element.\n * @csspart menu - The dropdown menu panel.\n *\n * @cssprop [--hx-split-button-menu-max-height=18rem] - Maximum height of the dropdown menu panel before scrolling.\n * @cssprop [--hx-split-button-bg=var(--hx-color-primary-500)] - Background color for both buttons.\n * @cssprop [--hx-split-button-color=var(--hx-color-neutral-0)] - Text/icon color for both buttons.\n * @cssprop [--hx-split-button-border-color=transparent] - Border color.\n * @cssprop [--hx-split-button-border-radius=var(--hx-border-radius-md)] - Border radius.\n * @cssprop [--hx-split-button-divider-color=var(--hx-color-primary-400)] - Color of the divider between primary and trigger.\n * @cssprop [--hx-split-button-font-family=var(--hx-font-family-sans)] - Font family.\n * @cssprop [--hx-split-button-font-weight=var(--hx-font-weight-semibold)] - Font weight.\n * @cssprop [--hx-split-button-focus-ring-color=var(--hx-focus-ring-color)] - Focus ring color.\n * @cssprop [--hx-split-button-menu-bg=var(--hx-color-neutral-0)] - Dropdown menu background.\n * @cssprop [--hx-split-button-menu-border-color=var(--hx-color-neutral-200)] - Dropdown menu border color.\n * @cssprop [--hx-split-button-menu-border-radius=var(--hx-border-radius-md)] - Dropdown menu border radius.\n * @cssprop [--hx-split-button-menu-shadow] - Dropdown menu box shadow.\n */\n@customElement('hx-split-button')\nexport class HelixSplitButton extends LitElement {\n static override styles = [tokenStyles, helixSplitButtonStyles];\n\n // ─── Internal References ───\n\n @query('.split-button__menu')\n private _menuPanel!: HTMLElement;\n\n @query('.split-button__trigger')\n private _triggerButton!: HTMLButtonElement;\n\n // ─── Internal State ───\n\n @state() private _open = false;\n\n // ─── Public Properties ───\n\n /**\n * Visual style variant of the split 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 split 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 split button is disabled. Both the primary button and the\n * trigger are disabled when this is true.\n * @attr disabled\n */\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /**\n * Primary button label text. When set, overrides the default slot content.\n * @attr label\n */\n @property({ type: String })\n label: string | undefined = undefined;\n\n /**\n * Accessible label for the dropdown trigger button. Override for localization.\n * @attr trigger-label\n */\n @property({ type: String, attribute: 'trigger-label' })\n triggerLabel = 'More actions';\n\n /**\n * Accessible label for the dropdown menu panel. Override for localization.\n * @attr menu-label\n */\n @property({ type: String, attribute: 'menu-label' })\n menuLabel = 'Secondary actions';\n\n // ─── Unique IDs ───\n\n private readonly _menuId = `hx-split-button-menu-${++_hxSplitButtonIdCounter}`;\n\n // ─── Lifecycle ───\n\n override connectedCallback(): void {\n super.connectedCallback();\n document.addEventListener('click', this._handleOutsideClick);\n document.addEventListener('keydown', this._handleDocumentKeydown);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n document.removeEventListener('click', this._handleOutsideClick);\n document.removeEventListener('keydown', this._handleDocumentKeydown);\n }\n\n // ─── Outside-click / document keydown ───\n\n private readonly _handleOutsideClick = (e: MouseEvent): void => {\n if (!this._open) return;\n const target = e.target as Node;\n if (!this.contains(target) && target !== this) {\n this._closeMenu();\n }\n };\n\n private readonly _handleDocumentKeydown = (e: KeyboardEvent): void => {\n if (!this._open) return;\n if (e.key === 'Tab') {\n this._closeMenu();\n }\n };\n\n // ─── Primary Button Handlers ───\n\n private _handlePrimaryClick(e: MouseEvent): void {\n if (this.disabled) {\n e.preventDefault();\n e.stopPropagation();\n return;\n }\n\n /**\n * Dispatched when the primary 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\n private _handlePrimaryKeydown(e: KeyboardEvent): void {\n if (this.disabled) return;\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n this._openMenu();\n }\n }\n\n // ─── Trigger Button Handlers ───\n\n private _handleTriggerClick(e: MouseEvent): void {\n if (this.disabled) {\n e.preventDefault();\n e.stopPropagation();\n return;\n }\n // Stop propagation so _handleOutsideClick does not immediately close.\n e.stopPropagation();\n this._toggleMenu();\n }\n\n private _handleTriggerKeydown(e: KeyboardEvent): void {\n if (this.disabled) return;\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n this._openMenu();\n }\n }\n\n // ─── Menu Key Navigation ───\n\n private _handleMenuKeydown(e: KeyboardEvent): void {\n const items = this._getMenuItems();\n if (items.length === 0) return;\n\n // document.activeElement returns the hx-menu-item host element when its\n // inner shadow DOM element has focus, which matches items[] directly.\n const currentIndex = items.findIndex((item) => item === document.activeElement);\n\n switch (e.key) {\n case 'ArrowDown': {\n e.preventDefault();\n const next = currentIndex < items.length - 1 ? currentIndex + 1 : 0;\n items[next]?.focus();\n break;\n }\n case 'ArrowUp': {\n e.preventDefault();\n const prev = currentIndex > 0 ? currentIndex - 1 : items.length - 1;\n items[prev]?.focus();\n break;\n }\n case 'Escape': {\n e.preventDefault();\n this._closeMenu();\n this._triggerButton?.focus();\n break;\n }\n case 'Home': {\n e.preventDefault();\n items[0]?.focus();\n break;\n }\n case 'End': {\n e.preventDefault();\n items[items.length - 1]?.focus();\n break;\n }\n }\n }\n\n // ─── Menu Item Selection ───\n\n private _handleMenuItemSelect(e: Event): void {\n const custom = e as CustomEvent<{ item: HelixMenuItem; value: string }>;\n this._closeMenu();\n this._triggerButton?.focus();\n\n const item = custom.detail.item;\n const label = item?.textContent?.trim() ?? '';\n\n /**\n * Dispatched when a menu item is selected.\n * @event hx-select\n */\n this.dispatchEvent(\n new CustomEvent<{ value: string; label: string }>('hx-select', {\n bubbles: true,\n composed: true,\n detail: { value: custom.detail.value, label },\n }),\n );\n }\n\n // ─── Menu Helpers ───\n\n private _openMenu(): void {\n if (this._open) return;\n this._open = true;\n // Focus the first enabled menu item after the panel renders\n this.updateComplete\n .then(() => {\n const items = this._getMenuItems();\n items[0]?.focus();\n })\n .catch(() => undefined);\n }\n\n private _closeMenu(): void {\n this._open = false;\n }\n\n private _toggleMenu(): void {\n if (this._open) {\n this._closeMenu();\n } else {\n this._openMenu();\n }\n }\n\n /**\n * Returns the enabled hx-menu-item host elements assigned to the `menu` slot.\n * HelixMenuItem overrides focus() to delegate to its inner element, so calling\n * .focus() on hosts works correctly. document.activeElement returns the host\n * element when the inner shadow element has focus, enabling correct index tracking.\n */\n private _getMenuItems(): HelixMenuItem[] {\n const slot = this.shadowRoot?.querySelector<HTMLSlotElement>('slot[name=\"menu\"]');\n if (!slot) return [];\n\n return slot\n .assignedElements({ flatten: true })\n .filter(\n (el): el is HelixMenuItem =>\n el.tagName.toLowerCase() === 'hx-menu-item' && !(el as HelixMenuItem).disabled,\n );\n }\n\n // ─── Render ───\n\n override render() {\n const containerClasses = {\n 'split-button': true,\n [`split-button--${this.variant}`]: true,\n [`split-button--${this.size}`]: true,\n };\n\n const menuClasses = {\n 'split-button__menu': true,\n 'split-button__menu--open': this._open,\n };\n\n const chevronClasses = {\n 'split-button__chevron': true,\n 'split-button__chevron--open': this._open,\n };\n\n return html`\n <div class=${classMap(containerClasses)}>\n <!-- Primary action button -->\n <button\n part=\"button\"\n class=\"split-button__primary\"\n ?disabled=${this.disabled}\n type=\"button\"\n @click=${this._handlePrimaryClick}\n @keydown=${this._handlePrimaryKeydown}\n >\n ${this.label !== undefined ? this.label : html`<slot></slot>`}\n </button>\n\n <!-- Dropdown trigger button -->\n <button\n part=\"trigger\"\n class=\"split-button__trigger\"\n ?disabled=${this.disabled}\n aria-haspopup=\"menu\"\n aria-expanded=${this._open ? 'true' : 'false'}\n aria-controls=${this._menuId}\n aria-label=${this.triggerLabel}\n type=\"button\"\n @click=${this._handleTriggerClick}\n @keydown=${this._handleTriggerKeydown}\n >\n <span class=${classMap(chevronClasses)} aria-hidden=\"true\">\n <svg\n width=\"12\"\n height=\"8\"\n viewBox=\"0 0 12 8\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M1 1.5L6 6.5L11 1.5\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </span>\n </button>\n\n <!-- Dropdown menu panel -->\n <div\n part=\"menu\"\n id=${this._menuId}\n class=${classMap(menuClasses)}\n role=\"menu\"\n aria-label=${this.menuLabel}\n @keydown=${this._handleMenuKeydown}\n @hx-item-select=${this._handleMenuItemSelect}\n >\n <slot name=\"menu\"></slot>\n </div>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-split-button': HelixSplitButton;\n }\n}\n"],"names":["helixSplitButtonStyles","css","_hxSplitButtonIdCounter","HelixSplitButton","LitElement","e","target","items","currentIndex","item","next","_a","prev","_b","_c","_d","_e","custom","label","slot","el","containerClasses","menuClasses","chevronClasses","html","classMap","tokenStyles","__decorateClass","query","state","property","customElement"],"mappings":";;;;AAEO,MAAMA,IAAyBC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAA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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { css as c, LitElement as u, nothing as d, html as h } from "lit";
|
|
2
2
|
import { property as r, customElement as v } from "lit/decorators.js";
|
|
3
|
-
import {
|
|
3
|
+
import { tokenStyles as f } from "@helixui/tokens/lit";
|
|
4
4
|
const b = c`
|
|
5
5
|
:host {
|
|
6
6
|
display: flex;
|
|
@@ -348,4 +348,4 @@ e = o([
|
|
|
348
348
|
export {
|
|
349
349
|
e as H
|
|
350
350
|
};
|
|
351
|
-
//# sourceMappingURL=hx-split-panel-
|
|
351
|
+
//# sourceMappingURL=hx-split-panel-D9Jg5qKO.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hx-split-panel-C9Sy7XVW.js","sources":["../../src/components/hx-split-panel/hx-split-panel.styles.ts","../../src/components/hx-split-panel/hx-split-panel.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixSplitPanelStyles = css`\n :host {\n display: flex;\n --_divider-size: var(--hx-split-panel-divider-size, 4px);\n --_divider-color: var(--hx-split-panel-divider-color, var(--hx-color-neutral-200));\n --_divider-hover-color: var(--hx-split-panel-divider-hover-color, var(--hx-color-primary-500));\n overflow: hidden;\n }\n\n :host([orientation='horizontal']) {\n flex-direction: row;\n width: 100%;\n height: 100%;\n }\n\n :host([orientation='vertical']) {\n flex-direction: column;\n width: 100%;\n height: 100%;\n }\n\n .panel {\n overflow: auto;\n min-width: 0;\n min-height: 0;\n }\n\n .panel--start {\n flex-shrink: 0;\n }\n\n .panel--end {\n flex: 1;\n }\n\n :host([orientation='horizontal']) .panel--start {\n height: 100%;\n }\n\n :host([orientation='vertical']) .panel--start {\n width: 100%;\n }\n\n /* ─── Divider Track (flex child wrapper) ─── */\n\n .divider-track {\n flex-shrink: 0;\n position: relative;\n overflow: visible;\n display: flex;\n align-items: stretch;\n }\n\n :host([orientation='horizontal']) .divider-track {\n width: var(--_divider-size);\n height: 100%;\n }\n\n :host([orientation='vertical']) .divider-track {\n width: 100%;\n height: var(--_divider-size);\n }\n\n /* ─── Divider (separator role — no interactive children) ─── */\n\n .divider {\n flex: 1;\n background-color: var(--_divider-color);\n cursor: col-resize;\n transition: background-color 0.15s ease;\n touch-action: none;\n user-select: none;\n -webkit-user-select: none;\n outline: none;\n }\n\n :host([orientation='horizontal']) .divider {\n cursor: col-resize;\n }\n\n :host([orientation='vertical']) .divider {\n cursor: row-resize;\n }\n\n .divider:hover,\n .divider:focus-visible {\n background-color: var(--_divider-hover-color);\n }\n\n .divider:focus-visible {\n outline: 2px solid var(--_divider-hover-color);\n outline-offset: 2px;\n box-shadow: 0 0 0 4px color-mix(in srgb, var(--_divider-hover-color) 30%, transparent);\n }\n\n :host([disabled]) .divider {\n cursor: default;\n pointer-events: none;\n }\n\n :host([disabled]) .divider:hover,\n :host([disabled]) .divider:focus-visible {\n background-color: var(--_divider-color);\n outline: none;\n box-shadow: none;\n }\n\n /* ─── Collapse Controls (siblings of separator, not children) ─── */\n\n .collapse-controls {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n z-index: 2;\n pointer-events: auto;\n }\n\n :host([orientation='vertical']) .collapse-controls {\n flex-direction: row;\n }\n\n .collapse-btn {\n background: var(--_divider-hover-color);\n border: 2px solid white;\n color: white;\n width: 20px;\n height: 20px;\n border-radius: 50%;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 8px;\n padding: 0;\n line-height: 1;\n flex-shrink: 0;\n }\n\n .collapse-btn:hover {\n filter: brightness(1.1);\n }\n\n .collapse-btn:focus-visible {\n outline: 2px solid white;\n outline-offset: 2px;\n }\n`;\n","import { LitElement, html, nothing, type PropertyValues } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { tokenStyles } from '@helixui/tokens/lit';\nimport { helixSplitPanelStyles } from './hx-split-panel.styles.js';\n\n/**\n * A resizable two-pane layout with a draggable divider.\n *\n * @summary Resizable split panel with start and end panes.\n *\n * @tag hx-split-panel\n *\n * @slot start - The first (start) panel content.\n * @slot end - The second (end) panel content.\n *\n * @csspart start - The start panel container.\n * @csspart divider - The draggable divider element.\n * @csspart end - The end panel container.\n *\n * @fires hx-reposition - Fired when the divider is moved. Detail: `{ position: number }`.\n *\n * @cssprop [--hx-split-panel-divider-size=4px] - Width (horizontal) or height (vertical) of the divider.\n * @cssprop [--hx-split-panel-divider-color=var(--hx-color-neutral-200)] - Default divider color.\n * @cssprop [--hx-split-panel-divider-hover-color=var(--hx-color-primary-500)] - Divider color on hover/focus.\n *\n * @example Drupal Twig usage:\n * ```twig\n * <hx-split-panel\n * position=\"50\"\n * orientation=\"horizontal\"\n * min=\"10\"\n * max=\"90\"\n * collapsible\n * >\n * <div slot=\"start\">{{ start_content }}</div>\n * <div slot=\"end\">{{ end_content }}</div>\n * </hx-split-panel>\n *\n * Attribute-settable: position, position-in-pixels, orientation, disabled, min, max, collapsible, collapsed\n * JS-only (complex types): snap (use .snap=${[25, 50, 75]} in Lit templates,\n * or snap=\"[25,50,75]\" as JSON string in Twig)\n * ```\n */\n@customElement('hx-split-panel')\nexport class HelixSplitPanel extends LitElement {\n static override styles = [tokenStyles, helixSplitPanelStyles];\n\n /**\n * Position of the divider as a percentage (0–100) of the start panel.\n * @attr position\n */\n @property({ type: Number, reflect: true })\n position = 50;\n\n /**\n * Position of the divider in pixels (alternative to `position`).\n * When set, takes precedence over `position` until the host is measured.\n * @attr position-in-pixels\n */\n @property({ type: Number, attribute: 'position-in-pixels' })\n positionInPixels: number | undefined;\n\n /**\n * Orientation of the split.\n * @attr orientation\n */\n @property({ type: String, reflect: true })\n orientation: 'horizontal' | 'vertical' = 'horizontal';\n\n /**\n * Minimum position as a percentage (0–100). Prevents full collapse of start panel.\n * @attr min\n */\n @property({ type: Number, reflect: true })\n min = 0;\n\n /**\n * Maximum position as a percentage (0–100). Prevents full expansion of start panel.\n * @attr max\n */\n @property({ type: Number, reflect: true })\n max = 100;\n\n /**\n * Snap points as an array of percentages. The divider snaps to the\n * nearest point within a 5% threshold.\n * Accepts JSON array string in HTML: snap=\"[25, 50, 75]\"\n * @attr snap\n */\n @property({\n attribute: 'snap',\n converter: {\n fromAttribute(value: string | null): number[] {\n if (!value) return [];\n try {\n const parsed = JSON.parse(value) as unknown;\n if (Array.isArray(parsed)) return (parsed as unknown[]).map(Number);\n return [];\n } catch {\n return value\n .split(',')\n .map((s) => Number(s.trim()))\n .filter((n) => !isNaN(n));\n }\n },\n toAttribute(value: number[]): string {\n return JSON.stringify(value);\n },\n },\n })\n snap: number[] = [];\n\n /**\n * When true, the divider cannot be dragged.\n * @attr disabled\n */\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /**\n * When true, collapse/expand buttons appear on the divider.\n * @attr collapsible\n */\n @property({ type: Boolean, reflect: true })\n collapsible = false;\n\n /**\n * Which panel is collapsed: 'start', 'end', or null (not collapsed).\n * @attr collapsed\n */\n @property({ type: String, reflect: true })\n collapsed: 'start' | 'end' | null = null;\n\n private _dragging = false;\n private _dragStart = 0;\n private _positionAtDragStart = 0;\n private _positionBeforeCollapse = 50;\n\n private _clamp(value: number): number {\n return Math.min(this.max, Math.max(this.min, value));\n }\n\n private _snapToPoint(value: number): number {\n if (!this.snap.length) return value;\n const threshold = 5;\n for (const point of this.snap) {\n if (Math.abs(value - point) <= threshold) return point;\n }\n return value;\n }\n\n private _setPosition(percent: number): void {\n const clamped = this._clamp(this._snapToPoint(percent));\n if (clamped === this.position) return;\n this.position = clamped;\n this.dispatchEvent(\n new CustomEvent<{ position: number }>('hx-reposition', {\n detail: { position: this.position },\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n private _getHostSize(): number {\n if (this.orientation === 'horizontal') {\n return this.offsetWidth;\n }\n return this.offsetHeight;\n }\n\n private _onPointerDown = (e: PointerEvent): void => {\n if (this.disabled) return;\n const divider = e.currentTarget as HTMLElement;\n divider.setPointerCapture(e.pointerId);\n this._dragging = true;\n this._dragStart = this.orientation === 'horizontal' ? e.clientX : e.clientY;\n this._positionAtDragStart = this.position;\n e.preventDefault();\n };\n\n private _onPointerMove = (e: PointerEvent): void => {\n if (!this._dragging) return;\n const current = this.orientation === 'horizontal' ? e.clientX : e.clientY;\n const delta = current - this._dragStart;\n const hostSize = this._getHostSize();\n if (hostSize === 0) return;\n const deltaPercent = (delta / hostSize) * 100;\n this._setPosition(this._positionAtDragStart + deltaPercent);\n };\n\n private _onPointerUp = (): void => {\n this._dragging = false;\n };\n\n private _onKeyDown = (e: KeyboardEvent): void => {\n if (this.disabled) return;\n switch (e.key) {\n case 'ArrowLeft':\n case 'ArrowUp':\n e.preventDefault();\n this._setPosition(this.position - 1);\n break;\n case 'ArrowRight':\n case 'ArrowDown':\n e.preventDefault();\n this._setPosition(this.position + 1);\n break;\n case 'PageUp':\n e.preventDefault();\n this._setPosition(this.position + 10);\n break;\n case 'PageDown':\n e.preventDefault();\n this._setPosition(this.position - 10);\n break;\n case 'Home':\n e.preventDefault();\n this._setPosition(this.min);\n break;\n case 'End':\n e.preventDefault();\n this._setPosition(this.max);\n break;\n }\n };\n\n private _collapseStart = (): void => {\n this.collapsed = 'start';\n };\n\n private _collapseEnd = (): void => {\n this.collapsed = 'end';\n };\n\n private _expand = (): void => {\n this.collapsed = null;\n };\n\n override updated(changedProperties: PropertyValues): void {\n super.updated(changedProperties);\n if (!changedProperties.has('collapsed')) return;\n\n const prev = changedProperties.get('collapsed');\n\n if (this.collapsed === 'start') {\n // Save restore point when transitioning from non-collapsed state (or initial render)\n if (prev === null || prev === undefined) this._positionBeforeCollapse = this.position;\n this._setPosition(this.min);\n } else if (this.collapsed === 'end') {\n if (prev === null || prev === undefined) this._positionBeforeCollapse = this.position;\n this._setPosition(this.max);\n } else if (this.collapsed === null && prev !== null && prev !== undefined) {\n // Only expand when transitioning from an explicitly collapsed state (not first render)\n this._setPosition(this._positionBeforeCollapse);\n }\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n if (this.positionInPixels !== undefined) {\n // Convert pixel position to percentage after first paint\n requestAnimationFrame(() => {\n if (this.positionInPixels !== undefined) {\n const hostSize = this._getHostSize();\n if (hostSize > 0) {\n this._setPosition((this.positionInPixels / hostSize) * 100);\n }\n }\n });\n }\n }\n\n private _startPanelStyle(): string {\n if (this.orientation === 'horizontal') {\n return `width: ${this.position}%;`;\n }\n return `height: ${this.position}%;`;\n }\n\n override render() {\n return html`\n <div part=\"start\" class=\"panel panel--start\" style=${this._startPanelStyle()}>\n <slot name=\"start\"></slot>\n </div>\n <div class=\"divider-track\">\n <div\n part=\"divider\"\n class=\"divider\"\n role=\"separator\"\n aria-label=\"Resize panels\"\n aria-orientation=${this.orientation === 'horizontal' ? 'vertical' : 'horizontal'}\n aria-valuenow=${this.position}\n aria-valuemin=${this.min}\n aria-valuemax=${this.max}\n aria-disabled=${this.disabled ? 'true' : nothing}\n tabindex=${this.disabled ? '-1' : '0'}\n @pointerdown=${this._onPointerDown}\n @pointermove=${this._onPointerMove}\n @pointerup=${this._onPointerUp}\n @keydown=${this._onKeyDown}\n ></div>\n ${this.collapsible\n ? this.collapsed\n ? html`<div class=\"collapse-controls\">\n <button\n type=\"button\"\n class=\"collapse-btn\"\n aria-label=${`Expand ${this.collapsed} panel`}\n @click=${this._expand}\n >\n ${this.collapsed === 'start' ? '▶' : '◀'}\n </button>\n </div>`\n : html`<div class=\"collapse-controls\">\n <button\n type=\"button\"\n class=\"collapse-btn\"\n aria-label=\"Collapse start panel\"\n @click=${this._collapseStart}\n >\n ◀\n </button>\n <button\n type=\"button\"\n class=\"collapse-btn\"\n aria-label=\"Collapse end panel\"\n @click=${this._collapseEnd}\n >\n ▶\n </button>\n </div>`\n : nothing}\n </div>\n <div part=\"end\" class=\"panel panel--end\">\n <slot name=\"end\"></slot>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-split-panel': HelixSplitPanel;\n }\n}\n"],"names":["helixSplitPanelStyles","css","HelixSplitPanel","LitElement","e","delta","hostSize","deltaPercent","value","threshold","point","percent","clamped","changedProperties","prev","html","nothing","tokenStyles","__decorateClass","property","parsed","s","n","customElement"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"hx-split-panel-D9Jg5qKO.js","sources":["../../src/components/hx-split-panel/hx-split-panel.styles.ts","../../src/components/hx-split-panel/hx-split-panel.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixSplitPanelStyles = css`\n :host {\n display: flex;\n --_divider-size: var(--hx-split-panel-divider-size, 4px);\n --_divider-color: var(--hx-split-panel-divider-color, var(--hx-color-neutral-200));\n --_divider-hover-color: var(--hx-split-panel-divider-hover-color, var(--hx-color-primary-500));\n overflow: hidden;\n }\n\n :host([orientation='horizontal']) {\n flex-direction: row;\n width: 100%;\n height: 100%;\n }\n\n :host([orientation='vertical']) {\n flex-direction: column;\n width: 100%;\n height: 100%;\n }\n\n .panel {\n overflow: auto;\n min-width: 0;\n min-height: 0;\n }\n\n .panel--start {\n flex-shrink: 0;\n }\n\n .panel--end {\n flex: 1;\n }\n\n :host([orientation='horizontal']) .panel--start {\n height: 100%;\n }\n\n :host([orientation='vertical']) .panel--start {\n width: 100%;\n }\n\n /* ─── Divider Track (flex child wrapper) ─── */\n\n .divider-track {\n flex-shrink: 0;\n position: relative;\n overflow: visible;\n display: flex;\n align-items: stretch;\n }\n\n :host([orientation='horizontal']) .divider-track {\n width: var(--_divider-size);\n height: 100%;\n }\n\n :host([orientation='vertical']) .divider-track {\n width: 100%;\n height: var(--_divider-size);\n }\n\n /* ─── Divider (separator role — no interactive children) ─── */\n\n .divider {\n flex: 1;\n background-color: var(--_divider-color);\n cursor: col-resize;\n transition: background-color 0.15s ease;\n touch-action: none;\n user-select: none;\n -webkit-user-select: none;\n outline: none;\n }\n\n :host([orientation='horizontal']) .divider {\n cursor: col-resize;\n }\n\n :host([orientation='vertical']) .divider {\n cursor: row-resize;\n }\n\n .divider:hover,\n .divider:focus-visible {\n background-color: var(--_divider-hover-color);\n }\n\n .divider:focus-visible {\n outline: 2px solid var(--_divider-hover-color);\n outline-offset: 2px;\n box-shadow: 0 0 0 4px color-mix(in srgb, var(--_divider-hover-color) 30%, transparent);\n }\n\n :host([disabled]) .divider {\n cursor: default;\n pointer-events: none;\n }\n\n :host([disabled]) .divider:hover,\n :host([disabled]) .divider:focus-visible {\n background-color: var(--_divider-color);\n outline: none;\n box-shadow: none;\n }\n\n /* ─── Collapse Controls (siblings of separator, not children) ─── */\n\n .collapse-controls {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n z-index: 2;\n pointer-events: auto;\n }\n\n :host([orientation='vertical']) .collapse-controls {\n flex-direction: row;\n }\n\n .collapse-btn {\n background: var(--_divider-hover-color);\n border: 2px solid white;\n color: white;\n width: 20px;\n height: 20px;\n border-radius: 50%;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 8px;\n padding: 0;\n line-height: 1;\n flex-shrink: 0;\n }\n\n .collapse-btn:hover {\n filter: brightness(1.1);\n }\n\n .collapse-btn:focus-visible {\n outline: 2px solid white;\n outline-offset: 2px;\n }\n`;\n","import { LitElement, html, nothing, type PropertyValues } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { tokenStyles } from '@helixui/tokens/lit';\nimport { helixSplitPanelStyles } from './hx-split-panel.styles.js';\n\n/**\n * A resizable two-pane layout with a draggable divider.\n *\n * @summary Resizable split panel with start and end panes.\n *\n * @tag hx-split-panel\n *\n * @slot start - The first (start) panel content.\n * @slot end - The second (end) panel content.\n *\n * @csspart start - The start panel container.\n * @csspart divider - The draggable divider element.\n * @csspart end - The end panel container.\n *\n * @fires hx-reposition - Fired when the divider is moved. Detail: `{ position: number }`.\n *\n * @cssprop [--hx-split-panel-divider-size=4px] - Width (horizontal) or height (vertical) of the divider.\n * @cssprop [--hx-split-panel-divider-color=var(--hx-color-neutral-200)] - Default divider color.\n * @cssprop [--hx-split-panel-divider-hover-color=var(--hx-color-primary-500)] - Divider color on hover/focus.\n *\n * @example Drupal Twig usage:\n * ```twig\n * <hx-split-panel\n * position=\"50\"\n * orientation=\"horizontal\"\n * min=\"10\"\n * max=\"90\"\n * collapsible\n * >\n * <div slot=\"start\">{{ start_content }}</div>\n * <div slot=\"end\">{{ end_content }}</div>\n * </hx-split-panel>\n *\n * Attribute-settable: position, position-in-pixels, orientation, disabled, min, max, collapsible, collapsed\n * JS-only (complex types): snap (use .snap=${[25, 50, 75]} in Lit templates,\n * or snap=\"[25,50,75]\" as JSON string in Twig)\n * ```\n */\n@customElement('hx-split-panel')\nexport class HelixSplitPanel extends LitElement {\n static override styles = [tokenStyles, helixSplitPanelStyles];\n\n /**\n * Position of the divider as a percentage (0–100) of the start panel.\n * @attr position\n */\n @property({ type: Number, reflect: true })\n position = 50;\n\n /**\n * Position of the divider in pixels (alternative to `position`).\n * When set, takes precedence over `position` until the host is measured.\n * @attr position-in-pixels\n */\n @property({ type: Number, attribute: 'position-in-pixels' })\n positionInPixels: number | undefined;\n\n /**\n * Orientation of the split.\n * @attr orientation\n */\n @property({ type: String, reflect: true })\n orientation: 'horizontal' | 'vertical' = 'horizontal';\n\n /**\n * Minimum position as a percentage (0–100). Prevents full collapse of start panel.\n * @attr min\n */\n @property({ type: Number, reflect: true })\n min = 0;\n\n /**\n * Maximum position as a percentage (0–100). Prevents full expansion of start panel.\n * @attr max\n */\n @property({ type: Number, reflect: true })\n max = 100;\n\n /**\n * Snap points as an array of percentages. The divider snaps to the\n * nearest point within a 5% threshold.\n * Accepts JSON array string in HTML: snap=\"[25, 50, 75]\"\n * @attr snap\n */\n @property({\n attribute: 'snap',\n converter: {\n fromAttribute(value: string | null): number[] {\n if (!value) return [];\n try {\n const parsed = JSON.parse(value) as unknown;\n if (Array.isArray(parsed)) return (parsed as unknown[]).map(Number);\n return [];\n } catch {\n return value\n .split(',')\n .map((s) => Number(s.trim()))\n .filter((n) => !isNaN(n));\n }\n },\n toAttribute(value: number[]): string {\n return JSON.stringify(value);\n },\n },\n })\n snap: number[] = [];\n\n /**\n * When true, the divider cannot be dragged.\n * @attr disabled\n */\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /**\n * When true, collapse/expand buttons appear on the divider.\n * @attr collapsible\n */\n @property({ type: Boolean, reflect: true })\n collapsible = false;\n\n /**\n * Which panel is collapsed: 'start', 'end', or null (not collapsed).\n * @attr collapsed\n */\n @property({ type: String, reflect: true })\n collapsed: 'start' | 'end' | null = null;\n\n private _dragging = false;\n private _dragStart = 0;\n private _positionAtDragStart = 0;\n private _positionBeforeCollapse = 50;\n\n private _clamp(value: number): number {\n return Math.min(this.max, Math.max(this.min, value));\n }\n\n private _snapToPoint(value: number): number {\n if (!this.snap.length) return value;\n const threshold = 5;\n for (const point of this.snap) {\n if (Math.abs(value - point) <= threshold) return point;\n }\n return value;\n }\n\n private _setPosition(percent: number): void {\n const clamped = this._clamp(this._snapToPoint(percent));\n if (clamped === this.position) return;\n this.position = clamped;\n this.dispatchEvent(\n new CustomEvent<{ position: number }>('hx-reposition', {\n detail: { position: this.position },\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n private _getHostSize(): number {\n if (this.orientation === 'horizontal') {\n return this.offsetWidth;\n }\n return this.offsetHeight;\n }\n\n private _onPointerDown = (e: PointerEvent): void => {\n if (this.disabled) return;\n const divider = e.currentTarget as HTMLElement;\n divider.setPointerCapture(e.pointerId);\n this._dragging = true;\n this._dragStart = this.orientation === 'horizontal' ? e.clientX : e.clientY;\n this._positionAtDragStart = this.position;\n e.preventDefault();\n };\n\n private _onPointerMove = (e: PointerEvent): void => {\n if (!this._dragging) return;\n const current = this.orientation === 'horizontal' ? e.clientX : e.clientY;\n const delta = current - this._dragStart;\n const hostSize = this._getHostSize();\n if (hostSize === 0) return;\n const deltaPercent = (delta / hostSize) * 100;\n this._setPosition(this._positionAtDragStart + deltaPercent);\n };\n\n private _onPointerUp = (): void => {\n this._dragging = false;\n };\n\n private _onKeyDown = (e: KeyboardEvent): void => {\n if (this.disabled) return;\n switch (e.key) {\n case 'ArrowLeft':\n case 'ArrowUp':\n e.preventDefault();\n this._setPosition(this.position - 1);\n break;\n case 'ArrowRight':\n case 'ArrowDown':\n e.preventDefault();\n this._setPosition(this.position + 1);\n break;\n case 'PageUp':\n e.preventDefault();\n this._setPosition(this.position + 10);\n break;\n case 'PageDown':\n e.preventDefault();\n this._setPosition(this.position - 10);\n break;\n case 'Home':\n e.preventDefault();\n this._setPosition(this.min);\n break;\n case 'End':\n e.preventDefault();\n this._setPosition(this.max);\n break;\n }\n };\n\n private _collapseStart = (): void => {\n this.collapsed = 'start';\n };\n\n private _collapseEnd = (): void => {\n this.collapsed = 'end';\n };\n\n private _expand = (): void => {\n this.collapsed = null;\n };\n\n override updated(changedProperties: PropertyValues): void {\n super.updated(changedProperties);\n if (!changedProperties.has('collapsed')) return;\n\n const prev = changedProperties.get('collapsed');\n\n if (this.collapsed === 'start') {\n // Save restore point when transitioning from non-collapsed state (or initial render)\n if (prev === null || prev === undefined) this._positionBeforeCollapse = this.position;\n this._setPosition(this.min);\n } else if (this.collapsed === 'end') {\n if (prev === null || prev === undefined) this._positionBeforeCollapse = this.position;\n this._setPosition(this.max);\n } else if (this.collapsed === null && prev !== null && prev !== undefined) {\n // Only expand when transitioning from an explicitly collapsed state (not first render)\n this._setPosition(this._positionBeforeCollapse);\n }\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n if (this.positionInPixels !== undefined) {\n // Convert pixel position to percentage after first paint\n requestAnimationFrame(() => {\n if (this.positionInPixels !== undefined) {\n const hostSize = this._getHostSize();\n if (hostSize > 0) {\n this._setPosition((this.positionInPixels / hostSize) * 100);\n }\n }\n });\n }\n }\n\n private _startPanelStyle(): string {\n if (this.orientation === 'horizontal') {\n return `width: ${this.position}%;`;\n }\n return `height: ${this.position}%;`;\n }\n\n override render() {\n return html`\n <div part=\"start\" class=\"panel panel--start\" style=${this._startPanelStyle()}>\n <slot name=\"start\"></slot>\n </div>\n <div class=\"divider-track\">\n <div\n part=\"divider\"\n class=\"divider\"\n role=\"separator\"\n aria-label=\"Resize panels\"\n aria-orientation=${this.orientation === 'horizontal' ? 'vertical' : 'horizontal'}\n aria-valuenow=${this.position}\n aria-valuemin=${this.min}\n aria-valuemax=${this.max}\n aria-disabled=${this.disabled ? 'true' : nothing}\n tabindex=${this.disabled ? '-1' : '0'}\n @pointerdown=${this._onPointerDown}\n @pointermove=${this._onPointerMove}\n @pointerup=${this._onPointerUp}\n @keydown=${this._onKeyDown}\n ></div>\n ${this.collapsible\n ? this.collapsed\n ? html`<div class=\"collapse-controls\">\n <button\n type=\"button\"\n class=\"collapse-btn\"\n aria-label=${`Expand ${this.collapsed} panel`}\n @click=${this._expand}\n >\n ${this.collapsed === 'start' ? '▶' : '◀'}\n </button>\n </div>`\n : html`<div class=\"collapse-controls\">\n <button\n type=\"button\"\n class=\"collapse-btn\"\n aria-label=\"Collapse start panel\"\n @click=${this._collapseStart}\n >\n ◀\n </button>\n <button\n type=\"button\"\n class=\"collapse-btn\"\n aria-label=\"Collapse end panel\"\n @click=${this._collapseEnd}\n >\n ▶\n </button>\n </div>`\n : nothing}\n </div>\n <div part=\"end\" class=\"panel panel--end\">\n <slot name=\"end\"></slot>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-split-panel': HelixSplitPanel;\n }\n}\n"],"names":["helixSplitPanelStyles","css","HelixSplitPanel","LitElement","e","delta","hostSize","deltaPercent","value","threshold","point","percent","clamped","changedProperties","prev","html","nothing","tokenStyles","__decorateClass","property","parsed","s","n","customElement"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { css as c, LitElement as h, html as f } from "lit";
|
|
2
2
|
import { property as a, customElement as g } from "lit/decorators.js";
|
|
3
|
-
import {
|
|
3
|
+
import { tokenStyles as y } from "@helixui/tokens/lit";
|
|
4
4
|
const u = c`
|
|
5
5
|
:host {
|
|
6
6
|
display: block;
|
|
@@ -151,4 +151,4 @@ t = s([
|
|
|
151
151
|
export {
|
|
152
152
|
t as H
|
|
153
153
|
};
|
|
154
|
-
//# sourceMappingURL=hx-stack-
|
|
154
|
+
//# sourceMappingURL=hx-stack-C3xUwi6-.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hx-stack-
|
|
1
|
+
{"version":3,"file":"hx-stack-C3xUwi6-.js","sources":["../../src/components/hx-stack/hx-stack.styles.ts","../../src/components/hx-stack/hx-stack.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixStackStyles = css`\n :host {\n display: block;\n }\n\n :host([inline]) {\n display: inline-block;\n }\n\n [part='base'] {\n display: flex;\n flex-direction: column;\n gap: var(--hx-spacing-md, 1rem);\n }\n\n /* ─── Direction ─── */\n\n :host([direction='horizontal']) [part='base'] {\n flex-direction: row;\n }\n\n :host([direction='vertical']) [part='base'] {\n flex-direction: column;\n }\n\n /* ─── Wrap ─── */\n\n :host([wrap]) [part='base'] {\n flex-wrap: wrap;\n }\n\n /* ─── Alignment ─── */\n\n :host([align='start']) [part='base'] {\n align-items: flex-start;\n }\n\n :host([align='center']) [part='base'] {\n align-items: center;\n }\n\n :host([align='end']) [part='base'] {\n align-items: flex-end;\n }\n\n :host([align='stretch']) [part='base'] {\n align-items: stretch;\n }\n\n :host([align='baseline']) [part='base'] {\n align-items: baseline;\n }\n\n /* ─── Justify ─── */\n\n :host([justify='start']) [part='base'] {\n justify-content: flex-start;\n }\n\n :host([justify='center']) [part='base'] {\n justify-content: center;\n }\n\n :host([justify='end']) [part='base'] {\n justify-content: flex-end;\n }\n\n :host([justify='between']) [part='base'] {\n justify-content: space-between;\n }\n\n :host([justify='around']) [part='base'] {\n justify-content: space-around;\n }\n\n :host([justify='evenly']) [part='base'] {\n justify-content: space-evenly;\n }\n\n /* ─── Gap ─── */\n\n :host([gap='none']) [part='base'] {\n gap: 0;\n }\n\n :host([gap='xs']) [part='base'] {\n gap: var(--hx-spacing-xs, 0.25rem);\n }\n\n :host([gap='sm']) [part='base'] {\n gap: var(--hx-spacing-sm, 0.5rem);\n }\n\n :host([gap='md']) [part='base'] {\n gap: var(--hx-spacing-md, 1rem);\n }\n\n :host([gap='lg']) [part='base'] {\n gap: var(--hx-spacing-lg, 1.5rem);\n }\n\n :host([gap='xl']) [part='base'] {\n gap: var(--hx-spacing-xl, 2rem);\n }\n`;\n","import { LitElement, html } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { tokenStyles } from '@helixui/tokens/lit';\nimport { helixStackStyles } from './hx-stack.styles.js';\n\n/**\n * A flexbox layout wrapper for consistent vertical/horizontal spacing between children.\n *\n * @summary Flexbox stack layout utility for arranging children with consistent spacing.\n *\n * @tag hx-stack\n *\n * @slot - Default slot for any child content.\n *\n * @csspart base - The inner flex container.\n */\n@customElement('hx-stack')\nexport class HelixStack extends LitElement {\n static override styles = [tokenStyles, helixStackStyles];\n\n /**\n * Direction of the stack layout.\n * @attr direction\n */\n @property({ type: String, reflect: true })\n direction: 'horizontal' | 'vertical' = 'vertical';\n\n /**\n * Gap between children using design tokens.\n * @attr gap\n */\n @property({ type: String, reflect: true })\n gap: 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' = 'md';\n\n /**\n * Align-items value for cross-axis alignment.\n * @attr align\n */\n @property({ type: String, reflect: true })\n align: 'start' | 'center' | 'end' | 'stretch' | 'baseline' = 'stretch';\n\n /**\n * Justify-content value for main-axis distribution.\n * @attr justify\n */\n @property({ type: String, reflect: true })\n justify: 'start' | 'center' | 'end' | 'between' | 'around' | 'evenly' = 'start';\n\n /**\n * When true, children wrap onto multiple lines.\n * @attr wrap\n */\n @property({ type: Boolean, reflect: true })\n wrap = false;\n\n /**\n * When true, the component renders as `display: inline-flex`.\n * @attr inline\n */\n @property({ type: Boolean, reflect: true })\n inline = false;\n\n override connectedCallback(): void {\n super.connectedCallback();\n if (!this.hasAttribute('role')) {\n this.setAttribute('role', 'presentation');\n }\n }\n\n override render() {\n return html`\n <div part=\"base\">\n <slot></slot>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-stack': HelixStack;\n }\n}\n"],"names":["helixStackStyles","css","HelixStack","LitElement","html","tokenStyles","__decorateClass","property","customElement"],"mappings":";;;AAEO,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;;;;;;ACezB,IAAMC,IAAN,cAAyBC,EAAW;AAAA,EAApC,cAAA;AAAA,UAAA,GAAA,SAAA,GAQL,KAAA,YAAuC,YAOvC,KAAA,MAAiD,MAOjD,KAAA,QAA6D,WAO7D,KAAA,UAAwE,SAOxE,KAAA,OAAO,IAOP,KAAA,SAAS;AAAA,EAAA;AAAA,EAEA,oBAA0B;AACjC,UAAM,kBAAA,GACD,KAAK,aAAa,MAAM,KAC3B,KAAK,aAAa,QAAQ,cAAc;AAAA,EAE5C;AAAA,EAES,SAAS;AAChB,WAAOC;AAAA;AAAA;AAAA;AAAA;AAAA,EAKT;AACF;AA3DaF,EACK,SAAS,CAACG,GAAaL,CAAgB;AAOvDM,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,QAAQ,SAAS,IAAM;AAAA,GAP9BL,EAQX,WAAA,aAAA,CAAA;AAOAI,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,QAAQ,SAAS,IAAM;AAAA,GAd9BL,EAeX,WAAA,OAAA,CAAA;AAOAI,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,QAAQ,SAAS,IAAM;AAAA,GArB9BL,EAsBX,WAAA,SAAA,CAAA;AAOAI,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,QAAQ,SAAS,IAAM;AAAA,GA5B9BL,EA6BX,WAAA,WAAA,CAAA;AAOAI,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,SAAS,SAAS,IAAM;AAAA,GAnC/BL,EAoCX,WAAA,QAAA,CAAA;AAOAI,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,SAAS,SAAS,IAAM;AAAA,GA1C/BL,EA2CX,WAAA,UAAA,CAAA;AA3CWA,IAANI,EAAA;AAAA,EADNE,EAAc,UAAU;AAAA,GACZN,CAAA;"}
|