@helixui/library 3.0.0-next.65 → 3.1.0-next.66
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 +6549 -318
- package/dist/components/hx-accordion/hx-accordion.d.ts +3 -0
- package/dist/components/hx-accordion/hx-accordion.d.ts.map +1 -1
- package/dist/components/hx-action-bar/hx-action-bar.d.ts +14 -0
- package/dist/components/hx-action-bar/hx-action-bar.d.ts.map +1 -1
- package/dist/components/hx-action-bar/index.js +1 -1
- package/dist/components/hx-alert/hx-alert.d.ts +36 -0
- package/dist/components/hx-alert/hx-alert.d.ts.map +1 -1
- package/dist/components/hx-avatar/hx-avatar.d.ts +17 -0
- package/dist/components/hx-avatar/hx-avatar.d.ts.map +1 -1
- package/dist/components/hx-badge/hx-badge.d.ts +35 -0
- package/dist/components/hx-badge/hx-badge.d.ts.map +1 -1
- package/dist/components/hx-banner/hx-banner.d.ts +34 -0
- package/dist/components/hx-banner/hx-banner.d.ts.map +1 -1
- package/dist/components/hx-breadcrumb/hx-breadcrumb.d.ts +3 -0
- package/dist/components/hx-breadcrumb/hx-breadcrumb.d.ts.map +1 -1
- package/dist/components/hx-breadcrumb/index.js +1 -1
- package/dist/components/hx-button/hx-button.d.ts +42 -0
- 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 +2 -0
- package/dist/components/hx-button-group/hx-button-group.d.ts.map +1 -1
- package/dist/components/hx-card/hx-card.d.ts +28 -0
- package/dist/components/hx-card/hx-card.d.ts.map +1 -1
- package/dist/components/hx-card/index.js +1 -1
- package/dist/components/hx-carousel/hx-carousel.d.ts +25 -0
- package/dist/components/hx-carousel/hx-carousel.d.ts.map +1 -1
- package/dist/components/hx-checkbox/hx-checkbox.d.ts +31 -0
- 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/hx-checkbox-group.d.ts +14 -0
- package/dist/components/hx-checkbox-group/hx-checkbox-group.d.ts.map +1 -1
- package/dist/components/hx-checkbox-group/index.js +1 -1
- package/dist/components/hx-clinical-status/hx-clinical-status.d.ts +37 -0
- package/dist/components/hx-clinical-status/hx-clinical-status.d.ts.map +1 -1
- package/dist/components/hx-code-snippet/hx-code-snippet.d.ts +35 -0
- package/dist/components/hx-code-snippet/hx-code-snippet.d.ts.map +1 -1
- package/dist/components/hx-color-picker/hx-color-picker.d.ts +29 -0
- package/dist/components/hx-color-picker/hx-color-picker.d.ts.map +1 -1
- package/dist/components/hx-combobox/hx-combobox.d.ts +49 -0
- package/dist/components/hx-combobox/hx-combobox.d.ts.map +1 -1
- package/dist/components/hx-combobox/index.js +1 -1
- package/dist/components/hx-container/hx-container.d.ts +5 -0
- package/dist/components/hx-container/hx-container.d.ts.map +1 -1
- package/dist/components/hx-copy-button/hx-copy-button.d.ts +24 -0
- package/dist/components/hx-copy-button/hx-copy-button.d.ts.map +1 -1
- package/dist/components/hx-counter/hx-counter.d.ts +7 -0
- package/dist/components/hx-counter/hx-counter.d.ts.map +1 -1
- package/dist/components/hx-data-table/hx-data-table.d.ts +29 -0
- package/dist/components/hx-data-table/hx-data-table.d.ts.map +1 -1
- package/dist/components/hx-data-table/hx-data-table.styles.d.ts.map +1 -1
- package/dist/components/hx-data-table/index.js +1 -1
- package/dist/components/hx-date-picker/hx-date-picker.d.ts +44 -0
- package/dist/components/hx-date-picker/hx-date-picker.d.ts.map +1 -1
- package/dist/components/hx-date-picker/index.js +1 -1
- package/dist/components/hx-dialog/hx-dialog.d.ts +31 -0
- package/dist/components/hx-dialog/hx-dialog.d.ts.map +1 -1
- package/dist/components/hx-dialog/index.js +1 -1
- package/dist/components/hx-divider/hx-divider.d.ts +9 -0
- package/dist/components/hx-divider/hx-divider.d.ts.map +1 -1
- package/dist/components/hx-divider/index.js +1 -1
- package/dist/components/hx-drawer/hx-drawer.d.ts +30 -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 +6 -0
- 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/hx-field.d.ts +15 -0
- package/dist/components/hx-field/hx-field.d.ts.map +1 -1
- package/dist/components/hx-field/index.js +1 -1
- package/dist/components/hx-field-label/hx-field-label.d.ts +11 -0
- package/dist/components/hx-field-label/hx-field-label.d.ts.map +1 -1
- package/dist/components/hx-field-label/index.js +1 -1
- package/dist/components/hx-file-upload/hx-file-upload.d.ts +35 -0
- package/dist/components/hx-file-upload/hx-file-upload.d.ts.map +1 -1
- package/dist/components/hx-file-upload/index.js +1 -1
- package/dist/components/hx-grid/hx-grid.d.ts +5 -0
- package/dist/components/hx-grid/hx-grid.d.ts.map +1 -1
- package/dist/components/hx-help-text/hx-help-text.d.ts +8 -0
- package/dist/components/hx-help-text/hx-help-text.d.ts.map +1 -1
- package/dist/components/hx-help-text/index.js +1 -1
- package/dist/components/hx-icon/hx-icon.d.ts +5 -0
- package/dist/components/hx-icon/hx-icon.d.ts.map +1 -1
- package/dist/components/hx-icon-button/hx-icon-button.d.ts +27 -0
- package/dist/components/hx-icon-button/hx-icon-button.d.ts.map +1 -1
- package/dist/components/hx-icon-button/index.js +1 -1
- package/dist/components/hx-image/hx-image.d.ts +4 -0
- package/dist/components/hx-image/hx-image.d.ts.map +1 -1
- package/dist/components/hx-link/hx-link.d.ts +15 -0
- 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.d.ts +3 -0
- package/dist/components/hx-list/hx-list.d.ts.map +1 -1
- package/dist/components/hx-menu/hx-menu.d.ts +6 -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/hx-meter.d.ts +23 -0
- package/dist/components/hx-meter/hx-meter.d.ts.map +1 -1
- package/dist/components/hx-nav/hx-nav.d.ts +29 -0
- package/dist/components/hx-nav/hx-nav.d.ts.map +1 -1
- package/dist/components/hx-number-input/hx-number-input.d.ts +34 -0
- 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/hx-overflow-menu.d.ts +26 -0
- 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-pagination/hx-pagination.d.ts +21 -0
- package/dist/components/hx-pagination/hx-pagination.d.ts.map +1 -1
- package/dist/components/hx-pagination/index.js +1 -1
- package/dist/components/hx-patient-banner/hx-patient-banner.d.ts +23 -0
- package/dist/components/hx-patient-banner/hx-patient-banner.d.ts.map +1 -1
- package/dist/components/hx-phi-field/hx-phi-field.d.ts +14 -0
- package/dist/components/hx-phi-field/hx-phi-field.d.ts.map +1 -1
- package/dist/components/hx-phi-field/index.js +1 -1
- package/dist/components/hx-popover/hx-popover.d.ts +15 -0
- package/dist/components/hx-popover/hx-popover.d.ts.map +1 -1
- package/dist/components/hx-popover/index.js +1 -1
- package/dist/components/hx-popup/hx-popup.d.ts +1 -0
- package/dist/components/hx-popup/hx-popup.d.ts.map +1 -1
- package/dist/components/hx-progress-bar/hx-progress-bar.d.ts +17 -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-progress-ring/hx-progress-ring.d.ts +15 -0
- package/dist/components/hx-progress-ring/hx-progress-ring.d.ts.map +1 -1
- package/dist/components/hx-prose/hx-prose.d.ts +2 -0
- package/dist/components/hx-prose/hx-prose.d.ts.map +1 -1
- package/dist/components/hx-radio-group/hx-radio-group.d.ts +14 -0
- package/dist/components/hx-radio-group/hx-radio-group.d.ts.map +1 -1
- package/dist/components/hx-radio-group/index.js +1 -1
- package/dist/components/hx-rating/hx-rating.d.ts +13 -0
- package/dist/components/hx-rating/hx-rating.d.ts.map +1 -1
- package/dist/components/hx-select/hx-select.d.ts +43 -0
- package/dist/components/hx-select/hx-select.d.ts.map +1 -1
- package/dist/components/hx-select/hx-select.styles.d.ts.map +1 -1
- package/dist/components/hx-select/index.js +1 -1
- package/dist/components/hx-side-nav/hx-nav-item.styles.d.ts.map +1 -1
- package/dist/components/hx-side-nav/hx-side-nav.d.ts +19 -0
- package/dist/components/hx-side-nav/hx-side-nav.d.ts.map +1 -1
- package/dist/components/hx-side-nav/index.js +1 -1
- package/dist/components/hx-skeleton/hx-skeleton.d.ts +5 -0
- package/dist/components/hx-skeleton/hx-skeleton.d.ts.map +1 -1
- package/dist/components/hx-slider/hx-slider.d.ts +38 -0
- package/dist/components/hx-slider/hx-slider.d.ts.map +1 -1
- package/dist/components/hx-slider/index.js +1 -1
- package/dist/components/hx-spinner/hx-spinner.d.ts +10 -0
- package/dist/components/hx-spinner/hx-spinner.d.ts.map +1 -1
- package/dist/components/hx-split-button/hx-split-button.d.ts +39 -0
- 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-split-panel/hx-split-panel.d.ts +12 -0
- package/dist/components/hx-split-panel/hx-split-panel.d.ts.map +1 -1
- package/dist/components/hx-split-panel/index.js +1 -1
- package/dist/components/hx-stack/hx-stack.d.ts +5 -0
- package/dist/components/hx-stack/hx-stack.d.ts.map +1 -1
- package/dist/components/hx-stat/hx-stat.d.ts +24 -0
- package/dist/components/hx-stat/hx-stat.d.ts.map +1 -1
- package/dist/components/hx-status-indicator/hx-status-indicator.d.ts +13 -0
- package/dist/components/hx-status-indicator/hx-status-indicator.d.ts.map +1 -1
- package/dist/components/hx-steps/hx-steps.d.ts +15 -0
- package/dist/components/hx-steps/hx-steps.d.ts.map +1 -1
- package/dist/components/hx-structured-list/hx-structured-list.d.ts +7 -0
- package/dist/components/hx-structured-list/hx-structured-list.d.ts.map +1 -1
- package/dist/components/hx-switch/hx-switch.d.ts +42 -0
- package/dist/components/hx-switch/hx-switch.d.ts.map +1 -1
- package/dist/components/hx-switch/index.js +1 -1
- package/dist/components/hx-table/hx-table.d.ts +14 -0
- package/dist/components/hx-table/hx-table.d.ts.map +1 -1
- package/dist/components/hx-tabs/hx-tabs.d.ts +4 -0
- package/dist/components/hx-tabs/hx-tabs.d.ts.map +1 -1
- package/dist/components/hx-tag/hx-tag.d.ts +36 -0
- package/dist/components/hx-tag/hx-tag.d.ts.map +1 -1
- package/dist/components/hx-text/hx-text.d.ts +22 -0
- package/dist/components/hx-text/hx-text.d.ts.map +1 -1
- package/dist/components/hx-text-input/hx-text-input.d.ts +30 -0
- package/dist/components/hx-text-input/hx-text-input.d.ts.map +1 -1
- package/dist/components/hx-text-input/index.js +1 -1
- package/dist/components/hx-textarea/hx-textarea.d.ts +27 -0
- 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/hx-theme.d.ts +3 -0
- package/dist/components/hx-theme/hx-theme.d.ts.map +1 -1
- package/dist/components/hx-theme/index.js +1 -1
- package/dist/components/hx-time-picker/hx-time-picker.d.ts +32 -0
- package/dist/components/hx-time-picker/hx-time-picker.d.ts.map +1 -1
- package/dist/components/hx-time-picker/index.js +1 -1
- package/dist/components/hx-toast/hx-toast.d.ts +24 -0
- package/dist/components/hx-toast/hx-toast.d.ts.map +1 -1
- package/dist/components/hx-toggle-button/hx-toggle-button.d.ts +35 -0
- package/dist/components/hx-toggle-button/hx-toggle-button.d.ts.map +1 -1
- package/dist/components/hx-toggle-button/hx-toggle-button.styles.d.ts.map +1 -1
- package/dist/components/hx-toggle-button/index.js +1 -1
- package/dist/components/hx-tooltip/hx-tooltip.d.ts +13 -0
- package/dist/components/hx-tooltip/hx-tooltip.d.ts.map +1 -1
- package/dist/components/hx-tooltip/index.js +1 -1
- package/dist/components/hx-top-nav/hx-top-nav.d.ts +21 -0
- package/dist/components/hx-top-nav/hx-top-nav.d.ts.map +1 -1
- package/dist/components/hx-top-nav/index.js +1 -1
- package/dist/components/hx-tree-view/hx-tree-view.d.ts +6 -0
- package/dist/components/hx-tree-view/hx-tree-view.d.ts.map +1 -1
- package/dist/css/helix-all.css +263 -253
- package/dist/css/helix-core.css +26 -26
- package/dist/css/helix-data.css +8 -7
- package/dist/css/helix-feedback.css +2 -2
- package/dist/css/helix-forms.css +137 -131
- package/dist/css/helix-layout.css +3 -3
- package/dist/css/helix-navigation.css +35 -35
- package/dist/css/helix-overlay.css +32 -29
- package/dist/css/helix-tokens.css +12 -0
- package/dist/css/helix-utility.css +18 -18
- package/dist/css/hx-action-bar.css +3 -3
- package/dist/css/hx-button.css +10 -10
- package/dist/css/hx-card.css +6 -6
- package/dist/css/hx-checkbox-group.css +2 -2
- package/dist/css/hx-checkbox.css +5 -5
- package/dist/css/hx-combobox.css +13 -13
- package/dist/css/hx-data-table.css +8 -7
- package/dist/css/hx-date-picker.css +20 -20
- package/dist/css/hx-dialog.css +10 -10
- package/dist/css/hx-divider.css +2 -2
- package/dist/css/hx-drawer.css +12 -9
- package/dist/css/hx-dropdown.css +2 -2
- package/dist/css/hx-field-label.css +2 -2
- package/dist/css/hx-field.css +2 -2
- package/dist/css/hx-file-upload.css +11 -11
- package/dist/css/hx-help-text.css +2 -2
- package/dist/css/hx-icon-button.css +6 -6
- package/dist/css/hx-link.css +2 -2
- package/dist/css/hx-menu.css +2 -2
- package/dist/css/hx-number-input.css +12 -12
- package/dist/css/hx-overflow-menu.css +7 -7
- package/dist/css/hx-pagination.css +10 -10
- package/dist/css/hx-phi-field.css +2 -2
- package/dist/css/hx-popover.css +5 -5
- package/dist/css/hx-progress-bar.css +2 -2
- package/dist/css/hx-radio-group.css +2 -2
- package/dist/css/hx-select.css +11 -8
- package/dist/css/hx-side-nav.css +9 -9
- package/dist/css/hx-slider.css +9 -9
- package/dist/css/hx-split-button.css +15 -15
- package/dist/css/hx-split-panel.css +3 -3
- package/dist/css/hx-switch.css +4 -4
- package/dist/css/hx-text-input.css +7 -7
- package/dist/css/hx-textarea.css +7 -7
- package/dist/css/hx-time-picker.css +11 -11
- package/dist/css/hx-toggle-button.css +17 -14
- package/dist/css/hx-tooltip.css +3 -3
- package/dist/css/hx-top-nav.css +7 -7
- package/dist/css/index.css +1 -1
- package/dist/css/manifest.json +162 -163
- package/dist/index.js +40 -40
- package/dist/shared/hx-accordion-Wt52OOZD.js.map +1 -1
- package/dist/shared/{hx-action-bar-BKMADbHj.js → hx-action-bar-6UzmViHI.js} +4 -4
- package/dist/shared/hx-action-bar-6UzmViHI.js.map +1 -0
- package/dist/shared/hx-alert-D7n94HwI.js.map +1 -1
- package/dist/shared/hx-avatar-iLYzu8MJ.js.map +1 -1
- package/dist/shared/hx-badge-CVCmMPyW.js.map +1 -1
- package/dist/shared/hx-banner-C_He7Tr4.js.map +1 -1
- package/dist/shared/{hx-breadcrumb-item-CldCwD1d.js → hx-breadcrumb-item-BgG5RcmA.js} +3 -3
- package/dist/shared/hx-breadcrumb-item-BgG5RcmA.js.map +1 -0
- package/dist/shared/{hx-button-Ddl-T6T-.js → hx-button-CQZswjtQ.js} +15 -15
- package/dist/shared/hx-button-CQZswjtQ.js.map +1 -0
- package/dist/shared/hx-button-group-BJOGWoMa.js.map +1 -1
- package/dist/shared/{hx-card-ycveujjL.js → hx-card-Dy_FuLfS.js} +23 -23
- package/dist/shared/hx-card-Dy_FuLfS.js.map +1 -0
- package/dist/shared/hx-carousel-item-D_dCv61-.js.map +1 -1
- package/dist/shared/{hx-checkbox-DkkoWoye.js → hx-checkbox-ZKjOF7_3.js} +17 -17
- package/dist/shared/{hx-checkbox-DkkoWoye.js.map → hx-checkbox-ZKjOF7_3.js.map} +1 -1
- package/dist/shared/{hx-checkbox-group-C3poJ-Zw.js → hx-checkbox-group-XjOBHLiP.js} +3 -3
- package/dist/shared/hx-checkbox-group-XjOBHLiP.js.map +1 -0
- package/dist/shared/hx-clinical-status-BS5lcddT.js.map +1 -1
- package/dist/shared/hx-code-snippet-B7wUKzyb.js.map +1 -1
- package/dist/shared/hx-color-picker-DBaKTVLr.js.map +1 -1
- package/dist/shared/{hx-combobox-BmgYT7Ar.js → hx-combobox-DLwnvHVd.js} +17 -17
- package/dist/shared/hx-combobox-DLwnvHVd.js.map +1 -0
- package/dist/shared/hx-container-DVI7sxfX.js.map +1 -1
- package/dist/shared/hx-copy-button-8deNUdwP.js.map +1 -1
- package/dist/shared/hx-counter-CKfl_g8K.js.map +1 -1
- package/dist/shared/{hx-data-table-B6h0RPn0.js → hx-data-table-CnLxo9PH.js} +77 -76
- package/dist/shared/hx-data-table-CnLxo9PH.js.map +1 -0
- package/dist/shared/{hx-date-picker-Dq2Nb68_.js → hx-date-picker-D7H7CsVH.js} +21 -21
- package/dist/shared/hx-date-picker-D7H7CsVH.js.map +1 -0
- package/dist/shared/{hx-dialog-CvIlY0Tc.js → hx-dialog-BW-jetzN.js} +33 -33
- package/dist/shared/hx-dialog-BW-jetzN.js.map +1 -0
- package/dist/shared/{hx-divider-DwpOrzMW.js → hx-divider-CvyUVcp-.js} +13 -13
- package/dist/shared/hx-divider-CvyUVcp-.js.map +1 -0
- package/dist/shared/{hx-drawer-Cx2ZJhBe.js → hx-drawer-BT52I4tk.js} +13 -10
- package/dist/shared/hx-drawer-BT52I4tk.js.map +1 -0
- package/dist/shared/{hx-dropdown-BjDrPUq5.js → hx-dropdown-BpVpL6Dz.js} +3 -3
- package/dist/shared/{hx-dropdown-BjDrPUq5.js.map → hx-dropdown-BpVpL6Dz.js.map} +1 -1
- package/dist/shared/{hx-field-Dp3qQMut.js → hx-field-BX4zE3z5.js} +7 -7
- package/dist/shared/hx-field-BX4zE3z5.js.map +1 -0
- package/dist/shared/{hx-field-label-BC8QViXv.js → hx-field-label-DtJzb1r3.js} +8 -8
- package/dist/shared/hx-field-label-DtJzb1r3.js.map +1 -0
- package/dist/shared/{hx-file-upload-B6Yl1u0i.js → hx-file-upload-BNuepoGn.js} +34 -34
- package/dist/shared/hx-file-upload-BNuepoGn.js.map +1 -0
- package/dist/shared/hx-grid-CXZf3jeK.js.map +1 -1
- package/dist/shared/{hx-help-text-D7eytSim.js → hx-help-text-Br3igJv5.js} +7 -7
- package/dist/shared/hx-help-text-Br3igJv5.js.map +1 -0
- package/dist/shared/hx-icon-CcyDPDYY.js.map +1 -1
- package/dist/shared/{hx-icon-button-BHneqPCU.js → hx-icon-button-CqXH5Wwb.js} +7 -7
- package/dist/shared/hx-icon-button-CqXH5Wwb.js.map +1 -0
- package/dist/shared/hx-image-2gt14zZd.js.map +1 -1
- package/dist/shared/{hx-link-BESrWK8M.js → hx-link-Bem4Gn68.js} +8 -8
- package/dist/shared/hx-link-Bem4Gn68.js.map +1 -0
- package/dist/shared/hx-list-_9qVv02L.js.map +1 -1
- package/dist/shared/{hx-menu-divider-Ck-9Os1t.js → hx-menu-divider-DsHWyPHy.js} +37 -37
- package/dist/shared/hx-menu-divider-DsHWyPHy.js.map +1 -0
- package/dist/shared/hx-meter-TbROk-dw.js.map +1 -1
- package/dist/shared/hx-nav-BcYDmjf7.js.map +1 -1
- package/dist/shared/{hx-nav-item-pqPasRUm.js → hx-nav-item-BTMMQv6c.js} +34 -30
- package/dist/shared/hx-nav-item-BTMMQv6c.js.map +1 -0
- package/dist/shared/{hx-number-input-mOIZ3-46.js → hx-number-input-l6jeaGWW.js} +71 -71
- package/dist/shared/hx-number-input-l6jeaGWW.js.map +1 -0
- package/dist/shared/{hx-overflow-menu-Dprb9lnT.js → hx-overflow-menu-DJ4qpgmi.js} +12 -12
- package/dist/shared/hx-overflow-menu-DJ4qpgmi.js.map +1 -0
- package/dist/shared/{hx-pagination-AguTQjYC.js → hx-pagination-5FeVFIve.js} +64 -64
- package/dist/shared/hx-pagination-5FeVFIve.js.map +1 -0
- package/dist/shared/hx-patient-banner-uE6gqLpT.js.map +1 -1
- package/dist/shared/{hx-phi-field-BC_XowhC.js → hx-phi-field-DxeWcRm9.js} +3 -3
- package/dist/shared/hx-phi-field-DxeWcRm9.js.map +1 -0
- package/dist/shared/{hx-popover-B2_203ct.js → hx-popover-C05QcD9m.js} +6 -6
- package/dist/shared/hx-popover-C05QcD9m.js.map +1 -0
- package/dist/shared/hx-popup-DZXpsJ1R.js.map +1 -1
- package/dist/shared/{hx-progress-bar-KjEkEJLy.js → hx-progress-bar-CJdwAeDg.js} +11 -11
- package/dist/shared/hx-progress-bar-CJdwAeDg.js.map +1 -0
- package/dist/shared/hx-progress-ring-3zMwvrwD.js.map +1 -1
- package/dist/shared/hx-prose-BCtK7YL6.js.map +1 -1
- package/dist/shared/{hx-radio-BBC5qZgE.js → hx-radio-QHrhL908.js} +11 -11
- package/dist/shared/hx-radio-QHrhL908.js.map +1 -0
- package/dist/shared/hx-rating-C3E3ENJb.js.map +1 -1
- package/dist/shared/{hx-select-CixTo7jp.js → hx-select-BuMvRDkY.js} +47 -44
- package/dist/shared/hx-select-BuMvRDkY.js.map +1 -0
- package/dist/shared/hx-skeleton-LxkI0pxr.js.map +1 -1
- package/dist/shared/{hx-slider-DFHuzF3N.js → hx-slider-wcF_oyNJ.js} +41 -41
- package/dist/shared/hx-slider-wcF_oyNJ.js.map +1 -0
- package/dist/shared/hx-spinner-BKjuCdZB.js.map +1 -1
- package/dist/shared/{hx-split-button-CGcJMmCG.js → hx-split-button-CEkQqbF9.js} +32 -32
- package/dist/shared/hx-split-button-CEkQqbF9.js.map +1 -0
- package/dist/shared/{hx-split-panel-C-1R10Mc.js → hx-split-panel-BymHlV5e.js} +4 -4
- package/dist/shared/hx-split-panel-BymHlV5e.js.map +1 -0
- package/dist/shared/hx-stack-DGfcOfWJ.js.map +1 -1
- package/dist/shared/hx-stat-BTpykQAt.js.map +1 -1
- package/dist/shared/hx-status-indicator-X2QEWNFt.js.map +1 -1
- package/dist/shared/hx-step-CRNQlmSo.js.map +1 -1
- package/dist/shared/hx-structured-list-CqNbaEXg.js.map +1 -1
- package/dist/shared/{hx-switch-DqOD9JR7.js → hx-switch-CbunfMHW.js} +5 -5
- package/dist/shared/hx-switch-CbunfMHW.js.map +1 -0
- package/dist/shared/hx-tab-panel-BIzKfW5i.js.map +1 -1
- package/dist/shared/hx-tag-CgnrNnte.js.map +1 -1
- package/dist/shared/hx-td-Bra35cH4.js.map +1 -1
- package/dist/shared/hx-text-DMC2CPlL.js.map +1 -1
- package/dist/shared/{hx-text-input--q0GH78x.js → hx-text-input-eSPVURd5.js} +8 -8
- package/dist/shared/hx-text-input-eSPVURd5.js.map +1 -0
- package/dist/shared/{hx-textarea-CK621vSL.js → hx-textarea-C4DjRmo4.js} +12 -12
- package/dist/shared/hx-textarea-C4DjRmo4.js.map +1 -0
- package/dist/shared/{hx-theme-DfEy-SJA.js → hx-theme-DP4oPU1i.js} +44 -35
- package/dist/shared/hx-theme-DP4oPU1i.js.map +1 -0
- package/dist/shared/{hx-time-picker-tPUfgElQ.js → hx-time-picker-BtbHX7A4.js} +28 -28
- package/dist/shared/hx-time-picker-BtbHX7A4.js.map +1 -0
- package/dist/shared/{hx-toggle-button-L-uBJr-a.js → hx-toggle-button-FOvw-ebx.js} +26 -23
- package/dist/shared/hx-toggle-button-FOvw-ebx.js.map +1 -0
- package/dist/shared/{hx-tooltip-B_zfKvwc.js → hx-tooltip-BoZi2crX.js} +4 -4
- package/dist/shared/hx-tooltip-BoZi2crX.js.map +1 -0
- package/dist/shared/{hx-top-nav-CATbRvIv.js → hx-top-nav-Cd9zvv1B.js} +20 -20
- package/dist/shared/hx-top-nav-Cd9zvv1B.js.map +1 -0
- package/dist/shared/hx-tree-item-A45WCiBu.js.map +1 -1
- package/dist/shared/toast-factory-BPPnG3mM.js.map +1 -1
- package/figma-inventory.json +8526 -511
- package/package.json +2 -2
- package/dist/shared/hx-action-bar-BKMADbHj.js.map +0 -1
- package/dist/shared/hx-breadcrumb-item-CldCwD1d.js.map +0 -1
- package/dist/shared/hx-button-Ddl-T6T-.js.map +0 -1
- package/dist/shared/hx-card-ycveujjL.js.map +0 -1
- package/dist/shared/hx-checkbox-group-C3poJ-Zw.js.map +0 -1
- package/dist/shared/hx-combobox-BmgYT7Ar.js.map +0 -1
- package/dist/shared/hx-data-table-B6h0RPn0.js.map +0 -1
- package/dist/shared/hx-date-picker-Dq2Nb68_.js.map +0 -1
- package/dist/shared/hx-dialog-CvIlY0Tc.js.map +0 -1
- package/dist/shared/hx-divider-DwpOrzMW.js.map +0 -1
- package/dist/shared/hx-drawer-Cx2ZJhBe.js.map +0 -1
- package/dist/shared/hx-field-Dp3qQMut.js.map +0 -1
- package/dist/shared/hx-field-label-BC8QViXv.js.map +0 -1
- package/dist/shared/hx-file-upload-B6Yl1u0i.js.map +0 -1
- package/dist/shared/hx-help-text-D7eytSim.js.map +0 -1
- package/dist/shared/hx-icon-button-BHneqPCU.js.map +0 -1
- package/dist/shared/hx-link-BESrWK8M.js.map +0 -1
- package/dist/shared/hx-menu-divider-Ck-9Os1t.js.map +0 -1
- package/dist/shared/hx-nav-item-pqPasRUm.js.map +0 -1
- package/dist/shared/hx-number-input-mOIZ3-46.js.map +0 -1
- package/dist/shared/hx-overflow-menu-Dprb9lnT.js.map +0 -1
- package/dist/shared/hx-pagination-AguTQjYC.js.map +0 -1
- package/dist/shared/hx-phi-field-BC_XowhC.js.map +0 -1
- package/dist/shared/hx-popover-B2_203ct.js.map +0 -1
- package/dist/shared/hx-progress-bar-KjEkEJLy.js.map +0 -1
- package/dist/shared/hx-radio-BBC5qZgE.js.map +0 -1
- package/dist/shared/hx-select-CixTo7jp.js.map +0 -1
- package/dist/shared/hx-slider-DFHuzF3N.js.map +0 -1
- package/dist/shared/hx-split-button-CGcJMmCG.js.map +0 -1
- package/dist/shared/hx-split-panel-C-1R10Mc.js.map +0 -1
- package/dist/shared/hx-switch-DqOD9JR7.js.map +0 -1
- package/dist/shared/hx-text-input--q0GH78x.js.map +0 -1
- package/dist/shared/hx-textarea-CK621vSL.js.map +0 -1
- package/dist/shared/hx-theme-DfEy-SJA.js.map +0 -1
- package/dist/shared/hx-time-picker-tPUfgElQ.js.map +0 -1
- package/dist/shared/hx-toggle-button-L-uBJr-a.js.map +0 -1
- package/dist/shared/hx-tooltip-B_zfKvwc.js.map +0 -1
- package/dist/shared/hx-top-nav-CATbRvIv.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hx-overflow-menu-DJ4qpgmi.js","sources":["../../src/components/hx-overflow-menu/hx-overflow-menu.styles.ts","../../src/components/hx-overflow-menu/hx-overflow-menu.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixOverflowMenuStyles = 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 /* ─── Trigger Button ─── */\n\n .trigger {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border: var(--hx-border-width-thin, 1px) solid transparent;\n border-radius: var(--hx-border-radius-md, 0.375rem);\n background-color: transparent;\n color: var(--hx-overflow-menu-button-color, var(--hx-color-text-secondary, #475569));\n cursor: pointer;\n transition:\n background-color var(--hx-transition-fast, 150ms ease),\n color var(--hx-transition-fast, 150ms ease);\n flex-shrink: 0;\n padding: 0;\n line-height: 1;\n }\n\n .trigger:focus-visible {\n outline: var(--hx-focus-ring-width, 2px) solid\n var(\n --hx-overflow-menu-focus-ring-color,\n var(--hx-focus-ring-color, var(--hx-color-primary-500))\n );\n outline-offset: var(--hx-focus-ring-offset, 2px);\n }\n\n .trigger:hover:not([disabled]) {\n background-color: var(--hx-color-surface-sunken, #f1f5f9);\n }\n\n .trigger--open {\n background-color: var(--hx-color-surface-sunken, #f1f5f9);\n }\n\n /* ─── Size Variants ─── */\n\n .trigger--sm {\n width: var(--hx-size-8, 2rem);\n height: var(--hx-size-8, 2rem);\n min-width: var(--hx-size-touch-target, 2.75rem);\n min-height: var(--hx-size-touch-target, 2.75rem);\n font-size: var(--hx-font-size-sm, 0.875rem);\n }\n\n .trigger--md {\n width: var(--hx-size-10, 2.5rem);\n height: var(--hx-size-10, 2.5rem);\n min-width: var(--hx-size-touch-target, 2.75rem);\n min-height: var(--hx-size-touch-target, 2.75rem);\n font-size: var(--hx-font-size-md, 1rem);\n }\n\n .trigger--lg {\n width: var(--hx-size-12, 3rem);\n height: var(--hx-size-12, 3rem);\n font-size: var(--hx-font-size-lg, 1.125rem);\n }\n\n /* ─── Panel ─── */\n\n .panel {\n position: fixed;\n z-index: var(--hx-overflow-menu-panel-z-index, 1000);\n min-width: var(--hx-overflow-menu-panel-min-width, 160px);\n background: var(--hx-overflow-menu-panel-bg, var(--hx-color-surface-default, #ffffff));\n border: var(--hx-overflow-menu-panel-border, 1px solid var(--hx-color-border-default, #e2e8f0));\n border-radius: var(\n --hx-overflow-menu-panel-border-radius,\n var(--hx-border-radius-md, 0.375rem)\n );\n box-shadow: var(\n --hx-overflow-menu-panel-shadow,\n 0 4px 16px var(--hx-overlay-black-12, rgba(0, 0, 0, 0.12))\n );\n padding: var(--hx-space-1, 0.25rem) 0;\n outline: none;\n }\n\n /* ─── Slot: menu items ─── */\n\n ::slotted([role='menuitem']),\n ::slotted([role='menuitemcheckbox']),\n ::slotted([role='menuitemradio']) {\n display: block;\n width: 100%;\n padding: var(--hx-space-2, 0.5rem) var(--hx-space-3, 0.75rem);\n background: none;\n border: none;\n text-align: start;\n font-size: var(--hx-font-size-sm, 0.875rem);\n color: var(--hx-color-text-primary, #0f172a);\n cursor: pointer;\n white-space: nowrap;\n box-sizing: border-box;\n }\n\n ::slotted([role='menuitem']:hover),\n ::slotted([role='menuitemcheckbox']:hover),\n ::slotted([role='menuitemradio']:hover) {\n background-color: var(--hx-color-surface-raised, #f8fafc);\n }\n\n ::slotted([role='menuitem']:focus-visible),\n ::slotted([role='menuitemcheckbox']:focus-visible),\n ::slotted([role='menuitemradio']:focus-visible) {\n outline: var(--hx-focus-ring-width, 2px) solid\n var(\n --hx-overflow-menu-focus-ring-color,\n var(--hx-focus-ring-color, var(--hx-color-primary-500))\n );\n outline-offset: 0;\n }\n\n /* ─── Reduced Motion ─── */\n\n @media (prefers-reduced-motion: reduce) {\n .trigger {\n transition: none;\n }\n }\n\n /* ─── High Contrast Mode (forced-colors) ─── */\n\n @media (forced-colors: active) {\n .trigger {\n forced-color-adjust: none;\n background-color: ButtonFace;\n color: ButtonText;\n border: 2px solid ButtonText;\n }\n\n .trigger:focus-visible {\n outline: 3px solid Highlight;\n outline-offset: 2px;\n }\n\n .trigger[disabled] {\n color: GrayText;\n border-color: GrayText;\n opacity: 1;\n }\n\n :host([disabled]) {\n opacity: 1;\n }\n\n .panel {\n background-color: Canvas;\n border: 2px solid CanvasText;\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';\n\nimport { HelixElement, createIdCounter } from '../../base/index.js';\nimport { helixOverflowMenuStyles } from './hx-overflow-menu.styles.js';\n\nconst _nextOverflowMenuId = createIdCounter('hx-overflow-menu');\n\n/**\n * An overflow menu (kebab/meatball menu) that reveals hidden actions via a\n * floating panel. Composed from a trigger button and a slotted menu panel.\n *\n * @summary \"...\" or kebab icon button that reveals hidden actions.\n *\n * @tag hx-overflow-menu\n *\n * @slot - Menu items (e.g. `<button role=\"menuitem\">` or `<hx-menu-item>` elements).\n *\n * @fires {CustomEvent<{value: string}>} hx-select - Dispatched when a menu item is selected.\n * @fires {CustomEvent<void>} hx-show - Dispatched when the panel opens.\n * @fires {CustomEvent<void>} hx-hide - Dispatched when the panel closes.\n *\n * @csspart button - The trigger icon button element.\n * @csspart trigger - Alias for button — the trigger icon button element.\n * @csspart panel - The floating menu panel container.\n * @csspart menu - Alias for panel — the floating menu panel container.\n *\n * @cssprop [--hx-overflow-menu-panel-bg=var(--hx-color-neutral-0,#fff)] - Panel background color.\n * @cssprop [--hx-overflow-menu-panel-border=1px solid var(--hx-color-neutral-200,#e5e7eb)] - Panel border.\n * @cssprop [--hx-overflow-menu-panel-border-radius=var(--hx-border-radius-md)] - Panel border radius.\n * @cssprop [--hx-overflow-menu-panel-shadow=0 4px 16px rgba(0,0,0,0.12)] - Panel box shadow.\n * @cssprop [--hx-overflow-menu-panel-min-width=160px] - Minimum panel width.\n * @cssprop [--hx-overflow-menu-panel-z-index=1000] - Panel z-index.\n * @cssprop [--hx-overflow-menu-button-color=var(--hx-color-neutral-600)] - Trigger icon color.\n *\n * @example\n * ```html\n * <hx-overflow-menu>\n * <button role=\"menuitem\">Edit</button>\n * <button role=\"menuitem\">Delete</button>\n * </hx-overflow-menu>\n * ```\n * @cssprop [--hx-opacity-disabled] - Opacity.\n * @cssprop [--hx-border-width-thin] - Width.\n * @cssprop [--hx-border-radius-md] - CSS custom property.\n * @cssprop [--hx-color-neutral-600] - Color.\n * @cssprop [--hx-transition-fast] - Transition timing.\n * @cssprop [--hx-focus-ring-width] - Width.\n * @cssprop [--hx-overflow-menu-focus-ring-color] - Color.\n * @cssprop [--hx-focus-ring-color] - Color.\n * @cssprop [--hx-color-primary-500] - Color.\n * @cssprop [--hx-focus-ring-offset] - CSS custom property.\n * @cssprop [--hx-color-neutral-100] - Color.\n * @cssprop [--hx-size-8] - Size token.\n * @cssprop [--hx-size-touch-target] - Size token.\n * @cssprop [--hx-font-size-sm] - Font size.\n * @cssprop [--hx-size-10] - Size token.\n * @cssprop [--hx-font-size-md] - Font size.\n * @cssprop [--hx-size-12] - Size token.\n * @cssprop [--hx-font-size-lg] - Font size.\n * @cssprop [--hx-color-neutral-0] - Color.\n * @cssprop [--hx-color-neutral-200] - Color.\n * @cssprop [--hx-overlay-black-12] - Overlay color.\n * @cssprop [--hx-space-1] - Spacing token.\n * @cssprop [--hx-space-2] - Spacing token.\n * @cssprop [--hx-space-3] - Spacing token.\n * @cssprop [--hx-color-neutral-900] - Color.\n * @cssprop [--hx-color-neutral-50] - Color.\n */\n@customElement('hx-overflow-menu')\nexport class HelixOverflowMenu extends HelixElement {\n static override styles = [helixOverflowMenuStyles];\n\n /**\n * Preferred placement of the floating panel relative to the trigger.\n * @attr placement\n */\n @property({ type: String, reflect: true })\n placement:\n | 'top'\n | 'top-start'\n | 'top-end'\n | 'bottom'\n | 'bottom-start'\n | 'bottom-end'\n | 'left'\n | 'left-start'\n | 'left-end'\n | 'right'\n | 'right-start'\n | 'right-end' = 'bottom-end';\n\n /**\n * Size of the trigger 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 trigger button is disabled.\n * @attr disabled\n */\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /**\n * Icon orientation: vertical (kebab ⋮) or horizontal (meatball ···).\n * @attr icon\n */\n @property({ type: String, reflect: true })\n icon: 'vertical' | 'horizontal' = 'vertical';\n\n /**\n * Accessible label for the trigger button.\n * @attr label\n */\n @property({ type: String, reflect: true })\n label = 'More actions';\n\n /**\n * Accessible label for the menu panel. Reflected as `label-menu`.\n * @attr label-menu\n */\n @property({ type: String, reflect: true, attribute: 'label-menu' })\n labelMenu = 'Actions';\n\n /**\n * Tracks whether the overflow menu panel is currently open and visible.\n * @internal\n */\n @state() private _open = false;\n\n /**\n * Unique ID for the floating panel element, used to wire aria-controls on the trigger button.\n * @internal\n */\n private readonly _panelId = `${_nextOverflowMenuId()}-panel`;\n\n /** @internal */\n @query('[part~=\"button\"]') private _buttonEl!: HTMLButtonElement | null;\n\n /** @internal */\n @query('[part~=\"panel\"]') private _panelEl!: HTMLElement | null;\n\n // ─── Lifecycle ───\n\n override connectedCallback(): void {\n super.connectedCallback();\n document.addEventListener('click', this._handleDocumentClick, true);\n this.addEventListener('keydown', this._handleKeydown);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n document.removeEventListener('click', this._handleDocumentClick, true);\n this.removeEventListener('keydown', this._handleKeydown);\n }\n\n // ─── Open / Close ───\n\n /** @internal */\n private async _show(): Promise<void> {\n if (this._open || this.disabled) return;\n this._open = true;\n await this.updateComplete;\n await this._updatePosition();\n this._focusFirstItem();\n this.dispatchEvent(new CustomEvent<void>('hx-show', { bubbles: true, composed: true }));\n }\n\n /** @internal */\n private _hide(): void {\n if (!this._open) return;\n this._open = false;\n this.dispatchEvent(new CustomEvent<void>('hx-hide', { bubbles: true, composed: true }));\n }\n\n /** @internal */\n private _toggle(): void {\n if (this._open) {\n this._hide();\n } else {\n void this._show();\n }\n }\n\n // ─── Positioning (Floating UI) ───\n\n /** @internal */\n private async _updatePosition(): Promise<void> {\n const trigger = this._buttonEl as HTMLElement | null;\n const panel = this._panelEl;\n if (!trigger || !panel) return;\n\n const { computePosition, flip, shift, offset } = await import('@floating-ui/dom');\n const { x, y } = await computePosition(trigger, panel, {\n placement: this.placement,\n strategy: 'fixed',\n middleware: [offset(4), flip(), shift({ padding: 8 })],\n });\n\n Object.assign(panel.style, {\n left: `${x}px`,\n top: `${y}px`,\n });\n }\n\n // ─── Focus management ───\n\n /** @internal */\n private _focusFirstItem(): void {\n const items = this._getMenuItems();\n items[0]?.focus();\n }\n\n /** @internal */\n private _getMenuItems(): HTMLElement[] {\n const slot = this.shadowRoot?.querySelector('slot') as HTMLSlotElement | null;\n return (\n (slot\n ?.assignedElements({ flatten: true })\n .filter(\n (el) =>\n el instanceof HTMLElement &&\n !el.hasAttribute('disabled') &&\n !(el as HTMLButtonElement).disabled &&\n (el.getAttribute('role') === 'menuitem' ||\n el.getAttribute('role') === 'menuitemcheckbox' ||\n el.getAttribute('role') === 'menuitemradio' ||\n el.tagName.toLowerCase().startsWith('hx-')),\n ) as HTMLElement[]) ?? []\n );\n }\n\n // ─── Event Handlers (arrow function class fields — stable reference, no bind needed) ───\n\n /** @internal */\n private readonly _handleTriggerClick = (e: MouseEvent): void => {\n e.stopPropagation();\n this._toggle();\n };\n\n /** @internal */\n private readonly _handleDocumentClick = (e: MouseEvent): void => {\n if (!this._open) return;\n const path = e.composedPath();\n if (!path.includes(this)) {\n this._hide();\n }\n };\n\n /** @internal */\n private readonly _handleKeydown = (e: KeyboardEvent): void => {\n if (!this._open) return;\n if (e.key === 'Escape') {\n e.stopPropagation();\n this._hide();\n this._buttonEl?.focus();\n return;\n }\n if (e.key === 'Tab') {\n this._hide();\n return;\n }\n if (e.key === 'ArrowDown' || e.key === 'ArrowUp' || e.key === 'Home' || e.key === 'End') {\n e.preventDefault();\n e.stopPropagation();\n const items = this._getMenuItems();\n if (items.length === 0) return;\n const focused = items.indexOf(document.activeElement as HTMLElement);\n let next: number;\n if (e.key === 'ArrowDown') {\n next = focused < 0 || focused >= items.length - 1 ? 0 : focused + 1;\n } else if (e.key === 'ArrowUp') {\n next = focused <= 0 ? items.length - 1 : focused - 1;\n } else if (e.key === 'Home') {\n next = 0;\n } else {\n next = items.length - 1;\n }\n items[next]?.focus();\n }\n };\n\n /** @internal */\n private readonly _handleSlotClick = (e: Event): void => {\n const target = e.target as HTMLElement;\n const menuItem = target.closest(\n '[role=\"menuitem\"], [role=\"menuitemcheckbox\"], [role=\"menuitemradio\"]',\n ) as HTMLElement | null;\n if (!menuItem) return;\n if (menuItem.hasAttribute('disabled') || (menuItem as HTMLButtonElement).disabled) return;\n const value = menuItem.getAttribute('data-value') ?? menuItem.textContent?.trim() ?? '';\n this.dispatchEvent(\n new CustomEvent<{ value: string }>('hx-select', {\n bubbles: true,\n composed: true,\n detail: { value },\n }),\n );\n this._hide();\n };\n\n // ─── SVG Icons ───\n\n /** @internal */\n private _renderIcon() {\n if (this.icon === 'horizontal') {\n return html`\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"1em\"\n height=\"1em\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <circle cx=\"5\" cy=\"12\" r=\"2\" />\n <circle cx=\"12\" cy=\"12\" r=\"2\" />\n <circle cx=\"19\" cy=\"12\" r=\"2\" />\n </svg>\n `;\n }\n return html`\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"1em\"\n height=\"1em\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <circle cx=\"12\" cy=\"5\" r=\"2\" />\n <circle cx=\"12\" cy=\"12\" r=\"2\" />\n <circle cx=\"12\" cy=\"19\" r=\"2\" />\n </svg>\n `;\n }\n\n // ─── Render ───\n\n override render() {\n const btnClasses = {\n trigger: true,\n [`trigger--${this.size}`]: true,\n 'trigger--open': this._open,\n };\n\n return html`\n <button\n part=\"button trigger\"\n class=${classMap(btnClasses)}\n type=\"button\"\n aria-label=${this.label}\n aria-haspopup=\"menu\"\n aria-expanded=${String(this._open)}\n aria-controls=${this._open ? this._panelId : nothing}\n ?disabled=${this.disabled}\n @click=${this._handleTriggerClick}\n >\n ${this._renderIcon()}\n </button>\n ${this._open\n ? html`\n <div\n id=${this._panelId}\n part=\"panel menu\"\n role=\"menu\"\n aria-label=${this.labelMenu}\n class=\"panel\"\n @click=${this._handleSlotClick}\n >\n <slot></slot>\n </div>\n `\n : nothing}\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-overflow-menu': HelixOverflowMenu;\n }\n}\n"],"names":["helixOverflowMenuStyles","css","_nextOverflowMenuId","createIdCounter","HelixOverflowMenu","HelixElement","_a","items","focused","next","_b","menuItem","value","trigger","panel","computePosition","flip","shift","offset","x","y","slot","el","html","btnClasses","classMap","nothing","__decorateClass","property","state","query","customElement"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { css as x, nothing as d, html as
|
|
1
|
+
import { css as x, nothing as d, html as u } from "lit";
|
|
2
2
|
import { property as l, state as v, customElement as m } from "lit/decorators.js";
|
|
3
3
|
import { classMap as y } from "lit/directives/class-map.js";
|
|
4
4
|
import { repeat as P } from "lit/directives/repeat.js";
|
|
@@ -43,10 +43,10 @@ const $ = x`
|
|
|
43
43
|
min-height: var(--hx-pagination-button-size, var(--hx-touch-target-min, 2.75rem));
|
|
44
44
|
padding: 0 var(--hx-space-2, 0.5rem);
|
|
45
45
|
border: var(--hx-border-width-thin, 1px) solid
|
|
46
|
-
var(--hx-pagination-border-color, var(--hx-color-
|
|
46
|
+
var(--hx-pagination-border-color, var(--hx-color-border-strong, #94a3b8));
|
|
47
47
|
border-radius: var(--hx-pagination-border-radius, var(--hx-border-radius-md, 0.375rem));
|
|
48
|
-
background: var(--hx-pagination-bg, var(--hx-color-
|
|
49
|
-
color: var(--hx-pagination-color, var(--hx-color-
|
|
48
|
+
background: var(--hx-pagination-bg, var(--hx-color-surface-default, #ffffff));
|
|
49
|
+
color: var(--hx-pagination-color, var(--hx-color-text-primary, #0f172a));
|
|
50
50
|
font-size: var(--hx-font-size-sm, 0.875rem);
|
|
51
51
|
font-family: inherit;
|
|
52
52
|
cursor: pointer;
|
|
@@ -59,7 +59,7 @@ const $ = x`
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
.button:hover:not(:disabled) {
|
|
62
|
-
background: var(--hx-pagination-hover-bg, var(--hx-color-
|
|
62
|
+
background: var(--hx-pagination-hover-bg, var(--hx-color-surface-sunken, #f1f5f9));
|
|
63
63
|
border-color: var(--hx-pagination-hover-border-color, var(--hx-color-primary-500, #2563eb));
|
|
64
64
|
}
|
|
65
65
|
|
|
@@ -75,7 +75,7 @@ const $ = x`
|
|
|
75
75
|
--hx-pagination-active-border-color,
|
|
76
76
|
var(--hx-pagination-active-bg, var(--hx-color-primary-500, #2563eb))
|
|
77
77
|
);
|
|
78
|
-
color: var(--hx-pagination-active-color, var(--hx-color-
|
|
78
|
+
color: var(--hx-pagination-active-color, var(--hx-color-text-on-primary, #ffffff));
|
|
79
79
|
font-weight: var(--hx-font-weight-semibold, 600);
|
|
80
80
|
cursor: default;
|
|
81
81
|
pointer-events: none;
|
|
@@ -92,7 +92,7 @@ const $ = x`
|
|
|
92
92
|
justify-content: center;
|
|
93
93
|
min-width: var(--hx-pagination-button-size, var(--hx-touch-target-min, 2.75rem));
|
|
94
94
|
min-height: var(--hx-pagination-button-size, var(--hx-touch-target-min, 2.75rem));
|
|
95
|
-
color: var(--hx-pagination-ellipsis-color, var(--hx-color-
|
|
95
|
+
color: var(--hx-pagination-ellipsis-color, var(--hx-color-text-muted, #64748b));
|
|
96
96
|
font-size: var(--hx-font-size-sm, 0.875rem);
|
|
97
97
|
user-select: none;
|
|
98
98
|
}
|
|
@@ -113,7 +113,7 @@ const $ = x`
|
|
|
113
113
|
align-items: center;
|
|
114
114
|
gap: var(--hx-space-2, 0.5rem);
|
|
115
115
|
font-size: var(--hx-font-size-sm, 0.875rem);
|
|
116
|
-
color: var(--hx-color-
|
|
116
|
+
color: var(--hx-color-text-muted, #64748b);
|
|
117
117
|
white-space: nowrap;
|
|
118
118
|
}
|
|
119
119
|
|
|
@@ -121,10 +121,10 @@ const $ = x`
|
|
|
121
121
|
min-height: var(--hx-pagination-button-size, var(--hx-touch-target-min, 2.75rem));
|
|
122
122
|
padding: 0 var(--hx-space-2, 0.5rem);
|
|
123
123
|
border: var(--hx-border-width-thin, 1px) solid
|
|
124
|
-
var(--hx-pagination-border-color, var(--hx-color-
|
|
124
|
+
var(--hx-pagination-border-color, var(--hx-color-border-strong, #94a3b8));
|
|
125
125
|
border-radius: var(--hx-pagination-border-radius, var(--hx-border-radius-md, 0.375rem));
|
|
126
|
-
background: var(--hx-pagination-bg, var(--hx-color-
|
|
127
|
-
color: var(--hx-pagination-color, var(--hx-color-
|
|
126
|
+
background: var(--hx-pagination-bg, var(--hx-color-surface-default, #ffffff));
|
|
127
|
+
color: var(--hx-pagination-color, var(--hx-color-text-primary, #0f172a));
|
|
128
128
|
font-size: var(--hx-font-size-sm, 0.875rem);
|
|
129
129
|
font-family: inherit;
|
|
130
130
|
cursor: pointer;
|
|
@@ -197,44 +197,44 @@ const $ = x`
|
|
|
197
197
|
}
|
|
198
198
|
}
|
|
199
199
|
`;
|
|
200
|
-
var z = Object.defineProperty, _ = Object.getOwnPropertyDescriptor, s = (
|
|
201
|
-
for (var a = e > 1 ? void 0 : e ? _(t,
|
|
202
|
-
(c =
|
|
203
|
-
return e && a && z(t,
|
|
200
|
+
var z = Object.defineProperty, _ = Object.getOwnPropertyDescriptor, s = (r, t, i, e) => {
|
|
201
|
+
for (var a = e > 1 ? void 0 : e ? _(t, i) : t, n = r.length - 1, c; n >= 0; n--)
|
|
202
|
+
(c = r[n]) && (a = (e ? c(t, i, a) : c(a)) || a);
|
|
203
|
+
return e && a && z(t, i, a), a;
|
|
204
204
|
};
|
|
205
205
|
let o = class extends w {
|
|
206
206
|
constructor() {
|
|
207
|
-
super(...arguments), this.totalPages = 1, this.currentPage = 1, this.siblingCount = 1, this.boundaryCount = 1, this.showFirstLast = !1, this.label = "Pagination", this.pageSize = 25, this.showPageSize = !1, this.labelRowsPerPage = "Rows per page:", this.firstPageLabel = "First page", this.previousPageLabel = "Previous page", this.nextPageLabel = "Next page", this.lastPageLabel = "Last page", this.labelPageMessage = (
|
|
207
|
+
super(...arguments), this.totalPages = 1, this.currentPage = 1, this.siblingCount = 1, this.boundaryCount = 1, this.showFirstLast = !1, this.label = "Pagination", this.pageSize = 25, this.showPageSize = !1, this.labelRowsPerPage = "Rows per page:", this.firstPageLabel = "First page", this.previousPageLabel = "Previous page", this.nextPageLabel = "Next page", this.lastPageLabel = "Last page", this.labelPageMessage = (r, t) => `Page ${r} of ${t}`, this.labelPageButton = (r) => `Page ${r}`, this._rovingKey = null, this._liveMessage = "", this._pageRangeCache = null;
|
|
208
208
|
}
|
|
209
209
|
// ─── Helpers ───
|
|
210
210
|
/** @internal */
|
|
211
211
|
_buildPageRange() {
|
|
212
212
|
var f;
|
|
213
|
-
const
|
|
214
|
-
if (((f = this._pageRangeCache) == null ? void 0 : f.key) ===
|
|
215
|
-
const t = Math.max(1, this.totalPages),
|
|
216
|
-
Math.min(
|
|
213
|
+
const r = `${this.totalPages}-${this.currentPage}-${this.siblingCount}-${this.boundaryCount}`;
|
|
214
|
+
if (((f = this._pageRangeCache) == null ? void 0 : f.key) === r) return this._pageRangeCache.result;
|
|
215
|
+
const t = Math.max(1, this.totalPages), i = Math.min(Math.max(1, this.currentPage), t), e = Math.max(0, this.boundaryCount), a = Math.max(0, this.siblingCount), n = this._range(1, Math.min(e, t)), c = this._range(Math.max(t - e + 1, e + 1), t), g = Math.max(
|
|
216
|
+
Math.min(i - a, t - e - a * 2 - 1),
|
|
217
217
|
e + 2
|
|
218
|
-
),
|
|
219
|
-
Math.max(
|
|
218
|
+
), p = Math.min(
|
|
219
|
+
Math.max(i + a, e + a * 2 + 2),
|
|
220
220
|
c.length > 0 ? (c[0] ?? t) - 2 : t - 1
|
|
221
221
|
), h = [];
|
|
222
222
|
for (const b of n) h.push(b);
|
|
223
|
-
|
|
224
|
-
for (const b of this._range(
|
|
225
|
-
|
|
223
|
+
g > e + 2 ? h.push("ellipsis") : e + 1 < g && h.push(e + 1);
|
|
224
|
+
for (const b of this._range(g, p)) h.push(b);
|
|
225
|
+
p < t - e - 1 ? h.push("ellipsis") : p < t - e && h.push(t - e);
|
|
226
226
|
for (const b of c) h.push(b);
|
|
227
|
-
return this._pageRangeCache = { key:
|
|
227
|
+
return this._pageRangeCache = { key: r, result: h }, h;
|
|
228
228
|
}
|
|
229
229
|
/** @internal */
|
|
230
|
-
_range(
|
|
231
|
-
const
|
|
232
|
-
for (let e =
|
|
233
|
-
return
|
|
230
|
+
_range(r, t) {
|
|
231
|
+
const i = [];
|
|
232
|
+
for (let e = r; e <= t; e++) i.push(e);
|
|
233
|
+
return i;
|
|
234
234
|
}
|
|
235
235
|
/** @internal */
|
|
236
|
-
_navigate(
|
|
237
|
-
const t = Math.min(Math.max(1,
|
|
236
|
+
_navigate(r) {
|
|
237
|
+
const t = Math.min(Math.max(1, r), this.totalPages);
|
|
238
238
|
t !== this.currentPage && (this.currentPage = t, this._rovingKey = null, this._liveMessage = this.labelPageMessage(t, this.totalPages), this.dispatchEvent(
|
|
239
239
|
new CustomEvent("hx-page-change", {
|
|
240
240
|
detail: { page: t },
|
|
@@ -243,18 +243,18 @@ let o = class extends w {
|
|
|
243
243
|
})
|
|
244
244
|
), this.updateComplete.then(() => {
|
|
245
245
|
var e;
|
|
246
|
-
const
|
|
246
|
+
const i = (e = this.shadowRoot) == null ? void 0 : e.querySelector(
|
|
247
247
|
`button[data-roving-key="${t}"]`
|
|
248
248
|
);
|
|
249
|
-
|
|
249
|
+
i == null || i.focus();
|
|
250
250
|
}));
|
|
251
251
|
}
|
|
252
252
|
/** @internal */
|
|
253
|
-
_handlePageSizeChange(
|
|
254
|
-
const t =
|
|
255
|
-
|
|
253
|
+
_handlePageSizeChange(r) {
|
|
254
|
+
const t = r.target, i = Number(t.value);
|
|
255
|
+
i !== this.pageSize && (this.pageSize = i, this.dispatchEvent(
|
|
256
256
|
new CustomEvent("hx-page-size-change", {
|
|
257
|
-
detail: { pageSize:
|
|
257
|
+
detail: { pageSize: i },
|
|
258
258
|
bubbles: !0,
|
|
259
259
|
composed: !0
|
|
260
260
|
})
|
|
@@ -265,35 +265,35 @@ let o = class extends w {
|
|
|
265
265
|
return this._rovingKey ?? this.currentPage;
|
|
266
266
|
}
|
|
267
267
|
/** @internal */
|
|
268
|
-
_handleFocusin(
|
|
269
|
-
const t =
|
|
268
|
+
_handleFocusin(r) {
|
|
269
|
+
const t = r.target;
|
|
270
270
|
if (t.tagName !== "BUTTON") return;
|
|
271
|
-
const
|
|
272
|
-
|
|
271
|
+
const i = t.dataset.rovingKey;
|
|
272
|
+
i !== void 0 && (this._rovingKey = isNaN(Number(i)) ? i : Number(i));
|
|
273
273
|
}
|
|
274
274
|
/** @internal */
|
|
275
|
-
_handleKeydown(
|
|
276
|
-
var c,
|
|
277
|
-
if (
|
|
275
|
+
_handleKeydown(r) {
|
|
276
|
+
var c, g;
|
|
277
|
+
if (r.key !== "ArrowLeft" && r.key !== "ArrowRight" && r.key !== "Home" && r.key !== "End")
|
|
278
278
|
return;
|
|
279
|
-
|
|
279
|
+
r.preventDefault();
|
|
280
280
|
const t = (c = this.shadowRoot) == null ? void 0 : c.querySelector(".list");
|
|
281
281
|
if (!t) return;
|
|
282
|
-
const
|
|
282
|
+
const i = Array.from(t.querySelectorAll("button:not([disabled])")), e = (g = this.shadowRoot) == null ? void 0 : g.activeElement, a = e ? i.indexOf(e) : 0;
|
|
283
283
|
let n;
|
|
284
|
-
if (
|
|
285
|
-
const
|
|
286
|
-
if (!
|
|
287
|
-
const h =
|
|
288
|
-
h !== void 0 && (this._rovingKey = isNaN(Number(h)) ? h : Number(h)),
|
|
284
|
+
if (r.key === "Home" ? n = 0 : r.key === "End" ? n = i.length - 1 : n = r.key === "ArrowLeft" ? Math.max(0, a - 1) : Math.min(i.length - 1, a + 1), n !== a || r.key === "Home" || r.key === "End") {
|
|
285
|
+
const p = i[n];
|
|
286
|
+
if (!p) return;
|
|
287
|
+
const h = p.dataset.rovingKey;
|
|
288
|
+
h !== void 0 && (this._rovingKey = isNaN(Number(h)) ? h : Number(h)), p.focus();
|
|
289
289
|
}
|
|
290
290
|
}
|
|
291
291
|
// ─── Render ───
|
|
292
292
|
render() {
|
|
293
|
-
const
|
|
294
|
-
return
|
|
293
|
+
const r = this._buildPageRange(), t = this.currentPage <= 1, i = this.currentPage >= this.totalPages, e = this._effectiveRovingKey;
|
|
294
|
+
return u`
|
|
295
295
|
<div class="pagination-root">
|
|
296
|
-
${this.showPageSize ?
|
|
296
|
+
${this.showPageSize ? u`
|
|
297
297
|
<div part="page-size-wrapper" class="page-size-wrapper">
|
|
298
298
|
<label part="page-size-label" class="page-size-label">
|
|
299
299
|
${this.labelRowsPerPage}
|
|
@@ -303,7 +303,7 @@ let o = class extends w {
|
|
|
303
303
|
@change=${this._handlePageSizeChange}
|
|
304
304
|
>
|
|
305
305
|
${[10, 25, 50, 100].map(
|
|
306
|
-
(a) =>
|
|
306
|
+
(a) => u`<option value=${a} ?selected=${a === this.pageSize}>${a}</option>`
|
|
307
307
|
)}
|
|
308
308
|
</select>
|
|
309
309
|
</label>
|
|
@@ -321,7 +321,7 @@ let o = class extends w {
|
|
|
321
321
|
@keydown=${this._handleKeydown}
|
|
322
322
|
@focusin=${this._handleFocusin}
|
|
323
323
|
>
|
|
324
|
-
${this.showFirstLast ?
|
|
324
|
+
${this.showFirstLast ? u`
|
|
325
325
|
<li part="item" class="item">
|
|
326
326
|
<button
|
|
327
327
|
part="button"
|
|
@@ -352,17 +352,17 @@ let o = class extends w {
|
|
|
352
352
|
</li>
|
|
353
353
|
|
|
354
354
|
${P(
|
|
355
|
-
|
|
355
|
+
r,
|
|
356
356
|
(a, n) => a === "ellipsis" ? `ellipsis-${n}` : `page-${a}`,
|
|
357
357
|
(a) => {
|
|
358
358
|
if (a === "ellipsis")
|
|
359
|
-
return
|
|
359
|
+
return u`
|
|
360
360
|
<li part="item" class="item">
|
|
361
361
|
<span part="ellipsis" class="ellipsis" aria-hidden="true">…</span>
|
|
362
362
|
</li>
|
|
363
363
|
`;
|
|
364
364
|
const n = a === this.currentPage;
|
|
365
|
-
return
|
|
365
|
+
return u`
|
|
366
366
|
<li part="item" class="item">
|
|
367
367
|
<button
|
|
368
368
|
part="button"
|
|
@@ -385,7 +385,7 @@ let o = class extends w {
|
|
|
385
385
|
<button
|
|
386
386
|
part="button"
|
|
387
387
|
class="button"
|
|
388
|
-
?disabled=${
|
|
388
|
+
?disabled=${i}
|
|
389
389
|
tabindex=${e === "next" ? 0 : -1}
|
|
390
390
|
data-roving-key="next"
|
|
391
391
|
aria-label=${this.nextPageLabel}
|
|
@@ -395,12 +395,12 @@ let o = class extends w {
|
|
|
395
395
|
</button>
|
|
396
396
|
</li>
|
|
397
397
|
|
|
398
|
-
${this.showFirstLast ?
|
|
398
|
+
${this.showFirstLast ? u`
|
|
399
399
|
<li part="item" class="item">
|
|
400
400
|
<button
|
|
401
401
|
part="button"
|
|
402
402
|
class="button"
|
|
403
|
-
?disabled=${
|
|
403
|
+
?disabled=${i}
|
|
404
404
|
tabindex=${e === "last" ? 0 : -1}
|
|
405
405
|
data-roving-key="last"
|
|
406
406
|
aria-label=${this.lastPageLabel}
|
|
@@ -474,4 +474,4 @@ o = s([
|
|
|
474
474
|
export {
|
|
475
475
|
o as H
|
|
476
476
|
};
|
|
477
|
-
//# sourceMappingURL=hx-pagination-
|
|
477
|
+
//# sourceMappingURL=hx-pagination-5FeVFIve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hx-pagination-5FeVFIve.js","sources":["../../src/components/hx-pagination/hx-pagination.styles.ts","../../src/components/hx-pagination/hx-pagination.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixPaginationStyles = css`\n :host {\n display: block;\n font-family: var(--hx-pagination-font-family, var(--hx-font-family-sans, sans-serif));\n }\n\n .pagination-root {\n display: flex;\n align-items: center;\n gap: var(--hx-space-4, 1rem);\n flex-wrap: wrap;\n }\n\n nav {\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .list {\n display: flex;\n align-items: center;\n gap: var(--hx-pagination-gap, var(--hx-space-1, 0.25rem));\n list-style: none;\n margin: 0;\n padding: 0;\n }\n\n .item {\n display: flex;\n }\n\n .button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: var(--hx-pagination-button-size, var(--hx-touch-target-min, 2.75rem));\n min-height: var(--hx-pagination-button-size, var(--hx-touch-target-min, 2.75rem));\n padding: 0 var(--hx-space-2, 0.5rem);\n border: var(--hx-border-width-thin, 1px) solid\n var(--hx-pagination-border-color, var(--hx-color-border-strong, #94a3b8));\n border-radius: var(--hx-pagination-border-radius, var(--hx-border-radius-md, 0.375rem));\n background: var(--hx-pagination-bg, var(--hx-color-surface-default, #ffffff));\n color: var(--hx-pagination-color, var(--hx-color-text-primary, #0f172a));\n font-size: var(--hx-font-size-sm, 0.875rem);\n font-family: inherit;\n cursor: pointer;\n transition:\n background-color var(--hx-transition-fast, 150ms) ease,\n border-color var(--hx-transition-fast, 150ms) ease,\n color var(--hx-transition-fast, 150ms) ease;\n text-decoration: none;\n white-space: nowrap;\n }\n\n .button:hover:not(:disabled) {\n background: var(--hx-pagination-hover-bg, var(--hx-color-surface-sunken, #f1f5f9));\n border-color: var(--hx-pagination-hover-border-color, var(--hx-color-primary-500, #2563eb));\n }\n\n .button:focus-visible {\n outline: var(--hx-focus-ring-width, 2px) solid\n var(--hx-pagination-focus-ring-color, var(--hx-focus-ring-color, var(--hx-color-primary-500)));\n outline-offset: var(--hx-focus-ring-offset, 2px);\n }\n\n .button[aria-current='page'] {\n background: var(--hx-pagination-active-bg, var(--hx-color-primary-500, #2563eb));\n border-color: var(\n --hx-pagination-active-border-color,\n var(--hx-pagination-active-bg, var(--hx-color-primary-500, #2563eb))\n );\n color: var(--hx-pagination-active-color, var(--hx-color-text-on-primary, #ffffff));\n font-weight: var(--hx-font-weight-semibold, 600);\n cursor: default;\n pointer-events: none;\n }\n\n .button:disabled {\n opacity: var(--hx-opacity-disabled, 0.5);\n pointer-events: none;\n }\n\n .ellipsis {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: var(--hx-pagination-button-size, var(--hx-touch-target-min, 2.75rem));\n min-height: var(--hx-pagination-button-size, var(--hx-touch-target-min, 2.75rem));\n color: var(--hx-pagination-ellipsis-color, var(--hx-color-text-muted, #64748b));\n font-size: var(--hx-font-size-sm, 0.875rem);\n user-select: none;\n }\n\n .button[aria-disabled='true'] {\n cursor: default;\n pointer-events: none;\n }\n\n /* Page size selector */\n .page-size-wrapper {\n display: flex;\n align-items: center;\n }\n\n .page-size-label {\n display: flex;\n align-items: center;\n gap: var(--hx-space-2, 0.5rem);\n font-size: var(--hx-font-size-sm, 0.875rem);\n color: var(--hx-color-text-muted, #64748b);\n white-space: nowrap;\n }\n\n .page-size-select {\n min-height: var(--hx-pagination-button-size, var(--hx-touch-target-min, 2.75rem));\n padding: 0 var(--hx-space-2, 0.5rem);\n border: var(--hx-border-width-thin, 1px) solid\n var(--hx-pagination-border-color, var(--hx-color-border-strong, #94a3b8));\n border-radius: var(--hx-pagination-border-radius, var(--hx-border-radius-md, 0.375rem));\n background: var(--hx-pagination-bg, var(--hx-color-surface-default, #ffffff));\n color: var(--hx-pagination-color, var(--hx-color-text-primary, #0f172a));\n font-size: var(--hx-font-size-sm, 0.875rem);\n font-family: inherit;\n cursor: pointer;\n }\n\n .page-size-select:focus-visible {\n outline: var(--hx-focus-ring-width, 2px) solid\n var(--hx-pagination-focus-ring-color, var(--hx-focus-ring-color, var(--hx-color-primary-500)));\n outline-offset: var(--hx-focus-ring-offset, 2px);\n }\n\n /* Visually hidden — used for aria-live status messages */\n .visually-hidden {\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 @media (prefers-reduced-motion: reduce) {\n .button {\n transition: none;\n }\n }\n\n /* Windows High Contrast / forced-colors support */\n @media (forced-colors: active) {\n .button {\n border: 1px solid ButtonText;\n color: ButtonText;\n background: ButtonFace;\n forced-color-adjust: none;\n }\n\n .button:hover:not(:disabled) {\n border-color: Highlight;\n color: Highlight;\n }\n\n .button:focus-visible {\n outline-color: Highlight;\n }\n\n .button[aria-current='page'] {\n background: Highlight;\n border-color: Highlight;\n color: HighlightText;\n }\n\n .button:disabled {\n color: GrayText;\n border-color: GrayText;\n opacity: 1;\n }\n\n .button[aria-disabled='true'] {\n color: GrayText;\n }\n\n .page-size-select {\n border-color: ButtonText;\n color: ButtonText;\n background: ButtonFace;\n forced-color-adjust: none;\n }\n }\n`;\n","import { html, nothing } from 'lit';\nimport '../../utilities/document-token-adoption.js';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { HelixElement } from '../../base/index.js';\nimport { helixPaginationStyles } from './hx-pagination.styles.js';\n\n/** Detail for the hx-page-change event dispatched by hx-pagination. */\nexport interface HxPageChangeDetail {\n page: number;\n}\n\n/** Detail for the hx-page-size-change event dispatched by hx-pagination. */\nexport interface HxPageSizeChangeDetail {\n pageSize: number;\n}\n\n/**\n * A pagination component for navigating content listings.\n *\n * @summary Page navigation with page numbers, prev/next, and ellipsis.\n *\n * @tag hx-pagination\n *\n * @csspart nav - The wrapping `<nav>` element.\n * @csspart list - The `<ul>` containing pagination items.\n * @csspart item - Each `<li>` item.\n * @csspart button - Each page button or prev/next control.\n * @csspart ellipsis - The ellipsis (`…`) span between page groups.\n * @csspart page-size-wrapper - The wrapper `<div>` around the page-size selector.\n * @csspart page-size-label - The `<label>` element for the page-size selector.\n * @csspart page-size-select - The `<select>` element for page-size.\n *\n * @cssprop [--hx-pagination-gap=0.25rem] - Gap between pagination buttons. Inherits from --hx-spacing-1.\n * @cssprop [--hx-pagination-button-size=2.25rem] - Minimum width and height of each button.\n * @cssprop [--hx-pagination-border-color] - Border color of buttons. Inherits from --hx-color-border (final fallback: #d1d5db).\n * @cssprop [--hx-pagination-border-radius] - Border radius of buttons. Inherits from --hx-border-radius-md (final fallback: 0.375rem).\n * @cssprop [--hx-pagination-bg] - Background color of buttons. Inherits from --hx-color-surface (final fallback: #ffffff).\n * @cssprop [--hx-pagination-color] - Text color of buttons. Inherits from --hx-color-text-primary (final fallback: #111827).\n * @cssprop [--hx-pagination-hover-bg] - Background color of buttons on hover. Inherits from --hx-color-surface-hover (final fallback: #f3f4f6).\n * @cssprop [--hx-pagination-hover-border-color] - Border color of buttons on hover. Inherits from --hx-color-primary (final fallback: #2563eb).\n * @cssprop [--hx-pagination-active-bg] - Background color of the active/current page button. Inherits from --hx-color-primary (final fallback: #2563eb).\n * @cssprop [--hx-pagination-active-color] - Text color of the active/current page button. Inherits from --hx-color-surface (final fallback: #ffffff).\n * @cssprop [--hx-pagination-active-border-color] - Border color of the active/current page button. Defaults to --hx-pagination-active-bg.\n * @cssprop [--hx-pagination-ellipsis-color] - Color of ellipsis characters. Inherits from --hx-color-text-secondary (final fallback: #6b7280).\n * @cssprop [--hx-transition-fast=150ms] - Duration used for hover/focus transitions.\n *\n * @fires {CustomEvent<{ page: number }>} hx-page-change - Fired when the user navigates to a new page.\n * @fires {CustomEvent<{ pageSize: number }>} hx-page-size-change - Fired when the user selects a new page size.\n *\n * @example\n * ```html\n * <hx-pagination total-pages=\"10\" current-page=\"1\"></hx-pagination>\n * ```\n *\n * @example Drupal / Twig integration\n * ```twig\n * {#\n * Drupal's pager uses 0-based page index in the URL (?page=N).\n * This component is 1-based, so add 1 to the Drupal page value.\n * Listen to hx-page-change and update the URL query param:\n * element.addEventListener('hx-page-change', (e) => {\n * const params = new URLSearchParams(location.search);\n * params.set('page', e.detail.page - 1); // convert back to 0-based\n * history.pushState({}, '', '?' + params.toString());\n * });\n * #}\n * <hx-pagination\n * total-pages=\"{{ total_pages }}\"\n * current-page=\"{{ pager.current_page + 1 }}\"\n * label=\"{{ 'Pagination'|t }}\"\n * {{ show_first_last ? 'show-first-last' : '' }}\n * ></hx-pagination>\n * ```\n * @cssprop [--hx-pagination-font-family=var(--hx-font-family-sans)] - CSS custom property.\n * @cssprop [--hx-font-family-sans] - Font family.\n * @cssprop [--hx-space-4] - Spacing token.\n * @cssprop [--hx-space-1] - Spacing token.\n * @cssprop [--hx-touch-target-min] - Minimum touch target size.\n * @cssprop [--hx-space-2] - Spacing token.\n * @cssprop [--hx-border-width-thin] - Width.\n * @cssprop [--hx-color-neutral-300] - Color.\n * @cssprop [--hx-border-radius-md] - CSS custom property.\n * @cssprop [--hx-color-neutral-0] - Color.\n * @cssprop [--hx-color-neutral-900] - Color.\n * @cssprop [--hx-font-size-sm] - Font size.\n * @cssprop [--hx-color-neutral-100] - Color.\n * @cssprop [--hx-color-primary-500] - Color.\n * @cssprop [--hx-focus-ring-width] - Width.\n * @cssprop [--hx-pagination-focus-ring-color=var(--hx-focus-ring-color)] - Color.\n * @cssprop [--hx-focus-ring-color] - Color.\n * @cssprop [--hx-focus-ring-offset] - CSS custom property.\n * @cssprop [--hx-font-weight-semibold] - Font weight.\n * @cssprop [--hx-opacity-disabled] - Opacity.\n * @cssprop [--hx-color-neutral-500] - Color.\n */\n@customElement('hx-pagination')\nexport class HelixPagination extends HelixElement {\n static override styles = [helixPaginationStyles];\n\n /**\n * Total number of pages.\n * @attr total-pages\n */\n @property({ type: Number, attribute: 'total-pages', reflect: true })\n totalPages = 1;\n\n /**\n * The currently active page (1-based).\n * @attr current-page\n */\n @property({ type: Number, attribute: 'current-page' })\n currentPage = 1;\n\n /**\n * Number of page buttons shown on each side of the current page.\n * @attr sibling-count\n */\n @property({ type: Number, attribute: 'sibling-count', reflect: true })\n siblingCount = 1;\n\n /**\n * Number of pages always shown at the start and end of the list.\n * @attr boundary-count\n */\n @property({ type: Number, attribute: 'boundary-count', reflect: true })\n boundaryCount = 1;\n\n /**\n * Whether to show First and Last page buttons.\n * @attr show-first-last\n */\n @property({ type: Boolean, attribute: 'show-first-last', reflect: true })\n showFirstLast = false;\n\n /**\n * Accessible label for the `<nav>` element.\n * @attr label\n */\n @property({ type: String, reflect: true })\n label = 'Pagination';\n\n /**\n * The number of items displayed per page. When set, a page-size selector\n * `<select>` is rendered. Set `show-page-size` to display the selector.\n * @attr page-size\n */\n @property({ type: Number, attribute: 'page-size', reflect: true })\n pageSize = 25;\n\n /**\n * Whether to show the page-size selector UI.\n * @attr show-page-size\n */\n @property({ type: Boolean, attribute: 'show-page-size', reflect: true })\n showPageSize = false;\n\n /**\n * Label text for the rows-per-page selector.\n * @attr label-rows-per-page\n */\n @property({ type: String, attribute: 'label-rows-per-page' })\n labelRowsPerPage = 'Rows per page:';\n\n /**\n * Accessible label for the \"First page\" navigation button.\n * @attr first-page-label\n */\n @property({ attribute: 'first-page-label' })\n firstPageLabel = 'First page';\n\n /**\n * Accessible label for the \"Previous page\" navigation button.\n * @attr previous-page-label\n */\n @property({ attribute: 'previous-page-label' })\n previousPageLabel = 'Previous page';\n\n /**\n * Accessible label for the \"Next page\" navigation button.\n * @attr next-page-label\n */\n @property({ attribute: 'next-page-label' })\n nextPageLabel = 'Next page';\n\n /**\n * Accessible label for the \"Last page\" navigation button.\n * @attr last-page-label\n */\n @property({ attribute: 'last-page-label' })\n lastPageLabel = 'Last page';\n\n /**\n * Function to format the page navigation announcement. Override for i18n.\n */\n @property({ attribute: false })\n labelPageMessage: (current: number, total: number) => string = (current, total) =>\n `Page ${current} of ${total}`;\n\n /**\n * Function to format page button aria-labels. Override for i18n.\n */\n @property({ attribute: false })\n labelPageButton: (page: number) => string = (page) => `Page ${page}`;\n\n /** Tracks the roving tabindex target. Null means default to currentPage. */\n /** @internal */\n @state() private _rovingKey: number | string | null = null;\n\n /** Text for the aria-live region, updated on navigation. */\n /** @internal */\n @state() private _liveMessage = '';\n\n /** Memoization cache for _buildPageRange. */\n /** @internal */\n private _pageRangeCache: { key: string; result: Array<number | 'ellipsis'> } | null = null;\n\n // ─── Helpers ───\n\n /** @internal */\n private _buildPageRange(): Array<number | 'ellipsis'> {\n const key = `${this.totalPages}-${this.currentPage}-${this.siblingCount}-${this.boundaryCount}`;\n if (this._pageRangeCache?.key === key) return this._pageRangeCache.result;\n\n const total = Math.max(1, this.totalPages);\n const current = Math.min(Math.max(1, this.currentPage), total);\n const boundary = Math.max(0, this.boundaryCount);\n const sibling = Math.max(0, this.siblingCount);\n\n const startPages = this._range(1, Math.min(boundary, total));\n const endPages = this._range(Math.max(total - boundary + 1, boundary + 1), total);\n\n const siblingStart = Math.max(\n Math.min(current - sibling, total - boundary - sibling * 2 - 1),\n boundary + 2,\n );\n const siblingEnd = Math.min(\n Math.max(current + sibling, boundary + sibling * 2 + 2),\n endPages.length > 0 ? (endPages[0] ?? total) - 2 : total - 1,\n );\n\n const items: Array<number | 'ellipsis'> = [];\n\n for (const p of startPages) items.push(p);\n\n if (siblingStart > boundary + 2) {\n items.push('ellipsis');\n } else if (boundary + 1 < siblingStart) {\n items.push(boundary + 1);\n }\n\n for (const p of this._range(siblingStart, siblingEnd)) items.push(p);\n\n if (siblingEnd < total - boundary - 1) {\n items.push('ellipsis');\n } else if (siblingEnd < total - boundary) {\n items.push(total - boundary);\n }\n\n for (const p of endPages) items.push(p);\n\n this._pageRangeCache = { key, result: items };\n return items;\n }\n\n /** @internal */\n private _range(start: number, end: number): number[] {\n const result: number[] = [];\n for (let i = start; i <= end; i++) result.push(i);\n return result;\n }\n\n /** @internal */\n private _navigate(page: number): void {\n const clamped = Math.min(Math.max(1, page), this.totalPages);\n if (clamped === this.currentPage) return;\n\n this.currentPage = clamped;\n this._rovingKey = null; // reset so focus follows the new current page\n this._liveMessage = this.labelPageMessage(clamped, this.totalPages);\n this.dispatchEvent(\n new CustomEvent<{ page: number }>('hx-page-change', {\n detail: { page: clamped },\n bubbles: true,\n composed: true,\n }),\n );\n\n // PAGINATION-005: restore focus to the new current-page button after render\n void this.updateComplete.then(() => {\n const btn = this.shadowRoot?.querySelector<HTMLButtonElement>(\n `button[data-roving-key=\"${clamped}\"]`,\n );\n btn?.focus();\n });\n }\n\n /** @internal */\n private _handlePageSizeChange(e: Event): void {\n const select = e.target as HTMLSelectElement;\n const newSize = Number(select.value);\n if (newSize === this.pageSize) return;\n\n this.pageSize = newSize;\n this.dispatchEvent(\n new CustomEvent<{ pageSize: number }>('hx-page-size-change', {\n detail: { pageSize: newSize },\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n /** @internal */\n private get _effectiveRovingKey(): number | string {\n return this._rovingKey ?? this.currentPage;\n }\n\n /** @internal */\n private _handleFocusin(e: FocusEvent): void {\n const btn = e.target as HTMLElement;\n if (btn.tagName !== 'BUTTON') return;\n const key = btn.dataset['rovingKey'];\n if (key === undefined) return;\n this._rovingKey = isNaN(Number(key)) ? key : Number(key);\n }\n\n /** @internal */\n private _handleKeydown(e: KeyboardEvent): void {\n if (e.key !== 'ArrowLeft' && e.key !== 'ArrowRight' && e.key !== 'Home' && e.key !== 'End')\n return;\n e.preventDefault();\n\n const list = this.shadowRoot?.querySelector('.list');\n if (!list) return;\n\n // Collect all non-disabled buttons (disabled prev/next excluded; aria-disabled current page included)\n const buttons = Array.from(list.querySelectorAll<HTMLButtonElement>('button:not([disabled])'));\n const focused = this.shadowRoot?.activeElement as HTMLButtonElement | null;\n const currentIdx = focused ? buttons.indexOf(focused) : 0;\n\n let nextIdx: number;\n if (e.key === 'Home') {\n nextIdx = 0;\n } else if (e.key === 'End') {\n nextIdx = buttons.length - 1;\n } else {\n nextIdx =\n e.key === 'ArrowLeft'\n ? Math.max(0, currentIdx - 1)\n : Math.min(buttons.length - 1, currentIdx + 1);\n }\n\n if (nextIdx !== currentIdx || e.key === 'Home' || e.key === 'End') {\n const nextBtn = buttons[nextIdx];\n if (!nextBtn) return;\n const key = nextBtn.dataset['rovingKey'];\n if (key !== undefined) {\n this._rovingKey = isNaN(Number(key)) ? key : Number(key);\n }\n nextBtn.focus();\n }\n }\n\n // ─── Render ───\n\n override render() {\n const pages = this._buildPageRange();\n const isFirst = this.currentPage <= 1;\n const isLast = this.currentPage >= this.totalPages;\n const rovingKey = this._effectiveRovingKey;\n\n return html`\n <div class=\"pagination-root\">\n ${this.showPageSize\n ? html`\n <div part=\"page-size-wrapper\" class=\"page-size-wrapper\">\n <label part=\"page-size-label\" class=\"page-size-label\">\n ${this.labelRowsPerPage}\n <select\n part=\"page-size-select\"\n class=\"page-size-select\"\n @change=${this._handlePageSizeChange}\n >\n ${[10, 25, 50, 100].map(\n (n) =>\n html`<option value=${n} ?selected=${n === this.pageSize}>${n}</option>`,\n )}\n </select>\n </label>\n </div>\n `\n : nothing}\n\n <nav part=\"nav\" aria-label=${this.label}>\n <span class=\"visually-hidden\" aria-live=\"polite\" aria-atomic=\"true\"\n >${this._liveMessage}</span\n >\n <ul\n part=\"list\"\n class=\"list\"\n role=\"list\"\n @keydown=${this._handleKeydown}\n @focusin=${this._handleFocusin}\n >\n ${this.showFirstLast\n ? html`\n <li part=\"item\" class=\"item\">\n <button\n part=\"button\"\n class=\"button\"\n ?disabled=${isFirst}\n tabindex=${rovingKey === 'first' ? 0 : -1}\n data-roving-key=\"first\"\n aria-label=${this.firstPageLabel}\n @click=${() => this._navigate(1)}\n >\n «\n </button>\n </li>\n `\n : nothing}\n\n <li part=\"item\" class=\"item\">\n <button\n part=\"button\"\n class=\"button\"\n ?disabled=${isFirst}\n tabindex=${rovingKey === 'prev' ? 0 : -1}\n data-roving-key=\"prev\"\n aria-label=${this.previousPageLabel}\n @click=${() => this._navigate(this.currentPage - 1)}\n >\n ‹\n </button>\n </li>\n\n ${repeat(\n pages,\n (page, i) => (page === 'ellipsis' ? `ellipsis-${i}` : `page-${page}`),\n (page) => {\n if (page === 'ellipsis') {\n return html`\n <li part=\"item\" class=\"item\">\n <span part=\"ellipsis\" class=\"ellipsis\" aria-hidden=\"true\">…</span>\n </li>\n `;\n }\n const isCurrent = page === this.currentPage;\n return html`\n <li part=\"item\" class=\"item\">\n <button\n part=\"button\"\n class=${classMap({ button: true })}\n aria-disabled=${isCurrent ? 'true' : nothing}\n tabindex=${rovingKey === page ? 0 : -1}\n data-roving-key=${page}\n aria-current=${isCurrent ? 'page' : nothing}\n aria-label=${this.labelPageButton(page)}\n @click=${() => this._navigate(page)}\n >\n ${page}\n </button>\n </li>\n `;\n },\n )}\n\n <li part=\"item\" class=\"item\">\n <button\n part=\"button\"\n class=\"button\"\n ?disabled=${isLast}\n tabindex=${rovingKey === 'next' ? 0 : -1}\n data-roving-key=\"next\"\n aria-label=${this.nextPageLabel}\n @click=${() => this._navigate(this.currentPage + 1)}\n >\n ›\n </button>\n </li>\n\n ${this.showFirstLast\n ? html`\n <li part=\"item\" class=\"item\">\n <button\n part=\"button\"\n class=\"button\"\n ?disabled=${isLast}\n tabindex=${rovingKey === 'last' ? 0 : -1}\n data-roving-key=\"last\"\n aria-label=${this.lastPageLabel}\n @click=${() => this._navigate(this.totalPages)}\n >\n »\n </button>\n </li>\n `\n : nothing}\n </ul>\n </nav>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-pagination': HelixPagination;\n }\n}\n\n/** Canonical type alias for HelixPagination. Use this when typing hx-pagination element references. */\nexport type HxPagination = HelixPagination;\n"],"names":["helixPaginationStyles","css","HelixPagination","HelixElement","current","total","page","key","_a","boundary","sibling","startPages","endPages","siblingStart","siblingEnd","items","p","start","end","result","i","clamped","btn","e","select","newSize","list","buttons","focused","_b","currentIdx","nextIdx","nextBtn","pages","isFirst","isLast","rovingKey","html","n","nothing","repeat","isCurrent","classMap","__decorateClass","property","state","customElement"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hx-patient-banner-uE6gqLpT.js","sources":["../../src/components/hx-patient-banner/hx-patient-banner.styles.ts","../../src/components/hx-patient-banner/hx-patient-banner.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixPatientBannerStyles = css`\n :host {\n display: block;\n width: 100%;\n\n /* ─── Private token vars (3-tier cascade) ─── */\n --_bg: var(--hx-patient-banner-bg, var(--hx-color-neutral-50, #f8fafc));\n --_border-color: var(--hx-patient-banner-border-color, var(--hx-color-neutral-200, #e2e8f0));\n --_padding: var(\n --hx-patient-banner-padding,\n var(--hx-space-3, 0.75rem) var(--hx-space-4, 1rem)\n );\n --_gap: var(--hx-patient-banner-gap, var(--hx-space-4, 1rem));\n --_font-family: var(--hx-patient-banner-font-family, var(--hx-font-family-sans, sans-serif));\n --_label-color: var(--hx-patient-banner-label-color, var(--hx-color-neutral-500, #64748b));\n --_label-font-size: var(--hx-patient-banner-label-font-size, var(--hx-font-size-xs, 0.75rem));\n --_value-color: var(--hx-patient-banner-value-color, var(--hx-color-neutral-900, #0f172a));\n --_value-font-size: var(--hx-patient-banner-value-font-size, var(--hx-font-size-sm, 0.875rem));\n --_photo-size: var(--hx-patient-banner-photo-size, var(--hx-space-10, 2.5rem));\n --_photo-bg: var(--hx-patient-banner-photo-bg, var(--hx-color-neutral-200, #e2e8f0));\n }\n\n * {\n box-sizing: border-box;\n }\n\n /* ─── Banner Container ─── */\n\n .banner {\n display: flex;\n align-items: center;\n gap: var(--_gap);\n padding: var(--_padding);\n background-color: var(--_bg);\n border-bottom: var(--hx-border-width-thin, 1px) solid var(--_border-color);\n font-family: var(--_font-family);\n width: 100%;\n position: relative;\n }\n\n /* ─── Photo Area ─── */\n\n .banner__photo-area {\n flex-shrink: 0;\n width: var(--_photo-size);\n height: var(--_photo-size);\n /* Minimum touch target for interactive photo content (WCAG 2.5.8). */\n min-width: var(--hx-touch-target-size, 44px);\n min-height: var(--hx-touch-target-size, 44px);\n border-radius: var(--hx-border-radius-full, 9999px);\n overflow: hidden;\n display: flex;\n align-items: center;\n justify-content: center;\n background-color: var(--_photo-bg);\n }\n\n /* ─── Fields Grid ─── */\n\n .banner__fields {\n display: flex;\n flex-wrap: wrap;\n gap: var(--_gap);\n flex: 1;\n min-width: 0;\n }\n\n /* ─── Individual Field ─── */\n\n .field {\n display: flex;\n flex-direction: column;\n gap: var(--hx-space-1, 0.25rem);\n min-width: 0;\n }\n\n .field__label {\n font-size: var(--_label-font-size);\n color: var(--_label-color);\n font-weight: var(--hx-font-weight-medium, 500);\n line-height: var(--hx-line-height-tight, 1.25);\n white-space: nowrap;\n }\n\n .field__value {\n font-size: var(--_value-font-size);\n color: var(--_value-color);\n font-weight: var(--hx-font-weight-normal, 400);\n line-height: var(--hx-line-height-normal, 1.5);\n display: flex;\n align-items: center;\n gap: var(--hx-space-1, 0.25rem);\n }\n\n /* ─── Identifier Rule Violation ─── */\n /* Visual indicator when Joint Commission two-identifier rule is not met. */\n\n :host([aria-invalid='true']) .banner {\n border-bottom-color: var(--hx-color-error-400, #f87171);\n background-color: var(--hx-color-error-50, #fef2f2);\n /* Darken label color to maintain 4.5:1 contrast on error-50 background. */\n --_label-color: var(--hx-patient-banner-label-color, var(--hx-color-neutral-700, #334155));\n }\n\n :host([aria-invalid='true']) .banner::before {\n content: '';\n display: block;\n position: absolute;\n inset-inline-start: 0;\n top: 0;\n bottom: 0;\n width: var(--hx-border-width-thick, 4px);\n background-color: var(--hx-color-error-500, #dc2626);\n border-radius: 0;\n }\n\n /* ─── Visually-hidden violation live region ─── */\n /* Announces identifier rule violations to screen readers without visible text. */\n\n .violation-message {\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-width: 0;\n }\n\n /* ─── Motion reduction ─── */\n\n @media (prefers-reduced-motion: reduce) {\n * {\n transition: none !important;\n animation: none !important;\n }\n }\n\n /* ─── Forced Colors (Windows High Contrast) ─── */\n\n @media (forced-colors: active) {\n .banner {\n border-bottom-color: CanvasText;\n }\n\n :host([aria-invalid='true']) .banner {\n border-bottom-color: LinkText;\n }\n\n :host([aria-invalid='true']) .banner::before {\n background-color: LinkText;\n }\n\n .banner__photo-area {\n border: 1px solid CanvasText;\n }\n }\n`;\n","import { html, nothing, type PropertyValues } from 'lit';\nimport '../../utilities/document-token-adoption.js';\nimport { customElement, property, state, query } from 'lit/decorators.js';\nimport { HelixElement } from '../../base/index.js';\nimport { helixPatientBannerStyles } from './hx-patient-banner.styles.js';\n\n/**\n * Patient identification banner implementing Joint Commission NPSG.01.01.01 two-identifier rule.\n * Renders as a landmark region containing named slots for patient identification fields.\n * Integrates with hx-phi-field for HIPAA-compliant display of masked identifiers.\n *\n * ## Security Model — Event Composition\n *\n * This component dispatches and propagates two categories of composed events:\n *\n * ### `hx-identifier-rule-violation` (dispatched by this component)\n * Fired with `composed: true` when the two-identifier rule is violated. The event detail\n * contains only structural metadata (`populatedIdentifiers` count, `requiredIdentifiers`\n * count) and the `patientId` attribute value. **No raw PHI is included.**\n *\n * The `patientId` is a developer-provided attribute intended as a correlation key for\n * application logic — it should be an opaque internal identifier (e.g., a UUID or\n * encounter ID), not a human-readable identifier like an MRN or SSN.\n *\n * ### `hx-phi-access` (bubbles from slotted hx-phi-field children)\n * Slotted `hx-phi-field` elements dispatch `hx-phi-access` with `composed: true`. These\n * events bubble through this component's shadow DOM via slot projection. This component\n * does NOT re-dispatch or modify these events. See `hx-phi-field` documentation for the\n * security model of those events.\n *\n * ### Consumer Responsibilities\n *\n * - **Multi-tenant isolation**: In micro-frontend architectures where multiple patient\n * contexts share a document, scope event listeners to the appropriate DOM subtree.\n * Both `hx-phi-access` and `hx-identifier-rule-violation` use `composed: true` and\n * will bubble through shared ancestors across shadow boundaries.\n * - **patientId hygiene**: Set the `patient-id` attribute to an opaque internal\n * identifier, not a human-readable clinical identifier. This value appears in\n * composed events that cross shadow boundaries.\n *\n * @summary Patient identification banner with two-identifier rule enforcement.\n *\n * @tag hx-patient-banner\n *\n * @slot photo - Optional patient photo slot.\n * @slot name - Patient name field content.\n * @slot mrn - Medical record number field content. Use hx-phi-field for HIPAA compliance.\n * @slot dob - Date of birth field content. Use hx-phi-field for HIPAA compliance.\n * @slot allergies - Allergy status/flag content.\n * @slot code-status - Code status content.\n *\n * @csspart banner - The outer banner container.\n * @csspart photo-area - The photo slot wrapper.\n * @csspart fields - The fields grid container.\n * @csspart field - An individual field container (applied to all field wrappers).\n * @csspart field-label - The field label element.\n * @csspart field-value - The field value slot wrapper.\n * @csspart violation-message - The visually-hidden identifier rule violation status message.\n *\n * @fires {CustomEvent<PatientIdentifierRuleViolationDetail>} hx-identifier-rule-violation -\n * Fired when fewer than 2 identifier slots are populated and enforce-identifier-rule is\n * true. Contains structural metadata only — no raw PHI. Dispatched with `composed: true`.\n *\n * @cssprop [--hx-patient-banner-bg=var(--hx-color-neutral-50,#f9fafb)] - Banner background color.\n * @cssprop [--hx-patient-banner-border-color=var(--hx-color-neutral-200,#e5e7eb)] - Banner border color.\n * @cssprop [--hx-patient-banner-padding=var(--hx-space-3,0.75rem) var(--hx-space-4,1rem)] - Banner padding.\n * @cssprop [--hx-patient-banner-gap=var(--hx-space-4,1rem)] - Gap between banner fields.\n * @cssprop [--hx-patient-banner-font-family=var(--hx-font-family-sans,sans-serif)] - Banner font family.\n * @cssprop [--hx-patient-banner-label-color=var(--hx-color-neutral-500,#6b7280)] - Field label color.\n * @cssprop [--hx-patient-banner-label-font-size=var(--hx-font-size-xs,0.75rem)] - Field label font size.\n * @cssprop [--hx-patient-banner-value-color=var(--hx-color-neutral-900,#111827)] - Field value color.\n * @cssprop [--hx-patient-banner-value-font-size=var(--hx-font-size-sm,0.875rem)] - Field value font size.\n * @cssprop [--hx-patient-banner-photo-size=var(--hx-space-10,2.5rem)] - Photo area size.\n * @cssprop [--hx-patient-banner-photo-bg=var(--hx-color-neutral-200,#e5e7eb)] - Photo area background color when empty.\n */\n@customElement('hx-patient-banner')\nexport class HelixPatientBanner extends HelixElement {\n static override styles = [helixPatientBannerStyles];\n\n // ─── Public Properties ───\n\n /**\n * Optional patient ID used as context in identifier rule violation events.\n * @attr patient-id\n */\n @property({ type: String, attribute: 'patient-id' })\n patientId: string = '';\n\n /**\n * Accessible label for the banner landmark region.\n * @attr label-patient\n */\n @property({ type: String, attribute: 'label-patient' })\n labelPatient: string = 'Patient identification';\n\n /**\n * Visible label for the name field.\n * @attr label-name\n */\n @property({ type: String, attribute: 'label-name' })\n labelName: string = 'Patient name';\n\n /**\n * Visible label for the MRN field.\n * @attr label-mrn\n */\n @property({ type: String, attribute: 'label-mrn' })\n labelMrn: string = 'MRN';\n\n /**\n * Visible label for the date of birth field.\n * @attr label-dob\n */\n @property({ type: String, attribute: 'label-dob' })\n labelDob: string = 'Date of birth';\n\n /**\n * Visible label for the allergies field.\n * @attr label-allergies\n */\n @property({ type: String, attribute: 'label-allergies' })\n labelAllergies: string = 'Allergies';\n\n /**\n * Visible label for the code status field.\n * @attr label-code-status\n */\n @property({ type: String, attribute: 'label-code-status' })\n labelCodeStatus: string = 'Code status';\n\n /**\n * Whether to enforce the Joint Commission NPSG.01.01.01 two-identifier rule.\n * When true, fires hx-identifier-rule-violation if fewer than 2 identifier\n * slots (name, mrn, dob) are populated.\n * @attr enforce-identifier-rule\n */\n @property({\n attribute: 'enforce-identifier-rule',\n reflect: true,\n converter: {\n fromAttribute: (value: string | null) => value !== 'false',\n toAttribute: (value: boolean) => String(value),\n },\n })\n enforceIdentifierRule: boolean = true;\n\n // ─── Internal State ───\n\n /** @internal */\n @state() private _identifierCount: number = 0;\n\n /** @internal */\n @state() private _isViolating: boolean = false;\n\n // ─── Slot Queries ───\n\n /** @internal */\n @query('slot[name=\"name\"]') private _nameSlot!: HTMLSlotElement | null;\n\n /** @internal */\n @query('slot[name=\"mrn\"]') private _mrnSlot!: HTMLSlotElement | null;\n\n /** @internal */\n @query('slot[name=\"dob\"]') private _dobSlot!: HTMLSlotElement | null;\n\n // ─── Lifecycle ───\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.setAttribute('role', 'banner');\n this.setAttribute('aria-label', this.labelPatient);\n }\n\n protected override updated(changedProperties: PropertyValues<this>): void {\n super.updated(changedProperties);\n\n if (changedProperties.has('labelPatient')) {\n this.setAttribute('aria-label', this.labelPatient);\n }\n\n if (changedProperties.has('enforceIdentifierRule')) {\n this._checkIdentifierRule();\n }\n }\n\n // ─── Private Helpers ───\n\n private _countPopulatedIdentifiers(): number {\n let count = 0;\n\n const slots = [this._nameSlot, this._mrnSlot, this._dobSlot];\n for (const slot of slots) {\n if (slot && slot.assignedNodes({ flatten: true }).length > 0) {\n count++;\n }\n }\n\n return count;\n }\n\n private _checkIdentifierRule(): void {\n const count = this._countPopulatedIdentifiers();\n this._identifierCount = count;\n\n if (this.enforceIdentifierRule && count < 2) {\n this._isViolating = true;\n this.setAttribute('aria-invalid', 'true');\n this.dispatchEvent(\n new CustomEvent<PatientIdentifierRuleViolationDetail>('hx-identifier-rule-violation', {\n bubbles: true,\n composed: true,\n detail: {\n populatedIdentifiers: count,\n requiredIdentifiers: 2,\n patientId: this.patientId,\n },\n }),\n );\n } else {\n this._isViolating = false;\n this.removeAttribute('aria-invalid');\n }\n }\n\n // ─── Event Handlers ───\n\n private _handleSlotChange(): void {\n this._checkIdentifierRule();\n }\n\n // ─── Render ───\n\n override render() {\n const violationMessage = this._isViolating\n ? `Warning: patient identification incomplete. ${this._identifierCount} of 2 required identifiers present.`\n : nothing;\n\n return html`\n <div part=\"banner\" class=\"banner\">\n <div part=\"photo-area\" class=\"banner__photo-area\" aria-hidden=\"true\">\n <slot name=\"photo\"></slot>\n </div>\n\n <div part=\"fields\" class=\"banner__fields\">\n <div part=\"field\" class=\"field\">\n <span part=\"field-label\" class=\"field__label\">${this.labelName}</span>\n <div part=\"field-value\" class=\"field__value\">\n <slot name=\"name\" @slotchange=${this._handleSlotChange}></slot>\n </div>\n </div>\n\n <div part=\"field\" class=\"field\">\n <span part=\"field-label\" class=\"field__label\">${this.labelMrn}</span>\n <div part=\"field-value\" class=\"field__value\">\n <slot name=\"mrn\" @slotchange=${this._handleSlotChange}></slot>\n </div>\n </div>\n\n <div part=\"field\" class=\"field\">\n <span part=\"field-label\" class=\"field__label\">${this.labelDob}</span>\n <div part=\"field-value\" class=\"field__value\">\n <slot name=\"dob\" @slotchange=${this._handleSlotChange}></slot>\n </div>\n </div>\n\n <div part=\"field\" class=\"field\">\n <span part=\"field-label\" class=\"field__label\">${this.labelAllergies}</span>\n <div part=\"field-value\" class=\"field__value\">\n <slot name=\"allergies\"></slot>\n </div>\n </div>\n\n <div part=\"field\" class=\"field\">\n <span part=\"field-label\" class=\"field__label\">${this.labelCodeStatus}</span>\n <div part=\"field-value\" class=\"field__value\">\n <slot name=\"code-status\"></slot>\n </div>\n </div>\n </div>\n </div>\n\n ${violationMessage !== nothing\n ? html`<div\n part=\"violation-message\"\n class=\"violation-message\"\n role=\"alert\"\n aria-live=\"assertive\"\n >\n ${violationMessage}\n </div>`\n : nothing}\n `;\n }\n}\n\n/**\n * Event detail for identifier rule violations. Contains only structural metadata\n * about the validation state — never raw PHI values.\n *\n * **Security note**: The `patientId` field reflects the `patient-id` HTML attribute,\n * which should be set to an opaque internal identifier (UUID, encounter ID), not a\n * human-readable clinical identifier. This value crosses shadow DOM boundaries via\n * `composed: true` events.\n */\nexport interface PatientIdentifierRuleViolationDetail {\n /** Number of identifier slots currently populated (0, 1, or 2). */\n populatedIdentifiers: number;\n /** Minimum required identifiers per NPSG.01.01.01 (always 2). */\n requiredIdentifiers: number;\n /** Opaque patient identifier from the patient-id attribute. Should NOT contain raw PHI. */\n patientId: string;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-patient-banner': HelixPatientBanner;\n }\n}\n"],"names":["helixPatientBannerStyles","css","HelixPatientBanner","HelixElement","changedProperties","count","slots","slot","violationMessage","nothing","html","__decorateClass","property","value","state","query","customElement"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"hx-patient-banner-uE6gqLpT.js","sources":["../../src/components/hx-patient-banner/hx-patient-banner.styles.ts","../../src/components/hx-patient-banner/hx-patient-banner.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixPatientBannerStyles = css`\n :host {\n display: block;\n width: 100%;\n\n /* ─── Private token vars (3-tier cascade) ─── */\n --_bg: var(--hx-patient-banner-bg, var(--hx-color-neutral-50, #f8fafc));\n --_border-color: var(--hx-patient-banner-border-color, var(--hx-color-neutral-200, #e2e8f0));\n --_padding: var(\n --hx-patient-banner-padding,\n var(--hx-space-3, 0.75rem) var(--hx-space-4, 1rem)\n );\n --_gap: var(--hx-patient-banner-gap, var(--hx-space-4, 1rem));\n --_font-family: var(--hx-patient-banner-font-family, var(--hx-font-family-sans, sans-serif));\n --_label-color: var(--hx-patient-banner-label-color, var(--hx-color-neutral-500, #64748b));\n --_label-font-size: var(--hx-patient-banner-label-font-size, var(--hx-font-size-xs, 0.75rem));\n --_value-color: var(--hx-patient-banner-value-color, var(--hx-color-neutral-900, #0f172a));\n --_value-font-size: var(--hx-patient-banner-value-font-size, var(--hx-font-size-sm, 0.875rem));\n --_photo-size: var(--hx-patient-banner-photo-size, var(--hx-space-10, 2.5rem));\n --_photo-bg: var(--hx-patient-banner-photo-bg, var(--hx-color-neutral-200, #e2e8f0));\n }\n\n * {\n box-sizing: border-box;\n }\n\n /* ─── Banner Container ─── */\n\n .banner {\n display: flex;\n align-items: center;\n gap: var(--_gap);\n padding: var(--_padding);\n background-color: var(--_bg);\n border-bottom: var(--hx-border-width-thin, 1px) solid var(--_border-color);\n font-family: var(--_font-family);\n width: 100%;\n position: relative;\n }\n\n /* ─── Photo Area ─── */\n\n .banner__photo-area {\n flex-shrink: 0;\n width: var(--_photo-size);\n height: var(--_photo-size);\n /* Minimum touch target for interactive photo content (WCAG 2.5.8). */\n min-width: var(--hx-touch-target-size, 44px);\n min-height: var(--hx-touch-target-size, 44px);\n border-radius: var(--hx-border-radius-full, 9999px);\n overflow: hidden;\n display: flex;\n align-items: center;\n justify-content: center;\n background-color: var(--_photo-bg);\n }\n\n /* ─── Fields Grid ─── */\n\n .banner__fields {\n display: flex;\n flex-wrap: wrap;\n gap: var(--_gap);\n flex: 1;\n min-width: 0;\n }\n\n /* ─── Individual Field ─── */\n\n .field {\n display: flex;\n flex-direction: column;\n gap: var(--hx-space-1, 0.25rem);\n min-width: 0;\n }\n\n .field__label {\n font-size: var(--_label-font-size);\n color: var(--_label-color);\n font-weight: var(--hx-font-weight-medium, 500);\n line-height: var(--hx-line-height-tight, 1.25);\n white-space: nowrap;\n }\n\n .field__value {\n font-size: var(--_value-font-size);\n color: var(--_value-color);\n font-weight: var(--hx-font-weight-normal, 400);\n line-height: var(--hx-line-height-normal, 1.5);\n display: flex;\n align-items: center;\n gap: var(--hx-space-1, 0.25rem);\n }\n\n /* ─── Identifier Rule Violation ─── */\n /* Visual indicator when Joint Commission two-identifier rule is not met. */\n\n :host([aria-invalid='true']) .banner {\n border-bottom-color: var(--hx-color-error-400, #f87171);\n background-color: var(--hx-color-error-50, #fef2f2);\n /* Darken label color to maintain 4.5:1 contrast on error-50 background. */\n --_label-color: var(--hx-patient-banner-label-color, var(--hx-color-neutral-700, #334155));\n }\n\n :host([aria-invalid='true']) .banner::before {\n content: '';\n display: block;\n position: absolute;\n inset-inline-start: 0;\n top: 0;\n bottom: 0;\n width: var(--hx-border-width-thick, 4px);\n background-color: var(--hx-color-error-500, #dc2626);\n border-radius: 0;\n }\n\n /* ─── Visually-hidden violation live region ─── */\n /* Announces identifier rule violations to screen readers without visible text. */\n\n .violation-message {\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-width: 0;\n }\n\n /* ─── Motion reduction ─── */\n\n @media (prefers-reduced-motion: reduce) {\n * {\n transition: none !important;\n animation: none !important;\n }\n }\n\n /* ─── Forced Colors (Windows High Contrast) ─── */\n\n @media (forced-colors: active) {\n .banner {\n border-bottom-color: CanvasText;\n }\n\n :host([aria-invalid='true']) .banner {\n border-bottom-color: LinkText;\n }\n\n :host([aria-invalid='true']) .banner::before {\n background-color: LinkText;\n }\n\n .banner__photo-area {\n border: 1px solid CanvasText;\n }\n }\n`;\n","import { html, nothing, type PropertyValues } from 'lit';\nimport '../../utilities/document-token-adoption.js';\nimport { customElement, property, state, query } from 'lit/decorators.js';\nimport { HelixElement } from '../../base/index.js';\nimport { helixPatientBannerStyles } from './hx-patient-banner.styles.js';\n\n/**\n * Patient identification banner implementing Joint Commission NPSG.01.01.01 two-identifier rule.\n * Renders as a landmark region containing named slots for patient identification fields.\n * Integrates with hx-phi-field for HIPAA-compliant display of masked identifiers.\n *\n * ## Security Model — Event Composition\n *\n * This component dispatches and propagates two categories of composed events:\n *\n * ### `hx-identifier-rule-violation` (dispatched by this component)\n * Fired with `composed: true` when the two-identifier rule is violated. The event detail\n * contains only structural metadata (`populatedIdentifiers` count, `requiredIdentifiers`\n * count) and the `patientId` attribute value. **No raw PHI is included.**\n *\n * The `patientId` is a developer-provided attribute intended as a correlation key for\n * application logic — it should be an opaque internal identifier (e.g., a UUID or\n * encounter ID), not a human-readable identifier like an MRN or SSN.\n *\n * ### `hx-phi-access` (bubbles from slotted hx-phi-field children)\n * Slotted `hx-phi-field` elements dispatch `hx-phi-access` with `composed: true`. These\n * events bubble through this component's shadow DOM via slot projection. This component\n * does NOT re-dispatch or modify these events. See `hx-phi-field` documentation for the\n * security model of those events.\n *\n * ### Consumer Responsibilities\n *\n * - **Multi-tenant isolation**: In micro-frontend architectures where multiple patient\n * contexts share a document, scope event listeners to the appropriate DOM subtree.\n * Both `hx-phi-access` and `hx-identifier-rule-violation` use `composed: true` and\n * will bubble through shared ancestors across shadow boundaries.\n * - **patientId hygiene**: Set the `patient-id` attribute to an opaque internal\n * identifier, not a human-readable clinical identifier. This value appears in\n * composed events that cross shadow boundaries.\n *\n * @summary Patient identification banner with two-identifier rule enforcement.\n *\n * @tag hx-patient-banner\n *\n * @slot photo - Optional patient photo slot.\n * @slot name - Patient name field content.\n * @slot mrn - Medical record number field content. Use hx-phi-field for HIPAA compliance.\n * @slot dob - Date of birth field content. Use hx-phi-field for HIPAA compliance.\n * @slot allergies - Allergy status/flag content.\n * @slot code-status - Code status content.\n *\n * @csspart banner - The outer banner container.\n * @csspart photo-area - The photo slot wrapper.\n * @csspart fields - The fields grid container.\n * @csspart field - An individual field container (applied to all field wrappers).\n * @csspart field-label - The field label element.\n * @csspart field-value - The field value slot wrapper.\n * @csspart violation-message - The visually-hidden identifier rule violation status message.\n *\n * @fires {CustomEvent<PatientIdentifierRuleViolationDetail>} hx-identifier-rule-violation -\n * Fired when fewer than 2 identifier slots are populated and enforce-identifier-rule is\n * true. Contains structural metadata only — no raw PHI. Dispatched with `composed: true`.\n *\n * @cssprop [--hx-patient-banner-bg=var(--hx-color-neutral-50,#f9fafb)] - Banner background color.\n * @cssprop [--hx-patient-banner-border-color=var(--hx-color-neutral-200,#e5e7eb)] - Banner border color.\n * @cssprop [--hx-patient-banner-padding=var(--hx-space-3,0.75rem) var(--hx-space-4,1rem)] - Banner padding.\n * @cssprop [--hx-patient-banner-gap=var(--hx-space-4,1rem)] - Gap between banner fields.\n * @cssprop [--hx-patient-banner-font-family=var(--hx-font-family-sans,sans-serif)] - Banner font family.\n * @cssprop [--hx-patient-banner-label-color=var(--hx-color-neutral-500,#6b7280)] - Field label color.\n * @cssprop [--hx-patient-banner-label-font-size=var(--hx-font-size-xs,0.75rem)] - Field label font size.\n * @cssprop [--hx-patient-banner-value-color=var(--hx-color-neutral-900,#111827)] - Field value color.\n * @cssprop [--hx-patient-banner-value-font-size=var(--hx-font-size-sm,0.875rem)] - Field value font size.\n * @cssprop [--hx-patient-banner-photo-size=var(--hx-space-10,2.5rem)] - Photo area size.\n * @cssprop [--hx-patient-banner-photo-bg=var(--hx-color-neutral-200,#e5e7eb)] - Photo area background color when empty.\n * @cssprop [--hx-color-neutral-50] - Color.\n * @cssprop [--hx-color-neutral-200] - Color.\n * @cssprop [--hx-space-3] - Spacing token.\n * @cssprop [--hx-space-4] - Spacing token.\n * @cssprop [--hx-font-family-sans] - Font family.\n * @cssprop [--hx-color-neutral-500] - Color.\n * @cssprop [--hx-font-size-xs] - Font size.\n * @cssprop [--hx-color-neutral-900] - Color.\n * @cssprop [--hx-font-size-sm] - Font size.\n * @cssprop [--hx-space-10] - Spacing token.\n * @cssprop [--hx-border-width-thin] - Width.\n * @cssprop [--hx-touch-target-size] - Minimum touch target size.\n * @cssprop [--hx-border-radius-full] - CSS custom property.\n * @cssprop [--hx-space-1] - Spacing token.\n * @cssprop [--hx-font-weight-medium] - Font weight.\n * @cssprop [--hx-line-height-tight] - Line height.\n * @cssprop [--hx-font-weight-normal] - Font weight.\n * @cssprop [--hx-line-height-normal] - Line height.\n * @cssprop [--hx-color-error-400] - Color.\n * @cssprop [--hx-color-error-50] - Color.\n * @cssprop [--hx-color-neutral-700] - Color.\n * @cssprop [--hx-border-width-thick] - Width.\n * @cssprop [--hx-color-error-500] - Color.\n */\n@customElement('hx-patient-banner')\nexport class HelixPatientBanner extends HelixElement {\n static override styles = [helixPatientBannerStyles];\n\n // ─── Public Properties ───\n\n /**\n * Optional patient ID used as context in identifier rule violation events.\n * @attr patient-id\n */\n @property({ type: String, attribute: 'patient-id' })\n patientId: string = '';\n\n /**\n * Accessible label for the banner landmark region.\n * @attr label-patient\n */\n @property({ type: String, attribute: 'label-patient' })\n labelPatient: string = 'Patient identification';\n\n /**\n * Visible label for the name field.\n * @attr label-name\n */\n @property({ type: String, attribute: 'label-name' })\n labelName: string = 'Patient name';\n\n /**\n * Visible label for the MRN field.\n * @attr label-mrn\n */\n @property({ type: String, attribute: 'label-mrn' })\n labelMrn: string = 'MRN';\n\n /**\n * Visible label for the date of birth field.\n * @attr label-dob\n */\n @property({ type: String, attribute: 'label-dob' })\n labelDob: string = 'Date of birth';\n\n /**\n * Visible label for the allergies field.\n * @attr label-allergies\n */\n @property({ type: String, attribute: 'label-allergies' })\n labelAllergies: string = 'Allergies';\n\n /**\n * Visible label for the code status field.\n * @attr label-code-status\n */\n @property({ type: String, attribute: 'label-code-status' })\n labelCodeStatus: string = 'Code status';\n\n /**\n * Whether to enforce the Joint Commission NPSG.01.01.01 two-identifier rule.\n * When true, fires hx-identifier-rule-violation if fewer than 2 identifier\n * slots (name, mrn, dob) are populated.\n * @attr enforce-identifier-rule\n */\n @property({\n attribute: 'enforce-identifier-rule',\n reflect: true,\n converter: {\n fromAttribute: (value: string | null) => value !== 'false',\n toAttribute: (value: boolean) => String(value),\n },\n })\n enforceIdentifierRule: boolean = true;\n\n // ─── Internal State ───\n\n /** @internal */\n @state() private _identifierCount: number = 0;\n\n /** @internal */\n @state() private _isViolating: boolean = false;\n\n // ─── Slot Queries ───\n\n /** @internal */\n @query('slot[name=\"name\"]') private _nameSlot!: HTMLSlotElement | null;\n\n /** @internal */\n @query('slot[name=\"mrn\"]') private _mrnSlot!: HTMLSlotElement | null;\n\n /** @internal */\n @query('slot[name=\"dob\"]') private _dobSlot!: HTMLSlotElement | null;\n\n // ─── Lifecycle ───\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.setAttribute('role', 'banner');\n this.setAttribute('aria-label', this.labelPatient);\n }\n\n protected override updated(changedProperties: PropertyValues<this>): void {\n super.updated(changedProperties);\n\n if (changedProperties.has('labelPatient')) {\n this.setAttribute('aria-label', this.labelPatient);\n }\n\n if (changedProperties.has('enforceIdentifierRule')) {\n this._checkIdentifierRule();\n }\n }\n\n // ─── Private Helpers ───\n\n private _countPopulatedIdentifiers(): number {\n let count = 0;\n\n const slots = [this._nameSlot, this._mrnSlot, this._dobSlot];\n for (const slot of slots) {\n if (slot && slot.assignedNodes({ flatten: true }).length > 0) {\n count++;\n }\n }\n\n return count;\n }\n\n private _checkIdentifierRule(): void {\n const count = this._countPopulatedIdentifiers();\n this._identifierCount = count;\n\n if (this.enforceIdentifierRule && count < 2) {\n this._isViolating = true;\n this.setAttribute('aria-invalid', 'true');\n this.dispatchEvent(\n new CustomEvent<PatientIdentifierRuleViolationDetail>('hx-identifier-rule-violation', {\n bubbles: true,\n composed: true,\n detail: {\n populatedIdentifiers: count,\n requiredIdentifiers: 2,\n patientId: this.patientId,\n },\n }),\n );\n } else {\n this._isViolating = false;\n this.removeAttribute('aria-invalid');\n }\n }\n\n // ─── Event Handlers ───\n\n private _handleSlotChange(): void {\n this._checkIdentifierRule();\n }\n\n // ─── Render ───\n\n override render() {\n const violationMessage = this._isViolating\n ? `Warning: patient identification incomplete. ${this._identifierCount} of 2 required identifiers present.`\n : nothing;\n\n return html`\n <div part=\"banner\" class=\"banner\">\n <div part=\"photo-area\" class=\"banner__photo-area\" aria-hidden=\"true\">\n <slot name=\"photo\"></slot>\n </div>\n\n <div part=\"fields\" class=\"banner__fields\">\n <div part=\"field\" class=\"field\">\n <span part=\"field-label\" class=\"field__label\">${this.labelName}</span>\n <div part=\"field-value\" class=\"field__value\">\n <slot name=\"name\" @slotchange=${this._handleSlotChange}></slot>\n </div>\n </div>\n\n <div part=\"field\" class=\"field\">\n <span part=\"field-label\" class=\"field__label\">${this.labelMrn}</span>\n <div part=\"field-value\" class=\"field__value\">\n <slot name=\"mrn\" @slotchange=${this._handleSlotChange}></slot>\n </div>\n </div>\n\n <div part=\"field\" class=\"field\">\n <span part=\"field-label\" class=\"field__label\">${this.labelDob}</span>\n <div part=\"field-value\" class=\"field__value\">\n <slot name=\"dob\" @slotchange=${this._handleSlotChange}></slot>\n </div>\n </div>\n\n <div part=\"field\" class=\"field\">\n <span part=\"field-label\" class=\"field__label\">${this.labelAllergies}</span>\n <div part=\"field-value\" class=\"field__value\">\n <slot name=\"allergies\"></slot>\n </div>\n </div>\n\n <div part=\"field\" class=\"field\">\n <span part=\"field-label\" class=\"field__label\">${this.labelCodeStatus}</span>\n <div part=\"field-value\" class=\"field__value\">\n <slot name=\"code-status\"></slot>\n </div>\n </div>\n </div>\n </div>\n\n ${violationMessage !== nothing\n ? html`<div\n part=\"violation-message\"\n class=\"violation-message\"\n role=\"alert\"\n aria-live=\"assertive\"\n >\n ${violationMessage}\n </div>`\n : nothing}\n `;\n }\n}\n\n/**\n * Event detail for identifier rule violations. Contains only structural metadata\n * about the validation state — never raw PHI values.\n *\n * **Security note**: The `patientId` field reflects the `patient-id` HTML attribute,\n * which should be set to an opaque internal identifier (UUID, encounter ID), not a\n * human-readable clinical identifier. This value crosses shadow DOM boundaries via\n * `composed: true` events.\n */\nexport interface PatientIdentifierRuleViolationDetail {\n /** Number of identifier slots currently populated (0, 1, or 2). */\n populatedIdentifiers: number;\n /** Minimum required identifiers per NPSG.01.01.01 (always 2). */\n requiredIdentifiers: number;\n /** Opaque patient identifier from the patient-id attribute. Should NOT contain raw PHI. */\n patientId: string;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-patient-banner': HelixPatientBanner;\n }\n}\n"],"names":["helixPatientBannerStyles","css","HelixPatientBanner","HelixElement","changedProperties","count","slots","slot","violationMessage","nothing","html","__decorateClass","property","value","state","query","customElement"],"mappings":"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"}
|
|
@@ -21,12 +21,12 @@ const _ = c`
|
|
|
21
21
|
.phi-field__value--masked {
|
|
22
22
|
user-select: none;
|
|
23
23
|
-webkit-user-select: none;
|
|
24
|
-
color: var(--hx-phi-field-masked-color, var(--hx-color-
|
|
24
|
+
color: var(--hx-phi-field-masked-color, var(--hx-color-text-muted, #64748b));
|
|
25
25
|
letter-spacing: var(--hx-phi-field-letter-spacing, 0.1em);
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
.phi-field__value--revealed {
|
|
29
|
-
color: var(--hx-phi-field-value-color, var(--hx-color-
|
|
29
|
+
color: var(--hx-phi-field-value-color, var(--hx-color-text-primary, #0f172a));
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
/* ─── Screen Reader Status ─── */
|
|
@@ -391,4 +391,4 @@ i = r([
|
|
|
391
391
|
export {
|
|
392
392
|
i as H
|
|
393
393
|
};
|
|
394
|
-
//# sourceMappingURL=hx-phi-field-
|
|
394
|
+
//# sourceMappingURL=hx-phi-field-DxeWcRm9.js.map
|