@helixui/library 3.3.1-next.118 → 3.4.0-next.121
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/custom-elements.json +422 -322
- package/dist/components/hx-alert/hx-alert.d.ts +11 -0
- package/dist/components/hx-alert/hx-alert.d.ts.map +1 -1
- package/dist/components/hx-alert/hx-alert.styles.d.ts.map +1 -1
- package/dist/components/hx-alert/index.js +1 -1
- package/dist/components/hx-badge/hx-badge.styles.d.ts.map +1 -1
- package/dist/components/hx-badge/index.js +1 -1
- package/dist/components/hx-banner/hx-banner.d.ts +9 -1
- package/dist/components/hx-banner/hx-banner.d.ts.map +1 -1
- package/dist/components/hx-banner/index.js +1 -1
- package/dist/components/hx-button/hx-button.d.ts +11 -1
- package/dist/components/hx-button/hx-button.d.ts.map +1 -1
- package/dist/components/hx-button/index.js +1 -1
- package/dist/components/hx-button-group/hx-button-group.d.ts +13 -0
- package/dist/components/hx-button-group/hx-button-group.d.ts.map +1 -1
- package/dist/components/hx-button-group/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-color-picker/index.js +1 -1
- package/dist/components/hx-combobox/index.js +1 -1
- package/dist/components/hx-data-table/hx-data-table.d.ts.map +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-drawer/hx-drawer.d.ts +201 -0
- package/dist/components/hx-drawer/hx-drawer.d.ts.map +1 -1
- package/dist/components/hx-drawer/hx-drawer.styles.d.ts.map +1 -1
- package/dist/components/hx-drawer/index.js +1 -1
- package/dist/components/hx-dropdown/hx-dropdown.d.ts +96 -8
- 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-icon-button/hx-icon-button.d.ts +16 -3
- package/dist/components/hx-icon-button/hx-icon-button.d.ts.map +1 -1
- package/dist/components/hx-icon-button/hx-icon-button.styles.d.ts.map +1 -1
- package/dist/components/hx-icon-button/index.js +1 -1
- package/dist/components/hx-link/hx-link.d.ts +10 -1
- package/dist/components/hx-link/hx-link.d.ts.map +1 -1
- package/dist/components/hx-link/index.js +1 -1
- package/dist/components/hx-list/hx-list-item.d.ts +27 -1
- package/dist/components/hx-list/hx-list-item.d.ts.map +1 -1
- package/dist/components/hx-list/hx-list.d.ts +28 -0
- package/dist/components/hx-list/hx-list.d.ts.map +1 -1
- package/dist/components/hx-list/index.js +1 -1
- package/dist/components/hx-menu/hx-menu-divider.d.ts +10 -0
- package/dist/components/hx-menu/hx-menu-divider.d.ts.map +1 -1
- package/dist/components/hx-menu/hx-menu-item.d.ts +99 -2
- package/dist/components/hx-menu/hx-menu-item.d.ts.map +1 -1
- package/dist/components/hx-menu/hx-menu-item.styles.d.ts.map +1 -1
- package/dist/components/hx-menu/hx-menu.d.ts +117 -2
- 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/hx-meter.d.ts +39 -0
- package/dist/components/hx-meter/hx-meter.d.ts.map +1 -1
- package/dist/components/hx-meter/hx-meter.styles.d.ts.map +1 -1
- package/dist/components/hx-meter/index.js +1 -1
- package/dist/components/hx-overflow-menu/hx-overflow-menu.d.ts +132 -1
- package/dist/components/hx-overflow-menu/hx-overflow-menu.d.ts.map +1 -1
- package/dist/components/hx-overflow-menu/index.js +1 -1
- package/dist/components/hx-phi-field/hx-phi-field.d.ts +0 -1
- package/dist/components/hx-phi-field/hx-phi-field.d.ts.map +1 -1
- package/dist/components/hx-popover/index.js +1 -1
- package/dist/components/hx-progress-bar/hx-progress-bar.d.ts +33 -0
- package/dist/components/hx-progress-bar/hx-progress-bar.d.ts.map +1 -1
- package/dist/components/hx-progress-bar/index.js +1 -1
- package/dist/components/hx-radio-group/index.js +1 -1
- package/dist/components/hx-select/hx-select.d.ts +1 -0
- package/dist/components/hx-select/hx-select.d.ts.map +1 -1
- package/dist/components/hx-select/index.js +1 -1
- package/dist/components/hx-spinner/hx-spinner.d.ts +14 -0
- package/dist/components/hx-spinner/hx-spinner.d.ts.map +1 -1
- package/dist/components/hx-spinner/index.js +1 -1
- package/dist/components/hx-split-button/hx-split-button.d.ts +94 -7
- package/dist/components/hx-split-button/hx-split-button.d.ts.map +1 -1
- package/dist/components/hx-split-button/index.js +1 -1
- package/dist/components/hx-stat/hx-stat.d.ts +28 -0
- package/dist/components/hx-stat/hx-stat.d.ts.map +1 -1
- package/dist/components/hx-stat/index.js +1 -1
- package/dist/components/hx-switch/index.js +1 -1
- package/dist/components/hx-table/hx-td.d.ts +30 -3
- package/dist/components/hx-table/hx-td.d.ts.map +1 -1
- package/dist/components/hx-table/hx-th.d.ts +39 -3
- package/dist/components/hx-table/hx-th.d.ts.map +1 -1
- package/dist/components/hx-table/hx-tr.d.ts +26 -0
- package/dist/components/hx-table/hx-tr.d.ts.map +1 -1
- package/dist/components/hx-table/index.js +1 -1
- package/dist/components/hx-tabs/hx-tab-panel.d.ts +34 -0
- package/dist/components/hx-tabs/hx-tab-panel.d.ts.map +1 -1
- package/dist/components/hx-tabs/hx-tab.d.ts +45 -2
- package/dist/components/hx-tabs/hx-tab.d.ts.map +1 -1
- package/dist/components/hx-tabs/hx-tab.styles.d.ts.map +1 -1
- package/dist/components/hx-tabs/hx-tabs.d.ts +32 -2
- 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/hx-tag.styles.d.ts.map +1 -1
- package/dist/components/hx-tag/index.js +1 -1
- package/dist/components/hx-theme/hx-theme.d.ts +10 -5
- package/dist/components/hx-theme/hx-theme.d.ts.map +1 -1
- package/dist/components/hx-time-picker/hx-time-picker.d.ts +210 -2
- package/dist/components/hx-time-picker/hx-time-picker.d.ts.map +1 -1
- package/dist/components/hx-time-picker/hx-time-picker.styles.d.ts.map +1 -1
- package/dist/components/hx-time-picker/index.js +1 -1
- package/dist/components/hx-toast/hx-toast-stack.d.ts +14 -0
- package/dist/components/hx-toast/hx-toast-stack.d.ts.map +1 -1
- package/dist/components/hx-toast/hx-toast.d.ts +22 -3
- package/dist/components/hx-toast/hx-toast.d.ts.map +1 -1
- package/dist/components/hx-toast/index.js +1 -1
- package/dist/components/hx-toast/toast-factory.d.ts.map +1 -1
- package/dist/components/hx-toggle-button/index.js +1 -1
- package/dist/components/hx-tree-view/hx-tree-item.d.ts +117 -12
- package/dist/components/hx-tree-view/hx-tree-item.d.ts.map +1 -1
- package/dist/components/hx-tree-view/hx-tree-view.d.ts +87 -7
- package/dist/components/hx-tree-view/hx-tree-view.d.ts.map +1 -1
- package/dist/components/hx-tree-view/index.js +1 -1
- package/dist/css/helix-all.css +123 -0
- package/dist/css/helix-core.css +81 -0
- package/dist/css/helix-feedback.css +14 -0
- package/dist/css/helix-forms.css +11 -0
- package/dist/css/helix-overlay.css +17 -0
- package/dist/css/hx-alert.css +9 -0
- package/dist/css/hx-badge.css +28 -0
- package/dist/css/hx-drawer.css +17 -0
- package/dist/css/hx-icon-button.css +30 -0
- package/dist/css/hx-meter.css +5 -0
- package/dist/css/hx-tag.css +23 -0
- package/dist/css/hx-time-picker.css +11 -0
- package/dist/css/index.css +1 -1
- package/dist/css/manifest.json +3 -1
- package/dist/index.js +35 -35
- package/dist/shared/aria-idref-CxvyzfQS.js +126 -0
- package/dist/shared/aria-idref-CxvyzfQS.js.map +1 -0
- package/dist/shared/{hx-alert-CLn7CstP.js → hx-alert-Bto8-TIi.js} +55 -37
- package/dist/shared/hx-alert-Bto8-TIi.js.map +1 -0
- package/dist/shared/{hx-badge-CQXgOXJM.js → hx-badge-JlFtAdxS.js} +37 -9
- package/dist/shared/hx-badge-JlFtAdxS.js.map +1 -0
- package/dist/shared/{hx-banner-D3DzpfcP.js → hx-banner-fpRnciIO.js} +13 -5
- package/dist/shared/hx-banner-fpRnciIO.js.map +1 -0
- package/dist/shared/{hx-button-DPY6SPVT.js → hx-button-BOwAEcF1.js} +108 -85
- package/dist/shared/{hx-button-DPY6SPVT.js.map → hx-button-BOwAEcF1.js.map} +1 -1
- package/dist/shared/{hx-button-group-BI-QBqmO.js → hx-button-group-DcHP5MBv.js} +15 -16
- package/dist/shared/{hx-button-group-BI-QBqmO.js.map → hx-button-group-DcHP5MBv.js.map} +1 -1
- package/dist/shared/{hx-checkbox-BdgoUeWi.js → hx-checkbox-C48KYKFq.js} +87 -87
- package/dist/shared/hx-checkbox-C48KYKFq.js.map +1 -0
- package/dist/shared/{hx-checkbox-group-LWezHrvS.js → hx-checkbox-group-BJIAX3zU.js} +2 -2
- package/dist/shared/{hx-checkbox-group-LWezHrvS.js.map → hx-checkbox-group-BJIAX3zU.js.map} +1 -1
- package/dist/shared/{hx-color-picker-DVhZl88b.js → hx-color-picker-Dk4cBwYQ.js} +2 -2
- package/dist/shared/{hx-color-picker-DVhZl88b.js.map → hx-color-picker-Dk4cBwYQ.js.map} +1 -1
- package/dist/shared/{hx-combobox-DvlezcDV.js → hx-combobox-BTLO9qiK.js} +2 -2
- package/dist/shared/{hx-combobox-DvlezcDV.js.map → hx-combobox-BTLO9qiK.js.map} +1 -1
- package/dist/shared/{hx-data-table-CLqVqdxr.js → hx-data-table-Ct3gQ6ya.js} +3 -2
- package/dist/shared/{hx-data-table-CLqVqdxr.js.map → hx-data-table-Ct3gQ6ya.js.map} +1 -1
- package/dist/shared/{hx-date-picker-N-0aG5XL.js → hx-date-picker-CiR7FVnR.js} +2 -2
- package/dist/shared/{hx-date-picker-N-0aG5XL.js.map → hx-date-picker-CiR7FVnR.js.map} +1 -1
- package/dist/shared/{hx-dialog-DzB7VytW.js → hx-dialog-AOZpHSuF.js} +2 -2
- package/dist/shared/{hx-dialog-DzB7VytW.js.map → hx-dialog-AOZpHSuF.js.map} +1 -1
- package/dist/shared/{hx-drawer-Y1Ui2IWJ.js → hx-drawer-DH6CdAN1.js} +300 -98
- package/dist/shared/hx-drawer-DH6CdAN1.js.map +1 -0
- package/dist/shared/hx-dropdown-DiLd40Lm.js +401 -0
- package/dist/shared/hx-dropdown-DiLd40Lm.js.map +1 -0
- package/dist/shared/{hx-icon-button-CGNdQSFM.js → hx-icon-button-a6OpeQz5.js} +149 -68
- package/dist/shared/hx-icon-button-a6OpeQz5.js.map +1 -0
- package/dist/shared/{hx-link-C-O6vq0Q.js → hx-link-CMnZRUtQ.js} +55 -43
- package/dist/shared/hx-link-CMnZRUtQ.js.map +1 -0
- package/dist/shared/{hx-list-MyEhh8c7.js → hx-list-De66EtAP.js} +163 -107
- package/dist/shared/hx-list-De66EtAP.js.map +1 -0
- package/dist/shared/hx-menu-divider-BjiRIWKq.js +797 -0
- package/dist/shared/hx-menu-divider-BjiRIWKq.js.map +1 -0
- package/dist/shared/{hx-meter-BPscsw5t.js → hx-meter-BJdh6nrF.js} +105 -64
- package/dist/shared/hx-meter-BJdh6nrF.js.map +1 -0
- package/dist/shared/hx-overflow-menu-BQ4fiMYu.js +492 -0
- package/dist/shared/hx-overflow-menu-BQ4fiMYu.js.map +1 -0
- package/dist/shared/hx-phi-field-C19oxlrr.js.map +1 -1
- package/dist/shared/{hx-popover-CHxWY_cd.js → hx-popover-B9W8-tC0.js} +2 -2
- package/dist/shared/{hx-popover-CHxWY_cd.js.map → hx-popover-B9W8-tC0.js.map} +1 -1
- package/dist/shared/hx-progress-bar-C8nDMdYa.js +290 -0
- package/dist/shared/hx-progress-bar-C8nDMdYa.js.map +1 -0
- package/dist/shared/{hx-radio-CeGzARNk.js → hx-radio-Z1lV1zTO.js} +2 -2
- package/dist/shared/{hx-radio-CeGzARNk.js.map → hx-radio-Z1lV1zTO.js.map} +1 -1
- package/dist/shared/{hx-select-DrcS-YRJ.js → hx-select-D18CnJ0e.js} +2 -2
- package/dist/shared/hx-select-D18CnJ0e.js.map +1 -0
- package/dist/shared/{hx-spinner-DL5AYr16.js → hx-spinner-BB0h2hKZ.js} +62 -34
- package/dist/shared/hx-spinner-BB0h2hKZ.js.map +1 -0
- package/dist/shared/{hx-split-button-Djnc5Aeg.js → hx-split-button-BoABoEm5.js} +153 -82
- package/dist/shared/hx-split-button-BoABoEm5.js.map +1 -0
- package/dist/shared/{hx-stat-WOcNV1Ry.js → hx-stat-Dtf9lz-O.js} +77 -47
- package/dist/shared/hx-stat-Dtf9lz-O.js.map +1 -0
- package/dist/shared/{hx-switch-BX_8uNUs.js → hx-switch-B6kr-EwE.js} +2 -2
- package/dist/shared/{hx-switch-BX_8uNUs.js.map → hx-switch-B6kr-EwE.js.map} +1 -1
- package/dist/shared/{hx-tab-panel-DspCrKqo.js → hx-tab-panel-BQtBXKLD.js} +255 -131
- package/dist/shared/hx-tab-panel-BQtBXKLD.js.map +1 -0
- package/dist/shared/{hx-tag-CNSmdyaK.js → hx-tag-C5aCUpVi.js} +63 -40
- package/dist/shared/hx-tag-C5aCUpVi.js.map +1 -0
- package/dist/shared/{hx-td-DnnEMIuA.js → hx-td-BGkFOJEK.js} +267 -123
- package/dist/shared/hx-td-BGkFOJEK.js.map +1 -0
- package/dist/shared/hx-theme-BsefFWTO.js.map +1 -1
- package/dist/shared/hx-time-picker-iwCD7rzW.js +1038 -0
- package/dist/shared/hx-time-picker-iwCD7rzW.js.map +1 -0
- package/dist/shared/{hx-toggle-button-Dcz9IlUm.js → hx-toggle-button-BQ81EDkl.js} +2 -2
- package/dist/shared/{hx-toggle-button-Dcz9IlUm.js.map → hx-toggle-button-BQ81EDkl.js.map} +1 -1
- package/dist/shared/hx-tree-item-CHrUhuZL.js +925 -0
- package/dist/shared/hx-tree-item-CHrUhuZL.js.map +1 -0
- package/dist/shared/menu-roving-DmMnzJhn.js +14 -0
- package/dist/shared/menu-roving-DmMnzJhn.js.map +1 -0
- package/dist/shared/menu-tree-BNM0SYYq.js +42 -0
- package/dist/shared/menu-tree-BNM0SYYq.js.map +1 -0
- package/dist/shared/{toast-factory-YSznocIV.js → toast-factory-CL2BzdSB.js} +128 -77
- package/dist/shared/toast-factory-CL2BzdSB.js.map +1 -0
- package/dist/utils/aria-idref.d.ts.map +1 -1
- package/dist/utils/menu-label.d.ts +18 -0
- package/dist/utils/menu-label.d.ts.map +1 -0
- package/dist/utils/menu-roving.d.ts +28 -0
- package/dist/utils/menu-roving.d.ts.map +1 -0
- package/dist/utils/menu-tree.d.ts +41 -0
- package/dist/utils/menu-tree.d.ts.map +1 -0
- package/dist/utils/tree-walk.d.ts +53 -0
- package/dist/utils/tree-walk.d.ts.map +1 -0
- package/figma-inventory.json +69 -20
- package/package.json +2 -2
- package/dist/shared/aria-idref-Q0yiSR3p.js +0 -104
- package/dist/shared/aria-idref-Q0yiSR3p.js.map +0 -1
- package/dist/shared/hx-alert-CLn7CstP.js.map +0 -1
- package/dist/shared/hx-badge-CQXgOXJM.js.map +0 -1
- package/dist/shared/hx-banner-D3DzpfcP.js.map +0 -1
- package/dist/shared/hx-checkbox-BdgoUeWi.js.map +0 -1
- package/dist/shared/hx-drawer-Y1Ui2IWJ.js.map +0 -1
- package/dist/shared/hx-dropdown-DJWlF94E.js +0 -316
- package/dist/shared/hx-dropdown-DJWlF94E.js.map +0 -1
- package/dist/shared/hx-icon-button-CGNdQSFM.js.map +0 -1
- package/dist/shared/hx-link-C-O6vq0Q.js.map +0 -1
- package/dist/shared/hx-list-MyEhh8c7.js.map +0 -1
- package/dist/shared/hx-menu-divider-C2omnPtj.js +0 -558
- package/dist/shared/hx-menu-divider-C2omnPtj.js.map +0 -1
- package/dist/shared/hx-meter-BPscsw5t.js.map +0 -1
- package/dist/shared/hx-overflow-menu-DCLsdIBy.js +0 -374
- package/dist/shared/hx-overflow-menu-DCLsdIBy.js.map +0 -1
- package/dist/shared/hx-progress-bar-Bn3JEPUf.js +0 -258
- package/dist/shared/hx-progress-bar-Bn3JEPUf.js.map +0 -1
- package/dist/shared/hx-select-DrcS-YRJ.js.map +0 -1
- package/dist/shared/hx-spinner-DL5AYr16.js.map +0 -1
- package/dist/shared/hx-split-button-Djnc5Aeg.js.map +0 -1
- package/dist/shared/hx-stat-WOcNV1Ry.js.map +0 -1
- package/dist/shared/hx-tab-panel-DspCrKqo.js.map +0 -1
- package/dist/shared/hx-tag-CNSmdyaK.js.map +0 -1
- package/dist/shared/hx-td-DnnEMIuA.js.map +0 -1
- package/dist/shared/hx-time-picker-BoEIZwzv.js +0 -688
- package/dist/shared/hx-time-picker-BoEIZwzv.js.map +0 -1
- package/dist/shared/hx-tree-item-C2CiWuDE.js +0 -703
- package/dist/shared/hx-tree-item-C2CiWuDE.js.map +0 -1
- package/dist/shared/toast-factory-YSznocIV.js.map +0 -1
|
@@ -1,558 +0,0 @@
|
|
|
1
|
-
import { css as p, html as u, nothing as h } from "lit";
|
|
2
|
-
import { property as c, customElement as f, state as x, query as g } from "lit/decorators.js";
|
|
3
|
-
import { f as v } from "./forced-colors-CTEDFRGa.js";
|
|
4
|
-
import { d as y } from "./dev-warn-YlwPHjtX.js";
|
|
5
|
-
import { H as b } from "./helix-element-BNEYeiys.js";
|
|
6
|
-
import { classMap as k } from "lit/directives/class-map.js";
|
|
7
|
-
const I = p`
|
|
8
|
-
:host {
|
|
9
|
-
display: block;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
.menu {
|
|
13
|
-
display: flex;
|
|
14
|
-
flex-direction: column;
|
|
15
|
-
padding: var(--hx-space-1, 0.25rem);
|
|
16
|
-
background: var(--hx-menu-bg, var(--hx-color-surface-default, #ffffff));
|
|
17
|
-
border: var(--hx-border-width-thin, 1px) solid
|
|
18
|
-
var(--hx-menu-border-color, var(--hx-color-border-default, #d6dbd5));
|
|
19
|
-
border-radius: var(--hx-menu-border-radius, var(--hx-border-radius-md, 0.375rem));
|
|
20
|
-
box-shadow: var(
|
|
21
|
-
--hx-menu-shadow,
|
|
22
|
-
var(--hx-shadow-md, 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1))
|
|
23
|
-
);
|
|
24
|
-
min-width: var(--hx-menu-min-width, 10rem);
|
|
25
|
-
max-height: var(--hx-menu-max-height, 20rem);
|
|
26
|
-
overflow-y: auto;
|
|
27
|
-
outline: none;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/* ─── High Contrast Mode (forced-colors) ─── */
|
|
31
|
-
|
|
32
|
-
@media (forced-colors: active) {
|
|
33
|
-
.menu {
|
|
34
|
-
background-color: Canvas;
|
|
35
|
-
border: 2px solid CanvasText;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
`;
|
|
39
|
-
var w = Object.defineProperty, C = Object.getOwnPropertyDescriptor, _ = (e, t, s, n) => {
|
|
40
|
-
for (var i = n > 1 ? void 0 : n ? C(t, s) : t, r = e.length - 1, a; r >= 0; r--)
|
|
41
|
-
(a = e[r]) && (i = (n ? a(t, s, i) : a(i)) || i);
|
|
42
|
-
return n && i && w(t, s, i), i;
|
|
43
|
-
};
|
|
44
|
-
let d = class extends b {
|
|
45
|
-
constructor() {
|
|
46
|
-
super(...arguments), this.label = "", this._focusedIndex = -1, this._typeaheadBuffer = "", this._typeaheadTimer = null;
|
|
47
|
-
}
|
|
48
|
-
/** @internal */
|
|
49
|
-
_getItems() {
|
|
50
|
-
return Array.from(this.querySelectorAll("hx-menu-item")).filter(
|
|
51
|
-
(e) => !e.disabled && !e.loading
|
|
52
|
-
);
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Synchronize roving tabindex across all enabled items.
|
|
56
|
-
* Only the active item (or first item if none active) gets tabindex=0.
|
|
57
|
-
*/
|
|
58
|
-
/** @internal */
|
|
59
|
-
_syncRovingTabIndex() {
|
|
60
|
-
const e = this._getItems(), t = this._focusedIndex >= 0 ? this._focusedIndex : 0;
|
|
61
|
-
e.forEach((s, n) => {
|
|
62
|
-
s.setRovingTabIndex(n === t ? 0 : -1);
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
/** Focus the first menu item. */
|
|
66
|
-
focusFirst() {
|
|
67
|
-
const t = this._getItems()[0];
|
|
68
|
-
t !== void 0 && (this._focusedIndex = 0, this._syncRovingTabIndex(), t.focus());
|
|
69
|
-
}
|
|
70
|
-
/** Focus the last menu item. */
|
|
71
|
-
focusLast() {
|
|
72
|
-
const e = this._getItems(), t = e[e.length - 1];
|
|
73
|
-
t !== void 0 && (this._focusedIndex = e.length - 1, this._syncRovingTabIndex(), t.focus());
|
|
74
|
-
}
|
|
75
|
-
/** @internal */
|
|
76
|
-
_focusItem(e) {
|
|
77
|
-
const t = this._getItems();
|
|
78
|
-
if (t.length === 0) return;
|
|
79
|
-
this._focusedIndex = Math.max(0, Math.min(e, t.length - 1)), this._syncRovingTabIndex();
|
|
80
|
-
const s = t[this._focusedIndex];
|
|
81
|
-
s !== void 0 && s.focus();
|
|
82
|
-
}
|
|
83
|
-
/** @internal */
|
|
84
|
-
_updateFocusedIndex() {
|
|
85
|
-
var n;
|
|
86
|
-
const e = this._getItems(), t = ((n = this.shadowRoot) == null ? void 0 : n.activeElement) ?? document.activeElement, s = e.findIndex((i) => i.matches(":focus-within") || i === t);
|
|
87
|
-
s !== -1 && (this._focusedIndex = s);
|
|
88
|
-
}
|
|
89
|
-
/** @internal */
|
|
90
|
-
_handleKeyDown(e) {
|
|
91
|
-
this._updateFocusedIndex();
|
|
92
|
-
const t = this._getItems();
|
|
93
|
-
if (t.length !== 0)
|
|
94
|
-
switch (e.key) {
|
|
95
|
-
case "ArrowDown":
|
|
96
|
-
e.preventDefault(), this._focusItem(this._focusedIndex + 1 < t.length ? this._focusedIndex + 1 : 0);
|
|
97
|
-
break;
|
|
98
|
-
case "ArrowUp":
|
|
99
|
-
e.preventDefault(), this._focusItem(this._focusedIndex > 0 ? this._focusedIndex - 1 : t.length - 1);
|
|
100
|
-
break;
|
|
101
|
-
case "Home":
|
|
102
|
-
e.preventDefault(), this._focusItem(0);
|
|
103
|
-
break;
|
|
104
|
-
case "End":
|
|
105
|
-
e.preventDefault(), this._focusItem(t.length - 1);
|
|
106
|
-
break;
|
|
107
|
-
case "Escape":
|
|
108
|
-
e.preventDefault(), this.dispatchEvent(new CustomEvent("hx-close", { bubbles: !0, composed: !0 }));
|
|
109
|
-
break;
|
|
110
|
-
default:
|
|
111
|
-
e.key.length === 1 && e.key !== " " && !e.ctrlKey && !e.metaKey && !e.altKey && this._handleTypeahead(e.key, t);
|
|
112
|
-
break;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
/** @internal */
|
|
116
|
-
_handleTypeahead(e, t) {
|
|
117
|
-
this._typeaheadTimer !== null && clearTimeout(this._typeaheadTimer), this._typeaheadBuffer += e.toLowerCase(), this._typeaheadTimer = setTimeout(() => {
|
|
118
|
-
this._typeaheadBuffer = "", this._typeaheadTimer = null;
|
|
119
|
-
}, 500);
|
|
120
|
-
const s = t.findIndex((n) => {
|
|
121
|
-
var r;
|
|
122
|
-
return n.disabled || n.hasAttribute("disabled") ? !1 : (((r = n.textContent) == null ? void 0 : r.trim().toLowerCase()) ?? "").startsWith(this._typeaheadBuffer);
|
|
123
|
-
});
|
|
124
|
-
s !== -1 && this._focusItem(s);
|
|
125
|
-
}
|
|
126
|
-
/** @internal */
|
|
127
|
-
_handleSlotChange(e) {
|
|
128
|
-
const t = e.target;
|
|
129
|
-
if (!(t instanceof HTMLSlotElement)) return;
|
|
130
|
-
const s = /* @__PURE__ */ new Set(["hx-menu-item", "hx-menu-divider"]), n = t.assignedElements().filter((i) => !s.has(i.tagName.toLowerCase()));
|
|
131
|
-
n.length > 0 && y(
|
|
132
|
-
"hx-menu",
|
|
133
|
-
`Default slot expects <hx-menu-item> or <hx-menu-divider> elements. Found unexpected: ${n.map((i) => `<${i.tagName.toLowerCase()}>`).join(", ")}`
|
|
134
|
-
), this._syncRovingTabIndex();
|
|
135
|
-
}
|
|
136
|
-
/** @internal */
|
|
137
|
-
_handleItemSelect(e) {
|
|
138
|
-
if (!(e instanceof CustomEvent)) return;
|
|
139
|
-
const t = e.detail, s = this._getItems();
|
|
140
|
-
this._focusedIndex = s.indexOf(t.item), this.dispatchEvent(
|
|
141
|
-
new CustomEvent("hx-select", {
|
|
142
|
-
bubbles: !0,
|
|
143
|
-
composed: !0,
|
|
144
|
-
detail: { item: t.item, value: t.value }
|
|
145
|
-
})
|
|
146
|
-
);
|
|
147
|
-
}
|
|
148
|
-
disconnectedCallback() {
|
|
149
|
-
super.disconnectedCallback(), this._typeaheadTimer !== null && (clearTimeout(this._typeaheadTimer), this._typeaheadTimer = null);
|
|
150
|
-
}
|
|
151
|
-
firstUpdated() {
|
|
152
|
-
this.label;
|
|
153
|
-
}
|
|
154
|
-
render() {
|
|
155
|
-
return u`
|
|
156
|
-
<div
|
|
157
|
-
part="base"
|
|
158
|
-
class="menu"
|
|
159
|
-
role="menu"
|
|
160
|
-
aria-label=${this.label || "Menu"}
|
|
161
|
-
@keydown=${this._handleKeyDown}
|
|
162
|
-
@hx-item-select=${this._handleItemSelect}
|
|
163
|
-
>
|
|
164
|
-
<slot @slotchange=${this._handleSlotChange}></slot>
|
|
165
|
-
</div>
|
|
166
|
-
`;
|
|
167
|
-
}
|
|
168
|
-
};
|
|
169
|
-
d.styles = [I, v];
|
|
170
|
-
_([
|
|
171
|
-
c({ type: String, reflect: !0 })
|
|
172
|
-
], d.prototype, "label", 2);
|
|
173
|
-
d = _([
|
|
174
|
-
f("hx-menu")
|
|
175
|
-
], d);
|
|
176
|
-
const S = p`
|
|
177
|
-
:host {
|
|
178
|
-
display: block;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
:host([disabled]) {
|
|
182
|
-
pointer-events: none;
|
|
183
|
-
opacity: var(--hx-opacity-disabled, 0.5);
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
.menu-item {
|
|
187
|
-
display: flex;
|
|
188
|
-
align-items: center;
|
|
189
|
-
gap: var(--hx-space-2, 0.5rem);
|
|
190
|
-
min-height: var(--hx-touch-target-min, 44px);
|
|
191
|
-
padding: var(--hx-space-2, 0.5rem) var(--hx-space-3, 0.75rem);
|
|
192
|
-
border-radius: var(--hx-border-radius-sm, 0.25rem);
|
|
193
|
-
cursor: pointer;
|
|
194
|
-
color: var(--hx-menu-item-color, var(--hx-color-text-primary, #0d1825));
|
|
195
|
-
font-size: var(--hx-font-size-sm, 0.875rem);
|
|
196
|
-
font-family: var(--hx-menu-item-font-family, var(--hx-font-family-sans, sans-serif));
|
|
197
|
-
line-height: var(--hx-line-height-tight, 1.25);
|
|
198
|
-
user-select: none;
|
|
199
|
-
-webkit-user-select: none;
|
|
200
|
-
outline: none;
|
|
201
|
-
background: none;
|
|
202
|
-
width: 100%;
|
|
203
|
-
box-sizing: border-box;
|
|
204
|
-
transition: background-color var(--hx-transition-fast, 150ms ease);
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
.menu-item:hover,
|
|
208
|
-
.menu-item:focus-visible {
|
|
209
|
-
background-color: var(--hx-menu-item-hover-bg, var(--hx-color-surface-sunken, #ebeee9));
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
.menu-item:focus-visible {
|
|
213
|
-
outline: var(--hx-focus-ring-width, 2px) solid
|
|
214
|
-
var(--hx-menu-item-focus-ring-color, var(--hx-focus-ring-color, #0f7078));
|
|
215
|
-
outline-offset: var(--hx-menu-item-focus-ring-offset, 0px);
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
.menu-item__prefix,
|
|
219
|
-
.menu-item__suffix {
|
|
220
|
-
display: inline-flex;
|
|
221
|
-
align-items: center;
|
|
222
|
-
flex-shrink: 0;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
.menu-item__label {
|
|
226
|
-
flex: 1 1 auto;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
.menu-item__checked-icon {
|
|
230
|
-
display: inline-flex;
|
|
231
|
-
align-items: center;
|
|
232
|
-
flex-shrink: 0;
|
|
233
|
-
width: 1em;
|
|
234
|
-
opacity: 0;
|
|
235
|
-
transition: opacity var(--hx-transition-fast, 150ms ease);
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
.menu-item--checked .menu-item__checked-icon {
|
|
239
|
-
opacity: 1;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
.menu-item__submenu-icon {
|
|
243
|
-
display: inline-flex;
|
|
244
|
-
align-items: center;
|
|
245
|
-
flex-shrink: 0;
|
|
246
|
-
margin-inline-start: auto;
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
.menu-item__spinner {
|
|
250
|
-
width: 1em;
|
|
251
|
-
height: 1em;
|
|
252
|
-
flex-shrink: 0;
|
|
253
|
-
animation: hx-menu-spin var(--hx-duration-spinner, 750ms) linear infinite;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
@keyframes hx-menu-spin {
|
|
257
|
-
to {
|
|
258
|
-
transform: rotate(360deg);
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
@media (prefers-reduced-motion: reduce) {
|
|
263
|
-
.menu-item {
|
|
264
|
-
transition: none;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
.menu-item__checked-icon {
|
|
268
|
-
transition: none;
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
.menu-item__spinner {
|
|
272
|
-
animation: none;
|
|
273
|
-
opacity: var(--hx-opacity-muted, 0.6);
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
/* ─── High Contrast Mode (forced-colors) ─── */
|
|
278
|
-
|
|
279
|
-
@media (forced-colors: active) {
|
|
280
|
-
.menu-item {
|
|
281
|
-
forced-color-adjust: none;
|
|
282
|
-
color: CanvasText;
|
|
283
|
-
background-color: Canvas;
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
.menu-item:hover,
|
|
287
|
-
.menu-item:focus-visible {
|
|
288
|
-
background-color: Highlight;
|
|
289
|
-
color: HighlightText;
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
.menu-item:focus-visible {
|
|
293
|
-
outline: 2px solid Highlight;
|
|
294
|
-
outline-offset: -2px;
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
:host([disabled]) .menu-item {
|
|
298
|
-
color: GrayText;
|
|
299
|
-
opacity: 1;
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
`;
|
|
303
|
-
var T = Object.defineProperty, E = Object.getOwnPropertyDescriptor, l = (e, t, s, n) => {
|
|
304
|
-
for (var i = n > 1 ? void 0 : n ? E(t, s) : t, r = e.length - 1, a; r >= 0; r--)
|
|
305
|
-
(a = e[r]) && (i = (n ? a(t, s, i) : a(i)) || i);
|
|
306
|
-
return n && i && T(t, s, i), i;
|
|
307
|
-
};
|
|
308
|
-
let o = class extends b {
|
|
309
|
-
constructor() {
|
|
310
|
-
super(...arguments), this._rovingTabIndex = -1, this.value = "", this.disabled = !1, this.checked = !1, this.type = "normal", this.loading = !1, this._hasSubmenu = !1, this._submenuOpen = !1;
|
|
311
|
-
}
|
|
312
|
-
/** @internal Set the roving tabindex value. Called by parent hx-menu. */
|
|
313
|
-
setRovingTabIndex(e) {
|
|
314
|
-
this._rovingTabIndex = e;
|
|
315
|
-
}
|
|
316
|
-
/** Set whether the nested submenu is open. Called by the component managing submenu visibility. */
|
|
317
|
-
setSubmenuOpen(e) {
|
|
318
|
-
this._submenuOpen = e;
|
|
319
|
-
}
|
|
320
|
-
/** Focus the inner interactive element. */
|
|
321
|
-
focus(e) {
|
|
322
|
-
var t;
|
|
323
|
-
(t = this._menuItemEl) == null || t.focus(e);
|
|
324
|
-
}
|
|
325
|
-
connectedCallback() {
|
|
326
|
-
super.connectedCallback(), this.closest('hx-menu, hx-split-button, [role="menu"], [role="menubar"]');
|
|
327
|
-
}
|
|
328
|
-
/** @internal */
|
|
329
|
-
_handleSubmenuSlotChange(e) {
|
|
330
|
-
const t = e.target;
|
|
331
|
-
this._hasSubmenu = t.assignedElements().length > 0;
|
|
332
|
-
}
|
|
333
|
-
/** @internal */
|
|
334
|
-
_activate() {
|
|
335
|
-
if (!(this.disabled || this.loading)) {
|
|
336
|
-
if (this.type === "checkbox")
|
|
337
|
-
this.checked = !this.checked;
|
|
338
|
-
else if (this.type === "radio") {
|
|
339
|
-
const e = this.closest("hx-menu");
|
|
340
|
-
e ? e.querySelectorAll(':scope > hx-menu-item[type="radio"]').forEach((t) => {
|
|
341
|
-
t.checked = t === this;
|
|
342
|
-
}) : this.checked = !0;
|
|
343
|
-
}
|
|
344
|
-
this.dispatchEvent(
|
|
345
|
-
new CustomEvent("hx-item-select", {
|
|
346
|
-
bubbles: !0,
|
|
347
|
-
composed: !0,
|
|
348
|
-
detail: { item: this, value: this.value }
|
|
349
|
-
})
|
|
350
|
-
);
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
/** @internal */
|
|
354
|
-
_handleClick(e) {
|
|
355
|
-
if (this.disabled || this.loading) {
|
|
356
|
-
e.preventDefault(), e.stopPropagation();
|
|
357
|
-
return;
|
|
358
|
-
}
|
|
359
|
-
this._activate();
|
|
360
|
-
}
|
|
361
|
-
/** @internal */
|
|
362
|
-
_handleKeyDown(e) {
|
|
363
|
-
if (e.key === "Enter" || e.key === " ") {
|
|
364
|
-
e.preventDefault(), this._activate();
|
|
365
|
-
return;
|
|
366
|
-
}
|
|
367
|
-
if (e.key === "ArrowRight" && this._hasSubmenu) {
|
|
368
|
-
e.preventDefault(), this.dispatchEvent(
|
|
369
|
-
new CustomEvent("hx-item-submenu-open", {
|
|
370
|
-
bubbles: !0,
|
|
371
|
-
composed: !0,
|
|
372
|
-
detail: { item: this }
|
|
373
|
-
})
|
|
374
|
-
);
|
|
375
|
-
return;
|
|
376
|
-
}
|
|
377
|
-
e.key === "ArrowLeft" && (e.preventDefault(), this.dispatchEvent(
|
|
378
|
-
new CustomEvent("hx-item-submenu-close", {
|
|
379
|
-
bubbles: !0,
|
|
380
|
-
composed: !0,
|
|
381
|
-
detail: { item: this }
|
|
382
|
-
})
|
|
383
|
-
));
|
|
384
|
-
}
|
|
385
|
-
/** @internal */
|
|
386
|
-
_renderCheckedIcon() {
|
|
387
|
-
return u`
|
|
388
|
-
<span part="checked-icon" class="menu-item__checked-icon" aria-hidden="true">
|
|
389
|
-
<svg
|
|
390
|
-
width="1em"
|
|
391
|
-
height="1em"
|
|
392
|
-
viewBox="0 0 24 24"
|
|
393
|
-
fill="none"
|
|
394
|
-
stroke="currentColor"
|
|
395
|
-
stroke-width="3"
|
|
396
|
-
stroke-linecap="round"
|
|
397
|
-
stroke-linejoin="round"
|
|
398
|
-
>
|
|
399
|
-
<polyline points="20 6 9 17 4 12" />
|
|
400
|
-
</svg>
|
|
401
|
-
</span>
|
|
402
|
-
`;
|
|
403
|
-
}
|
|
404
|
-
/** @internal */
|
|
405
|
-
_renderSubmenuIcon() {
|
|
406
|
-
return u`
|
|
407
|
-
<span part="submenu-icon" class="menu-item__submenu-icon" aria-hidden="true">
|
|
408
|
-
<svg
|
|
409
|
-
width="1em"
|
|
410
|
-
height="1em"
|
|
411
|
-
viewBox="0 0 24 24"
|
|
412
|
-
fill="none"
|
|
413
|
-
stroke="currentColor"
|
|
414
|
-
stroke-width="2"
|
|
415
|
-
stroke-linecap="round"
|
|
416
|
-
stroke-linejoin="round"
|
|
417
|
-
>
|
|
418
|
-
<polyline points="9 18 15 12 9 6" />
|
|
419
|
-
</svg>
|
|
420
|
-
</span>
|
|
421
|
-
`;
|
|
422
|
-
}
|
|
423
|
-
/** @internal */
|
|
424
|
-
_renderSpinner() {
|
|
425
|
-
return u`
|
|
426
|
-
<svg class="menu-item__spinner" aria-hidden="true" viewBox="0 0 24 24" fill="none">
|
|
427
|
-
<circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="3" opacity="0.3" />
|
|
428
|
-
<path
|
|
429
|
-
d="M12 2a10 10 0 0 1 10 10"
|
|
430
|
-
stroke="currentColor"
|
|
431
|
-
stroke-width="3"
|
|
432
|
-
stroke-linecap="round"
|
|
433
|
-
/>
|
|
434
|
-
</svg>
|
|
435
|
-
`;
|
|
436
|
-
}
|
|
437
|
-
/** @internal */
|
|
438
|
-
_getRole() {
|
|
439
|
-
switch (this.type) {
|
|
440
|
-
case "checkbox":
|
|
441
|
-
return "menuitemcheckbox";
|
|
442
|
-
case "radio":
|
|
443
|
-
return "menuitemradio";
|
|
444
|
-
default:
|
|
445
|
-
return "menuitem";
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
render() {
|
|
449
|
-
const e = this._getRole(), t = this.type === "checkbox" || this.type === "radio", s = {
|
|
450
|
-
"menu-item": !0,
|
|
451
|
-
"menu-item--checked": this.checked
|
|
452
|
-
};
|
|
453
|
-
return u`
|
|
454
|
-
<div
|
|
455
|
-
part="base"
|
|
456
|
-
class=${k(s)}
|
|
457
|
-
role=${e}
|
|
458
|
-
tabindex=${this.disabled ? "-1" : String(this._rovingTabIndex)}
|
|
459
|
-
aria-disabled=${this.disabled ? "true" : h}
|
|
460
|
-
aria-checked=${t ? this.checked ? "true" : "false" : h}
|
|
461
|
-
aria-haspopup=${this._hasSubmenu ? "menu" : h}
|
|
462
|
-
aria-expanded=${this._hasSubmenu ? this._submenuOpen ? "true" : "false" : h}
|
|
463
|
-
aria-busy=${this.loading ? "true" : h}
|
|
464
|
-
@click=${this._handleClick}
|
|
465
|
-
@keydown=${this._handleKeyDown}
|
|
466
|
-
>
|
|
467
|
-
${this.loading ? this._renderSpinner() : h}
|
|
468
|
-
${t ? this._renderCheckedIcon() : h}
|
|
469
|
-
<span part="prefix" class="menu-item__prefix">
|
|
470
|
-
<slot name="prefix"></slot>
|
|
471
|
-
</span>
|
|
472
|
-
<span part="label" class="menu-item__label">
|
|
473
|
-
<slot></slot>
|
|
474
|
-
</span>
|
|
475
|
-
<span part="suffix" class="menu-item__suffix">
|
|
476
|
-
<slot name="suffix"></slot>
|
|
477
|
-
</span>
|
|
478
|
-
${this._hasSubmenu ? this._renderSubmenuIcon() : h}
|
|
479
|
-
<slot name="submenu" @slotchange=${this._handleSubmenuSlotChange}></slot>
|
|
480
|
-
</div>
|
|
481
|
-
`;
|
|
482
|
-
}
|
|
483
|
-
};
|
|
484
|
-
o.styles = [S, v];
|
|
485
|
-
l([
|
|
486
|
-
x()
|
|
487
|
-
], o.prototype, "_rovingTabIndex", 2);
|
|
488
|
-
l([
|
|
489
|
-
c({ type: String })
|
|
490
|
-
], o.prototype, "value", 2);
|
|
491
|
-
l([
|
|
492
|
-
c({ type: Boolean, reflect: !0 })
|
|
493
|
-
], o.prototype, "disabled", 2);
|
|
494
|
-
l([
|
|
495
|
-
c({ type: Boolean, reflect: !0 })
|
|
496
|
-
], o.prototype, "checked", 2);
|
|
497
|
-
l([
|
|
498
|
-
c({ type: String, reflect: !0 })
|
|
499
|
-
], o.prototype, "type", 2);
|
|
500
|
-
l([
|
|
501
|
-
c({ type: Boolean, reflect: !0 })
|
|
502
|
-
], o.prototype, "loading", 2);
|
|
503
|
-
l([
|
|
504
|
-
x()
|
|
505
|
-
], o.prototype, "_hasSubmenu", 2);
|
|
506
|
-
l([
|
|
507
|
-
x()
|
|
508
|
-
], o.prototype, "_submenuOpen", 2);
|
|
509
|
-
l([
|
|
510
|
-
g(".menu-item")
|
|
511
|
-
], o.prototype, "_menuItemEl", 2);
|
|
512
|
-
o = l([
|
|
513
|
-
f("hx-menu-item")
|
|
514
|
-
], o);
|
|
515
|
-
const $ = p`
|
|
516
|
-
:host {
|
|
517
|
-
display: block;
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
.menu-divider {
|
|
521
|
-
height: var(--hx-border-width-thin, 1px);
|
|
522
|
-
background-color: var(--hx-menu-divider-color, var(--hx-color-border-default, #d6dbd5));
|
|
523
|
-
margin: var(--hx-space-1, 0.25rem) calc(-1 * var(--hx-space-1, 0.25rem));
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
/* ─── High Contrast Mode (forced-colors) ─── */
|
|
527
|
-
|
|
528
|
-
@media (forced-colors: active) {
|
|
529
|
-
.menu-divider {
|
|
530
|
-
background-color: GrayText;
|
|
531
|
-
}
|
|
532
|
-
}
|
|
533
|
-
`;
|
|
534
|
-
var D = Object.getOwnPropertyDescriptor, O = (e, t, s, n) => {
|
|
535
|
-
for (var i = n > 1 ? void 0 : n ? D(t, s) : t, r = e.length - 1, a; r >= 0; r--)
|
|
536
|
-
(a = e[r]) && (i = a(i) || i);
|
|
537
|
-
return i;
|
|
538
|
-
};
|
|
539
|
-
let m = class extends b {
|
|
540
|
-
render() {
|
|
541
|
-
return u`<div
|
|
542
|
-
part="base"
|
|
543
|
-
class="menu-divider"
|
|
544
|
-
role="separator"
|
|
545
|
-
aria-orientation="horizontal"
|
|
546
|
-
></div>`;
|
|
547
|
-
}
|
|
548
|
-
};
|
|
549
|
-
m.styles = [$, v];
|
|
550
|
-
m = O([
|
|
551
|
-
f("hx-menu-divider")
|
|
552
|
-
], m);
|
|
553
|
-
export {
|
|
554
|
-
d as H,
|
|
555
|
-
m as a,
|
|
556
|
-
o as b
|
|
557
|
-
};
|
|
558
|
-
//# sourceMappingURL=hx-menu-divider-C2omnPtj.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hx-menu-divider-C2omnPtj.js","sources":["../../src/components/hx-menu/hx-menu.styles.ts","../../src/components/hx-menu/hx-menu.ts","../../src/components/hx-menu/hx-menu-item.styles.ts","../../src/components/hx-menu/hx-menu-item.ts","../../src/components/hx-menu/hx-menu-divider.styles.ts","../../src/components/hx-menu/hx-menu-divider.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixMenuStyles = css`\n :host {\n display: block;\n }\n\n .menu {\n display: flex;\n flex-direction: column;\n padding: var(--hx-space-1, 0.25rem);\n background: var(--hx-menu-bg, var(--hx-color-surface-default, #ffffff));\n border: var(--hx-border-width-thin, 1px) solid\n var(--hx-menu-border-color, var(--hx-color-border-default, #d6dbd5));\n border-radius: var(--hx-menu-border-radius, var(--hx-border-radius-md, 0.375rem));\n box-shadow: var(\n --hx-menu-shadow,\n var(--hx-shadow-md, 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1))\n );\n min-width: var(--hx-menu-min-width, 10rem);\n max-height: var(--hx-menu-max-height, 20rem);\n overflow-y: auto;\n outline: none;\n }\n\n /* ─── High Contrast Mode (forced-colors) ─── */\n\n @media (forced-colors: active) {\n .menu {\n background-color: Canvas;\n border: 2px solid CanvasText;\n }\n }\n`;\n","import { html } from 'lit';\nimport '../../utilities/document-token-adoption.js';\nimport { customElement, property } from 'lit/decorators.js';\nimport { HelixElement } from '../../base/index.js';\nimport { forcedColorsInteractive } from '../../styles/forced-colors.js';\nimport { helixMenuStyles } from './hx-menu.styles.js';\nimport type { HelixMenuItem } from './hx-menu-item.js';\nimport { devWarn } from '../../utils/dev-warn.js';\n\n/**\n * A menu container that manages keyboard navigation over a list of menu items.\n * Use with `hx-menu-item` and `hx-menu-divider`.\n *\n * @summary Context/action menu with keyboard-navigable items.\n *\n * @tag hx-menu\n *\n * @slot - Default slot for hx-menu-item and hx-menu-divider elements.\n *\n * @fires {CustomEvent<{item: HelixMenuItem, value: string}>} hx-select - Dispatched when an item is selected.\n * @fires {CustomEvent<void>} hx-close - Dispatched when Escape is pressed.\n *\n * @csspart base - The root menu element.\n *\n * @cssprop [--hx-menu-bg=var(--hx-color-neutral-0)] - Menu background color.\n * @cssprop [--hx-menu-border-color=var(--hx-color-neutral-200)] - Menu border color.\n * @cssprop [--hx-menu-border-radius=var(--hx-border-radius-md)] - Menu border radius.\n * @cssprop [--hx-menu-shadow] - Menu box shadow.\n * @cssprop [--hx-menu-min-width=10rem] - Minimum menu width.\n * @cssprop [--hx-menu-max-height=20rem] - Maximum menu height before vertical scroll is activated.\n * @cssprop [--hx-space-1] - Spacing token.\n * @cssprop [--hx-color-neutral-0] - Color.\n * @cssprop [--hx-border-width-thin] - Width.\n * @cssprop [--hx-color-neutral-200] - Color.\n * @cssprop [--hx-border-radius-md] - CSS custom property.\n * @cssprop [--hx-shadow-md] - Box shadow.\n */\n@customElement('hx-menu')\nexport class HelixMenu extends HelixElement {\n static override styles = [helixMenuStyles, forcedColorsInteractive];\n\n /**\n * Accessible label for the menu. Rendered as `aria-label` on the inner\n * `role=\"menu\"` element when set.\n * @attr label\n */\n @property({ type: String, reflect: true })\n label = '';\n\n /**\n * Index of the currently focused menu item within the list of enabled items.\n * @internal\n */\n private _focusedIndex = -1;\n\n /**\n * Accumulated character buffer for typeahead search within menu items.\n * @internal\n */\n private _typeaheadBuffer = '';\n\n /**\n * Timer handle that clears the typeahead buffer after a period of inactivity.\n * @internal\n */\n private _typeaheadTimer: ReturnType<typeof setTimeout> | null = null;\n\n /** @internal */\n private _getItems(): HelixMenuItem[] {\n return Array.from(this.querySelectorAll<HelixMenuItem>('hx-menu-item')).filter(\n (item) => !item.disabled && !item.loading,\n );\n }\n\n /**\n * Synchronize roving tabindex across all enabled items.\n * Only the active item (or first item if none active) gets tabindex=0.\n */\n /** @internal */\n private _syncRovingTabIndex(): void {\n const items = this._getItems();\n const activeIndex = this._focusedIndex >= 0 ? this._focusedIndex : 0;\n items.forEach((item, i) => {\n item.setRovingTabIndex(i === activeIndex ? 0 : -1);\n });\n }\n\n /** Focus the first menu item. */\n focusFirst(): void {\n const items = this._getItems();\n const first = items[0];\n if (first !== undefined) {\n this._focusedIndex = 0;\n this._syncRovingTabIndex();\n first.focus();\n }\n }\n\n /** Focus the last menu item. */\n focusLast(): void {\n const items = this._getItems();\n const last = items[items.length - 1];\n if (last !== undefined) {\n this._focusedIndex = items.length - 1;\n this._syncRovingTabIndex();\n last.focus();\n }\n }\n\n /** @internal */\n private _focusItem(index: number): void {\n const items = this._getItems();\n if (items.length === 0) return;\n this._focusedIndex = Math.max(0, Math.min(index, items.length - 1));\n this._syncRovingTabIndex();\n const target = items[this._focusedIndex];\n if (target !== undefined) target.focus();\n }\n\n /** @internal */\n private _updateFocusedIndex(): void {\n const items = this._getItems();\n const active = this.shadowRoot?.activeElement ?? document.activeElement;\n // Find the active item by checking if any item's shadow root contains the active element\n const idx = items.findIndex((item) => item.matches(':focus-within') || item === active);\n if (idx !== -1) this._focusedIndex = idx;\n }\n\n /** @internal */\n private _handleKeyDown(e: KeyboardEvent): void {\n this._updateFocusedIndex();\n const items = this._getItems();\n if (items.length === 0) return;\n\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault();\n this._focusItem(this._focusedIndex + 1 < items.length ? this._focusedIndex + 1 : 0);\n break;\n case 'ArrowUp':\n e.preventDefault();\n this._focusItem(this._focusedIndex > 0 ? this._focusedIndex - 1 : items.length - 1);\n break;\n case 'Home':\n e.preventDefault();\n this._focusItem(0);\n break;\n case 'End':\n e.preventDefault();\n this._focusItem(items.length - 1);\n break;\n case 'Escape':\n e.preventDefault();\n this.dispatchEvent(new CustomEvent<void>('hx-close', { bubbles: true, composed: true }));\n break;\n default:\n if (e.key.length === 1 && e.key !== ' ' && !e.ctrlKey && !e.metaKey && !e.altKey) {\n this._handleTypeahead(e.key, items);\n }\n break;\n }\n }\n\n /** @internal */\n private _handleTypeahead(char: string, items: HelixMenuItem[]): void {\n if (this._typeaheadTimer !== null) {\n clearTimeout(this._typeaheadTimer);\n }\n this._typeaheadBuffer += char.toLowerCase();\n this._typeaheadTimer = setTimeout(() => {\n this._typeaheadBuffer = '';\n this._typeaheadTimer = null;\n }, 500);\n\n const match = items.findIndex((item) => {\n if (item.disabled || item.hasAttribute('disabled')) return false;\n const text = item.textContent?.trim().toLowerCase() ?? '';\n return text.startsWith(this._typeaheadBuffer);\n });\n\n if (match !== -1) {\n this._focusItem(match);\n }\n }\n\n /** @internal */\n private _handleSlotChange(e: Event): void {\n const slot = e.target;\n if (!(slot instanceof HTMLSlotElement)) return;\n const validTags = new Set(['hx-menu-item', 'hx-menu-divider']);\n const invalid = slot\n .assignedElements()\n .filter((el) => !validTags.has(el.tagName.toLowerCase()));\n if (invalid.length > 0) {\n devWarn(\n 'hx-menu',\n `Default slot expects <hx-menu-item> or <hx-menu-divider> elements. Found unexpected: ${invalid.map((el) => `<${el.tagName.toLowerCase()}>`).join(', ')}`,\n );\n }\n // Initialize roving tabindex when items are slotted\n this._syncRovingTabIndex();\n }\n\n /** @internal */\n private _handleItemSelect(e: Event): void {\n if (!(e instanceof CustomEvent)) return;\n const detail = (e as CustomEvent<{ item: HelixMenuItem; value: string }>).detail;\n const items = this._getItems();\n this._focusedIndex = items.indexOf(detail.item);\n\n this.dispatchEvent(\n new CustomEvent<{ item: HelixMenuItem; value: string }>('hx-select', {\n bubbles: true,\n composed: true,\n detail: { item: detail.item, value: detail.value },\n }),\n );\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n if (this._typeaheadTimer !== null) {\n clearTimeout(this._typeaheadTimer);\n this._typeaheadTimer = null;\n }\n }\n\n override firstUpdated(): void {\n if (!this.label) {\n devWarn(\n 'hx-menu',\n 'No accessible label provided. Set the `label` attribute on hx-menu so screen readers can identify this menu (WCAG 4.1.2).',\n );\n }\n }\n\n override render() {\n return html`\n <div\n part=\"base\"\n class=\"menu\"\n role=\"menu\"\n aria-label=${this.label || 'Menu'}\n @keydown=${this._handleKeyDown}\n @hx-item-select=${this._handleItemSelect}\n >\n <slot @slotchange=${this._handleSlotChange}></slot>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-menu': HelixMenu;\n }\n}\n","import { css } from 'lit';\n\nexport const helixMenuItemStyles = css`\n :host {\n display: block;\n }\n\n :host([disabled]) {\n pointer-events: none;\n opacity: var(--hx-opacity-disabled, 0.5);\n }\n\n .menu-item {\n display: flex;\n align-items: center;\n gap: var(--hx-space-2, 0.5rem);\n min-height: var(--hx-touch-target-min, 44px);\n padding: var(--hx-space-2, 0.5rem) var(--hx-space-3, 0.75rem);\n border-radius: var(--hx-border-radius-sm, 0.25rem);\n cursor: pointer;\n color: var(--hx-menu-item-color, var(--hx-color-text-primary, #0d1825));\n font-size: var(--hx-font-size-sm, 0.875rem);\n font-family: var(--hx-menu-item-font-family, var(--hx-font-family-sans, sans-serif));\n line-height: var(--hx-line-height-tight, 1.25);\n user-select: none;\n -webkit-user-select: none;\n outline: none;\n background: none;\n width: 100%;\n box-sizing: border-box;\n transition: background-color var(--hx-transition-fast, 150ms ease);\n }\n\n .menu-item:hover,\n .menu-item:focus-visible {\n background-color: var(--hx-menu-item-hover-bg, var(--hx-color-surface-sunken, #ebeee9));\n }\n\n .menu-item:focus-visible {\n outline: var(--hx-focus-ring-width, 2px) solid\n var(--hx-menu-item-focus-ring-color, var(--hx-focus-ring-color, #0f7078));\n outline-offset: var(--hx-menu-item-focus-ring-offset, 0px);\n }\n\n .menu-item__prefix,\n .menu-item__suffix {\n display: inline-flex;\n align-items: center;\n flex-shrink: 0;\n }\n\n .menu-item__label {\n flex: 1 1 auto;\n }\n\n .menu-item__checked-icon {\n display: inline-flex;\n align-items: center;\n flex-shrink: 0;\n width: 1em;\n opacity: 0;\n transition: opacity var(--hx-transition-fast, 150ms ease);\n }\n\n .menu-item--checked .menu-item__checked-icon {\n opacity: 1;\n }\n\n .menu-item__submenu-icon {\n display: inline-flex;\n align-items: center;\n flex-shrink: 0;\n margin-inline-start: auto;\n }\n\n .menu-item__spinner {\n width: 1em;\n height: 1em;\n flex-shrink: 0;\n animation: hx-menu-spin var(--hx-duration-spinner, 750ms) linear infinite;\n }\n\n @keyframes hx-menu-spin {\n to {\n transform: rotate(360deg);\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n .menu-item {\n transition: none;\n }\n\n .menu-item__checked-icon {\n transition: none;\n }\n\n .menu-item__spinner {\n animation: none;\n opacity: var(--hx-opacity-muted, 0.6);\n }\n }\n\n /* ─── High Contrast Mode (forced-colors) ─── */\n\n @media (forced-colors: active) {\n .menu-item {\n forced-color-adjust: none;\n color: CanvasText;\n background-color: Canvas;\n }\n\n .menu-item:hover,\n .menu-item:focus-visible {\n background-color: Highlight;\n color: HighlightText;\n }\n\n .menu-item:focus-visible {\n outline: 2px solid Highlight;\n outline-offset: -2px;\n }\n\n :host([disabled]) .menu-item {\n color: GrayText;\n opacity: 1;\n }\n }\n`;\n","import { html, nothing } from 'lit';\nimport '../../utilities/document-token-adoption.js';\nimport { customElement, property, query, state } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { HelixElement } from '../../base/index.js';\nimport { forcedColorsInteractive } from '../../styles/forced-colors.js';\nimport { helixMenuItemStyles } from './hx-menu-item.styles.js';\nimport { devWarn } from '../../utils/dev-warn.js';\n\n/**\n * A single interactive item for use inside `hx-menu`. Supports normal, checkbox,\n * and radio types, loading state, prefix/suffix slots, and submenu nesting.\n * Use `aria-label` on the parent `hx-menu` to provide an accessible name.\n *\n * @summary Interactive item within an hx-menu.\n *\n * @tag hx-menu-item\n *\n * @slot - Default slot for the item label.\n * @slot prefix - Icon or content rendered before the label.\n * @slot suffix - Shortcut text or icon rendered after the label.\n * @slot submenu - A nested hx-menu for submenu content.\n *\n * @fires {CustomEvent<{item: HelixMenuItem, value: string}>} hx-item-select - Dispatched when the item is activated via click, Enter, or Space.\n * @fires {CustomEvent<{item: HelixMenuItem}>} hx-item-submenu-open - Dispatched when ArrowRight is pressed on an item with a submenu.\n * @fires {CustomEvent<{item: HelixMenuItem}>} hx-item-submenu-close - Dispatched when ArrowLeft is pressed on an item, signaling the parent to close the submenu and return focus.\n *\n * @csspart base - The root item element.\n * @csspart prefix - Prefix slot wrapper.\n * @csspart label - Label slot wrapper.\n * @csspart suffix - Suffix slot wrapper.\n * @csspart submenu-icon - The chevron icon indicating a submenu.\n * @csspart checked-icon - The checkmark icon for checkbox-type items.\n *\n * @cssprop [--hx-menu-item-color=var(--hx-color-neutral-900)] - Item text color.\n * @cssprop [--hx-menu-item-hover-bg=var(--hx-color-neutral-100)] - Item hover/focus background.\n */\n@customElement('hx-menu-item')\nexport class HelixMenuItem extends HelixElement {\n static override styles = [helixMenuItemStyles, forcedColorsInteractive];\n\n /**\n * @internal Managed by parent hx-menu for roving tabindex.\n * Only the active item in the menu has tabindex=0; all others have -1.\n */\n @state()\n private _rovingTabIndex = -1;\n\n /** @internal Set the roving tabindex value. Called by parent hx-menu. */\n setRovingTabIndex(value: number): void {\n this._rovingTabIndex = value;\n }\n\n /** Set whether the nested submenu is open. Called by the component managing submenu visibility. */\n setSubmenuOpen(open: boolean): void {\n this._submenuOpen = open;\n }\n\n /**\n * The value associated with this item, emitted in the hx-select event.\n * @attr value\n */\n @property({ type: String })\n value = '';\n\n /**\n * Whether the item is disabled. Prevents interaction and event dispatch.\n * @attr disabled\n */\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /**\n * Whether the item is checked. Only meaningful when type=\"checkbox\".\n * @attr checked\n */\n @property({ type: Boolean, reflect: true })\n checked = false;\n\n /**\n * The type of menu item. \"checkbox\" renders a checkmark and toggles checked state.\n * \"radio\" renders a checkmark and emits selection for radio-group behavior.\n * @attr type\n */\n @property({ type: String, reflect: true })\n type: 'normal' | 'checkbox' | 'radio' = 'normal';\n\n /**\n * Whether the item is in a loading state. Shows a spinner and prevents interaction.\n * @attr loading\n */\n @property({ type: Boolean, reflect: true })\n loading = false;\n\n /** @internal */\n @state()\n private _hasSubmenu = false;\n\n /** @internal Tracks whether the nested submenu is currently open. */\n @state()\n private _submenuOpen = false;\n\n /** @internal */\n @query('.menu-item') private _menuItemEl!: HTMLElement | null;\n\n /** Focus the inner interactive element. */\n override focus(options?: FocusOptions): void {\n this._menuItemEl?.focus(options);\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n // WCAG 4.1.2: menuitem role is only valid inside a role=\"menu\" or role=\"menubar\" container.\n // Check the closest ancestor with a menu role.\n const menuHost = this.closest('hx-menu, hx-split-button, [role=\"menu\"], [role=\"menubar\"]');\n if (!menuHost) {\n devWarn(\n 'hx-menu-item',\n 'hx-menu-item must be used inside an hx-menu or an element with role=\"menu\". ' +\n 'An orphaned menuitem violates WCAG 1.3.1 (Info and Relationships).',\n );\n }\n }\n\n /** @internal */\n private _handleSubmenuSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n this._hasSubmenu = slot.assignedElements().length > 0;\n }\n\n /** @internal */\n private _activate(): void {\n if (this.disabled || this.loading) return;\n\n if (this.type === 'checkbox') {\n this.checked = !this.checked;\n } else if (this.type === 'radio') {\n const menu = this.closest('hx-menu');\n if (menu) {\n menu\n .querySelectorAll<HelixMenuItem>(':scope > hx-menu-item[type=\"radio\"]')\n .forEach((sibling) => {\n sibling.checked = sibling === this;\n });\n } else {\n this.checked = true;\n }\n }\n\n this.dispatchEvent(\n new CustomEvent<{ item: HelixMenuItem; value: string }>('hx-item-select', {\n bubbles: true,\n composed: true,\n detail: { item: this, value: this.value },\n }),\n );\n }\n\n /** @internal */\n private _handleClick(e: MouseEvent): void {\n if (this.disabled || this.loading) {\n e.preventDefault();\n e.stopPropagation();\n return;\n }\n this._activate();\n }\n\n /** @internal */\n private _handleKeyDown(e: KeyboardEvent): void {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n this._activate();\n return;\n }\n\n if (e.key === 'ArrowRight' && this._hasSubmenu) {\n e.preventDefault();\n this.dispatchEvent(\n new CustomEvent<{ item: HelixMenuItem }>('hx-item-submenu-open', {\n bubbles: true,\n composed: true,\n detail: { item: this },\n }),\n );\n return;\n }\n\n if (e.key === 'ArrowLeft') {\n e.preventDefault();\n this.dispatchEvent(\n new CustomEvent<{ item: HelixMenuItem }>('hx-item-submenu-close', {\n bubbles: true,\n composed: true,\n detail: { item: this },\n }),\n );\n }\n }\n\n /** @internal */\n private _renderCheckedIcon() {\n return html`\n <span part=\"checked-icon\" class=\"menu-item__checked-icon\" aria-hidden=\"true\">\n <svg\n width=\"1em\"\n height=\"1em\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n </span>\n `;\n }\n\n /** @internal */\n private _renderSubmenuIcon() {\n return html`\n <span part=\"submenu-icon\" class=\"menu-item__submenu-icon\" aria-hidden=\"true\">\n <svg\n width=\"1em\"\n height=\"1em\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <polyline points=\"9 18 15 12 9 6\" />\n </svg>\n </span>\n `;\n }\n\n /** @internal */\n private _renderSpinner() {\n return html`\n <svg class=\"menu-item__spinner\" aria-hidden=\"true\" viewBox=\"0 0 24 24\" fill=\"none\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"3\" opacity=\"0.3\" />\n <path\n d=\"M12 2a10 10 0 0 1 10 10\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n />\n </svg>\n `;\n }\n\n /** @internal */\n private _getRole(): string {\n switch (this.type) {\n case 'checkbox':\n return 'menuitemcheckbox';\n case 'radio':\n return 'menuitemradio';\n default:\n return 'menuitem';\n }\n }\n\n override render() {\n const role = this._getRole();\n const hasCheckableRole = this.type === 'checkbox' || this.type === 'radio';\n const classes = {\n 'menu-item': true,\n 'menu-item--checked': this.checked,\n };\n\n return html`\n <div\n part=\"base\"\n class=${classMap(classes)}\n role=${role}\n tabindex=${this.disabled ? '-1' : String(this._rovingTabIndex)}\n aria-disabled=${this.disabled ? 'true' : nothing}\n aria-checked=${hasCheckableRole ? (this.checked ? 'true' : 'false') : nothing}\n aria-haspopup=${this._hasSubmenu ? 'menu' : nothing}\n aria-expanded=${this._hasSubmenu ? (this._submenuOpen ? 'true' : 'false') : nothing}\n aria-busy=${this.loading ? 'true' : nothing}\n @click=${this._handleClick}\n @keydown=${this._handleKeyDown}\n >\n ${this.loading ? this._renderSpinner() : nothing}\n ${hasCheckableRole ? this._renderCheckedIcon() : nothing}\n <span part=\"prefix\" class=\"menu-item__prefix\">\n <slot name=\"prefix\"></slot>\n </span>\n <span part=\"label\" class=\"menu-item__label\">\n <slot></slot>\n </span>\n <span part=\"suffix\" class=\"menu-item__suffix\">\n <slot name=\"suffix\"></slot>\n </span>\n ${this._hasSubmenu ? this._renderSubmenuIcon() : nothing}\n <slot name=\"submenu\" @slotchange=${this._handleSubmenuSlotChange}></slot>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-menu-item': HelixMenuItem;\n }\n}\n","import { css } from 'lit';\n\nexport const helixMenuDividerStyles = css`\n :host {\n display: block;\n }\n\n .menu-divider {\n height: var(--hx-border-width-thin, 1px);\n background-color: var(--hx-menu-divider-color, var(--hx-color-border-default, #d6dbd5));\n margin: var(--hx-space-1, 0.25rem) calc(-1 * var(--hx-space-1, 0.25rem));\n }\n\n /* ─── High Contrast Mode (forced-colors) ─── */\n\n @media (forced-colors: active) {\n .menu-divider {\n background-color: GrayText;\n }\n }\n`;\n","import { html } from 'lit';\nimport '../../utilities/document-token-adoption.js';\nimport { customElement } from 'lit/decorators.js';\nimport { HelixElement } from '../../base/index.js';\nimport { forcedColorsInteractive } from '../../styles/forced-colors.js';\nimport { helixMenuDividerStyles } from './hx-menu-divider.styles.js';\n\n/**\n * A visual separator for grouping items within an `hx-menu`.\n *\n * @summary Horizontal divider between menu sections.\n *\n * @tag hx-menu-divider\n *\n * @csspart base - The root separator element.\n *\n * @cssprop [--hx-menu-divider-color=var(--hx-color-neutral-200)] - Divider line color.\n */\n@customElement('hx-menu-divider')\nexport class HelixMenuDivider extends HelixElement {\n static override styles = [helixMenuDividerStyles, forcedColorsInteractive];\n\n override render() {\n return html`<div\n part=\"base\"\n class=\"menu-divider\"\n role=\"separator\"\n aria-orientation=\"horizontal\"\n ></div>`;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-menu-divider': HelixMenuDivider;\n }\n}\n"],"names":["helixMenuStyles","css","HelixMenu","HelixElement","item","items","activeIndex","i","first","last","index","target","active","_a","idx","char","match","slot","validTags","invalid","el","devWarn","detail","html","forcedColorsInteractive","__decorateClass","property","customElement","helixMenuItemStyles","HelixMenuItem","value","open","options","menu","sibling","role","hasCheckableRole","classes","classMap","nothing","state","query","helixMenuDividerStyles","HelixMenuDivider"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hx-meter-BPscsw5t.js","sources":["../../src/components/hx-meter/hx-meter.styles.ts","../../src/components/hx-meter/hx-meter.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixMeterStyles = css`\n :host {\n display: block;\n width: 100%;\n }\n\n .meter {\n display: flex;\n flex-direction: column;\n gap: var(--hx-space-2, 0.5rem);\n width: 100%;\n outline: none;\n border-radius: var(--hx-border-radius-md, 0.375rem);\n }\n\n .meter:focus-visible {\n outline: var(--hx-focus-ring-width, 2px) solid var(--hx-focus-ring-color, #0f7078);\n outline-offset: var(--hx-focus-ring-offset, 2px);\n }\n\n .meter__label {\n font-size: var(--hx-font-size-sm, 0.875rem);\n font-weight: var(--hx-font-weight-medium, 500);\n color: var(--hx-meter-label-color, var(--hx-color-neutral-700, #313e4b));\n line-height: var(--hx-line-height-normal, 1.5);\n }\n\n .meter__track {\n position: relative;\n width: 100%;\n height: var(--hx-meter-track-height, var(--hx-space-2, 0.5rem));\n background-color: var(--hx-meter-track-color, var(--hx-color-neutral-200, #d6dbd5));\n border-radius: var(--hx-meter-track-radius, var(--hx-border-radius-full, 9999px));\n overflow: hidden;\n }\n\n .meter__indicator {\n position: absolute;\n inset-block: 0;\n inset-inline-start: 0;\n height: 100%;\n width: 100%;\n border-radius: inherit;\n background-color: var(--_indicator-color);\n transform-origin: left center;\n transform: scaleX(var(--_value-ratio, 0));\n transition:\n transform var(--hx-transition-fast, 150ms ease),\n background-color var(--hx-transition-fast, 150ms ease);\n }\n\n @media (prefers-reduced-motion: reduce) {\n .meter__indicator {\n transition: none;\n }\n }\n\n /* ─── Default (no thresholds configured) ─── */\n\n :host {\n --_indicator-color: var(--hx-meter-indicator-color, var(--hx-color-primary-500, #429797));\n }\n\n /* ─── Semantic state colors ─── */\n\n :host([data-state='optimum']) {\n --_indicator-color: var(--hx-meter-color-optimum, var(--hx-color-success-500, #3b9e58));\n }\n\n :host([data-state='warning']) {\n --_indicator-color: var(--hx-meter-color-warning, var(--hx-color-warning-500, #c2711c));\n }\n\n :host([data-state='danger']) {\n --_indicator-color: var(--hx-meter-color-danger, var(--hx-color-error-500, #e5493e));\n }\n\n /* ─── State Label (WCAG 1.4.1) ─── */\n /* Visible text label rendered below the track when a semantic state is active. */\n /* Ensures the meter state is not conveyed by fill color alone. */\n /* aria-hidden=\"true\" because aria-valuetext already includes the state for AT. */\n\n .meter__state-label {\n font-size: var(--hx-font-size-xs, 0.75rem);\n font-weight: var(--hx-font-weight-medium, 500);\n line-height: var(--hx-line-height-tight, 1.25);\n font-family: var(--hx-meter-font-family, var(--hx-font-family-sans, sans-serif));\n }\n\n .meter__state-label[data-state='optimum'] {\n color: var(--hx-meter-color-optimum, var(--hx-color-success-700, #146831));\n }\n\n .meter__state-label[data-state='warning'] {\n color: var(--hx-meter-color-warning, var(--hx-color-warning-700, #804605));\n }\n\n .meter__state-label[data-state='danger'] {\n color: var(--hx-meter-color-danger, var(--hx-color-error-700, #a21312));\n }\n\n /* ─── Native meter hidden (we use custom rendering) ─── */\n\n .meter__native {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n }\n\n /* ─── Forced Colors (Windows High Contrast) ─── */\n\n @media (forced-colors: active) {\n .meter__track {\n border: 1px solid CanvasText;\n }\n\n .meter__indicator {\n forced-color-adjust: none;\n background-color: Highlight;\n }\n }\n`;\n","import { html, nothing, type PropertyValues } from 'lit';\nimport '../../utilities/document-token-adoption.js';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { HelixElement, createIdCounter } from '../../base/index.js';\nimport { helixMeterStyles } from './hx-meter.styles.js';\nimport { forcedColorsSurface } from '../../styles/forced-colors.js';\n\ntype MeterState = 'optimum' | 'warning' | 'danger' | 'default';\n\nconst _nextMeterId = createIdCounter('hx-meter');\n\n/**\n * A scalar measurement within a known range — e.g., disk usage, health score,\n * or any numeric value with defined min/max bounds. Supports low/high/optimum\n * threshold markers for semantic color feedback.\n *\n * @summary Scalar measurement gauge within a defined range.\n *\n * @tag hx-meter\n *\n * @slot label - Visible label rendered above the meter track. When using this\n * slot without the `label` attribute, the accessible name is derived from the\n * slot content via `aria-labelledby`. The `label` attribute is NOT required\n * when slot content is provided — the component detects slot content and\n * switches to `aria-labelledby` automatically.\n *\n * @csspart base - The outer wrapper element.\n * @csspart track - The unfilled track bar element.\n * @csspart indicator - The filled bar indicating the current value.\n * @csspart label - The label wrapper element.\n *\n * @cssprop [--hx-meter-track-height] - Height of the track bar.\n * @cssprop [--hx-meter-track-color] - Background color of the unfilled track.\n * @cssprop [--hx-meter-track-radius] - Border radius of the track.\n * @cssprop [--hx-meter-indicator-color] - Default filled bar color (no thresholds).\n * @cssprop [--hx-meter-color-optimum] - Color when value is in the optimum zone.\n * @cssprop [--hx-meter-color-warning] - Color when value is in a warning zone.\n * @cssprop [--hx-meter-color-danger] - Color when value is in the danger zone.\n * @cssprop [--hx-meter-label-color] - Label text color.\n * @cssprop [--hx-space-2] - Spacing token.\n * @cssprop [--hx-border-radius-md] - CSS custom property.\n * @cssprop [--hx-focus-ring-width] - Width.\n * @cssprop [--hx-focus-ring-color] - Color.\n * @cssprop [--hx-focus-ring-offset] - CSS custom property.\n * @cssprop [--hx-font-size-sm] - Font size.\n * @cssprop [--hx-font-weight-medium] - Font weight.\n * @cssprop [--hx-color-neutral-700] - Color.\n * @cssprop [--hx-line-height-normal] - Line height.\n * @cssprop [--hx-color-neutral-200] - Color.\n * @cssprop [--hx-border-radius-full] - CSS custom property.\n * @cssprop [--hx-transition-fast] - Transition timing.\n * @cssprop [--hx-color-primary-500] - Color.\n * @cssprop [--hx-color-success-500] - Color.\n * @cssprop [--hx-color-warning-500] - Color.\n * @cssprop [--hx-color-error-500] - Color.\n * @cssprop [--hx-font-size-xs] - Font size.\n * @cssprop [--hx-line-height-tight] - Line height.\n * @cssprop [--hx-meter-font-family=var(--hx-font-family-sans)] - CSS custom property.\n * @cssprop [--hx-font-family-sans] - Font family.\n * @cssprop [--hx-color-success-700] - Color.\n * @cssprop [--hx-color-warning-700] - Color.\n * @cssprop [--hx-color-error-700] - Color.\n */\n@customElement('hx-meter')\nexport class HelixMeter extends HelixElement {\n static override styles = [helixMeterStyles, forcedColorsSurface];\n\n /** @internal */\n private _uid = _nextMeterId();\n\n /**\n * Current value of the meter.\n * @attr value\n */\n @property({ type: Number, reflect: true })\n value = 0;\n\n /**\n * Minimum value of the range.\n * @attr min\n */\n @property({ type: Number, reflect: true })\n min = 0;\n\n /**\n * Maximum value of the range.\n * @attr max\n */\n @property({ type: Number, reflect: true })\n max = 100;\n\n /**\n * Threshold below which the value is considered suboptimal (lower range warning).\n * @attr low\n */\n @property({ type: Number, reflect: true })\n low?: number;\n\n /**\n * Threshold above which the value is considered suboptimal (upper range warning).\n * @attr high\n */\n @property({ type: Number, reflect: true })\n high?: number;\n\n /**\n * The optimal value within the range. Used to determine which zone is \"good\".\n * @attr optimum\n */\n @property({ type: Number, reflect: true })\n optimum?: number;\n\n /**\n * Accessible label for the meter. Used as the visible label text and as\n * the source for `aria-labelledby`. When only slot content is provided\n * (no `label` attribute), the slot content is used for the accessible name.\n * @attr label\n */\n @property({ type: String })\n label?: string;\n\n /** @internal */\n @state()\n private _hasSlotContent = false;\n\n /** @internal */\n private _clampedValue(): number {\n return Math.min(Math.max(this.value, this.min), this.max);\n }\n\n /** @internal */\n private _percentage(): number {\n const range = this.max - this.min;\n if (range === 0) return 0;\n return ((this._clampedValue() - this.min) / range) * 100;\n }\n\n /** @internal */\n private _resolveState(): MeterState {\n const v = this._clampedValue();\n const hasLow = this.low !== undefined;\n const hasHigh = this.high !== undefined;\n const hasOptimum = this.optimum !== undefined;\n\n if (!hasLow && !hasHigh && !hasOptimum) return 'default';\n\n // When hasLow/hasHigh/hasOptimum are true, the corresponding property is defined.\n // Use nullish coalescing to satisfy the type checker while preserving the runtime logic.\n const lowVal = this.low ?? 0;\n const highVal = this.high ?? this.max;\n const inLowZone = hasLow && v < lowVal;\n const inHighZone = hasHigh && v > highVal;\n const inMiddleZone = !inLowZone && !inHighZone;\n\n if (!hasOptimum) {\n if (inLowZone || inHighZone) return 'warning';\n return 'optimum';\n }\n\n const opt = this.optimum ?? this.min;\n const optimumInLow = hasLow && opt < lowVal;\n const optimumInHigh = hasHigh && opt > highVal;\n const optimumInMiddle = !optimumInLow && !optimumInHigh;\n\n if (optimumInMiddle) {\n if (inMiddleZone) return 'optimum';\n return 'warning';\n } else if (optimumInLow) {\n if (inLowZone) return 'optimum';\n if (inMiddleZone) return 'warning';\n return 'danger';\n } else {\n // optimumInHigh\n if (inHighZone) return 'optimum';\n if (inMiddleZone) return 'warning';\n return 'danger';\n }\n }\n\n /** @internal */\n private _onLabelSlotChange(e: Event) {\n const slot = e.target as HTMLSlotElement;\n this._hasSlotContent = slot.assignedNodes({ flatten: true }).length > 0;\n }\n\n override updated(changedProperties: PropertyValues<this>): void {\n super.updated(changedProperties);\n // Set data-state on host so :host([data-state]) CSS selectors work\n this.dataset['state'] = this._resolveState();\n // Set --_value-ratio for GPU-compositable scaleX() transform on indicator\n const ratio = this._percentage() / 100;\n this.style.setProperty('--_value-ratio', String(Math.max(0, Math.min(1, ratio))));\n }\n\n // ─── WCAG 1.4.1: State label map ───\n // The indicator bar color alone is insufficient for color-blind users.\n // A visible state label is rendered below the track when a semantic state\n // (optimum/warning/danger) is active, providing a non-color visual cue.\n // aria-valuetext already embeds the state for AT users.\n\n /** @internal */\n private static readonly _STATE_LABELS: Partial<Record<MeterState, string>> = {\n optimum: 'Optimum',\n warning: 'Warning',\n danger: 'Danger',\n };\n\n override render() {\n const state = this._resolveState();\n const clampedValue = this._clampedValue();\n const stateLabel = state !== 'default' ? ` — ${state}` : '';\n const ariaValuetext = `${clampedValue} of ${this.max}${stateLabel}`;\n const hasVisibleLabel = this.label !== undefined || this._hasSlotContent;\n const visibleStateLabel = HelixMeter._STATE_LABELS[state];\n\n return html`\n <div\n part=\"base\"\n class=\"meter\"\n role=\"meter\"\n tabindex=\"0\"\n aria-valuenow=${clampedValue}\n aria-valuemin=${this.min}\n aria-valuemax=${this.max}\n aria-valuetext=${ariaValuetext}\n aria-label=${ifDefined(!hasVisibleLabel ? `${clampedValue} of ${this.max}` : undefined)}\n aria-labelledby=${ifDefined(hasVisibleLabel ? `${this._uid}-label` : undefined)}\n >\n <span\n id=${`${this._uid}-label`}\n part=\"label\"\n class=\"meter__label\"\n ?hidden=${!hasVisibleLabel}\n >\n <slot name=\"label\" @slotchange=${this._onLabelSlotChange}>${this.label ?? ''}</slot>\n </span>\n <div class=\"meter__track\" part=\"track\">\n <div part=\"indicator\" class=\"meter__indicator\"></div>\n </div>\n ${visibleStateLabel\n ? html`<span class=\"meter__state-label\" data-state=${state} aria-hidden=\"true\"\n >${visibleStateLabel}</span\n >`\n : nothing}\n <meter\n class=\"meter__native\"\n value=${clampedValue}\n min=${this.min}\n max=${this.max}\n low=${ifDefined(this.low)}\n high=${ifDefined(this.high)}\n optimum=${ifDefined(this.optimum)}\n aria-hidden=\"true\"\n tabindex=\"-1\"\n ></meter>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-meter': HelixMeter;\n }\n}\n"],"names":["helixMeterStyles","css","_nextMeterId","createIdCounter","HelixMeter","HelixElement","range","v","hasLow","hasHigh","hasOptimum","lowVal","highVal","inLowZone","inHighZone","inMiddleZone","opt","optimumInLow","optimumInHigh","slot","changedProperties","ratio","state","clampedValue","stateLabel","ariaValuetext","hasVisibleLabel","visibleStateLabel","html","ifDefined","nothing","forcedColorsSurface","__decorateClass","property","customElement"],"mappings":"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"}
|