@helixui/library 2.1.2 → 3.0.0-next.65
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 +904 -1044
- package/dist/base/helix-element.d.ts +20 -8
- package/dist/base/helix-element.d.ts.map +1 -1
- package/dist/components/hx-accordion/hx-accordion-item.d.ts +7 -4
- package/dist/components/hx-accordion/hx-accordion-item.d.ts.map +1 -1
- package/dist/components/hx-accordion/hx-accordion-item.styles.d.ts.map +1 -1
- package/dist/components/hx-accordion/hx-accordion.d.ts +3 -2
- package/dist/components/hx-accordion/hx-accordion.d.ts.map +1 -1
- package/dist/components/hx-accordion/hx-accordion.styles.d.ts.map +1 -1
- package/dist/components/hx-accordion/index.d.ts +1 -0
- package/dist/components/hx-accordion/index.d.ts.map +1 -1
- package/dist/components/hx-accordion/index.js +1 -1
- package/dist/components/hx-action-bar/hx-action-bar.d.ts +26 -14
- package/dist/components/hx-action-bar/hx-action-bar.d.ts.map +1 -1
- package/dist/components/hx-action-bar/hx-action-bar.styles.d.ts.map +1 -1
- package/dist/components/hx-action-bar/index.js +1 -1
- package/dist/components/hx-alert/hx-alert.d.ts +7 -2
- package/dist/components/hx-alert/hx-alert.d.ts.map +1 -1
- package/dist/components/hx-alert/hx-alert.styles.d.ts.map +1 -1
- package/dist/components/hx-alert/index.d.ts +1 -0
- package/dist/components/hx-alert/index.d.ts.map +1 -1
- package/dist/components/hx-alert/index.js +1 -1
- package/dist/components/hx-avatar/hx-avatar.d.ts +3 -2
- package/dist/components/hx-avatar/hx-avatar.d.ts.map +1 -1
- package/dist/components/hx-avatar/index.js +1 -1
- package/dist/components/hx-badge/hx-badge.d.ts +2 -9
- package/dist/components/hx-badge/hx-badge.d.ts.map +1 -1
- package/dist/components/hx-badge/hx-badge.styles.d.ts.map +1 -1
- package/dist/components/hx-badge/index.d.ts +1 -1
- package/dist/components/hx-badge/index.d.ts.map +1 -1
- package/dist/components/hx-badge/index.js +1 -1
- package/dist/components/hx-banner/hx-banner.d.ts +3 -2
- package/dist/components/hx-banner/hx-banner.d.ts.map +1 -1
- package/dist/components/hx-banner/hx-banner.styles.d.ts.map +1 -1
- package/dist/components/hx-banner/index.js +1 -1
- package/dist/components/hx-breadcrumb/hx-breadcrumb-item.d.ts +2 -2
- package/dist/components/hx-breadcrumb/hx-breadcrumb-item.d.ts.map +1 -1
- package/dist/components/hx-breadcrumb/hx-breadcrumb-item.styles.d.ts.map +1 -1
- package/dist/components/hx-breadcrumb/hx-breadcrumb.d.ts +9 -19
- package/dist/components/hx-breadcrumb/hx-breadcrumb.d.ts.map +1 -1
- package/dist/components/hx-breadcrumb/hx-breadcrumb.styles.d.ts.map +1 -1
- package/dist/components/hx-breadcrumb/index.js +1 -1
- package/dist/components/hx-button/hx-button.d.ts +31 -9
- package/dist/components/hx-button/hx-button.d.ts.map +1 -1
- package/dist/components/hx-button/hx-button.styles.d.ts.map +1 -1
- package/dist/components/hx-button/index.d.ts +1 -0
- package/dist/components/hx-button/index.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 +4 -6
- package/dist/components/hx-button-group/hx-button-group.d.ts.map +1 -1
- package/dist/components/hx-button-group/hx-button-group.styles.d.ts.map +1 -1
- package/dist/components/hx-button-group/index.js +1 -1
- package/dist/components/hx-card/hx-card.d.ts +19 -2
- package/dist/components/hx-card/hx-card.d.ts.map +1 -1
- package/dist/components/hx-card/hx-card.styles.d.ts.map +1 -1
- package/dist/components/hx-card/index.js +1 -1
- package/dist/components/hx-carousel/hx-carousel-item.d.ts +2 -2
- package/dist/components/hx-carousel/hx-carousel-item.d.ts.map +1 -1
- package/dist/components/hx-carousel/hx-carousel-item.styles.d.ts.map +1 -1
- package/dist/components/hx-carousel/hx-carousel.d.ts +2 -2
- package/dist/components/hx-carousel/hx-carousel.d.ts.map +1 -1
- package/dist/components/hx-carousel/hx-carousel.styles.d.ts.map +1 -1
- package/dist/components/hx-carousel/index.js +1 -1
- package/dist/components/hx-checkbox/hx-checkbox.d.ts +52 -5
- package/dist/components/hx-checkbox/hx-checkbox.d.ts.map +1 -1
- package/dist/components/hx-checkbox/hx-checkbox.styles.d.ts.map +1 -1
- package/dist/components/hx-checkbox/index.d.ts +1 -0
- package/dist/components/hx-checkbox/index.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 -20
- package/dist/components/hx-checkbox-group/hx-checkbox-group.d.ts.map +1 -1
- package/dist/components/hx-checkbox-group/hx-checkbox-group.styles.d.ts.map +1 -1
- package/dist/components/hx-checkbox-group/index.d.ts +1 -0
- package/dist/components/hx-checkbox-group/index.d.ts.map +1 -1
- package/dist/components/hx-checkbox-group/index.js +1 -1
- package/dist/components/hx-clinical-status/hx-clinical-status.styles.d.ts.map +1 -1
- package/dist/components/hx-clinical-status/index.js +1 -1
- package/dist/components/hx-code-snippet/hx-code-snippet.d.ts +3 -2
- package/dist/components/hx-code-snippet/hx-code-snippet.d.ts.map +1 -1
- package/dist/components/hx-code-snippet/hx-code-snippet.styles.d.ts.map +1 -1
- package/dist/components/hx-code-snippet/index.js +1 -1
- package/dist/components/hx-color-picker/hx-color-picker.d.ts +12 -19
- package/dist/components/hx-color-picker/hx-color-picker.d.ts.map +1 -1
- package/dist/components/hx-color-picker/hx-color-picker.styles.d.ts.map +1 -1
- package/dist/components/hx-color-picker/index.d.ts +1 -0
- package/dist/components/hx-color-picker/index.d.ts.map +1 -1
- package/dist/components/hx-color-picker/index.js +1 -1
- package/dist/components/hx-combobox/hx-combobox.d.ts +45 -22
- package/dist/components/hx-combobox/hx-combobox.d.ts.map +1 -1
- package/dist/components/hx-combobox/hx-combobox.styles.d.ts.map +1 -1
- package/dist/components/hx-combobox/index.d.ts +1 -0
- package/dist/components/hx-combobox/index.d.ts.map +1 -1
- package/dist/components/hx-combobox/index.js +1 -1
- package/dist/components/hx-container/hx-container.d.ts +2 -4
- package/dist/components/hx-container/hx-container.d.ts.map +1 -1
- package/dist/components/hx-container/hx-container.styles.d.ts.map +1 -1
- package/dist/components/hx-container/index.d.ts +0 -1
- package/dist/components/hx-container/index.d.ts.map +1 -1
- package/dist/components/hx-container/index.js +1 -1
- package/dist/components/hx-copy-button/hx-copy-button.d.ts +2 -2
- package/dist/components/hx-copy-button/hx-copy-button.d.ts.map +1 -1
- package/dist/components/hx-copy-button/hx-copy-button.styles.d.ts.map +1 -1
- package/dist/components/hx-copy-button/index.js +1 -1
- package/dist/components/hx-counter/hx-counter.d.ts +23 -2
- package/dist/components/hx-counter/hx-counter.d.ts.map +1 -1
- package/dist/components/hx-counter/hx-counter.styles.d.ts.map +1 -1
- package/dist/components/hx-counter/index.js +1 -1
- package/dist/components/hx-data-table/hx-data-table.d.ts +46 -2
- 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.d.ts +1 -0
- package/dist/components/hx-data-table/index.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 +35 -35
- package/dist/components/hx-date-picker/hx-date-picker.d.ts.map +1 -1
- package/dist/components/hx-date-picker/hx-date-picker.styles.d.ts.map +1 -1
- package/dist/components/hx-date-picker/index.d.ts +1 -0
- package/dist/components/hx-date-picker/index.d.ts.map +1 -1
- package/dist/components/hx-date-picker/index.js +1 -1
- package/dist/components/hx-dialog/hx-dialog.d.ts +44 -5
- package/dist/components/hx-dialog/hx-dialog.d.ts.map +1 -1
- package/dist/components/hx-dialog/hx-dialog.styles.d.ts.map +1 -1
- package/dist/components/hx-dialog/index.js +1 -1
- package/dist/components/hx-divider/hx-divider.d.ts +3 -4
- package/dist/components/hx-divider/hx-divider.d.ts.map +1 -1
- package/dist/components/hx-divider/hx-divider.styles.d.ts.map +1 -1
- package/dist/components/hx-divider/index.d.ts +0 -1
- package/dist/components/hx-divider/index.d.ts.map +1 -1
- package/dist/components/hx-divider/index.js +1 -1
- package/dist/components/hx-drawer/hx-drawer.d.ts +39 -2
- 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 +11 -7
- package/dist/components/hx-dropdown/hx-dropdown.d.ts.map +1 -1
- package/dist/components/hx-dropdown/hx-dropdown.styles.d.ts.map +1 -1
- package/dist/components/hx-dropdown/index.js +1 -1
- package/dist/components/hx-field/hx-field.d.ts +4 -3
- package/dist/components/hx-field/hx-field.d.ts.map +1 -1
- package/dist/components/hx-field/hx-field.styles.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 +2 -2
- package/dist/components/hx-field-label/hx-field-label.d.ts.map +1 -1
- package/dist/components/hx-field-label/hx-field-label.styles.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 +38 -18
- package/dist/components/hx-file-upload/hx-file-upload.d.ts.map +1 -1
- package/dist/components/hx-file-upload/hx-file-upload.styles.d.ts.map +1 -1
- package/dist/components/hx-file-upload/index.d.ts +1 -0
- package/dist/components/hx-file-upload/index.d.ts.map +1 -1
- package/dist/components/hx-file-upload/index.js +1 -1
- package/dist/components/hx-form/hx-form.d.ts +2 -2
- package/dist/components/hx-form/hx-form.d.ts.map +1 -1
- package/dist/components/hx-form/hx-form.styles.d.ts +8 -0
- package/dist/components/hx-form/hx-form.styles.d.ts.map +1 -1
- package/dist/components/hx-form/index.js +1 -1
- package/dist/components/hx-format-date/hx-format-date.d.ts +2 -2
- package/dist/components/hx-format-date/hx-format-date.d.ts.map +1 -1
- package/dist/components/hx-format-date/hx-format-date.styles.d.ts.map +1 -1
- package/dist/components/hx-format-date/index.js +1 -1
- package/dist/components/hx-grid/hx-grid.d.ts +4 -3
- package/dist/components/hx-grid/hx-grid.d.ts.map +1 -1
- package/dist/components/hx-grid/hx-grid.styles.d.ts.map +1 -1
- package/dist/components/hx-grid/index.js +1 -1
- package/dist/components/hx-help-text/hx-help-text.d.ts +2 -4
- package/dist/components/hx-help-text/hx-help-text.d.ts.map +1 -1
- package/dist/components/hx-help-text/hx-help-text.styles.d.ts.map +1 -1
- package/dist/components/hx-help-text/index.js +1 -1
- package/dist/components/hx-icon/hx-icon.d.ts +17 -2
- package/dist/components/hx-icon/hx-icon.d.ts.map +1 -1
- package/dist/components/hx-icon/hx-icon.styles.d.ts.map +1 -1
- package/dist/components/hx-icon/index.js +1 -1
- package/dist/components/hx-icon-button/hx-icon-button.d.ts +10 -14
- package/dist/components/hx-icon-button/hx-icon-button.d.ts.map +1 -1
- package/dist/components/hx-icon-button/hx-icon-button.styles.d.ts.map +1 -1
- package/dist/components/hx-icon-button/index.js +1 -1
- package/dist/components/hx-image/hx-image.d.ts +2 -2
- package/dist/components/hx-image/hx-image.d.ts.map +1 -1
- package/dist/components/hx-image/hx-image.styles.d.ts.map +1 -1
- package/dist/components/hx-image/index.js +1 -1
- package/dist/components/hx-link/hx-link.d.ts +4 -2
- package/dist/components/hx-link/hx-link.d.ts.map +1 -1
- package/dist/components/hx-link/hx-link.styles.d.ts.map +1 -1
- package/dist/components/hx-link/index.js +1 -1
- package/dist/components/hx-list/hx-list-item.d.ts +3 -2
- package/dist/components/hx-list/hx-list-item.d.ts.map +1 -1
- package/dist/components/hx-list/hx-list-item.styles.d.ts.map +1 -1
- package/dist/components/hx-list/hx-list.d.ts +3 -2
- package/dist/components/hx-list/hx-list.d.ts.map +1 -1
- package/dist/components/hx-list/hx-list.styles.d.ts.map +1 -1
- package/dist/components/hx-list/index.js +1 -1
- package/dist/components/hx-menu/hx-menu-divider.d.ts +2 -2
- package/dist/components/hx-menu/hx-menu-divider.d.ts.map +1 -1
- package/dist/components/hx-menu/hx-menu-divider.styles.d.ts.map +1 -1
- package/dist/components/hx-menu/hx-menu-item.d.ts +2 -2
- package/dist/components/hx-menu/hx-menu-item.d.ts.map +1 -1
- package/dist/components/hx-menu/hx-menu-item.styles.d.ts.map +1 -1
- package/dist/components/hx-menu/hx-menu.d.ts +2 -2
- package/dist/components/hx-menu/hx-menu.d.ts.map +1 -1
- package/dist/components/hx-menu/hx-menu.styles.d.ts.map +1 -1
- package/dist/components/hx-menu/index.js +1 -1
- package/dist/components/hx-meter/hx-meter.d.ts +3 -4
- package/dist/components/hx-meter/hx-meter.d.ts.map +1 -1
- package/dist/components/hx-meter/hx-meter.styles.d.ts.map +1 -1
- package/dist/components/hx-meter/index.js +1 -1
- package/dist/components/hx-nav/hx-nav.d.ts +2 -4
- package/dist/components/hx-nav/hx-nav.d.ts.map +1 -1
- package/dist/components/hx-nav/hx-nav.styles.d.ts.map +1 -1
- package/dist/components/hx-nav/index.d.ts +1 -1
- package/dist/components/hx-nav/index.d.ts.map +1 -1
- package/dist/components/hx-nav/index.js +1 -1
- package/dist/components/hx-number-input/hx-number-input.d.ts +14 -20
- package/dist/components/hx-number-input/hx-number-input.d.ts.map +1 -1
- package/dist/components/hx-number-input/hx-number-input.styles.d.ts.map +1 -1
- package/dist/components/hx-number-input/index.d.ts +1 -0
- package/dist/components/hx-number-input/index.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 +2 -2
- package/dist/components/hx-overflow-menu/hx-overflow-menu.d.ts.map +1 -1
- package/dist/components/hx-overflow-menu/hx-overflow-menu.styles.d.ts.map +1 -1
- package/dist/components/hx-overflow-menu/index.js +1 -1
- package/dist/components/hx-pagination/hx-pagination.d.ts +10 -2
- package/dist/components/hx-pagination/hx-pagination.d.ts.map +1 -1
- package/dist/components/hx-pagination/index.d.ts +1 -0
- package/dist/components/hx-pagination/index.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 +47 -5
- package/dist/components/hx-patient-banner/hx-patient-banner.d.ts.map +1 -1
- package/dist/components/hx-patient-banner/hx-patient-banner.styles.d.ts.map +1 -1
- package/dist/components/hx-patient-banner/index.js +1 -1
- package/dist/components/hx-phi-field/hx-phi-field.d.ts +87 -6
- package/dist/components/hx-phi-field/hx-phi-field.d.ts.map +1 -1
- package/dist/components/hx-phi-field/hx-phi-field.styles.d.ts.map +1 -1
- package/dist/components/hx-phi-field/index.js +1 -1
- package/dist/components/hx-popover/hx-popover.d.ts +4 -2
- package/dist/components/hx-popover/hx-popover.d.ts.map +1 -1
- package/dist/components/hx-popover/hx-popover.styles.d.ts.map +1 -1
- package/dist/components/hx-popover/index.js +1 -1
- package/dist/components/hx-popup/hx-popup.d.ts +7 -2
- package/dist/components/hx-popup/hx-popup.d.ts.map +1 -1
- package/dist/components/hx-popup/hx-popup.styles.d.ts.map +1 -1
- package/dist/components/hx-popup/index.js +1 -1
- package/dist/components/hx-progress-bar/hx-progress-bar.d.ts +3 -4
- 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 +3 -2
- package/dist/components/hx-progress-ring/hx-progress-ring.d.ts.map +1 -1
- package/dist/components/hx-progress-ring/hx-progress-ring.styles.d.ts.map +1 -1
- package/dist/components/hx-progress-ring/index.js +1 -1
- package/dist/components/hx-prose/hx-prose.d.ts +3 -2
- package/dist/components/hx-prose/hx-prose.d.ts.map +1 -1
- package/dist/components/hx-prose/hx-prose.styles.d.ts +8 -0
- package/dist/components/hx-prose/hx-prose.styles.d.ts.map +1 -1
- package/dist/components/hx-prose/index.js +1 -1
- package/dist/components/hx-radio-group/hx-radio-group.d.ts +14 -39
- package/dist/components/hx-radio-group/hx-radio-group.d.ts.map +1 -1
- package/dist/components/hx-radio-group/hx-radio-group.styles.d.ts.map +1 -1
- package/dist/components/hx-radio-group/hx-radio.d.ts +19 -4
- package/dist/components/hx-radio-group/hx-radio.d.ts.map +1 -1
- package/dist/components/hx-radio-group/hx-radio.styles.d.ts.map +1 -1
- package/dist/components/hx-radio-group/index.d.ts +1 -0
- package/dist/components/hx-radio-group/index.d.ts.map +1 -1
- package/dist/components/hx-radio-group/index.js +1 -1
- package/dist/components/hx-rating/hx-rating.d.ts +9 -20
- package/dist/components/hx-rating/hx-rating.d.ts.map +1 -1
- package/dist/components/hx-rating/hx-rating.styles.d.ts.map +1 -1
- package/dist/components/hx-rating/index.d.ts +1 -0
- package/dist/components/hx-rating/index.d.ts.map +1 -1
- package/dist/components/hx-rating/index.js +1 -1
- package/dist/components/hx-select/hx-select.d.ts +26 -17
- 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.d.ts +1 -0
- package/dist/components/hx-select/index.d.ts.map +1 -1
- package/dist/components/hx-select/index.js +1 -1
- package/dist/components/hx-side-nav/hx-nav-item.d.ts +2 -5
- package/dist/components/hx-side-nav/hx-nav-item.d.ts.map +1 -1
- package/dist/components/hx-side-nav/hx-nav-item.styles.d.ts.map +1 -1
- package/dist/components/hx-side-nav/hx-side-nav.d.ts +3 -2
- package/dist/components/hx-side-nav/hx-side-nav.d.ts.map +1 -1
- package/dist/components/hx-side-nav/hx-side-nav.styles.d.ts.map +1 -1
- package/dist/components/hx-side-nav/index.js +1 -1
- package/dist/components/hx-skeleton/hx-skeleton.d.ts +4 -3
- package/dist/components/hx-skeleton/hx-skeleton.d.ts.map +1 -1
- package/dist/components/hx-skeleton/hx-skeleton.styles.d.ts.map +1 -1
- package/dist/components/hx-skeleton/index.js +1 -1
- package/dist/components/hx-slider/hx-slider.d.ts +18 -22
- package/dist/components/hx-slider/hx-slider.d.ts.map +1 -1
- package/dist/components/hx-slider/hx-slider.styles.d.ts.map +1 -1
- package/dist/components/hx-slider/index.d.ts +1 -0
- package/dist/components/hx-slider/index.d.ts.map +1 -1
- package/dist/components/hx-slider/index.js +1 -1
- package/dist/components/hx-spinner/hx-spinner.d.ts +2 -2
- package/dist/components/hx-spinner/hx-spinner.d.ts.map +1 -1
- package/dist/components/hx-spinner/hx-spinner.styles.d.ts.map +1 -1
- package/dist/components/hx-spinner/index.js +1 -1
- package/dist/components/hx-split-button/hx-split-button.d.ts +10 -4
- package/dist/components/hx-split-button/hx-split-button.d.ts.map +1 -1
- package/dist/components/hx-split-button/hx-split-button.styles.d.ts.map +1 -1
- package/dist/components/hx-split-button/index.js +1 -1
- package/dist/components/hx-split-panel/hx-split-panel.d.ts +12 -2
- package/dist/components/hx-split-panel/hx-split-panel.d.ts.map +1 -1
- package/dist/components/hx-split-panel/hx-split-panel.styles.d.ts.map +1 -1
- package/dist/components/hx-split-panel/index.js +1 -1
- package/dist/components/hx-stack/hx-stack.d.ts +2 -2
- package/dist/components/hx-stack/hx-stack.d.ts.map +1 -1
- package/dist/components/hx-stack/hx-stack.styles.d.ts.map +1 -1
- package/dist/components/hx-stack/index.js +1 -1
- package/dist/components/hx-stat/hx-stat.d.ts +6 -2
- package/dist/components/hx-stat/hx-stat.d.ts.map +1 -1
- package/dist/components/hx-stat/hx-stat.styles.d.ts.map +1 -1
- package/dist/components/hx-stat/index.js +1 -1
- package/dist/components/hx-status-indicator/hx-status-indicator.d.ts +3 -2
- package/dist/components/hx-status-indicator/hx-status-indicator.d.ts.map +1 -1
- package/dist/components/hx-status-indicator/hx-status-indicator.styles.d.ts.map +1 -1
- package/dist/components/hx-status-indicator/index.js +1 -1
- package/dist/components/hx-steps/hx-step.d.ts +3 -2
- package/dist/components/hx-steps/hx-step.d.ts.map +1 -1
- package/dist/components/hx-steps/hx-step.styles.d.ts.map +1 -1
- package/dist/components/hx-steps/hx-steps.d.ts +11 -4
- package/dist/components/hx-steps/hx-steps.d.ts.map +1 -1
- package/dist/components/hx-steps/hx-steps.styles.d.ts.map +1 -1
- package/dist/components/hx-steps/index.js +1 -1
- package/dist/components/hx-structured-list/hx-structured-list.d.ts +3 -3
- package/dist/components/hx-structured-list/hx-structured-list.d.ts.map +1 -1
- package/dist/components/hx-structured-list/hx-structured-list.styles.d.ts.map +1 -1
- package/dist/components/hx-structured-list/index.js +1 -1
- package/dist/components/hx-style-scope/hx-style-scope.d.ts +4 -3
- package/dist/components/hx-style-scope/hx-style-scope.d.ts.map +1 -1
- package/dist/components/hx-style-scope/hx-style-scope.styles.d.ts.map +1 -1
- package/dist/components/hx-style-scope/index.js +1 -1
- package/dist/components/hx-switch/hx-switch.d.ts +25 -29
- package/dist/components/hx-switch/hx-switch.d.ts.map +1 -1
- package/dist/components/hx-switch/hx-switch.styles.d.ts.map +1 -1
- package/dist/components/hx-switch/index.d.ts +2 -1
- package/dist/components/hx-switch/index.d.ts.map +1 -1
- package/dist/components/hx-switch/index.js +1 -1
- package/dist/components/hx-table/hx-table.d.ts +3 -2
- package/dist/components/hx-table/hx-table.d.ts.map +1 -1
- package/dist/components/hx-table/hx-table.styles.d.ts.map +1 -1
- package/dist/components/hx-table/hx-tbody.d.ts +2 -2
- package/dist/components/hx-table/hx-tbody.d.ts.map +1 -1
- package/dist/components/hx-table/hx-td.d.ts +2 -2
- package/dist/components/hx-table/hx-td.d.ts.map +1 -1
- package/dist/components/hx-table/hx-tfoot.d.ts +2 -2
- package/dist/components/hx-table/hx-tfoot.d.ts.map +1 -1
- package/dist/components/hx-table/hx-th.d.ts +2 -2
- package/dist/components/hx-table/hx-th.d.ts.map +1 -1
- package/dist/components/hx-table/hx-thead.d.ts +2 -2
- package/dist/components/hx-table/hx-thead.d.ts.map +1 -1
- package/dist/components/hx-table/hx-tr.d.ts +2 -2
- package/dist/components/hx-table/hx-tr.d.ts.map +1 -1
- package/dist/components/hx-table/index.js +1 -1
- package/dist/components/hx-tabs/hx-tab-panel.d.ts +2 -2
- package/dist/components/hx-tabs/hx-tab-panel.d.ts.map +1 -1
- package/dist/components/hx-tabs/hx-tab-panel.styles.d.ts.map +1 -1
- package/dist/components/hx-tabs/hx-tab.d.ts +2 -2
- package/dist/components/hx-tabs/hx-tab.d.ts.map +1 -1
- package/dist/components/hx-tabs/hx-tab.styles.d.ts.map +1 -1
- package/dist/components/hx-tabs/hx-tabs.d.ts +14 -2
- package/dist/components/hx-tabs/hx-tabs.d.ts.map +1 -1
- package/dist/components/hx-tabs/hx-tabs.styles.d.ts.map +1 -1
- package/dist/components/hx-tabs/index.d.ts +1 -0
- package/dist/components/hx-tabs/index.d.ts.map +1 -1
- package/dist/components/hx-tabs/index.js +1 -1
- package/dist/components/hx-tag/hx-tag.d.ts +2 -4
- package/dist/components/hx-tag/hx-tag.d.ts.map +1 -1
- package/dist/components/hx-tag/hx-tag.styles.d.ts.map +1 -1
- package/dist/components/hx-tag/index.d.ts +0 -2
- package/dist/components/hx-tag/index.d.ts.map +1 -1
- package/dist/components/hx-tag/index.js +1 -1
- package/dist/components/hx-text/hx-text.d.ts +2 -2
- package/dist/components/hx-text/hx-text.d.ts.map +1 -1
- package/dist/components/hx-text/hx-text.styles.d.ts.map +1 -1
- package/dist/components/hx-text/index.js +1 -1
- package/dist/components/hx-text-input/hx-text-input.d.ts +34 -7
- package/dist/components/hx-text-input/hx-text-input.d.ts.map +1 -1
- package/dist/components/hx-text-input/hx-text-input.styles.d.ts.map +1 -1
- package/dist/components/hx-text-input/index.d.ts +1 -0
- package/dist/components/hx-text-input/index.d.ts.map +1 -1
- package/dist/components/hx-text-input/index.js +1 -1
- package/dist/components/hx-textarea/hx-textarea.d.ts +41 -25
- package/dist/components/hx-textarea/hx-textarea.d.ts.map +1 -1
- package/dist/components/hx-textarea/hx-textarea.styles.d.ts.map +1 -1
- package/dist/components/hx-textarea/index.d.ts +1 -0
- package/dist/components/hx-textarea/index.d.ts.map +1 -1
- package/dist/components/hx-textarea/index.js +1 -1
- package/dist/components/hx-theme/hx-theme.d.ts +3 -11
- package/dist/components/hx-theme/hx-theme.d.ts.map +1 -1
- package/dist/components/hx-theme/hx-theme.styles.d.ts.map +1 -1
- package/dist/components/hx-theme/index.d.ts +0 -2
- package/dist/components/hx-theme/index.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 +13 -31
- package/dist/components/hx-time-picker/hx-time-picker.d.ts.map +1 -1
- package/dist/components/hx-time-picker/hx-time-picker.styles.d.ts.map +1 -1
- package/dist/components/hx-time-picker/index.d.ts +1 -0
- package/dist/components/hx-time-picker/index.d.ts.map +1 -1
- package/dist/components/hx-time-picker/index.js +1 -1
- package/dist/components/hx-toast/hx-toast-stack.d.ts +2 -2
- package/dist/components/hx-toast/hx-toast-stack.d.ts.map +1 -1
- package/dist/components/hx-toast/hx-toast.d.ts +3 -2
- package/dist/components/hx-toast/hx-toast.d.ts.map +1 -1
- package/dist/components/hx-toast/hx-toast.styles.d.ts.map +1 -1
- package/dist/components/hx-toast/index.js +1 -1
- package/dist/components/hx-toggle-button/hx-toggle-button.d.ts +10 -13
- 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.d.ts +1 -0
- package/dist/components/hx-toggle-button/index.d.ts.map +1 -1
- package/dist/components/hx-toggle-button/index.js +1 -1
- package/dist/components/hx-tooltip/hx-tooltip.d.ts +2 -2
- package/dist/components/hx-tooltip/hx-tooltip.d.ts.map +1 -1
- package/dist/components/hx-tooltip/hx-tooltip.styles.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 +2 -2
- package/dist/components/hx-top-nav/hx-top-nav.d.ts.map +1 -1
- package/dist/components/hx-top-nav/hx-top-nav.styles.d.ts.map +1 -1
- package/dist/components/hx-top-nav/index.js +1 -1
- package/dist/components/hx-tree-view/hx-tree-item.d.ts +2 -4
- package/dist/components/hx-tree-view/hx-tree-item.d.ts.map +1 -1
- package/dist/components/hx-tree-view/hx-tree-item.styles.d.ts.map +1 -1
- package/dist/components/hx-tree-view/hx-tree-view.d.ts +2 -4
- package/dist/components/hx-tree-view/hx-tree-view.d.ts.map +1 -1
- package/dist/components/hx-tree-view/hx-tree-view.styles.d.ts.map +1 -1
- package/dist/components/hx-tree-view/index.d.ts +0 -4
- package/dist/components/hx-tree-view/index.d.ts.map +1 -1
- package/dist/components/hx-tree-view/index.js +1 -1
- package/dist/components/hx-visually-hidden/hx-visually-hidden.d.ts +2 -2
- package/dist/components/hx-visually-hidden/hx-visually-hidden.d.ts.map +1 -1
- package/dist/components/hx-visually-hidden/hx-visually-hidden.styles.d.ts.map +1 -1
- package/dist/components/hx-visually-hidden/index.js +1 -1
- package/dist/css/helix-all.css +3717 -786
- package/dist/css/helix-core.css +277 -64
- package/dist/css/helix-data.css +86 -7
- package/dist/css/helix-feedback.css +215 -69
- package/dist/css/helix-forms.css +2122 -127
- package/dist/css/helix-layout.css +53 -7
- package/dist/css/helix-media.css +40 -16
- package/dist/css/helix-navigation.css +209 -48
- package/dist/css/helix-overlay.css +99 -12
- package/dist/css/helix-tokens.css +30 -11
- package/dist/css/helix-utility.css +118 -9
- package/dist/css/hx-accordion.css +9 -1
- package/dist/css/hx-action-bar.css +17 -3
- package/dist/css/hx-alert.css +39 -18
- package/dist/css/hx-avatar.css +1 -1
- package/dist/css/hx-badge.css +59 -24
- package/dist/css/hx-banner.css +35 -18
- package/dist/css/hx-breadcrumb.css +27 -0
- package/dist/css/hx-button-group.css +13 -0
- package/dist/css/hx-button.css +6 -3
- package/dist/css/hx-card.css +18 -6
- package/dist/css/hx-carousel.css +40 -16
- package/dist/css/hx-checkbox-group.css +36 -4
- package/dist/css/hx-checkbox.css +74 -8
- package/dist/css/hx-clinical-status.css +46 -23
- package/dist/css/hx-code-snippet.css +25 -3
- package/dist/css/hx-color-picker.css +276 -1
- package/dist/css/hx-combobox.css +391 -1
- package/dist/css/hx-container.css +10 -6
- package/dist/css/hx-copy-button.css +31 -3
- package/dist/css/hx-counter.css +11 -1
- package/dist/css/hx-data-table.css +24 -1
- package/dist/css/hx-date-picker.css +437 -1
- package/dist/css/hx-dialog.css +23 -2
- package/dist/css/hx-divider.css +8 -0
- package/dist/css/hx-drawer.css +22 -1
- package/dist/css/hx-dropdown.css +10 -1
- package/dist/css/hx-field-label.css +18 -2
- package/dist/css/hx-field.css +39 -3
- package/dist/css/hx-file-upload.css +60 -12
- package/dist/css/hx-format-date.css +11 -0
- package/dist/css/hx-grid.css +10 -0
- package/dist/css/hx-help-text.css +25 -5
- package/dist/css/hx-icon-button.css +27 -0
- package/dist/css/hx-icon.css +8 -0
- package/dist/css/hx-image.css +11 -3
- package/dist/css/hx-link.css +24 -6
- package/dist/css/hx-list.css +10 -0
- package/dist/css/hx-menu.css +10 -2
- package/dist/css/hx-meter.css +28 -14
- package/dist/css/hx-nav.css +27 -12
- package/dist/css/hx-number-input.css +78 -0
- package/dist/css/hx-overflow-menu.css +41 -10
- package/dist/css/hx-pagination.css +13 -13
- package/dist/css/hx-patient-banner.css +30 -10
- package/dist/css/hx-phi-field.css +20 -3
- package/dist/css/hx-popover.css +16 -4
- package/dist/css/hx-popup.css +12 -0
- package/dist/css/hx-progress-bar.css +1 -1
- package/dist/css/hx-progress-ring.css +26 -4
- package/dist/css/hx-radio-group.css +35 -3
- package/dist/css/hx-rating.css +45 -4
- package/dist/css/hx-select.css +89 -9
- package/dist/css/hx-side-nav.css +26 -0
- package/dist/css/hx-skeleton.css +13 -1
- package/dist/css/hx-slider.css +16 -11
- package/dist/css/hx-spinner.css +15 -3
- package/dist/css/hx-split-button.css +37 -2
- package/dist/css/hx-split-panel.css +14 -0
- package/dist/css/hx-stack.css +10 -0
- package/dist/css/hx-stat.css +52 -5
- package/dist/css/hx-status-indicator.css +15 -2
- package/dist/css/hx-steps.css +12 -0
- package/dist/css/hx-structured-list.css +18 -2
- package/dist/css/hx-style-scope.css +11 -0
- package/dist/css/hx-switch.css +66 -4
- package/dist/css/hx-table.css +9 -1
- package/dist/css/hx-tabs.css +15 -3
- package/dist/css/hx-tag.css +24 -12
- package/dist/css/hx-text-input.css +71 -9
- package/dist/css/hx-text.css +38 -5
- package/dist/css/hx-textarea.css +71 -15
- package/dist/css/hx-theme.css +11 -0
- package/dist/css/hx-time-picker.css +224 -1
- package/dist/css/hx-toast.css +19 -7
- package/dist/css/hx-toggle-button.css +41 -4
- package/dist/css/hx-tooltip.css +16 -4
- package/dist/css/hx-top-nav.css +29 -8
- package/dist/css/hx-tree-view.css +9 -0
- package/dist/css/hx-visually-hidden.css +12 -0
- package/dist/css/index.css +1 -1
- package/dist/css/manifest.json +49 -11
- package/dist/form-test-utils.d.ts +45 -0
- package/dist/form-test-utils.d.ts.map +1 -0
- package/dist/index.d.ts +28 -14
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +189 -176
- package/dist/index.js.map +1 -1
- package/dist/mixins/FormMixin.d.ts +24 -5
- package/dist/mixins/FormMixin.d.ts.map +1 -1
- package/dist/mixins/aria-delegation.d.ts +1 -1
- package/dist/mixins/aria-delegation.d.ts.map +1 -1
- package/dist/mixins/index.d.ts +3 -1
- package/dist/mixins/index.d.ts.map +1 -1
- package/dist/shared/{FormMixin-Bjvw20G5.js → FormMixin-B8PXk5RQ.js} +31 -14
- package/dist/shared/FormMixin-B8PXk5RQ.js.map +1 -0
- package/dist/shared/{aria-delegation-CBP9eQ0M.js → aria-delegation-Doq6RRUy.js} +6 -6
- package/dist/shared/aria-delegation-Doq6RRUy.js.map +1 -0
- package/dist/shared/{id-counter-JhvVCnjh.js → helix-element-BNEYeiys.js} +35 -44
- package/dist/shared/helix-element-BNEYeiys.js.map +1 -0
- package/dist/shared/{hx-accordion-CpfO0YQo.js → hx-accordion-Wt52OOZD.js} +127 -80
- package/dist/shared/hx-accordion-Wt52OOZD.js.map +1 -0
- package/dist/shared/{hx-action-bar-BpY1Z1UV.js → hx-action-bar-BKMADbHj.js} +90 -75
- package/dist/shared/hx-action-bar-BKMADbHj.js.map +1 -0
- package/dist/shared/{hx-alert-CHOjTBds.js → hx-alert-D7n94HwI.js} +47 -26
- package/dist/shared/hx-alert-D7n94HwI.js.map +1 -0
- package/dist/shared/{hx-avatar-an-WsuLl.js → hx-avatar-iLYzu8MJ.js} +10 -10
- package/dist/shared/hx-avatar-iLYzu8MJ.js.map +1 -0
- package/dist/shared/{hx-badge-DDXTLoWi.js → hx-badge-CVCmMPyW.js} +78 -43
- package/dist/shared/hx-badge-CVCmMPyW.js.map +1 -0
- package/dist/shared/{hx-banner-B-WEDiq7.js → hx-banner-C_He7Tr4.js} +60 -43
- package/dist/shared/hx-banner-C_He7Tr4.js.map +1 -0
- package/dist/shared/{hx-breadcrumb-item-DzLyeL5Z.js → hx-breadcrumb-item-CldCwD1d.js} +123 -83
- package/dist/shared/hx-breadcrumb-item-CldCwD1d.js.map +1 -0
- package/dist/shared/{hx-button-DoN8jjQT.js → hx-button-Ddl-T6T-.js} +117 -92
- package/dist/shared/hx-button-Ddl-T6T-.js.map +1 -0
- package/dist/shared/{hx-button-group-BXlMQTt_.js → hx-button-group-BJOGWoMa.js} +33 -21
- package/dist/shared/hx-button-group-BJOGWoMa.js.map +1 -0
- package/dist/shared/{hx-card-BgXZXDuc.js → hx-card-ycveujjL.js} +64 -38
- package/dist/shared/hx-card-ycveujjL.js.map +1 -0
- package/dist/shared/{hx-carousel-item-Dwt9Pphz.js → hx-carousel-item-D_dCv61-.js} +76 -41
- package/dist/shared/hx-carousel-item-D_dCv61-.js.map +1 -0
- package/dist/shared/{hx-checkbox-CTEZ9IFq.js → hx-checkbox-DkkoWoye.js} +163 -79
- package/dist/shared/hx-checkbox-DkkoWoye.js.map +1 -0
- package/dist/shared/{hx-checkbox-group-DThZeN5d.js → hx-checkbox-group-C3poJ-Zw.js} +105 -79
- package/dist/shared/hx-checkbox-group-C3poJ-Zw.js.map +1 -0
- package/dist/shared/{hx-clinical-status-m4soOOwg.js → hx-clinical-status-BS5lcddT.js} +74 -51
- package/dist/shared/hx-clinical-status-BS5lcddT.js.map +1 -0
- package/dist/shared/{hx-code-snippet-CoLYvX1Z.js → hx-code-snippet-B7wUKzyb.js} +35 -13
- package/dist/shared/{hx-code-snippet-CoLYvX1Z.js.map → hx-code-snippet-B7wUKzyb.js.map} +1 -1
- package/dist/shared/{hx-color-picker-DhOaNe6-.js → hx-color-picker-DBaKTVLr.js} +360 -98
- package/dist/shared/hx-color-picker-DBaKTVLr.js.map +1 -0
- package/dist/shared/hx-combobox-BmgYT7Ar.js +929 -0
- package/dist/shared/hx-combobox-BmgYT7Ar.js.map +1 -0
- package/dist/shared/{hx-container-31QT9KV_.js → hx-container-DVI7sxfX.js} +27 -23
- package/dist/shared/hx-container-DVI7sxfX.js.map +1 -0
- package/dist/shared/{hx-copy-button-BoM0WsMd.js → hx-copy-button-8deNUdwP.js} +68 -40
- package/dist/shared/hx-copy-button-8deNUdwP.js.map +1 -0
- package/dist/shared/{hx-counter-CP42cSVK.js → hx-counter-CKfl_g8K.js} +88 -43
- package/dist/shared/hx-counter-CKfl_g8K.js.map +1 -0
- package/dist/shared/{hx-data-table-D5Ne-goy.js → hx-data-table-B6h0RPn0.js} +203 -132
- package/dist/shared/hx-data-table-B6h0RPn0.js.map +1 -0
- package/dist/shared/hx-date-picker-Dq2Nb68_.js +1077 -0
- package/dist/shared/hx-date-picker-Dq2Nb68_.js.map +1 -0
- package/dist/shared/{hx-dialog-D4ubstxx.js → hx-dialog-CvIlY0Tc.js} +85 -52
- package/dist/shared/hx-dialog-CvIlY0Tc.js.map +1 -0
- package/dist/shared/{hx-divider-BBtOLHRP.js → hx-divider-DwpOrzMW.js} +23 -15
- package/dist/shared/hx-divider-DwpOrzMW.js.map +1 -0
- package/dist/shared/{hx-drawer--WDLuWtS.js → hx-drawer-Cx2ZJhBe.js} +101 -66
- package/dist/shared/hx-drawer-Cx2ZJhBe.js.map +1 -0
- package/dist/shared/{hx-dropdown-n5-XSmiV.js → hx-dropdown-BjDrPUq5.js} +55 -46
- package/dist/shared/hx-dropdown-BjDrPUq5.js.map +1 -0
- package/dist/shared/{hx-field-CwT9tki1.js → hx-field-Dp3qQMut.js} +61 -25
- package/dist/shared/hx-field-Dp3qQMut.js.map +1 -0
- package/dist/shared/{hx-field-label-CcOK9VU3.js → hx-field-label-BC8QViXv.js} +41 -25
- package/dist/shared/hx-field-label-BC8QViXv.js.map +1 -0
- package/dist/shared/{hx-file-upload-Dwtu3WcB.js → hx-file-upload-B6Yl1u0i.js} +201 -130
- package/dist/shared/hx-file-upload-B6Yl1u0i.js.map +1 -0
- package/dist/shared/{hx-form-fJE-FJQV.js → hx-form-ButQFt9A.js} +13 -18
- package/dist/shared/hx-form-ButQFt9A.js.map +1 -0
- package/dist/shared/{hx-format-date-B7L9odbA.js → hx-format-date-CKnlQOmV.js} +20 -9
- package/dist/shared/hx-format-date-CKnlQOmV.js.map +1 -0
- package/dist/shared/{hx-grid-BIAR5h9m.js → hx-grid-CXZf3jeK.js} +28 -18
- package/dist/shared/hx-grid-CXZf3jeK.js.map +1 -0
- package/dist/shared/{hx-help-text-Bmb80bP4.js → hx-help-text-D7eytSim.js} +45 -25
- package/dist/shared/hx-help-text-D7eytSim.js.map +1 -0
- package/dist/shared/{hx-icon-BKHs3OLu.js → hx-icon-CcyDPDYY.js} +104 -62
- package/dist/shared/hx-icon-CcyDPDYY.js.map +1 -0
- package/dist/shared/{hx-icon-button-CJuy9xbw.js → hx-icon-button-BHneqPCU.js} +58 -42
- package/dist/shared/hx-icon-button-BHneqPCU.js.map +1 -0
- package/dist/shared/{hx-image-ztiXumZB.js → hx-image-2gt14zZd.js} +34 -26
- package/dist/shared/hx-image-2gt14zZd.js.map +1 -0
- package/dist/shared/{hx-link-IVsXmsKx.js → hx-link-BESrWK8M.js} +72 -48
- package/dist/shared/hx-link-BESrWK8M.js.map +1 -0
- package/dist/shared/{hx-list-CoTDMp19.js → hx-list-_9qVv02L.js} +91 -49
- package/dist/shared/hx-list-_9qVv02L.js.map +1 -0
- package/dist/shared/{hx-menu-divider-DRT8yHRZ.js → hx-menu-divider-Ck-9Os1t.js} +103 -60
- package/dist/shared/hx-menu-divider-Ck-9Os1t.js.map +1 -0
- package/dist/shared/{hx-meter-BvSJoqDp.js → hx-meter-TbROk-dw.js} +64 -49
- package/dist/shared/hx-meter-TbROk-dw.js.map +1 -0
- package/dist/shared/{hx-nav-l0Rp7WPW.js → hx-nav-BcYDmjf7.js} +71 -56
- package/dist/shared/hx-nav-BcYDmjf7.js.map +1 -0
- package/dist/shared/{hx-nav-item-CJN4VDrf.js → hx-nav-item-pqPasRUm.js} +67 -23
- package/dist/shared/hx-nav-item-pqPasRUm.js.map +1 -0
- package/dist/shared/{hx-number-input-0Waw7Z7u.js → hx-number-input-mOIZ3-46.js} +169 -96
- package/dist/shared/hx-number-input-mOIZ3-46.js.map +1 -0
- package/dist/shared/{hx-overflow-menu-DElwFSCd.js → hx-overflow-menu-Dprb9lnT.js} +70 -38
- package/dist/shared/hx-overflow-menu-Dprb9lnT.js.map +1 -0
- package/dist/shared/{hx-pagination-BNtx-LG6.js → hx-pagination-AguTQjYC.js} +35 -35
- package/dist/shared/hx-pagination-AguTQjYC.js.map +1 -0
- package/dist/shared/{hx-patient-banner-BKiN7nIE.js → hx-patient-banner-uE6gqLpT.js} +67 -47
- package/dist/shared/hx-patient-banner-uE6gqLpT.js.map +1 -0
- package/dist/shared/{hx-phi-field-BiJH3V-k.js → hx-phi-field-BC_XowhC.js} +158 -59
- package/dist/shared/hx-phi-field-BC_XowhC.js.map +1 -0
- package/dist/shared/{hx-popover-D63RXn5H.js → hx-popover-B2_203ct.js} +48 -34
- package/dist/shared/hx-popover-B2_203ct.js.map +1 -0
- package/dist/shared/{hx-popup-BQWMhvMO.js → hx-popup-DZXpsJ1R.js} +89 -64
- package/dist/shared/hx-popup-DZXpsJ1R.js.map +1 -0
- package/dist/shared/{hx-progress-bar-Cm0VihTN.js → hx-progress-bar-KjEkEJLy.js} +21 -20
- package/dist/shared/hx-progress-bar-KjEkEJLy.js.map +1 -0
- package/dist/shared/{hx-progress-ring-BJeiDr3q.js → hx-progress-ring-3zMwvrwD.js} +56 -34
- package/dist/shared/hx-progress-ring-3zMwvrwD.js.map +1 -0
- package/dist/shared/{hx-prose-Ml_L2zje.js → hx-prose-BCtK7YL6.js} +48 -15
- package/dist/shared/{hx-prose-Ml_L2zje.js.map → hx-prose-BCtK7YL6.js.map} +1 -1
- package/dist/shared/{hx-radio-f8c5ggHG.js → hx-radio-BBC5qZgE.js} +202 -123
- package/dist/shared/hx-radio-BBC5qZgE.js.map +1 -0
- package/dist/shared/{hx-rating-qRJZXskm.js → hx-rating-C3E3ENJb.js} +92 -69
- package/dist/shared/hx-rating-C3E3ENJb.js.map +1 -0
- package/dist/shared/{hx-select-B5wq9Swh.js → hx-select-CixTo7jp.js} +206 -136
- package/dist/shared/hx-select-CixTo7jp.js.map +1 -0
- package/dist/shared/{hx-skeleton-e5K9Qaxq.js → hx-skeleton-LxkI0pxr.js} +41 -29
- package/dist/shared/hx-skeleton-LxkI0pxr.js.map +1 -0
- package/dist/shared/{hx-slider-BvXtvxmN.js → hx-slider-DFHuzF3N.js} +79 -91
- package/dist/shared/hx-slider-DFHuzF3N.js.map +1 -0
- package/dist/shared/{hx-spinner-Dyese1Tb.js → hx-spinner-BKjuCdZB.js} +32 -20
- package/dist/shared/hx-spinner-BKjuCdZB.js.map +1 -0
- package/dist/shared/{hx-split-button-CPndTJlC.js → hx-split-button-CGcJMmCG.js} +59 -22
- package/dist/shared/hx-split-button-CGcJMmCG.js.map +1 -0
- package/dist/shared/{hx-split-panel-Dx72NaET.js → hx-split-panel-C-1R10Mc.js} +71 -47
- package/dist/shared/hx-split-panel-C-1R10Mc.js.map +1 -0
- package/dist/shared/{hx-stack-B76_1O6g.js → hx-stack-DGfcOfWJ.js} +21 -11
- package/dist/shared/hx-stack-DGfcOfWJ.js.map +1 -0
- package/dist/shared/{hx-stat-DKD2E7An.js → hx-stat-BTpykQAt.js} +103 -48
- package/dist/shared/hx-stat-BTpykQAt.js.map +1 -0
- package/dist/shared/{hx-status-indicator-ClWpK6zz.js → hx-status-indicator-X2QEWNFt.js} +36 -23
- package/dist/shared/hx-status-indicator-X2QEWNFt.js.map +1 -0
- package/dist/shared/{hx-step-C2Jk4mHa.js → hx-step-CRNQlmSo.js} +83 -32
- package/dist/shared/hx-step-CRNQlmSo.js.map +1 -0
- package/dist/shared/{hx-structured-list-DKlrv7kS.js → hx-structured-list-CqNbaEXg.js} +32 -16
- package/dist/shared/hx-structured-list-CqNbaEXg.js.map +1 -0
- package/dist/shared/hx-style-scope-TDnR8H4O.js +251 -0
- package/dist/shared/hx-style-scope-TDnR8H4O.js.map +1 -0
- package/dist/shared/{hx-switch-BzMN37PV.js → hx-switch-DqOD9JR7.js} +122 -81
- package/dist/shared/hx-switch-DqOD9JR7.js.map +1 -0
- package/dist/shared/{hx-tab-panel-J58zOSjq.js → hx-tab-panel-BIzKfW5i.js} +156 -102
- package/dist/shared/hx-tab-panel-BIzKfW5i.js.map +1 -0
- package/dist/shared/{hx-tag-F0ZcYj9b.js → hx-tag-CgnrNnte.js} +30 -18
- package/dist/shared/hx-tag-CgnrNnte.js.map +1 -0
- package/dist/shared/{hx-td-CNCvzBwY.js → hx-td-Bra35cH4.js} +55 -47
- package/dist/shared/hx-td-Bra35cH4.js.map +1 -0
- package/dist/shared/{hx-text-DcWBqZwx.js → hx-text-DMC2CPlL.js} +74 -41
- package/dist/shared/hx-text-DMC2CPlL.js.map +1 -0
- package/dist/shared/{hx-text-input-Scyeefec.js → hx-text-input--q0GH78x.js} +123 -61
- package/dist/shared/hx-text-input--q0GH78x.js.map +1 -0
- package/dist/shared/{hx-textarea-BfSJJtA1.js → hx-textarea-CK621vSL.js} +124 -89
- package/dist/shared/hx-textarea-CK621vSL.js.map +1 -0
- package/dist/shared/{hx-theme-pc1V7dyL.js → hx-theme-DfEy-SJA.js} +72 -64
- package/dist/shared/hx-theme-DfEy-SJA.js.map +1 -0
- package/dist/shared/{hx-time-picker-CZvmihHD.js → hx-time-picker-tPUfgElQ.js} +300 -82
- package/dist/shared/hx-time-picker-tPUfgElQ.js.map +1 -0
- package/dist/shared/{hx-toggle-button-BZUQUULm.js → hx-toggle-button-L-uBJr-a.js} +72 -42
- package/dist/shared/hx-toggle-button-L-uBJr-a.js.map +1 -0
- package/dist/shared/{hx-tooltip-Ny4i1Idj.js → hx-tooltip-B_zfKvwc.js} +44 -31
- package/dist/shared/hx-tooltip-B_zfKvwc.js.map +1 -0
- package/dist/shared/{hx-top-nav-CC4FW2Hp.js → hx-top-nav-CATbRvIv.js} +53 -30
- package/dist/shared/hx-top-nav-CATbRvIv.js.map +1 -0
- package/dist/shared/{hx-tree-item-CPQ9dJiK.js → hx-tree-item-A45WCiBu.js} +37 -9
- package/dist/shared/hx-tree-item-A45WCiBu.js.map +1 -0
- package/dist/shared/hx-visually-hidden-0bZKOWgT.js +66 -0
- package/dist/shared/hx-visually-hidden-0bZKOWgT.js.map +1 -0
- package/dist/shared/id-counter-DuX8vsui.js +11 -0
- package/dist/shared/id-counter-DuX8vsui.js.map +1 -0
- package/dist/shared/{toast-factory-CEMNOt1T.js → toast-factory-BPPnG3mM.js} +58 -46
- package/dist/shared/toast-factory-BPPnG3mM.js.map +1 -0
- package/dist/utilities/injectLightStyles.d.ts.map +1 -1
- package/dist/utilities/sanitizeCss.d.ts +43 -0
- package/dist/utilities/sanitizeCss.d.ts.map +1 -0
- package/figma-inventory.json +18614 -0
- package/package.json +35 -14
- package/dist/shared/FormMixin-Bjvw20G5.js.map +0 -1
- package/dist/shared/aria-delegation-CBP9eQ0M.js.map +0 -1
- package/dist/shared/document-token-adoption-DuYNKd4k.js +0 -21
- package/dist/shared/document-token-adoption-DuYNKd4k.js.map +0 -1
- package/dist/shared/hx-accordion-CpfO0YQo.js.map +0 -1
- package/dist/shared/hx-action-bar-BpY1Z1UV.js.map +0 -1
- package/dist/shared/hx-alert-CHOjTBds.js.map +0 -1
- package/dist/shared/hx-avatar-an-WsuLl.js.map +0 -1
- package/dist/shared/hx-badge-DDXTLoWi.js.map +0 -1
- package/dist/shared/hx-banner-B-WEDiq7.js.map +0 -1
- package/dist/shared/hx-breadcrumb-item-DzLyeL5Z.js.map +0 -1
- package/dist/shared/hx-button-DoN8jjQT.js.map +0 -1
- package/dist/shared/hx-button-group-BXlMQTt_.js.map +0 -1
- package/dist/shared/hx-card-BgXZXDuc.js.map +0 -1
- package/dist/shared/hx-carousel-item-Dwt9Pphz.js.map +0 -1
- package/dist/shared/hx-checkbox-CTEZ9IFq.js.map +0 -1
- package/dist/shared/hx-checkbox-group-DThZeN5d.js.map +0 -1
- package/dist/shared/hx-clinical-status-m4soOOwg.js.map +0 -1
- package/dist/shared/hx-color-picker-DhOaNe6-.js.map +0 -1
- package/dist/shared/hx-combobox-BJ4lQocO.js +0 -544
- package/dist/shared/hx-combobox-BJ4lQocO.js.map +0 -1
- package/dist/shared/hx-container-31QT9KV_.js.map +0 -1
- package/dist/shared/hx-copy-button-BoM0WsMd.js.map +0 -1
- package/dist/shared/hx-counter-CP42cSVK.js.map +0 -1
- package/dist/shared/hx-data-table-D5Ne-goy.js.map +0 -1
- package/dist/shared/hx-date-picker-Cd3I3WkX.js +0 -627
- package/dist/shared/hx-date-picker-Cd3I3WkX.js.map +0 -1
- package/dist/shared/hx-dialog-D4ubstxx.js.map +0 -1
- package/dist/shared/hx-divider-BBtOLHRP.js.map +0 -1
- package/dist/shared/hx-drawer--WDLuWtS.js.map +0 -1
- package/dist/shared/hx-dropdown-n5-XSmiV.js.map +0 -1
- package/dist/shared/hx-field-CwT9tki1.js.map +0 -1
- package/dist/shared/hx-field-label-CcOK9VU3.js.map +0 -1
- package/dist/shared/hx-file-upload-Dwtu3WcB.js.map +0 -1
- package/dist/shared/hx-form-fJE-FJQV.js.map +0 -1
- package/dist/shared/hx-format-date-B7L9odbA.js.map +0 -1
- package/dist/shared/hx-grid-BIAR5h9m.js.map +0 -1
- package/dist/shared/hx-help-text-Bmb80bP4.js.map +0 -1
- package/dist/shared/hx-icon-BKHs3OLu.js.map +0 -1
- package/dist/shared/hx-icon-button-CJuy9xbw.js.map +0 -1
- package/dist/shared/hx-image-ztiXumZB.js.map +0 -1
- package/dist/shared/hx-link-IVsXmsKx.js.map +0 -1
- package/dist/shared/hx-list-CoTDMp19.js.map +0 -1
- package/dist/shared/hx-menu-divider-DRT8yHRZ.js.map +0 -1
- package/dist/shared/hx-meter-BvSJoqDp.js.map +0 -1
- package/dist/shared/hx-nav-item-CJN4VDrf.js.map +0 -1
- package/dist/shared/hx-nav-l0Rp7WPW.js.map +0 -1
- package/dist/shared/hx-number-input-0Waw7Z7u.js.map +0 -1
- package/dist/shared/hx-overflow-menu-DElwFSCd.js.map +0 -1
- package/dist/shared/hx-pagination-BNtx-LG6.js.map +0 -1
- package/dist/shared/hx-patient-banner-BKiN7nIE.js.map +0 -1
- package/dist/shared/hx-phi-field-BiJH3V-k.js.map +0 -1
- package/dist/shared/hx-popover-D63RXn5H.js.map +0 -1
- package/dist/shared/hx-popup-BQWMhvMO.js.map +0 -1
- package/dist/shared/hx-progress-bar-Cm0VihTN.js.map +0 -1
- package/dist/shared/hx-progress-ring-BJeiDr3q.js.map +0 -1
- package/dist/shared/hx-radio-f8c5ggHG.js.map +0 -1
- package/dist/shared/hx-rating-qRJZXskm.js.map +0 -1
- package/dist/shared/hx-select-B5wq9Swh.js.map +0 -1
- package/dist/shared/hx-skeleton-e5K9Qaxq.js.map +0 -1
- package/dist/shared/hx-slider-BvXtvxmN.js.map +0 -1
- package/dist/shared/hx-spinner-Dyese1Tb.js.map +0 -1
- package/dist/shared/hx-split-button-CPndTJlC.js.map +0 -1
- package/dist/shared/hx-split-panel-Dx72NaET.js.map +0 -1
- package/dist/shared/hx-stack-B76_1O6g.js.map +0 -1
- package/dist/shared/hx-stat-DKD2E7An.js.map +0 -1
- package/dist/shared/hx-status-indicator-ClWpK6zz.js.map +0 -1
- package/dist/shared/hx-step-C2Jk4mHa.js.map +0 -1
- package/dist/shared/hx-structured-list-DKlrv7kS.js.map +0 -1
- package/dist/shared/hx-style-scope-CsQ2Phf_.js +0 -126
- package/dist/shared/hx-style-scope-CsQ2Phf_.js.map +0 -1
- package/dist/shared/hx-switch-BzMN37PV.js.map +0 -1
- package/dist/shared/hx-tab-panel-J58zOSjq.js.map +0 -1
- package/dist/shared/hx-tag-F0ZcYj9b.js.map +0 -1
- package/dist/shared/hx-td-CNCvzBwY.js.map +0 -1
- package/dist/shared/hx-text-DcWBqZwx.js.map +0 -1
- package/dist/shared/hx-text-input-Scyeefec.js.map +0 -1
- package/dist/shared/hx-textarea-BfSJJtA1.js.map +0 -1
- package/dist/shared/hx-theme-pc1V7dyL.js.map +0 -1
- package/dist/shared/hx-time-picker-CZvmihHD.js.map +0 -1
- package/dist/shared/hx-toggle-button-BZUQUULm.js.map +0 -1
- package/dist/shared/hx-tooltip-Ny4i1Idj.js.map +0 -1
- package/dist/shared/hx-top-nav-CC4FW2Hp.js.map +0 -1
- package/dist/shared/hx-tree-item-CPQ9dJiK.js.map +0 -1
- package/dist/shared/hx-visually-hidden-vKX8QjeX.js +0 -54
- package/dist/shared/hx-visually-hidden-vKX8QjeX.js.map +0 -1
- package/dist/shared/id-counter-JhvVCnjh.js.map +0 -1
- package/dist/shared/toast-factory-CEMNOt1T.js.map +0 -1
- package/dist/tools/cem-a11y-analyzer/analyzers/aria-analyzer.d.ts +0 -12
- package/dist/tools/cem-a11y-analyzer/analyzers/aria-analyzer.d.ts.map +0 -1
- package/dist/tools/cem-a11y-analyzer/analyzers/focus-analyzer.d.ts +0 -13
- package/dist/tools/cem-a11y-analyzer/analyzers/focus-analyzer.d.ts.map +0 -1
- package/dist/tools/cem-a11y-analyzer/analyzers/form-analyzer.d.ts +0 -13
- package/dist/tools/cem-a11y-analyzer/analyzers/form-analyzer.d.ts.map +0 -1
- package/dist/tools/cem-a11y-analyzer/analyzers/keyboard-analyzer.d.ts +0 -12
- package/dist/tools/cem-a11y-analyzer/analyzers/keyboard-analyzer.d.ts.map +0 -1
- package/dist/tools/cem-a11y-analyzer/analyzers/label-analyzer.d.ts +0 -13
- package/dist/tools/cem-a11y-analyzer/analyzers/label-analyzer.d.ts.map +0 -1
- package/dist/tools/cem-a11y-analyzer/analyzers/motion-analyzer.d.ts +0 -12
- package/dist/tools/cem-a11y-analyzer/analyzers/motion-analyzer.d.ts.map +0 -1
- package/dist/tools/cem-a11y-analyzer/index.d.ts +0 -14
- package/dist/tools/cem-a11y-analyzer/index.d.ts.map +0 -1
- package/dist/tools/cem-a11y-analyzer/reporter.d.ts +0 -6
- package/dist/tools/cem-a11y-analyzer/reporter.d.ts.map +0 -1
- package/dist/tools/cem-a11y-analyzer/scorer.d.ts +0 -22
- package/dist/tools/cem-a11y-analyzer/scorer.d.ts.map +0 -1
- package/dist/tools/cem-a11y-analyzer/types.d.ts +0 -171
- package/dist/tools/cem-a11y-analyzer/types.d.ts.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hx-patient-banner-BKiN7nIE.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, #f9fafb));\n --_border-color: var(--hx-patient-banner-border-color, var(--hx-color-neutral-200, #e5e7eb));\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, #6b7280));\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, #111827));\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, #e5e7eb));\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 44x44px touch target for interactive photo content. */\n min-width: 44px;\n min-height: 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, #374151));\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, #ef4444);\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","import { LitElement, html, nothing, type PropertyValues } from 'lit';\nimport '../../utilities/document-token-adoption.js';\nimport { customElement, property, state, query } from 'lit/decorators.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 * Note: hx-phi-access events fired by slotted hx-phi-field elements bubble through this\n * component via composed: true — no re-dispatch is required.\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 - Fired when fewer than 2 identifier slots are populated and enforce-identifier-rule is 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 LitElement {\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;\n\n /** @internal */\n @query('slot[name=\"mrn\"]') private _mrnSlot!: HTMLSlotElement;\n\n /** @internal */\n @query('slot[name=\"dob\"]') private _dobSlot!: HTMLSlotElement;\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\nexport interface PatientIdentifierRuleViolationDetail {\n populatedIdentifiers: number;\n requiredIdentifiers: number;\n patientId: string;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-patient-banner': HelixPatientBanner;\n }\n}\n"],"names":["helixPatientBannerStyles","css","HelixPatientBanner","LitElement","changedProperties","count","slots","slot","violationMessage","nothing","html","__decorateClass","property","value","state","query","customElement"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hx-phi-field-BiJH3V-k.js","sources":["../../src/components/hx-phi-field/hx-phi-field.styles.ts","../../src/components/hx-phi-field/hx-phi-field.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixPhiFieldStyles = css`\n :host {\n display: inline-flex;\n }\n\n /* ─── Container ─── */\n\n .phi-field {\n display: inline-flex;\n align-items: center;\n gap: var(--hx-space-2, 0.5rem);\n font-family: var(--hx-phi-field-font-family, var(--hx-font-family-mono, monospace));\n }\n\n /* ─── Value ─── */\n\n .phi-field__value--masked {\n user-select: none;\n -webkit-user-select: none;\n color: var(--hx-phi-field-masked-color, var(--hx-color-neutral-500, #6b7280));\n letter-spacing: 0.1em;\n }\n\n .phi-field__value--revealed {\n color: var(--hx-phi-field-value-color, var(--hx-color-neutral-900, #111827));\n }\n\n /* ─── Screen Reader Status ─── */\n\n .phi-field__status {\n position: absolute;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n padding: 0;\n margin: -1px;\n }\n\n /* ─── Toggle Button ─── */\n\n .phi-field__toggle {\n display: inline-flex;\n align-items: center;\n background: none;\n border: none;\n padding: var(--hx-space-1, 0.25rem);\n color: var(--hx-phi-field-toggle-color, var(--hx-color-primary-500, #2563eb));\n cursor: pointer;\n line-height: 1;\n border-radius: var(--hx-border-radius-sm, 0.25rem);\n }\n\n .phi-field__toggle:focus-visible {\n outline: var(--hx-focus-ring-width, 2px) solid\n var(\n --hx-phi-field-focus-ring-color,\n var(--hx-focus-ring-color, var(--hx-color-primary-500, #2563eb))\n );\n outline-offset: var(--hx-focus-ring-offset, 2px);\n }\n\n .phi-field__toggle:hover {\n opacity: var(--hx-opacity-90, 0.9);\n }\n\n .phi-field__toggle:active {\n opacity: var(--hx-opacity-50, 0.5);\n }\n\n .phi-field__toggle svg {\n width: 1em;\n height: 1em;\n pointer-events: none;\n }\n\n /* ─── Disabled State ─── */\n\n :host([disabled]) {\n opacity: var(--hx-phi-field-disabled-opacity, var(--hx-opacity-50, 0.5));\n pointer-events: none;\n cursor: not-allowed;\n }\n\n .phi-field--disabled .phi-field__toggle {\n cursor: not-allowed;\n }\n\n /* ─── Reduced Motion ─── */\n\n @media (prefers-reduced-motion: reduce) {\n .phi-field__toggle {\n transition: none;\n }\n }\n`;\n","import { LitElement, html, type TemplateResult } from 'lit';\nimport '../../utilities/document-token-adoption.js';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { helixPhiFieldStyles } from './hx-phi-field.styles.js';\n\n/**\n * HIPAA-compliant field component for rendering masked Protected Health Information (PHI).\n * PHI is masked by default and only rendered to the DOM when explicitly revealed. Access\n * events are fired on reveal, hide, and clipboard auto-clear for audit trail purposes.\n *\n * @summary HIPAA-compliant field for rendering masked Protected Health Information.\n *\n * @tag hx-phi-field\n *\n * @csspart container - The outer wrapper element.\n * @csspart value - The value display span (masked or revealed).\n * @csspart toggle - The reveal/hide toggle button.\n *\n * @fires {CustomEvent<PhiAccessEventDetail>} hx-phi-access - Fired on reveal, hide, and clipboard-clear actions.\n *\n * @cssprop [--hx-phi-field-font-family=var(--hx-font-family-mono,monospace)] - Font family for the masked value.\n * @cssprop [--hx-phi-field-value-color=var(--hx-color-neutral-900,#111827)] - Value text color.\n * @cssprop [--hx-phi-field-masked-color=var(--hx-color-neutral-500,#6b7280)] - Masked value text color.\n * @cssprop [--hx-phi-field-toggle-color=var(--hx-color-primary-500,#2563eb)] - Toggle button color.\n * @cssprop [--hx-phi-field-focus-ring-color=var(--hx-focus-ring-color,var(--hx-color-primary-500,#2563eb))] - Focus ring color.\n * @cssprop [--hx-phi-field-disabled-opacity=var(--hx-opacity-50,0.5)] - Opacity applied when the field is disabled.\n */\n@customElement('hx-phi-field')\nexport class HelixPhiField extends LitElement {\n static override styles = [helixPhiFieldStyles];\n\n // ─── Public Properties ───\n\n /**\n * The Protected Health Information value to display or mask.\n * @attr data\n */\n @property({ type: String })\n data: string = '';\n\n /**\n * The type of PHI field. Controls the masking pattern applied.\n * @attr field-type\n */\n @property({ type: String, reflect: true, attribute: 'field-type' })\n fieldType: 'ssn' | 'mrn' | 'dob' | 'insurance' = 'ssn';\n\n /**\n * Identifier used in audit events. Falls back to the element's id attribute.\n * @attr field-id\n */\n @property({ type: String, attribute: 'field-id' })\n fieldId: string = '';\n\n /**\n * Milliseconds after clipboard write before the clipboard is automatically cleared.\n * Defaults to 30000 (30 seconds).\n * @attr clipboard-timeout\n */\n @property({ type: Number, attribute: 'clipboard-timeout' })\n clipboardTimeout: number = 30000;\n\n /**\n * Accessible label describing the PHI field. Used as a prefix in screen reader\n * announcements (e.g., \"Social Security Number is masked\").\n * @attr label\n */\n @property({ type: String })\n label: string = '';\n\n /**\n * When set, disables all interaction with the field and prevents reveal.\n * @attr disabled\n * @reflect\n */\n @property({ type: Boolean, reflect: true })\n disabled: boolean = false;\n\n // ─── Internal State ───\n\n /** @internal */\n @state() private _masked = true;\n\n /** @internal */\n private _clipboardTimer: ReturnType<typeof setTimeout> | null = null;\n\n // ─── Lifecycle ───\n\n override connectedCallback(): void {\n super.connectedCallback();\n // Enforce HIPAA compliance: prevent browser autofill on the host element\n this.setAttribute('autocomplete', 'off');\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this._cancelClipboardTimer();\n }\n\n // ─── Private Helpers ───\n\n /** @internal */\n private _cancelClipboardTimer(): void {\n if (this._clipboardTimer !== null) {\n clearTimeout(this._clipboardTimer);\n this._clipboardTimer = null;\n }\n }\n\n /** @internal */\n private _scheduleClipboardClear(): void {\n this._cancelClipboardTimer();\n this._clipboardTimer = setTimeout(() => {\n this._clearClipboard();\n }, this.clipboardTimeout);\n }\n\n /** @internal */\n private _clearClipboard(): void {\n this._clipboardTimer = null;\n if (typeof navigator !== 'undefined' && navigator.clipboard) {\n navigator?.clipboard?.writeText('').catch(() => {\n // Clipboard clear failure is non-fatal — silently ignore\n });\n }\n this.dispatchEvent(\n new CustomEvent<PhiAccessEventDetail>('hx-phi-access', {\n bubbles: true,\n composed: true,\n detail: {\n fieldId: this.fieldId || this.id || '',\n action: 'clipboard-clear',\n timestamp: new Date().toISOString(),\n fieldType: this.fieldType,\n },\n }),\n );\n this._masked = true;\n }\n\n /** @internal */\n private _getMaskedValue(): string {\n if (!this.data) return '';\n\n switch (this.fieldType) {\n case 'ssn': {\n // Format: xxx-xx-xxxx → ***-**-xxxx (show last 4 digits)\n // Match the separator-delimited pattern first\n const ssnMatch = this.data.match(/^(\\d{3})(-?)(\\d{2})(-?)(\\d{4})$/);\n if (ssnMatch) {\n return `***${ssnMatch[2]}**${ssnMatch[4]}${ssnMatch[5]}`;\n }\n // Fallback: mask all but last 4 chars\n return this.data.slice(0, -4).replace(/\\d/g, '*') + this.data.slice(-4);\n }\n\n case 'mrn': {\n // Mask all but last 4 alphanumeric characters, preserve separators\n const chars = this.data.split('');\n const alphanumericIndices: number[] = [];\n chars.forEach((ch, i) => {\n if (/[a-zA-Z0-9]/.test(ch)) {\n alphanumericIndices.push(i);\n }\n });\n const revealCount = Math.min(4, alphanumericIndices.length);\n const maskUntilIdx = alphanumericIndices.length - revealCount;\n const indicesToMask = new Set(alphanumericIndices.slice(0, maskUntilIdx));\n return chars.map((ch, i) => (indicesToMask.has(i) ? '*' : ch)).join('');\n }\n\n case 'dob': {\n // Replace ALL digits with *, preserve separators\n return this.data.replace(/\\d/g, '*');\n }\n\n case 'insurance': {\n // Format: xxxx-xxxx-xxxx-xxxx → ****-****-****-xxxx (show last 4 digits)\n const insMatch = this.data.match(/^(\\d{4})(-?)(\\d{4})(-?)(\\d{4})(-?)(\\d{4})$/);\n if (insMatch) {\n return `****${insMatch[2]}****${insMatch[4]}****${insMatch[6]}${insMatch[7]}`;\n }\n // Fallback: mask all but last 4 chars\n return this.data.slice(0, -4).replace(/[a-zA-Z0-9]/g, '*') + this.data.slice(-4);\n }\n\n default: {\n // Exhaustive check — fieldType is typed, but guard defensively\n const _exhaustive: never = this.fieldType;\n return _exhaustive;\n }\n }\n }\n\n // ─── Event Handlers ───\n\n /** @internal */\n private _handleToggle(): void {\n if (this.disabled) return;\n\n // Dispatch BEFORE toggling state so action reflects the upcoming state\n this.dispatchEvent(\n new CustomEvent<PhiAccessEventDetail>('hx-phi-access', {\n bubbles: true,\n composed: true,\n detail: {\n fieldId: this.fieldId || this.id || '',\n action: this._masked ? 'reveal' : 'hide',\n timestamp: new Date().toISOString(),\n fieldType: this.fieldType,\n },\n }),\n );\n\n if (this._masked) {\n // Revealing: start clipboard clear timer\n this._masked = false;\n this._scheduleClipboardClear();\n } else {\n // Hiding: cancel any pending clipboard clear\n this._cancelClipboardTimer();\n this._masked = true;\n }\n }\n\n /** @internal */\n private _handleCopy(e: ClipboardEvent): void {\n if (this._masked) {\n e.preventDefault();\n }\n }\n\n /** @internal */\n private _handlePaste(e: ClipboardEvent): void {\n if (this._masked) {\n e.preventDefault();\n }\n }\n\n // ─── Render Helpers ───\n\n /** @internal */\n private _renderEyeIcon(): TemplateResult {\n return html`\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z\" />\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n </svg>\n `;\n }\n\n /** @internal */\n private _renderEyeOffIcon(): TemplateResult {\n return html`\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94\" />\n <path d=\"M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19\" />\n <line x1=\"1\" y1=\"1\" x2=\"23\" y2=\"23\" />\n </svg>\n `;\n }\n\n // ─── Render ───\n\n override render() {\n const fieldLabel = this.label || 'Protected health information';\n const maskedLabel = `${fieldLabel} is masked`;\n const revealedLabel = `${fieldLabel} is revealed`;\n const revealActionLabel = `Reveal ${fieldLabel.toLowerCase()}`;\n const hideActionLabel = `Hide ${fieldLabel.toLowerCase()}`;\n\n return html`\n <div\n part=\"container\"\n class=\"phi-field${this.disabled ? ' phi-field--disabled' : ''}\"\n @copy=${this._handleCopy}\n @paste=${this._handlePaste}\n >\n ${this._masked\n ? html`<span part=\"value\" class=\"phi-field__value phi-field__value--masked\"\n >${this._getMaskedValue()}</span\n >`\n : html`<span part=\"value\" class=\"phi-field__value phi-field__value--revealed\"\n >${this.data}</span\n >`}\n <span role=\"status\" aria-live=\"polite\" aria-atomic=\"true\" class=\"phi-field__status\">\n ${this._masked ? maskedLabel : revealedLabel}\n </span>\n <button\n part=\"toggle\"\n class=\"phi-field__toggle\"\n type=\"button\"\n ?disabled=${this.disabled}\n aria-label=${this._masked ? revealActionLabel : hideActionLabel}\n aria-pressed=${String(!this._masked)}\n @click=${this._handleToggle}\n >\n ${this._masked ? this._renderEyeIcon() : this._renderEyeOffIcon()}\n </button>\n </div>\n `;\n }\n}\n\nexport interface PhiAccessEventDetail {\n fieldId: string;\n /** The action that triggered the audit event. */\n action: 'reveal' | 'hide' | 'clipboard-clear';\n timestamp: string;\n fieldType: 'ssn' | 'mrn' | 'dob' | 'insurance';\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-phi-field': HelixPhiField;\n }\n}\n"],"names":["helixPhiFieldStyles","css","HelixPhiField","LitElement","_a","ssnMatch","chars","alphanumericIndices","ch","i","revealCount","maskUntilIdx","indicesToMask","insMatch","html","fieldLabel","maskedLabel","revealedLabel","revealActionLabel","hideActionLabel","__decorateClass","property","state","customElement"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hx-popover-D63RXn5H.js","sources":["../../src/components/hx-popover/hx-popover.styles.ts","../../src/components/hx-popover/hx-popover.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixPopoverStyles = css`\n :host {\n /* P2-05: display:contents lets the trigger-wrapper control layout inline;\n position:relative was vestigial — body uses position:fixed via Floating UI */\n display: contents;\n }\n\n .trigger-wrapper {\n display: inline-block;\n }\n\n [part='body'] {\n position: fixed;\n z-index: var(--hx-popover-z-index, 9999);\n max-width: var(--hx-popover-max-width, 320px);\n padding: var(--hx-popover-padding, var(--hx-space-3, 0.75rem));\n background: var(--hx-popover-bg, var(--hx-color-neutral-0, #ffffff));\n color: var(--hx-popover-color, var(--hx-color-neutral-900, #111827));\n font-family: var(--hx-font-family-sans, sans-serif);\n font-size: var(--hx-popover-font-size, var(--hx-font-size-sm, 0.875rem));\n line-height: var(--hx-line-height-normal, 1.5);\n border: 1px solid var(--hx-popover-border-color, var(--hx-color-neutral-200, #e5e7eb));\n border-radius: var(--hx-popover-border-radius, var(--hx-border-radius-md, 0.375rem));\n box-shadow: var(\n --hx-popover-shadow,\n var(--hx-shadow-md, 0 4px 16px var(--hx-overlay-black-12, rgba(0, 0, 0, 0.12)))\n );\n visibility: hidden;\n opacity: 0;\n transition:\n opacity var(--hx-popover-transition-duration, 0.2s) ease,\n visibility var(--hx-popover-transition-duration, 0.2s) ease;\n word-wrap: break-word;\n }\n\n [part='body'].visible {\n visibility: visible;\n opacity: 1;\n }\n\n [part='body']:focus-visible {\n outline: var(--hx-focus-ring-width, 2px) solid\n var(--hx-popover-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 [part='arrow'] {\n position: absolute;\n width: var(--hx-popover-arrow-size, 10px);\n height: var(--hx-popover-arrow-size, 10px);\n background: var(--hx-popover-bg, var(--hx-color-neutral-0, #ffffff));\n border: 1px solid var(--hx-popover-border-color, var(--hx-color-neutral-200, #e5e7eb));\n transform: rotate(45deg);\n pointer-events: none;\n }\n\n @media (prefers-reduced-motion: reduce) {\n [part='body'] {\n transition: none;\n }\n }\n`;\n","import { LitElement, html, nothing, type PropertyValues } from 'lit';\nimport '../../utilities/document-token-adoption.js';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { helixPopoverStyles } from './hx-popover.styles.js';\n\nlet _popoverCounter = 0;\n\n/**\n * A popover that displays rich floating content attached to a trigger element.\n *\n * @summary Rich floating overlay attached to a trigger element.\n *\n * @tag hx-popover\n *\n * @slot anchor - The trigger element that opens the popover.\n * @slot - Default slot for popover body content.\n *\n * @csspart body - The popover body container element.\n * @csspart arrow - The arrow indicator element.\n *\n * @cssprop [--hx-popover-bg=var(--hx-color-neutral-0)] - Popover background color.\n * @cssprop [--hx-popover-color=var(--hx-color-neutral-900)] - Popover text color.\n * @cssprop [--hx-popover-font-size=var(--hx-font-size-sm)] - Popover font size.\n * @cssprop [--hx-popover-max-width=320px] - Maximum popover width.\n * @cssprop [--hx-popover-padding] - Popover padding.\n * @cssprop [--hx-popover-border-color=var(--hx-color-neutral-200)] - Popover border color.\n * @cssprop [--hx-popover-border-radius=var(--hx-border-radius-md)] - Popover border radius.\n * @cssprop [--hx-popover-shadow] - Popover box shadow.\n * @cssprop [--hx-popover-z-index=9999] - Popover z-index.\n * @cssprop [--hx-popover-transition-duration=0.2s] - Show/hide transition duration.\n * @cssprop [--hx-popover-arrow-size=10px] - Size of the arrow indicator.\n *\n * @fires {CustomEvent} hx-show - Emitted when the popover begins to show.\n * @fires {CustomEvent} hx-after-show - Emitted after the popover is fully visible.\n * @fires {CustomEvent} hx-hide - Emitted when the popover begins to hide.\n * @fires {CustomEvent} hx-after-hide - Emitted after the popover is fully hidden.\n *\n * @example\n * ```html\n * <hx-popover placement=\"bottom\" trigger=\"click\">\n * <button slot=\"anchor\">Open Popover</button>\n * <p>Rich popover content here.</p>\n * </hx-popover>\n * ```\n */\n\n@customElement('hx-popover')\nexport class HelixPopover extends LitElement {\n static override styles = [helixPopoverStyles];\n\n /**\n * Whether the popover is open.\n * @attr open\n */\n @property({ type: Boolean, reflect: true })\n open = false;\n\n /**\n * Preferred placement of the popover relative to the anchor.\n * @attr placement\n */\n @property({ type: String, reflect: true })\n placement:\n | 'top'\n | 'top-start'\n | 'top-end'\n | 'right'\n | 'right-start'\n | 'right-end'\n | 'bottom'\n | 'bottom-start'\n | 'bottom-end'\n | 'left'\n | 'left-start'\n | 'left-end' = 'bottom';\n\n /**\n * How the popover is triggered.\n * @attr trigger\n */\n @property({ type: String, reflect: true })\n trigger: 'click' | 'hover' | 'focus' | 'manual' = 'click';\n\n /**\n * Distance in pixels between the popover and the anchor.\n * @attr distance\n */\n @property({ type: Number, reflect: true })\n distance = 8;\n\n /**\n * Alignment offset in pixels along the anchor.\n * @attr skidding\n */\n @property({ type: Number, reflect: true })\n skidding = 0;\n\n /**\n * Whether to show an arrow pointing to the anchor.\n * @attr arrow\n */\n @property({ type: Boolean, reflect: true })\n arrow = false;\n\n /**\n * Accessible label for the popover body (sets aria-label on the dialog).\n * @attr label\n */\n @property({ type: String, reflect: true })\n label = 'Popover';\n\n /**\n * Tracks whether the popover body is currently visible.\n * @internal\n */\n @state() private _visible = false;\n\n /**\n * The element that held focus before the popover opened, used to restore focus on close.\n * @internal\n */\n private _previousFocus: HTMLElement | null = null;\n\n /**\n * Unique ID assigned to the popover body element.\n * @internal\n */\n private readonly _popoverId = `hx-popover-${++_popoverCounter}`;\n\n /**\n * Timer ID for the deferred document click listener registration in _show().\n * Stored so it can be cancelled in disconnectedCallback to prevent leaks.\n * @internal\n */\n private _showTimer: ReturnType<typeof setTimeout> | null = null;\n\n /**\n * Timer ID for the hover-triggered hide delay.\n * WCAG 1.4.13: hoverable content must remain visible while the pointer is\n * over it. A 150 ms delay allows the pointer to move from the anchor into\n * the popover body without the content dismissing prematurely.\n * @internal\n */\n private _hoverHideTimer: ReturnType<typeof setTimeout> | null = null;\n\n // ─── Lifecycle ───\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n if (this._showTimer !== null) {\n clearTimeout(this._showTimer);\n this._showTimer = null;\n }\n if (this._hoverHideTimer !== null) {\n clearTimeout(this._hoverHideTimer);\n this._hoverHideTimer = null;\n }\n document.removeEventListener('click', this._handleDocumentClick);\n document.removeEventListener('keydown', this._handleDocumentKeydown);\n }\n\n override firstUpdated(): void {\n // HIGH-02: set aria-haspopup=\"dialog\" once on the anchor so assistive technology\n // announces the control's popup type before it is ever opened.\n this._setAnchorAriaAttributes(false);\n // Sync initial open state\n if (this.open) {\n void this._show();\n }\n }\n\n override updated(changedProperties: PropertyValues<this>): void {\n if (changedProperties.has('open')) {\n if (this.open) {\n void this._show();\n } else {\n void this._hide();\n }\n }\n }\n\n // ─── ARIA setup ───\n\n // HIGH-02: set aria-haspopup=\"dialog\" on firstUpdated and keep aria-expanded in sync\n /** @internal */\n private _setAnchorAriaAttributes(expanded: boolean): void {\n const anchorSlot = this.shadowRoot?.querySelector(\n 'slot[name=\"anchor\"]',\n ) as HTMLSlotElement | null;\n if (!anchorSlot) return;\n const anchorEl = anchorSlot.assignedElements()[0] as HTMLElement | undefined;\n if (anchorEl) {\n anchorEl.setAttribute('aria-expanded', String(expanded));\n anchorEl.setAttribute('aria-haspopup', 'dialog');\n // aria-controls is omitted: the body lives in Shadow DOM and axe-core\n // cannot resolve cross-root IDREF values, which causes a critical violation.\n }\n }\n\n // ─── Focus helpers ───\n\n /** Return all keyboard-focusable elements inside the popover body's slotted content. */\n /** @internal */\n private _getFocusableElements(): HTMLElement[] {\n const bodyEl = this.shadowRoot?.querySelector('[part=\"body\"]') as HTMLElement | null;\n if (!bodyEl) return [];\n\n // Gather focusable elements from the default slot's assigned nodes\n const defaultSlot = bodyEl.querySelector('slot:not([name])') as HTMLSlotElement | null;\n if (!defaultSlot) return [];\n\n const assigned = defaultSlot.assignedElements({ flatten: true });\n const focusableSelector =\n 'a[href], area[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"]), details > summary';\n\n const result: HTMLElement[] = [];\n for (const el of assigned) {\n if (el.matches(focusableSelector)) {\n result.push(el as HTMLElement);\n }\n const nested = el.querySelectorAll<HTMLElement>(focusableSelector);\n result.push(...nested);\n }\n return result;\n }\n\n // ─── Show/Hide ───\n\n /** @internal */\n private async _show(): Promise<void> {\n if (this._visible) return;\n // P0-02: save focus target before moving focus into dialog\n this._previousFocus = document.activeElement as HTMLElement | null;\n this.dispatchEvent(new CustomEvent<void>('hx-show', { bubbles: true, composed: true }));\n this._visible = true;\n this.open = true;\n this._setAnchorAriaAttributes(true);\n // P1-03 / HIGH-01: single keydown listener handles both Escape and focus trap.\n // Registered synchronously before any await so it is in place before the first\n // await el.updateComplete in tests.\n document.addEventListener('keydown', this._handleDocumentKeydown);\n await this.updateComplete;\n // hx-after-show fires after Lit has rendered the visible state. Dispatching here\n // (before _updatePosition) ensures it fires in the same microtask as the test's\n // await-continuation, so tests can rely on a single await el.updateComplete.\n this.dispatchEvent(new CustomEvent<void>('hx-after-show', { bubbles: true, composed: true }));\n // WCAG 2.4.3: only move focus into the popover when it contains interactive\n // content. For non-interactive (informational) popovers, stealing focus from\n // the trigger is unexpected and disruptive for keyboard users.\n const bodyEl = this.shadowRoot?.querySelector('[part=\"body\"]') as HTMLElement | null;\n if (bodyEl) {\n const hasInteractive = this._getFocusableElements().length > 0;\n if (hasInteractive) {\n bodyEl.focus();\n }\n }\n // P0-01: listen for outside clicks; deferred to avoid catching the opening click\n if (this._showTimer !== null) {\n clearTimeout(this._showTimer);\n }\n this._showTimer = setTimeout(() => {\n this._showTimer = null;\n document.addEventListener('click', this._handleDocumentClick);\n }, 0);\n await this._updatePosition();\n }\n\n // HIGH-03: _hideWithFocusRestore controls whether _previousFocus is restored.\n // Escape and programmatic close restore focus; click-outside does not.\n /** @internal */\n private async _hide(restoreFocus = true): Promise<void> {\n if (!this._visible) return;\n document.removeEventListener('click', this._handleDocumentClick);\n document.removeEventListener('keydown', this._handleDocumentKeydown);\n this.dispatchEvent(new CustomEvent<void>('hx-hide', { bubbles: true, composed: true }));\n this._visible = false;\n this.open = false;\n this._setAnchorAriaAttributes(false);\n // HIGH-03: only restore focus on Escape / programmatic close\n if (restoreFocus) {\n this._previousFocus?.focus();\n }\n this._previousFocus = null;\n await this.updateComplete;\n this.dispatchEvent(new CustomEvent<void>('hx-after-hide', { bubbles: true, composed: true }));\n }\n\n // ─── Positioning ───\n\n /** @internal */\n private async _updatePosition(): Promise<void> {\n const anchorSlot = this.shadowRoot?.querySelector(\n 'slot[name=\"anchor\"]',\n ) as HTMLSlotElement | null;\n if (!anchorSlot) return;\n const anchorEl = anchorSlot.assignedElements()[0] as HTMLElement | undefined;\n const bodyEl = this.shadowRoot?.querySelector('[part=\"body\"]') as HTMLElement | null;\n const arrowEl = this.arrow\n ? (this.shadowRoot?.querySelector('[part=\"arrow\"]') as HTMLElement | null)\n : null;\n\n if (!anchorEl || !bodyEl) return;\n\n const { computePosition, flip, shift, offset, arrow } = await import('@floating-ui/dom');\n\n const middleware = [\n offset({ mainAxis: this.distance, crossAxis: this.skidding }),\n flip(),\n shift({ padding: 8 }),\n ];\n\n if (arrowEl) {\n middleware.push(arrow({ element: arrowEl }));\n }\n\n const { x, y, placement, middlewareData } = await computePosition(anchorEl, bodyEl, {\n placement: this.placement,\n strategy: 'fixed',\n middleware,\n });\n\n Object.assign(bodyEl.style, {\n left: `${x}px`,\n top: `${y}px`,\n });\n\n if (arrowEl && middlewareData.arrow) {\n const arrowData = middlewareData.arrow;\n const basePlacement = placement.split('-')[0] ?? 'bottom';\n const oppositeSide: Record<string, string> = {\n top: 'bottom',\n right: 'left',\n bottom: 'top',\n left: 'right',\n };\n const staticSide = oppositeSide[basePlacement] ?? 'bottom';\n\n Object.assign(arrowEl.style, {\n left: arrowData.x != null ? `${arrowData.x}px` : '',\n top: arrowData.y != null ? `${arrowData.y}px` : '',\n right: '',\n bottom: '',\n [staticSide]: '-5px',\n });\n\n // P2-02: hide the two border sides facing the popover body so only\n // the outward-facing corner is visible (avoids the inner border line).\n // Reset all four sides first, then make the two inner-facing ones transparent.\n const borderSides = ['border-top', 'border-right', 'border-bottom', 'border-left'] as const;\n for (const side of borderSides) {\n arrowEl.style.setProperty(side, '');\n }\n // Maps base placement → the two sides that face inward toward the popover body\n const innerBorderMap: Record<string, readonly [string, string]> = {\n bottom: ['border-bottom', 'border-right'],\n top: ['border-top', 'border-left'],\n right: ['border-top', 'border-right'],\n left: ['border-bottom', 'border-left'],\n };\n const innerSides = innerBorderMap[basePlacement] ?? ['border-bottom', 'border-right'];\n arrowEl.style.setProperty(innerSides[0], '1px solid transparent');\n arrowEl.style.setProperty(innerSides[1], '1px solid transparent');\n }\n }\n\n // ─── Event Handlers ───\n\n // P1-03 / P0-01 / HIGH-01: single document-level keydown handler while popover is open.\n // Handles Escape (close) and Tab (focus trap) in one listener to reduce overhead.\n /**\n * Handles Escape to close the popover and Tab/Shift+Tab to trap focus within it.\n * @internal\n */\n private _handleDocumentKeydown = (e: KeyboardEvent): void => {\n if (!this._visible) return;\n\n if (e.key === 'Escape') {\n // HIGH-03: Escape always restores focus to the prior element\n void this._hide(true);\n return;\n }\n\n if (e.key === 'Tab') {\n // HIGH-01: trap Tab/Shift+Tab focus within the popover body\n const focusable = this._getFocusableElements();\n if (focusable.length === 0) return;\n\n const bodyEl = this.shadowRoot?.querySelector('[part=\"body\"]') as HTMLElement | null;\n const allFocusable = bodyEl ? [bodyEl, ...focusable] : focusable;\n if (allFocusable.length === 0) return;\n\n const first = allFocusable[0] as HTMLElement;\n const last = allFocusable[allFocusable.length - 1] as HTMLElement;\n\n if (e.shiftKey) {\n if (document.activeElement === first || this.shadowRoot?.activeElement === first) {\n e.preventDefault();\n last.focus();\n }\n } else {\n if (document.activeElement === last || this.shadowRoot?.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n };\n\n // P0-01: close when click target is outside this component\n /**\n * Closes the popover when a click occurs outside the component boundary.\n * @internal\n */\n private _handleDocumentClick = (e: Event): void => {\n // Shadow DOM retargets events from within to the host at document level,\n // so a click on the trigger wrapper appears as e.target === this.\n if (e.target !== this && !this.contains(e.target as Node)) {\n // HIGH-03: click-outside does NOT restore focus — let browser handle naturally\n void this._hide(false);\n }\n };\n\n /**\n * Toggles the popover open/closed when the anchor is clicked in click trigger mode.\n * @internal\n */\n private _handleAnchorClick = (): void => {\n if (this.trigger !== 'click') return;\n if (this._visible) {\n void this._hide(true);\n } else {\n void this._show();\n }\n };\n\n /**\n * Opens the popover when the anchor receives a mouseenter event in hover trigger mode.\n * @internal\n */\n private _handleAnchorMouseEnter = (): void => {\n if (this.trigger !== 'hover') return;\n void this._show();\n };\n\n /**\n * Closes the popover when the anchor receives a mouseleave event in hover trigger mode.\n * WCAG 1.4.13: applies a 150 ms delay so the pointer can move from anchor\n * into the popover body without the content dismissing prematurely.\n * @internal\n */\n private _handleAnchorMouseLeave = (): void => {\n if (this.trigger !== 'hover') return;\n this._scheduleHoverHide();\n };\n\n // CRITICAL-02: body hover handlers so moving the pointer from anchor into\n // the popover content does not trigger a hide.\n /** @internal */\n private _handleBodyMouseEnter = (): void => {\n // Cancel a pending hide that would have fired from the anchor's mouseleave.\n if (this.trigger !== 'hover') return;\n this._cancelHoverHide();\n };\n\n /** @internal */\n private _handleBodyMouseLeave = (): void => {\n if (this.trigger !== 'hover') return;\n this._scheduleHoverHide();\n };\n\n /**\n * Schedules a hide with a 150 ms delay for hover-triggered dismissal.\n * WCAG 1.4.13: the delay allows the pointer to travel between the anchor\n * and the popover body without the content disappearing.\n * @internal\n */\n private _scheduleHoverHide(): void {\n this._cancelHoverHide();\n this._hoverHideTimer = setTimeout(() => {\n this._hoverHideTimer = null;\n void this._hide(false);\n }, 150);\n }\n\n /**\n * Cancels any pending hover-triggered hide.\n * @internal\n */\n private _cancelHoverHide(): void {\n if (this._hoverHideTimer !== null) {\n clearTimeout(this._hoverHideTimer);\n this._hoverHideTimer = null;\n }\n }\n\n /** @internal */\n private _handleAnchorFocusIn = (): void => {\n // CRITICAL-02: keyboard users trigger hover-mode popovers via focusin\n if (this.trigger !== 'focus' && this.trigger !== 'hover') return;\n void this._show();\n };\n\n /** @internal */\n private _handleAnchorFocusOut = (e: FocusEvent): void => {\n // CRITICAL-02: for hover mode, only hide when focus leaves both the anchor\n // and the popover body (i.e. relatedTarget is outside the component).\n if (this.trigger !== 'focus' && this.trigger !== 'hover') return;\n const related = e.relatedTarget as Node | null;\n // If focus is moving into the shadow root (body element), keep popover open\n if (related && (this.contains(related) || this.shadowRoot?.contains(related))) return;\n void this._hide(true);\n };\n\n /** @internal */\n private _handleAnchorSlotChange(): void {\n this._setAnchorAriaAttributes(this._visible);\n }\n\n // ─── Render ───\n\n override render() {\n return html`\n <div\n class=\"trigger-wrapper\"\n @click=${this._handleAnchorClick}\n @mouseenter=${this._handleAnchorMouseEnter}\n @mouseleave=${this._handleAnchorMouseLeave}\n @focusin=${this._handleAnchorFocusIn}\n @focusout=${this._handleAnchorFocusOut}\n >\n <slot name=\"anchor\" @slotchange=${this._handleAnchorSlotChange}></slot>\n </div>\n <div\n part=\"body\"\n id=${this._popoverId}\n role=\"dialog\"\n aria-label=${this.label}\n aria-hidden=${!this._visible ? 'true' : nothing}\n tabindex=\"-1\"\n ?inert=${!this._visible}\n class=${this._visible ? 'visible' : ''}\n @mouseenter=${this._handleBodyMouseEnter}\n @mouseleave=${this._handleBodyMouseLeave}\n >\n <slot></slot>\n ${this.arrow ? html`<div part=\"arrow\"></div>` : ''}\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-popover': HelixPopover;\n }\n}\n"],"names":["helixPopoverStyles","css","_popoverCounter","HelixPopover","LitElement","focusable","bodyEl","_a","allFocusable","first","last","_b","_c","related","changedProperties","expanded","anchorSlot","anchorEl","defaultSlot","assigned","focusableSelector","result","el","nested","restoreFocus","arrowEl","computePosition","flip","shift","offset","arrow","middleware","y","placement","middlewareData","arrowData","basePlacement","staticSide","borderSides","side","innerSides","html","nothing","__decorateClass","property","state","customElement"],"mappings":";;;AAEO,MAAMA,IAAqBC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;ACGlC,IAAIC,IAAkB,GA0CTC,IAAN,cAA2BC,EAAW;AAAA,EAAtC,cAAA;AAAA,UAAA,GAAA,SAAA,GAQL,KAAA,OAAO,IAOP,KAAA,YAYiB,UAOjB,KAAA,UAAkD,SAOlD,KAAA,WAAW,GAOX,KAAA,WAAW,GAOX,KAAA,QAAQ,IAOR,KAAA,QAAQ,WAMC,KAAQ,WAAW,IAM5B,KAAQ,iBAAqC,MAM7C,KAAiB,aAAa,cAAc,EAAEF,CAAe,IAO7D,KAAQ,aAAmD,MAS3D,KAAQ,kBAAwD,MAsOhE,KAAQ,yBAAyB,CAAC,MAA2B;;AAC3D,UAAK,KAAK,UAEV;AAAA,YAAI,EAAE,QAAQ,UAAU;AAEtB,UAAK,KAAK,MAAM,EAAI;AACpB;AAAA,QACF;AAEA,YAAI,EAAE,QAAQ,OAAO;AAEnB,gBAAMG,IAAY,KAAK,sBAAA;AACvB,cAAIA,EAAU,WAAW,EAAG;AAE5B,gBAAMC,KAASC,IAAA,KAAK,eAAL,gBAAAA,EAAiB,cAAc,kBACxCC,IAAeF,IAAS,CAACA,GAAQ,GAAGD,CAAS,IAAIA;AACvD,cAAIG,EAAa,WAAW,EAAG;AAE/B,gBAAMC,IAAQD,EAAa,CAAC,GACtBE,IAAOF,EAAaA,EAAa,SAAS,CAAC;AAEjD,UAAI,EAAE,YACA,SAAS,kBAAkBC,OAASE,IAAA,KAAK,eAAL,gBAAAA,EAAiB,mBAAkBF,OACzE,EAAE,eAAA,GACFC,EAAK,MAAA,MAGH,SAAS,kBAAkBA,OAAQE,IAAA,KAAK,eAAL,gBAAAA,EAAiB,mBAAkBF,OACxE,EAAE,eAAA,GACFD,EAAM,MAAA;AAAA,QAGZ;AAAA;AAAA,IACF,GAOA,KAAQ,uBAAuB,CAAC,MAAmB;AAGjD,MAAI,EAAE,WAAW,QAAQ,CAAC,KAAK,SAAS,EAAE,MAAc,KAEjD,KAAK,MAAM,EAAK;AAAA,IAEzB,GAMA,KAAQ,qBAAqB,MAAY;AACvC,MAAI,KAAK,YAAY,YACjB,KAAK,WACF,KAAK,MAAM,EAAI,IAEf,KAAK,MAAA;AAAA,IAEd,GAMA,KAAQ,0BAA0B,MAAY;AAC5C,MAAI,KAAK,YAAY,WAChB,KAAK,MAAA;AAAA,IACZ,GAQA,KAAQ,0BAA0B,MAAY;AAC5C,MAAI,KAAK,YAAY,WACrB,KAAK,mBAAA;AAAA,IACP,GAKA,KAAQ,wBAAwB,MAAY;AAE1C,MAAI,KAAK,YAAY,WACrB,KAAK,iBAAA;AAAA,IACP,GAGA,KAAQ,wBAAwB,MAAY;AAC1C,MAAI,KAAK,YAAY,WACrB,KAAK,mBAAA;AAAA,IACP,GA4BA,KAAQ,uBAAuB,MAAY;AAEzC,MAAI,KAAK,YAAY,WAAW,KAAK,YAAY,WAC5C,KAAK,MAAA;AAAA,IACZ,GAGA,KAAQ,wBAAwB,CAAC,MAAwB;;AAGvD,UAAI,KAAK,YAAY,WAAW,KAAK,YAAY,QAAS;AAC1D,YAAMI,IAAU,EAAE;AAElB,MAAIA,MAAY,KAAK,SAASA,CAAO,MAAKN,IAAA,KAAK,eAAL,QAAAA,EAAiB,SAASM,OAC/D,KAAK,MAAM,EAAI;AAAA,IACtB;AAAA,EAAA;AAAA;AAAA,EA5WS,uBAA6B;AACpC,UAAM,qBAAA,GACF,KAAK,eAAe,SACtB,aAAa,KAAK,UAAU,GAC5B,KAAK,aAAa,OAEhB,KAAK,oBAAoB,SAC3B,aAAa,KAAK,eAAe,GACjC,KAAK,kBAAkB,OAEzB,SAAS,oBAAoB,SAAS,KAAK,oBAAoB,GAC/D,SAAS,oBAAoB,WAAW,KAAK,sBAAsB;AAAA,EACrE;AAAA,EAES,eAAqB;AAG5B,SAAK,yBAAyB,EAAK,GAE/B,KAAK,QACF,KAAK,MAAA;AAAA,EAEd;AAAA,EAES,QAAQC,GAA+C;AAC9D,IAAIA,EAAkB,IAAI,MAAM,MAC1B,KAAK,OACF,KAAK,MAAA,IAEL,KAAK,MAAA;AAAA,EAGhB;AAAA;AAAA;AAAA;AAAA,EAMQ,yBAAyBC,GAAyB;;AACxD,UAAMC,KAAaT,IAAA,KAAK,eAAL,gBAAAA,EAAiB;AAAA,MAClC;AAAA;AAEF,QAAI,CAACS,EAAY;AACjB,UAAMC,IAAWD,EAAW,iBAAA,EAAmB,CAAC;AAChD,IAAIC,MACFA,EAAS,aAAa,iBAAiB,OAAOF,CAAQ,CAAC,GACvDE,EAAS,aAAa,iBAAiB,QAAQ;AAAA,EAInD;AAAA;AAAA;AAAA;AAAA,EAMQ,wBAAuC;;AAC7C,UAAMX,KAASC,IAAA,KAAK,eAAL,gBAAAA,EAAiB,cAAc;AAC9C,QAAI,CAACD,EAAQ,QAAO,CAAA;AAGpB,UAAMY,IAAcZ,EAAO,cAAc,kBAAkB;AAC3D,QAAI,CAACY,EAAa,QAAO,CAAA;AAEzB,UAAMC,IAAWD,EAAY,iBAAiB,EAAE,SAAS,IAAM,GACzDE,IACJ,4KAEIC,IAAwB,CAAA;AAC9B,eAAWC,KAAMH,GAAU;AACzB,MAAIG,EAAG,QAAQF,CAAiB,KAC9BC,EAAO,KAAKC,CAAiB;AAE/B,YAAMC,IAASD,EAAG,iBAA8BF,CAAiB;AACjE,MAAAC,EAAO,KAAK,GAAGE,CAAM;AAAA,IACvB;AACA,WAAOF;AAAA,EACT;AAAA;AAAA;AAAA,EAKA,MAAc,QAAuB;;AACnC,QAAI,KAAK,SAAU;AAEnB,SAAK,iBAAiB,SAAS,eAC/B,KAAK,cAAc,IAAI,YAAkB,WAAW,EAAE,SAAS,IAAM,UAAU,GAAA,CAAM,CAAC,GACtF,KAAK,WAAW,IAChB,KAAK,OAAO,IACZ,KAAK,yBAAyB,EAAI,GAIlC,SAAS,iBAAiB,WAAW,KAAK,sBAAsB,GAChE,MAAM,KAAK,gBAIX,KAAK,cAAc,IAAI,YAAkB,iBAAiB,EAAE,SAAS,IAAM,UAAU,GAAA,CAAM,CAAC;AAI5F,UAAMf,KAASC,IAAA,KAAK,eAAL,gBAAAA,EAAiB,cAAc;AAC9C,IAAID,KACqB,KAAK,sBAAA,EAAwB,SAAS,KAE3DA,EAAO,MAAA,GAIP,KAAK,eAAe,QACtB,aAAa,KAAK,UAAU,GAE9B,KAAK,aAAa,WAAW,MAAM;AACjC,WAAK,aAAa,MAClB,SAAS,iBAAiB,SAAS,KAAK,oBAAoB;AAAA,IAC9D,GAAG,CAAC,GACJ,MAAM,KAAK,gBAAA;AAAA,EACb;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,MAAMkB,IAAe,IAAqB;;AACtD,IAAK,KAAK,aACV,SAAS,oBAAoB,SAAS,KAAK,oBAAoB,GAC/D,SAAS,oBAAoB,WAAW,KAAK,sBAAsB,GACnE,KAAK,cAAc,IAAI,YAAkB,WAAW,EAAE,SAAS,IAAM,UAAU,GAAA,CAAM,CAAC,GACtF,KAAK,WAAW,IAChB,KAAK,OAAO,IACZ,KAAK,yBAAyB,EAAK,GAE/BA,OACFjB,IAAA,KAAK,mBAAL,QAAAA,EAAqB,UAEvB,KAAK,iBAAiB,MACtB,MAAM,KAAK,gBACX,KAAK,cAAc,IAAI,YAAkB,iBAAiB,EAAE,SAAS,IAAM,UAAU,GAAA,CAAM,CAAC;AAAA,EAC9F;AAAA;AAAA;AAAA,EAKA,MAAc,kBAAiC;;AAC7C,UAAMS,KAAaT,IAAA,KAAK,eAAL,gBAAAA,EAAiB;AAAA,MAClC;AAAA;AAEF,QAAI,CAACS,EAAY;AACjB,UAAMC,IAAWD,EAAW,iBAAA,EAAmB,CAAC,GAC1CV,KAASK,IAAA,KAAK,eAAL,gBAAAA,EAAiB,cAAc,kBACxCc,IAAU,KAAK,SAChBb,IAAA,KAAK,eAAL,gBAAAA,EAAiB,cAAc,oBAChC;AAEJ,QAAI,CAACK,KAAY,CAACX,EAAQ;AAE1B,UAAM,EAAE,iBAAAoB,GAAiB,MAAAC,GAAM,OAAAC,GAAO,QAAAC,GAAQ,OAAAC,EAAA,IAAU,MAAM,OAAO,kBAAkB,GAEjFC,IAAa;AAAA,MACjBF,EAAO,EAAE,UAAU,KAAK,UAAU,WAAW,KAAK,UAAU;AAAA,MAC5DF,EAAA;AAAA,MACAC,EAAM,EAAE,SAAS,EAAA,CAAG;AAAA,IAAA;AAGtB,IAAIH,KACFM,EAAW,KAAKD,EAAM,EAAE,SAASL,EAAA,CAAS,CAAC;AAG7C,UAAM,EAAE,GAAG,GAAAO,GAAG,WAAAC,GAAW,gBAAAC,MAAmB,MAAMR,EAAgBT,GAAUX,GAAQ;AAAA,MAClF,WAAW,KAAK;AAAA,MAChB,UAAU;AAAA,MACV,YAAAyB;AAAA,IAAA,CACD;AAOD,QALA,OAAO,OAAOzB,EAAO,OAAO;AAAA,MAC1B,MAAM,GAAG,CAAC;AAAA,MACV,KAAK,GAAG0B,CAAC;AAAA,IAAA,CACV,GAEGP,KAAWS,EAAe,OAAO;AACnC,YAAMC,IAAYD,EAAe,OAC3BE,IAAgBH,EAAU,MAAM,GAAG,EAAE,CAAC,KAAK,UAO3CI,IANuC;AAAA,QAC3C,KAAK;AAAA,QACL,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,MAAM;AAAA,MAAA,EAEwBD,CAAa,KAAK;AAElD,aAAO,OAAOX,EAAQ,OAAO;AAAA,QAC3B,MAAMU,EAAU,KAAK,OAAO,GAAGA,EAAU,CAAC,OAAO;AAAA,QACjD,KAAKA,EAAU,KAAK,OAAO,GAAGA,EAAU,CAAC,OAAO;AAAA,QAChD,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,CAACE,CAAU,GAAG;AAAA,MAAA,CACf;AAKD,YAAMC,IAAc,CAAC,cAAc,gBAAgB,iBAAiB,aAAa;AACjF,iBAAWC,KAAQD;AACjB,QAAAb,EAAQ,MAAM,YAAYc,GAAM,EAAE;AASpC,YAAMC,IAN4D;AAAA,QAChE,QAAQ,CAAC,iBAAiB,cAAc;AAAA,QACxC,KAAK,CAAC,cAAc,aAAa;AAAA,QACjC,OAAO,CAAC,cAAc,cAAc;AAAA,QACpC,MAAM,CAAC,iBAAiB,aAAa;AAAA,MAAA,EAELJ,CAAa,KAAK,CAAC,iBAAiB,cAAc;AACpF,MAAAX,EAAQ,MAAM,YAAYe,EAAW,CAAC,GAAG,uBAAuB,GAChEf,EAAQ,MAAM,YAAYe,EAAW,CAAC,GAAG,uBAAuB;AAAA,IAClE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiHQ,qBAA2B;AACjC,SAAK,iBAAA,GACL,KAAK,kBAAkB,WAAW,MAAM;AACtC,WAAK,kBAAkB,MAClB,KAAK,MAAM,EAAK;AAAA,IACvB,GAAG,GAAG;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,mBAAyB;AAC/B,IAAI,KAAK,oBAAoB,SAC3B,aAAa,KAAK,eAAe,GACjC,KAAK,kBAAkB;AAAA,EAE3B;AAAA;AAAA,EAqBQ,0BAAgC;AACtC,SAAK,yBAAyB,KAAK,QAAQ;AAAA,EAC7C;AAAA;AAAA,EAIS,SAAS;AAChB,WAAOC;AAAA;AAAA;AAAA,iBAGM,KAAK,kBAAkB;AAAA,sBAClB,KAAK,uBAAuB;AAAA,sBAC5B,KAAK,uBAAuB;AAAA,mBAC/B,KAAK,oBAAoB;AAAA,oBACxB,KAAK,qBAAqB;AAAA;AAAA,0CAEJ,KAAK,uBAAuB;AAAA;AAAA;AAAA;AAAA,aAIzD,KAAK,UAAU;AAAA;AAAA,qBAEP,KAAK,KAAK;AAAA,sBACR,KAAK,WAAoBC,IAAT,MAAgB;AAAA;AAAA,iBAEtC,CAAC,KAAK,QAAQ;AAAA,gBACf,KAAK,WAAW,YAAY,EAAE;AAAA,sBACxB,KAAK,qBAAqB;AAAA,sBAC1B,KAAK,qBAAqB;AAAA;AAAA;AAAA,UAGtC,KAAK,QAAQD,8BAAiC,EAAE;AAAA;AAAA;AAAA,EAGxD;AACF;AAtfatC,EACK,SAAS,CAACH,CAAkB;AAO5C2C,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,SAAS,SAAS,IAAM;AAAA,GAP/BzC,EAQX,WAAA,QAAA,CAAA;AAOAwC,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,QAAQ,SAAS,IAAM;AAAA,GAd9BzC,EAeX,WAAA,aAAA,CAAA;AAmBAwC,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,QAAQ,SAAS,IAAM;AAAA,GAjC9BzC,EAkCX,WAAA,WAAA,CAAA;AAOAwC,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,QAAQ,SAAS,IAAM;AAAA,GAxC9BzC,EAyCX,WAAA,YAAA,CAAA;AAOAwC,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,QAAQ,SAAS,IAAM;AAAA,GA/C9BzC,EAgDX,WAAA,YAAA,CAAA;AAOAwC,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,SAAS,SAAS,IAAM;AAAA,GAtD/BzC,EAuDX,WAAA,SAAA,CAAA;AAOAwC,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,QAAQ,SAAS,IAAM;AAAA,GA7D9BzC,EA8DX,WAAA,SAAA,CAAA;AAMiBwC,EAAA;AAAA,EAAhBE,EAAA;AAAM,GApEI1C,EAoEM,WAAA,YAAA,CAAA;AApENA,IAANwC,EAAA;AAAA,EADNG,EAAc,YAAY;AAAA,GACd3C,CAAA;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hx-popup-BQWMhvMO.js","sources":["../../src/components/hx-popup/hx-popup.styles.ts","../../src/components/hx-popup/hx-popup.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixPopupStyles = css`\n :host {\n display: inline-block;\n }\n\n [part='popup'] {\n position: fixed;\n z-index: var(--hx-popup-z-index, 9000);\n inset: 0 auto auto 0;\n box-sizing: border-box;\n transition: var(--hx-popup-transition, none);\n }\n\n :host(:not([active])) [part='popup'] {\n display: none;\n }\n\n [part='arrow'] {\n position: absolute;\n width: var(--hx-arrow-size, 8px);\n height: var(--hx-arrow-size, 8px);\n background: var(--hx-arrow-color, var(--hx-color-neutral-0, #ffffff));\n transform: rotate(45deg);\n pointer-events: none;\n }\n\n @media (prefers-reduced-motion: reduce) {\n [part='popup'] {\n transition: none;\n }\n }\n`;\n","import { LitElement, html, type PropertyValues } from 'lit';\nimport '../../utilities/document-token-adoption.js';\nimport { customElement, property } from 'lit/decorators.js';\nimport {\n computePosition,\n flip as flipMiddleware,\n shift as shiftMiddleware,\n offset as offsetMiddleware,\n arrow as arrowMiddleware,\n autoUpdate,\n size as sizeMiddleware,\n autoPlacement as autoPlacementMiddleware,\n} from '@floating-ui/dom';\nimport type { Placement, Middleware } from '@floating-ui/dom';\nimport { helixPopupStyles } from './hx-popup.styles.js';\n\ntype PopupPlacement =\n | 'top'\n | 'top-start'\n | 'top-end'\n | 'right'\n | 'right-start'\n | 'right-end'\n | 'bottom'\n | 'bottom-start'\n | 'bottom-end'\n | 'left'\n | 'left-start'\n | 'left-end'\n | 'auto';\n\n// More precise type matching @floating-ui/dom's arrow middleware data structure\ntype ArrowData = { x?: number; y?: number; centerOffset: number };\n\n/**\n * A low-level positioning primitive that anchors a floating panel to a reference element.\n * This is the base that hx-tooltip, hx-dropdown, and hx-popover build upon.\n *\n * @summary Low-level popup positioning utility.\n *\n * @tag hx-popup\n *\n * @slot anchor - The reference element the popup is anchored to.\n * @slot - Default slot for popup content.\n *\n * @csspart popup - The popup container element.\n * @csspart arrow - The arrow indicator element (only present when `arrow` is true).\n *\n * @cssprop [--hx-popup-z-index=9000] - Z-index of the popup container.\n * @cssprop [--hx-popup-transition=none] - Transition applied to the popup element.\n * Consumers who need enter/exit animations can set this property AND override the\n * default `display: none` hide mechanism via `::part(popup)`. Example:\n * ```css\n * hx-popup { --hx-popup-transition: opacity 0.2s ease; }\n * hx-popup:not([active])::part(popup) { display: block; opacity: 0; pointer-events: none; }\n * hx-popup[active]::part(popup) { opacity: 1; }\n * ```\n * @cssprop [--hx-arrow-size=8px] - Size of the arrow element.\n * @cssprop [--hx-arrow-color=var(--hx-color-surface-overlay, #ffffff)] - Color of the arrow element.\n * @cssprop --hx-auto-size-available-width - Available width set by auto-size middleware (on :host).\n * @cssprop --hx-auto-size-available-height - Available height set by auto-size middleware (on :host).\n *\n * @fires {CustomEvent} hx-reposition - Emitted after the popup is repositioned.\n *\n * ## Accessibility Contract\n *\n * `hx-popup` is a **positioning utility**, not an interactive widget. It does not provide\n * ARIA semantics. Consumers are responsible for all accessibility:\n *\n * - **Popup role**: Add `role=\"tooltip\"`, `role=\"dialog\"`, `role=\"listbox\"`, etc. to the\n * slotted popup content depending on its purpose.\n * - **Trigger state**: The element that triggers the popup MUST set `aria-expanded=\"true/false\"`.\n * - **Association**: Use `aria-controls` on the trigger to reference the popup content element,\n * and `aria-labelledby` / `aria-describedby` as appropriate.\n * - **Focus management**: `hx-popup` does NOT trap focus. Consumers building dialogs or menus\n * MUST implement focus trapping and keyboard dismiss (Escape key) themselves.\n * - **Visibility**: The popup is hidden via `display: none` (CSS) and the `inert` attribute\n * when inactive. Both are reliable accessibility-tree hiding mechanisms.\n *\n * @example\n * ```html\n * <!-- Tooltip pattern -->\n * <hx-popup id=\"my-tooltip\" placement=\"bottom\" distance=\"8\">\n * <button\n * slot=\"anchor\"\n * aria-describedby=\"tooltip-content\"\n * aria-expanded=\"false\"\n * aria-controls=\"my-tooltip\"\n * >\n * Trigger\n * </button>\n * <div id=\"tooltip-content\" role=\"tooltip\">Tooltip text</div>\n * </hx-popup>\n * ```\n *\n * ## Drupal Integration\n *\n * `hx-popup` is a JS utility — Twig provides markup only. No Drupal behavior file is\n * required for basic usage, since the `anchor` slot and `active` attribute are sufficient.\n *\n * ```twig\n * {# Basic Twig usage — prefer anchor slot in server-rendered contexts #}\n * <hx-popup id=\"my-popup\" placement=\"bottom\" distance=\"8\">\n * <button\n * slot=\"anchor\"\n * aria-expanded=\"false\"\n * aria-controls=\"popup-content\"\n * >Open</button>\n * <div id=\"popup-content\" role=\"dialog\" aria-label=\"Popup content\">...</div>\n * </hx-popup>\n * ```\n *\n * ```js\n * // Drupal behavior for toggle interaction\n * Drupal.behaviors.helixPopup = {\n * attach(context) {\n * context.querySelectorAll('hx-popup').forEach((popup) => {\n * const trigger = popup.querySelector('[slot=\"anchor\"]');\n * if (!trigger) return;\n * trigger.addEventListener('click', () => {\n * popup.active = !popup.active;\n * trigger.setAttribute('aria-expanded', String(popup.active));\n * });\n * });\n * },\n * };\n * ```\n *\n * For Drupal-generated dynamic IDs, prefer the anchor **slot** over the `anchor` CSS selector\n * attribute, since slot-based anchoring does not require knowing the element's ID at render time.\n * If you must use the CSS selector form with dynamic IDs, pass the ID via a Twig variable:\n * ```twig\n * <hx-popup anchor=\"#{{ element['#id'] }}\" placement=\"bottom\">...</hx-popup>\n * ```\n */\n@customElement('hx-popup')\nexport class HelixPopup extends LitElement {\n static override styles = [helixPopupStyles];\n\n /** @internal */\n private _anchorSlotEl: Element | null = null;\n /** @internal */\n private _cleanupAutoUpdate: (() => void) | null = null;\n\n /**\n * The reference element to anchor the popup to.\n *\n * - **Attribute form** (`anchor=\"#selector\"`): Accepts a CSS selector string resolved via\n * `querySelector` from the component's root node. Use this in HTML/Twig markup.\n * - **Property form** (`el.anchor = element`): Accepts an `Element` reference directly.\n * Setting an Element via JS property does NOT reflect to the attribute.\n *\n * If not set, the element in the `anchor` slot is used.\n *\n * @attr anchor\n */\n @property({ attribute: 'anchor' })\n anchor: string | Element | null = null;\n\n /**\n * Preferred placement of the popup relative to the anchor.\n * @attr placement\n */\n @property({ type: String, reflect: true })\n placement:\n | 'top'\n | 'top-start'\n | 'top-end'\n | 'right'\n | 'right-start'\n | 'right-end'\n | 'bottom'\n | 'bottom-start'\n | 'bottom-end'\n | 'left'\n | 'left-start'\n | 'left-end'\n | 'auto' = 'bottom';\n\n /**\n * Whether the popup is visible.\n * @attr active\n */\n @property({ type: Boolean, reflect: true })\n active = false;\n\n /**\n * Gap in pixels between the popup and the anchor element.\n * @attr distance\n */\n @property({ type: Number, reflect: true })\n distance = 0;\n\n /**\n * Offset in pixels along the anchor element's axis.\n * @attr skidding\n */\n @property({ type: Number, reflect: true })\n skidding = 0;\n\n /**\n * Whether to show an arrow pointing to the anchor element.\n * @attr arrow\n */\n @property({ type: Boolean, reflect: true })\n arrow = false;\n\n /**\n * Manual placement of the arrow along the popup edge.\n * When not set, floating-ui calculates the optimal position.\n * @attr arrow-placement\n */\n @property({ attribute: 'arrow-placement', reflect: true })\n arrowPlacement: 'start' | 'center' | 'end' | null = null;\n\n /**\n * Minimum padding in pixels from the popup edge to the arrow.\n * @attr arrow-padding\n */\n @property({ type: Number, attribute: 'arrow-padding' })\n arrowPadding = 10;\n\n /**\n * When true, flips the popup to the opposite side to avoid overflow.\n * @attr flip\n */\n @property({ type: Boolean, reflect: true })\n flip = false;\n\n /**\n * Fallback placements to try when flipping. Accepts a JSON array string.\n *\n * @example\n * ```html\n * <!-- Try \"top\" then \"left\" before giving up -->\n * <hx-popup flip flip-fallback-placements='[\"top\",\"left\"]'>...</hx-popup>\n * ```\n *\n * @attr flip-fallback-placements\n */\n @property({\n attribute: 'flip-fallback-placements',\n converter: {\n fromAttribute(value: string | null): PopupPlacement[] {\n if (!value) return [];\n try {\n return JSON.parse(value) as PopupPlacement[];\n } catch {\n return [];\n }\n },\n toAttribute(value: PopupPlacement[]): string {\n return JSON.stringify(value);\n },\n },\n })\n flipFallbackPlacements: (\n | 'top'\n | 'top-start'\n | 'top-end'\n | 'right'\n | 'right-start'\n | 'right-end'\n | 'bottom'\n | 'bottom-start'\n | 'bottom-end'\n | 'left'\n | 'left-start'\n | 'left-end'\n | 'auto'\n )[] = [];\n\n /**\n * When true, shifts the popup along the axis to remain in the viewport.\n * @attr shift\n */\n @property({ type: Boolean, reflect: true })\n shift = false;\n\n /**\n * When true, resizes the popup to fit within the viewport.\n * Sets --hx-auto-size-available-width and --hx-auto-size-available-height CSS custom\n * properties on `:host` so they cascade into shadow DOM and are readable from light DOM.\n * @attr auto-size\n */\n @property({ type: Boolean, attribute: 'auto-size', reflect: true })\n autoSize = false;\n\n /**\n * Positioning strategy passed to floating-ui's `computePosition`.\n *\n * - `'fixed'` (default): works for most cases; positions relative to the viewport.\n * - `'absolute'`: use inside `overflow: hidden` / scroll containers where the popup is\n * positioned relative to the nearest positioned ancestor instead of the viewport.\n *\n * @attr strategy\n */\n @property({ reflect: true })\n strategy: 'fixed' | 'absolute' = 'fixed';\n\n // ─── Lifecycle ───\n\n override connectedCallback(): void {\n super.connectedCallback();\n if (this.active) {\n void this.updateComplete.then(() => this._startAutoUpdate());\n }\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this._stopAutoUpdate();\n }\n\n override updated(changedProperties: PropertyValues<this>): void {\n super.updated(changedProperties);\n\n const activeChanged = changedProperties.has('active');\n const positioningChanged =\n changedProperties.has('placement') ||\n changedProperties.has('distance') ||\n changedProperties.has('skidding') ||\n changedProperties.has('arrow') ||\n changedProperties.has('arrowPadding') ||\n changedProperties.has('arrowPlacement') ||\n changedProperties.has('flip') ||\n changedProperties.has('flipFallbackPlacements') ||\n changedProperties.has('shift') ||\n changedProperties.has('autoSize') ||\n changedProperties.has('anchor') ||\n changedProperties.has('strategy');\n\n if (activeChanged) {\n if (this.active) {\n this._startAutoUpdate();\n } else {\n this._stopAutoUpdate();\n // Clean up autoSize custom properties when popup goes inactive\n if (this.autoSize) {\n this.style.removeProperty('--hx-auto-size-available-width');\n this.style.removeProperty('--hx-auto-size-available-height');\n }\n }\n } else if (positioningChanged && this.active) {\n void this._reposition();\n }\n\n // Remove stale autoSize properties when autoSize is disabled\n if (changedProperties.has('autoSize') && !this.autoSize) {\n this.style.removeProperty('--hx-auto-size-available-width');\n this.style.removeProperty('--hx-auto-size-available-height');\n }\n }\n\n // ─── Anchor Resolution ───\n\n /** @internal */\n private _getAnchorElement(): Element | null {\n if (this.anchor instanceof Element) {\n return this.anchor;\n }\n if (typeof this.anchor === 'string') {\n return (this.getRootNode() as Document | ShadowRoot).querySelector(this.anchor);\n }\n return this._anchorSlotEl;\n }\n\n /** @internal */\n private _handleAnchorSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n const assigned = slot.assignedElements();\n this._anchorSlotEl = assigned[0] ?? null;\n if (this.active) {\n void this._reposition();\n }\n }\n\n // ─── Positioning ───\n\n /** @internal */\n private _startAutoUpdate(): void {\n this._stopAutoUpdate();\n const anchorEl = this._getAnchorElement();\n const popupEl = this.shadowRoot?.querySelector<HTMLElement>('[part=\"popup\"]');\n if (!anchorEl || !popupEl) return;\n\n this._cleanupAutoUpdate = autoUpdate(anchorEl, popupEl, () => {\n void this._reposition();\n });\n }\n\n /** @internal */\n private _stopAutoUpdate(): void {\n this._cleanupAutoUpdate?.();\n this._cleanupAutoUpdate = null;\n }\n\n /** @internal */\n private async _reposition(): Promise<void> {\n const anchorEl = this._getAnchorElement();\n const popupEl = this.shadowRoot?.querySelector<HTMLElement>('[part=\"popup\"]');\n if (!anchorEl || !popupEl) return;\n\n const arrowEl = this.arrow\n ? (this.shadowRoot?.querySelector<HTMLElement>('[part=\"arrow\"]') ?? null)\n : null;\n\n const middleware: Middleware[] = [\n offsetMiddleware({ mainAxis: this.distance, crossAxis: this.skidding }),\n ];\n\n if (this.placement === 'auto') {\n middleware.push(autoPlacementMiddleware());\n } else if (this.flip) {\n middleware.push(\n flipMiddleware({\n fallbackPlacements: this.flipFallbackPlacements as Placement[],\n }),\n );\n }\n\n if (this.shift) {\n middleware.push(shiftMiddleware({ padding: 8 }));\n }\n\n if (arrowEl) {\n middleware.push(arrowMiddleware({ element: arrowEl, padding: this.arrowPadding }));\n }\n\n if (this.autoSize) {\n middleware.push(\n sizeMiddleware({\n apply: ({ availableWidth, availableHeight }) => {\n // Set on :host so the custom properties cascade into shadow DOM and\n // are accessible from light DOM consumers via CSS inheritance.\n this.style.setProperty('--hx-auto-size-available-width', `${availableWidth}px`);\n this.style.setProperty('--hx-auto-size-available-height', `${availableHeight}px`);\n },\n }),\n );\n }\n\n const effectivePlacement: Placement =\n this.placement === 'auto' ? 'bottom' : (this.placement as Placement);\n\n // Set position strategy before computing — inline style takes precedence over CSS\n popupEl.style.position = this.strategy;\n\n const { x, y, placement, middlewareData } = await computePosition(anchorEl, popupEl, {\n placement: effectivePlacement,\n strategy: this.strategy,\n middleware,\n });\n\n Object.assign(popupEl.style, {\n left: `${x}px`,\n top: `${y}px`,\n });\n\n if (arrowEl) {\n const arrowData = middlewareData.arrow as ArrowData | undefined;\n this._positionArrow(arrowEl, placement, arrowData);\n }\n\n this.dispatchEvent(new CustomEvent<void>('hx-reposition', { bubbles: true, composed: true }));\n }\n\n /** @internal */\n private _positionArrow(\n arrowEl: HTMLElement,\n placement: Placement,\n arrowData: ArrowData | undefined,\n ): void {\n const basePlacement = placement.split('-')[0] as 'top' | 'right' | 'bottom' | 'left';\n const staticSides = {\n top: 'bottom',\n right: 'left',\n bottom: 'top',\n left: 'right',\n } as const;\n const staticSide = staticSides[basePlacement];\n\n const arrowStyle: Record<string, string> = {\n left: '',\n top: '',\n right: '',\n bottom: '',\n };\n\n if (this.arrowPlacement === 'start' || this.arrowPlacement === 'end') {\n const isVertical = basePlacement === 'top' || basePlacement === 'bottom';\n if (isVertical) {\n arrowStyle[this.arrowPlacement === 'start' ? 'left' : 'right'] = `${this.arrowPadding}px`;\n } else {\n arrowStyle[this.arrowPlacement === 'start' ? 'top' : 'bottom'] = `${this.arrowPadding}px`;\n }\n } else {\n // 'center' or null: use floating-ui computed position\n if (arrowData?.x != null) arrowStyle.left = `${arrowData.x}px`;\n if (arrowData?.y != null) arrowStyle.top = `${arrowData.y}px`;\n }\n\n arrowStyle[staticSide] = '-4px';\n arrowEl.setAttribute('data-placement', basePlacement);\n Object.assign(arrowEl.style, arrowStyle);\n }\n\n // ─── Public API ───\n\n /**\n * Forces the popup to recalculate its position.\n */\n async reposition(): Promise<void> {\n await this._reposition();\n }\n\n // ─── Render ───\n\n override render() {\n return html`\n <slot name=\"anchor\" @slotchange=${this._handleAnchorSlotChange}></slot>\n <div part=\"popup\" ?inert=${!this.active}>\n <slot></slot>\n ${this.arrow ? html`<div part=\"arrow\"></div>` : ''}\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-popup': HelixPopup;\n }\n}\n"],"names":["helixPopupStyles","css","HelixPopup","LitElement","changedProperties","activeChanged","positioningChanged","e","assigned","anchorEl","popupEl","_a","autoUpdate","arrowEl","_b","middleware","offsetMiddleware","autoPlacementMiddleware","flipMiddleware","shiftMiddleware","arrowMiddleware","sizeMiddleware","availableWidth","availableHeight","effectivePlacement","x","y","placement","middlewareData","computePosition","arrowData","basePlacement","staticSide","arrowStyle","html","__decorateClass","property","value","customElement"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hx-progress-bar-Cm0VihTN.js","sources":["../../src/components/hx-progress-bar/hx-progress-bar.styles.ts","../../src/components/hx-progress-bar/hx-progress-bar.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixProgressBarStyles = css`\n :host {\n display: block;\n }\n\n .sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border-width: 0;\n }\n\n .progress-bar {\n display: flex;\n flex-direction: column;\n gap: var(--hx-space-1, 0.25rem);\n }\n\n .progress-bar__label {\n font-family: var(--hx-progress-bar-label-font-family, var(--hx-font-family-sans, sans-serif));\n font-size: var(--hx-progress-bar-label-font-size, var(--hx-font-size-sm, 0.875rem));\n font-weight: var(--hx-progress-bar-label-font-weight, var(--hx-font-weight-medium, 500));\n color: var(--hx-progress-bar-label-color, var(--hx-color-neutral-700));\n line-height: var(--hx-line-height-tight, 1.25);\n }\n\n .progress-bar__track {\n position: relative;\n overflow: hidden;\n border-radius: var(--hx-progress-bar-border-radius, var(--hx-border-radius-full, 9999px));\n background-color: var(--hx-progress-bar-track-bg, var(--hx-color-neutral-100));\n width: 100%;\n }\n\n /* ─── Size Variants ─── */\n\n .progress-bar--sm .progress-bar__track {\n height: var(--hx-progress-bar-height-sm, var(--hx-space-1, 0.25rem));\n }\n\n .progress-bar--md .progress-bar__track {\n height: var(--hx-progress-bar-height-md, var(--hx-space-2, 0.5rem));\n }\n\n .progress-bar--lg .progress-bar__track {\n height: var(--hx-progress-bar-height-lg, var(--hx-space-3, 0.75rem));\n }\n\n .progress-bar__fill {\n height: 100%;\n width: 100%;\n border-radius: inherit;\n background-color: var(--hx-progress-bar-indicator-bg, var(--hx-color-primary-500));\n transform-origin: left center;\n transform: scaleX(var(--_value-ratio, 0));\n transition: transform var(--hx-transition-fast, 150ms ease);\n }\n\n @media (prefers-reduced-motion: reduce) {\n .progress-bar__fill {\n transition: none;\n }\n }\n\n /* ─── Variant Colors ─── */\n\n .progress-bar--default .progress-bar__fill {\n --hx-progress-bar-indicator-bg: var(--hx-color-primary-500);\n }\n\n .progress-bar--success .progress-bar__fill {\n --hx-progress-bar-indicator-bg: var(--hx-color-success-700);\n }\n\n .progress-bar--warning .progress-bar__fill {\n --hx-progress-bar-indicator-bg: var(--hx-color-warning-500);\n }\n\n .progress-bar--danger .progress-bar__fill {\n --hx-progress-bar-indicator-bg: var(--hx-color-error-500);\n }\n\n /* ─── Indeterminate Animation ─── */\n\n @keyframes hx-progress-indeterminate {\n 0% {\n transform: translateX(-100%) scaleX(0.4);\n }\n 50% {\n transform: translateX(50%) scaleX(0.6);\n }\n 100% {\n transform: translateX(250%) scaleX(0.4);\n }\n }\n\n .progress-bar--indeterminate .progress-bar__fill {\n transform: translateX(-100%) scaleX(0.4);\n transform-origin: left center;\n animation: hx-progress-indeterminate var(--hx-progress-bar-indeterminate-duration, 1.5s)\n ease-in-out infinite;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .progress-bar__fill {\n transition: none;\n }\n\n .progress-bar--indeterminate .progress-bar__fill {\n animation: none;\n transform: scaleX(1);\n opacity: var(--hx-opacity-disabled, 0.5); /* reduced from animation; no exact token for 0.4 */\n }\n }\n\n /* ─── High Contrast Mode ─── */\n\n @media (forced-colors: active) {\n .progress-bar__track {\n border: 1px solid ButtonText;\n background-color: Canvas;\n }\n\n .progress-bar__fill {\n background-color: Highlight;\n forced-color-adjust: none;\n }\n }\n`;\n","import { LitElement, html, nothing, type PropertyValues } from 'lit';\nimport '../../utilities/document-token-adoption.js';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { helixProgressBarStyles } from './hx-progress-bar.styles.js';\nimport { devWarn } from '../../utils/dev-warn.js';\n\n/**\n * A linear progress indicator for determinate and indeterminate states.\n *\n * @summary Displays task completion progress or an indeterminate loading state.\n *\n * @tag hx-progress-bar\n *\n * @slot label - Visible label text rendered above the progress bar track.\n *\n * @csspart track - The outer track container element.\n * @csspart fill - The filled portion indicating progress.\n * @csspart label - The label slot wrapper element.\n *\n * @cssprop [--hx-progress-bar-track-bg=var(--hx-color-neutral-100)] - Track background color.\n * @cssprop [--hx-progress-bar-indicator-bg=var(--hx-color-primary-500)] - Indicator fill color.\n * @cssprop [--hx-progress-bar-border-radius=var(--hx-border-radius-full)] - Track border radius.\n * @cssprop [--hx-progress-bar-height-sm=var(--hx-size-1)] - Track height for size=\"sm\".\n * @cssprop [--hx-progress-bar-height-md=var(--hx-size-2)] - Track height for size=\"md\".\n * @cssprop [--hx-progress-bar-height-lg=var(--hx-size-3)] - Track height for size=\"lg\".\n * @cssprop [--hx-progress-bar-label-font-family=var(--hx-font-family-sans)] - Label font family.\n * @cssprop [--hx-progress-bar-label-font-size=var(--hx-font-size-sm)] - Label font size.\n * @cssprop [--hx-progress-bar-label-font-weight=var(--hx-font-weight-medium)] - Label font weight.\n * @cssprop [--hx-progress-bar-label-color=var(--hx-color-neutral-700)] - Label text color.\n *\n * @fires {CustomEvent} hx-complete - Emitted when progress reaches 100%.\n */\n@customElement('hx-progress-bar')\nexport class HelixProgressBar extends LitElement {\n static override styles = [helixProgressBarStyles];\n\n /**\n * Current progress value (min–max). Set to null for indeterminate state.\n * @attr value\n */\n @property({ type: Number, reflect: true })\n value: number | null = null;\n\n /**\n * Minimum value for the progress bar.\n * @attr min\n */\n @property({ type: Number, reflect: true })\n min = 0;\n\n /**\n * Maximum value for the progress bar.\n * @attr max\n */\n @property({ type: Number, reflect: true })\n max = 100;\n\n /**\n * When true, displays an animated indeterminate loading state regardless of value.\n * @attr indeterminate\n */\n @property({ type: Boolean, reflect: true })\n indeterminate = false;\n\n /**\n * Accessible label for the progress bar (maps to aria-label when no label slot content is used).\n * @attr label\n */\n @property({ type: String, reflect: true })\n label = '';\n\n /**\n * Additional description for the progress operation, linked via aria-describedby.\n * @attr description\n */\n @property({ type: String, reflect: true })\n description = '';\n\n /**\n * Size of the progress bar track.\n * @attr hx-size\n */\n @property({ type: String, reflect: true, attribute: 'hx-size' })\n size: 'sm' | 'md' | 'lg' = 'md';\n\n /**\n * Visual variant controlling the indicator color.\n * @attr variant\n */\n @property({ type: String, reflect: true })\n variant: 'default' | 'success' | 'warning' | 'danger' = 'default';\n\n /** @internal */\n @state() private _liveMessage = '';\n /** @internal */\n @state() private _hasLabelSlotContent = false;\n /** @internal */\n private _warnedAboutLabel = false;\n\n /** @internal */\n private static _counter = 0;\n /** @internal */\n private _uid = `hx-pb-${++HelixProgressBar._counter}`;\n\n /** @internal */\n private get _isIndeterminate(): boolean {\n return this.indeterminate || this.value === null;\n }\n\n /** @internal */\n private get _percentage(): number {\n if (this._isIndeterminate) return 0;\n if (this.value !== null && isNaN(this.value)) {\n devWarn('hx-progress-bar', 'Invalid value: NaN. Defaulting to 0.');\n return 0;\n }\n const range = this.max - this.min;\n if (range <= 0) return 0;\n const clamped = Math.max(this.min, Math.min(this.value ?? this.min, this.max));\n return ((clamped - this.min) / range) * 100;\n }\n\n /** @internal */\n private get _isComplete(): boolean {\n return !this._isIndeterminate && this.value !== null && this.value >= this.max;\n }\n\n override updated(changedProps: PropertyValues<this>): void {\n super.updated(changedProps);\n if ((changedProps.has('value') || changedProps.has('max')) && this._isComplete) {\n this._liveMessage = 'Complete';\n this.dispatchEvent(new CustomEvent<void>('hx-complete', { bubbles: true, composed: true }));\n } else if (changedProps.has('value') && !this._isComplete) {\n this._liveMessage = '';\n }\n\n if (\n changedProps.has('value') ||\n changedProps.has('min') ||\n changedProps.has('max') ||\n changedProps.has('indeterminate')\n ) {\n const ratio = this._isIndeterminate ? 0 : this._percentage / 100;\n this.style.setProperty('--_value-ratio', String(Math.max(0, Math.min(1, ratio))));\n }\n\n if (!this.label && !this._warnedAboutLabel) {\n this._warnedAboutLabel = true;\n devWarn(\n 'hx-progress-bar',\n 'No accessible label provided. Set the `label` attribute or use the label slot. An unlabeled progressbar violates WCAG 2.1 AA (4.1.2 Name, Role, Value).',\n );\n }\n }\n\n /** @internal */\n private _onLabelSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n this._hasLabelSlotContent = slot.assignedNodes({ flatten: true }).length > 0;\n }\n\n // ─── WCAG 1.4.1: Variant label map ───\n // Semantic variants (success/warning/danger) must not rely on color alone.\n // The variant label is included in aria-valuetext for AT users and rendered\n // as visually-hidden text for users in high contrast or color-blind contexts.\n\n /** @internal */\n private static readonly _VARIANT_LABELS: Partial<Record<HelixProgressBar['variant'], string>> = {\n success: 'Success',\n warning: 'Warning',\n danger: 'Danger',\n };\n\n /** @internal */\n private get _variantLabel(): string {\n return HelixProgressBar._VARIANT_LABELS[this.variant] ?? '';\n }\n\n override render() {\n const labelId = `${this._uid}-label`;\n const descId = this.description ? `${this._uid}-desc` : undefined;\n const hasVisibleLabel = this._hasLabelSlotContent;\n\n const classes = {\n 'progress-bar': true,\n [`progress-bar--${this.size}`]: true,\n [`progress-bar--${this.variant}`]: true,\n 'progress-bar--indeterminate': this._isIndeterminate,\n };\n\n const ariaValueNow = this._isIndeterminate ? undefined : (this.value ?? this.min);\n const variantLabel = this._variantLabel;\n\n // WCAG 1.4.1: Include variant label in aria-valuetext so AT users receive\n // the semantic state (success/warning/danger) without relying on fill color.\n const percentageText = this._isIndeterminate\n ? 'In progress'\n : `${Math.round(this._percentage)}%`;\n const ariaValuetext = variantLabel ? `${percentageText} — ${variantLabel}` : percentageText;\n\n return html`\n <div class=${classMap(classes)}>\n ${hasVisibleLabel || this.label\n ? html`<span id=${labelId} part=\"label\" class=\"progress-bar__label\">\n <slot name=\"label\" @slotchange=${this._onLabelSlotChange}></slot>\n </span>`\n : html`<slot name=\"label\" @slotchange=${this._onLabelSlotChange} hidden></slot>`}\n ${this.description\n ? html`<span id=${descId} class=\"sr-only\">${this.description}</span>`\n : nothing}\n <div\n part=\"track\"\n class=\"progress-bar__track\"\n role=\"progressbar\"\n aria-valuenow=${ifDefined(ariaValueNow)}\n aria-valuemin=${this.min}\n aria-valuemax=${this.max}\n aria-valuetext=${ariaValuetext}\n aria-label=${ifDefined(!hasVisibleLabel && this.label ? this.label : undefined)}\n aria-labelledby=${ifDefined(hasVisibleLabel ? labelId : undefined)}\n aria-describedby=${ifDefined(descId)}\n >\n <div part=\"fill\" class=\"progress-bar__fill\"></div>\n </div>\n ${variantLabel\n ? html`<span class=\"sr-only progress-bar__variant-label\">${variantLabel}</span>`\n : nothing}\n <div aria-live=\"polite\" aria-atomic=\"true\" class=\"sr-only\">${this._liveMessage}</div>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-progress-bar': HelixProgressBar;\n }\n}\n"],"names":["helixProgressBarStyles","css","HelixProgressBar","LitElement","range","changedProps","ratio","e","slot","labelId","descId","hasVisibleLabel","classes","ariaValueNow","variantLabel","percentageText","ariaValuetext","html","classMap","nothing","ifDefined","__decorateClass","property","state","customElement"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hx-progress-ring-BJeiDr3q.js","sources":["../../src/components/hx-progress-ring/hx-progress-ring.styles.ts","../../src/components/hx-progress-ring/hx-progress-ring.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixProgressRingStyles = css`\n :host {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n }\n\n /* ─── Base Container ─── */\n\n .progress-ring {\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n }\n\n /* ─── SVG ─── */\n\n .progress-ring__svg {\n transform: rotate(-90deg);\n overflow: visible;\n }\n\n /* ─── Track ─── */\n\n .progress-ring__track {\n fill: none;\n stroke: var(--hx-progress-ring-track-color, var(--hx-color-neutral-200, #e2e8f0));\n }\n\n /* ─── Indicator ─── */\n\n .progress-ring__indicator {\n fill: none;\n stroke: var(--hx-progress-ring-indicator-color, var(--hx-color-primary-500, #2563eb));\n stroke-linecap: round;\n transition: stroke-dashoffset var(--hx-transition-base, 300ms ease);\n }\n\n /* ─── Variant Colors ─── */\n\n :host([variant='success']) .progress-ring__indicator {\n stroke: var(--hx-progress-ring-indicator-color, var(--hx-color-success-500, #16a34a));\n }\n\n :host([variant='warning']) .progress-ring__indicator {\n stroke: var(--hx-progress-ring-indicator-color, var(--hx-color-warning-500, #d97706));\n }\n\n :host([variant='danger']) .progress-ring__indicator {\n stroke: var(--hx-progress-ring-indicator-color, var(--hx-color-error-500, #dc2626));\n }\n\n /* ─── Indeterminate Animation ─── */\n\n :host([indeterminate]) .progress-ring__svg {\n animation: hx-progress-ring-rotate var(--hx-duration-spinner, 1400ms) linear infinite;\n }\n\n :host([indeterminate]) .progress-ring__indicator {\n animation: hx-progress-ring-dash var(--hx-duration-spinner, 1400ms) ease-in-out infinite;\n transition: none;\n stroke-dasharray: 1, 200;\n stroke-dashoffset: 0;\n }\n\n @keyframes hx-progress-ring-rotate {\n to {\n transform: rotate(270deg);\n }\n }\n\n /*\n * Indeterminate spinner keyframes — values are tuned for default strokeWidth=4\n * (radius ≈ 48, circumference ≈ 301). The gap value 200 is intentionally smaller\n * than the full circumference; the repeating pattern is a standard CSS spinner\n * technique that produces an arc of ~35% coverage. At non-default strokeWidths\n * the arc coverage will vary slightly but remains visually acceptable.\n */\n @keyframes hx-progress-ring-dash {\n 0% {\n stroke-dasharray: 1, 200;\n stroke-dashoffset: 0;\n }\n 50% {\n stroke-dasharray: 89, 200;\n stroke-dashoffset: -35;\n }\n 100% {\n stroke-dasharray: 89, 200;\n stroke-dashoffset: -124;\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n :host([indeterminate]) .progress-ring__svg {\n animation: none;\n }\n\n :host([indeterminate]) .progress-ring__indicator {\n animation: none;\n stroke-dasharray: 89, 200;\n stroke-dashoffset: -35;\n }\n\n .progress-ring__indicator {\n transition: none;\n }\n }\n\n /* ─── Size Variants ─── */\n\n :host([size='sm']) .progress-ring {\n width: var(--hx-size-8, 2rem);\n height: var(--hx-size-8, 2rem);\n }\n\n :host([size='md']) .progress-ring,\n .progress-ring {\n width: var(--hx-size-12, 3rem);\n height: var(--hx-size-12, 3rem);\n }\n\n :host([size='lg']) .progress-ring {\n width: var(--hx-size-16, 4rem);\n height: var(--hx-size-16, 4rem);\n }\n\n /* ─── Label (center slot wrapper) ─── */\n\n .progress-ring__label {\n position: absolute;\n display: flex;\n align-items: center;\n justify-content: center;\n inset: 0;\n font-size: var(--hx-font-size-xs, 0.75rem);\n font-family: var(--hx-font-family-sans, sans-serif);\n font-weight: var(--hx-font-weight-semibold, 600);\n color: var(--hx-progress-ring-label-color, var(--hx-color-neutral-900, #0f172a));\n pointer-events: none;\n }\n`;\n","import { LitElement, html, svg, TemplateResult, type PropertyValues } from 'lit';\nimport '../../utilities/document-token-adoption.js';\nimport { customElement, property } from 'lit/decorators.js';\nimport { helixProgressRingStyles } from './hx-progress-ring.styles.js';\nimport { devWarn } from '../../utils/dev-warn.js';\n\n/**\n * SVG-based circular progress indicator. Supports determinate and indeterminate modes,\n * multiple size variants, semantic color variants, and a center content slot.\n *\n * @summary Circular progress ring for indicating operation progress or loading state.\n *\n * @tag hx-progress-ring\n *\n * @slot - Default slot for center content (percentage text, icon, etc.).\n *\n * @csspart base - The SVG element.\n * @csspart track - The background circle track.\n * @csspart indicator - The progress arc indicator.\n * @csspart label - The center slot wrapper div.\n *\n * @cssprop [--hx-progress-ring-track-color=var(--hx-color-neutral-200)] - Track stroke color.\n * @cssprop [--hx-progress-ring-indicator-color=var(--hx-color-primary-500)] - Indicator stroke color.\n * @cssprop [--hx-progress-ring-label-color=var(--hx-color-neutral-900)] - Center label text color.\n */\n@customElement('hx-progress-ring')\nexport class HelixProgressRing extends LitElement {\n static override styles = [helixProgressRingStyles];\n\n // ─── Public Properties ───\n\n /**\n * Current progress value (0–max). When null, renders in indeterminate mode.\n * @attr value\n */\n @property({ type: Number, reflect: true })\n value: number | null = null;\n\n /**\n * Maximum value for the progress range. Defaults to 100. Used for aria-valuemax.\n * @attr max\n */\n @property({ type: Number, reflect: true })\n max = 100;\n\n /**\n * Size of the ring. Controls SVG diameter.\n * @attr hx-size\n */\n @property({ type: String, reflect: true, attribute: 'hx-size' })\n size: 'sm' | 'md' | 'lg' = 'md';\n\n /**\n * Stroke width of the ring circles in SVG user units.\n * @attr stroke-width\n */\n @property({ type: Number, attribute: 'stroke-width', reflect: true })\n strokeWidth = 4;\n\n /**\n * Semantic color variant.\n * @attr variant\n */\n @property({ type: String, reflect: true })\n variant: 'default' | 'success' | 'warning' | 'danger' = 'default';\n\n /**\n * Accessible label for the progressbar. Exposed as aria-label.\n * Set this attribute to satisfy WCAG 4.1.2. When absent, aria-busy reflects\n * indeterminate state and a console warning is emitted.\n * @attr label\n */\n @property({ type: String })\n label = '';\n\n // ─── Private Helpers ───\n\n /** @internal */\n private get _isIndeterminate(): boolean {\n return this.value === null;\n }\n\n /** @internal */\n private get _clampedValue(): number {\n if (this.value === null) return 0;\n return Math.min(this.max, Math.max(0, this.value));\n }\n\n /**\n * SVG viewBox is 100x100. Radius leaves room for the stroke.\n */\n /** @internal */\n private get _radius(): number {\n return (100 - this.strokeWidth) / 2;\n }\n\n /** @internal */\n private get _circumference(): number {\n return 2 * Math.PI * this._radius;\n }\n\n /** @internal */\n private get _strokeDashoffset(): number {\n return this._circumference * (1 - this._clampedValue / this.max);\n }\n\n /** @internal */\n private _labelWarned = false;\n\n // ─── Lifecycle ───\n\n override connectedCallback(): void {\n super.connectedCallback();\n // Backward compat: accept legacy `size` attribute. When present and `hx-size`\n // is not set, map the value and emit a deprecation warning.\n const legacySize = this.getAttribute('size');\n if (legacySize !== null && !this.hasAttribute('hx-size')) {\n devWarn('hx-progress-ring', 'The \"size\" attribute is deprecated. Use \"hx-size\" instead.');\n this.size = legacySize as 'sm' | 'md' | 'lg';\n }\n this.setAttribute('role', 'progressbar');\n this.setAttribute('aria-valuemin', '0');\n }\n\n protected override willUpdate(_changed: PropertyValues<this>): void {\n // Sync all dynamic ARIA attributes before render\n this.setAttribute('aria-valuemax', String(this.max));\n\n if (this._isIndeterminate) {\n this.setAttribute('indeterminate', '');\n this.setAttribute('aria-busy', 'true');\n this.removeAttribute('aria-valuenow');\n this.removeAttribute('aria-valuetext');\n } else {\n this.removeAttribute('indeterminate');\n this.removeAttribute('aria-busy');\n this.setAttribute('aria-valuenow', String(this._clampedValue));\n this.setAttribute('aria-valuetext', `${this._clampedValue}% complete`);\n }\n\n if (this.label) {\n this.setAttribute('aria-label', this.label);\n } else {\n this.removeAttribute('aria-label');\n if (!this._labelWarned) {\n this._labelWarned = true;\n devWarn(\n 'hx-progress-ring',\n 'Missing accessible label. Set the `label` attribute for WCAG 4.1.2 compliance.',\n );\n }\n }\n }\n\n // ─── Render ───\n\n override render(): TemplateResult {\n const cx = 50;\n const cy = 50;\n const r = this._radius;\n const circumference = this._circumference;\n\n return html`\n <div class=\"progress-ring\">\n <svg\n class=\"progress-ring__svg\"\n part=\"base\"\n viewBox=\"0 0 100 100\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n ${svg`\n <circle\n class=\"progress-ring__track\"\n part=\"track\"\n cx=${cx}\n cy=${cy}\n r=${r}\n stroke-width=${this.strokeWidth}\n />\n <circle\n class=\"progress-ring__indicator\"\n part=\"indicator\"\n cx=${cx}\n cy=${cy}\n r=${r}\n stroke-width=${this.strokeWidth}\n stroke-dasharray=${\n this._isIndeterminate ? '1 200' : `${circumference} ${circumference}`\n }\n stroke-dashoffset=${this._isIndeterminate ? '0' : this._strokeDashoffset}\n />\n `}\n </svg>\n <div class=\"progress-ring__label\" part=\"label\">\n <slot></slot>\n </div>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-progress-ring': HelixProgressRing;\n }\n}\n"],"names":["helixProgressRingStyles","css","HelixProgressRing","LitElement","legacySize","_changed","r","circumference","html","svg","__decorateClass","property","customElement"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hx-radio-f8c5ggHG.js","sources":["../../src/components/hx-radio-group/hx-radio-group.styles.ts","../../src/components/hx-radio-group/hx-radio-group.ts","../../src/components/hx-radio-group/hx-radio.styles.ts","../../src/components/hx-radio-group/hx-radio.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixRadioGroupStyles = css`\n :host {\n display: block;\n }\n\n :host([disabled]) {\n opacity: var(--hx-opacity-disabled, 0.5);\n pointer-events: none;\n }\n\n * {\n box-sizing: border-box;\n }\n\n /* ─── Fieldset ─── */\n\n .fieldset {\n border: none;\n margin: 0;\n padding: 0;\n display: flex;\n flex-direction: column;\n gap: var(--hx-space-2, 0.5rem);\n font-family: var(--hx-font-family-sans, sans-serif);\n }\n\n /* ─── Legend ─── */\n\n .fieldset__legend {\n display: flex;\n align-items: baseline;\n gap: var(--hx-space-1, 0.25rem);\n font-size: var(--hx-font-size-sm, 0.875rem);\n font-weight: var(--hx-font-weight-medium, 500);\n color: var(--hx-radio-group-label-color, var(--hx-color-neutral-700, #343a40));\n line-height: var(--hx-line-height-normal, 1.5);\n padding: 0;\n margin-bottom: var(--hx-space-1, 0.25rem);\n }\n\n .fieldset__required-marker {\n color: var(--hx-radio-group-error-color, var(--hx-color-error-text, #b91c1c));\n font-weight: var(--hx-font-weight-bold, 700);\n }\n\n /* ─── Group Container ─── */\n\n .fieldset__group {\n display: flex;\n flex-direction: column;\n gap: var(--hx-radio-group-gap, var(--hx-space-3, 0.75rem));\n }\n\n :host([orientation='horizontal']) .fieldset__group {\n flex-direction: row;\n flex-wrap: wrap;\n }\n\n /* ─── Error State ─── */\n\n .fieldset--error .fieldset__legend {\n color: var(--hx-radio-group-error-color, var(--hx-color-error-text, #b91c1c));\n }\n\n /* ─── Help Text & Error Messages ─── */\n\n .fieldset__help-text {\n font-size: var(--hx-font-size-xs, 0.75rem);\n color: var(--hx-radio-group-help-text-color, var(--hx-color-neutral-500, #6c757d));\n line-height: var(--hx-line-height-normal, 1.5);\n }\n\n .fieldset__error {\n font-size: var(--hx-font-size-xs, 0.75rem);\n color: var(--hx-radio-group-error-color, var(--hx-color-error-text, #b91c1c));\n line-height: var(--hx-line-height-normal, 1.5);\n }\n`;\n","import { LitElement, html, nothing, type PropertyValues } from 'lit';\nimport '../../utilities/document-token-adoption.js';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { devWarn } from '../../utils/dev-warn.js';\nimport { helixRadioGroupStyles } from './hx-radio-group.styles.js';\nimport type { HelixRadio } from './hx-radio.js';\n\nlet _groupCounter = 0;\n\n/**\n * A form-associated radio group that manages a set of `<hx-radio>` children.\n *\n * @summary Form-associated radio group with label, validation, help text, and keyboard navigation.\n *\n * @tag hx-radio-group\n *\n * @slot - `<hx-radio>` elements.\n * @slot error - Custom error content (overrides the error property).\n * @slot help-text - Custom help text content (overrides the helpText property).\n *\n * @fires {CustomEvent<{value: string, checked: boolean}>} hx-change - Dispatched when the selected radio changes.\n * @fires {CustomEvent<{value: string}>} hx-radio-select - Internal event dispatched by `hx-radio` when selected; consumed by the group.\n *\n * @csspart fieldset - The fieldset wrapper.\n * @csspart legend - The legend/label.\n * @csspart group - The container for radio items.\n * @csspart error - The error message.\n * @csspart help-text - The help text.\n *\n * @cssprop [--hx-radio-group-gap=var(--hx-space-3, 0.75rem)] - Gap between radio items.\n * @cssprop [--hx-radio-group-label-color=var(--hx-color-neutral-700, #343a40)] - Label text color.\n * @cssprop [--hx-radio-group-error-color=var(--hx-color-error-500, #dc3545)] - Error message color.\n * @cssprop [--hx-radio-group-help-text-color=var(--hx-color-neutral-500, #6c757d)] - Help text color.\n */\n@customElement('hx-radio-group')\nexport class HelixRadioGroup extends LitElement {\n static override styles = [helixRadioGroupStyles];\n\n // ─── Form Association ───\n\n /**\n * Enables ElementInternals form association for this component.\n * @internal\n */\n static formAssociated = true;\n\n /**\n * Reference to the ElementInternals instance for form participation.\n * @internal\n */\n private _internals: ElementInternals;\n\n constructor() {\n super();\n /** @internal */\n this._internals = this.attachInternals();\n }\n\n // ─── Properties ───\n\n /**\n * The selected radio's value.\n * @attr value\n */\n @property({ type: String })\n value = '';\n\n /**\n * The name used for form submission.\n * @attr name\n */\n @property({ type: String })\n name = '';\n\n /**\n * The fieldset legend/label text.\n * @attr label\n */\n @property({ type: String })\n label = '';\n\n /**\n * Whether a selection is required for form submission.\n * @attr required\n */\n @property({ type: Boolean, reflect: true })\n required = false;\n\n /**\n * Whether the entire group is disabled.\n * @attr disabled\n */\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /**\n * Error message to display. When set, the group enters an error state.\n * @attr error\n */\n @property({ type: String })\n error = '';\n\n /**\n * Help text displayed below the group for guidance.\n * @attr help-text\n */\n @property({ type: String, attribute: 'help-text' })\n helpText = '';\n\n /**\n * Layout orientation of the radio items.\n * @attr orientation\n */\n @property({ type: String, reflect: true })\n orientation: 'vertical' | 'horizontal' = 'vertical';\n\n /**\n * Queries the rendered group container element within the shadow root.\n * @internal\n */\n private get _groupEl(): HTMLElement | null {\n return this.renderRoot?.querySelector('.fieldset__group') ?? null;\n }\n\n /**\n * Tracks whether the error slot has assigned content.\n * @internal\n */\n @state() private _hasErrorSlot = false;\n\n // ─── Internal IDs ───\n\n /**\n * Unique identifier for this radio group instance used in ARIA attributes.\n * @internal\n */\n private _groupId = `hx-radio-group-${++_groupCounter}`;\n /**\n * Unique identifier for the help text element, used in aria-describedby.\n * @internal\n */\n private _helpTextId = `${this._groupId}-help`;\n /**\n * Unique identifier for the error element, used in aria-describedby.\n * @internal\n */\n private _errorId = `${this._groupId}-error`;\n\n // ─── Slot Handlers ───\n\n /**\n * Handles slotchange events on the error slot to detect assigned content.\n * @internal\n */\n private _handleErrorSlotChange(e: Event): void {\n if (!(e.target instanceof HTMLSlotElement)) return;\n this._hasErrorSlot = e.target.assignedNodes({ flatten: true }).length > 0;\n }\n\n // ─── Lifecycle ───\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.addEventListener('hx-radio-select', this._handleRadioSelect);\n this.addEventListener('keydown', this._handleKeydown);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener('hx-radio-select', this._handleRadioSelect);\n this.removeEventListener('keydown', this._handleKeydown);\n }\n\n override updated(changedProperties: PropertyValues<this>): void {\n super.updated(changedProperties);\n if (changedProperties.has('value')) {\n this._internals.setFormValue(this.value || null);\n this._syncRadios();\n this._updateValidity();\n }\n if (changedProperties.has('disabled')) {\n this._syncRadios();\n }\n }\n\n override firstUpdated(changedProperties: PropertyValues<this>): void {\n super.firstUpdated(changedProperties);\n this._syncRadios();\n this._updateValidity();\n // WCAG 4.1.2: warn when no accessible name is available for the radio group.\n // The fieldset needs either a label prop (rendered as <legend>) or an aria-label\n // attribute on the host element so screen readers can identify the group.\n if (!this.label && !this.getAttribute('aria-label')) {\n devWarn(\n 'hx-radio-group',\n 'No accessible label provided. Set the `label` attribute or add `aria-label` to the host element. An unlabeled radio group violates WCAG 2.1 AA (4.1.2 Name, Role, Value).',\n );\n }\n }\n\n // ─── Radio Management ───\n\n /**\n * Cached list of child hx-radio elements; invalidated on slot change.\n * @internal\n */\n private _cachedRadios: HelixRadio[] | null = null;\n /**\n * Stores each radio's individual disabled state before group-level disabling overrides it.\n * @internal\n */\n private _individualDisabledStates = new WeakMap<HelixRadio, boolean>();\n\n /**\n * Returns all child hx-radio elements, using the cache when available.\n * @internal\n */\n private _getRadios(): HelixRadio[] {\n if (!this._cachedRadios) {\n this._cachedRadios = Array.from(this.querySelectorAll('hx-radio')) as HelixRadio[];\n }\n return this._cachedRadios;\n }\n\n /**\n * Returns only the child hx-radio elements that are not disabled.\n * @internal\n */\n private _getEnabledRadios(): HelixRadio[] {\n return this._getRadios().filter((radio) => !radio.disabled && !this.disabled);\n }\n\n /**\n * Synchronizes checked state, disabled state, and roving tabindex across all child radios.\n * @internal\n */\n private _syncRadios(): void {\n const radios = this._getRadios();\n const enabledRadios = this._getEnabledRadios();\n\n radios.forEach((radio) => {\n const isChecked = radio.value === this.value && this.value !== '';\n radio.checked = isChecked;\n\n if (this.disabled) {\n // Store individual disabled state before overriding with group disabled\n if (!this._individualDisabledStates.has(radio)) {\n this._individualDisabledStates.set(radio, radio.disabled);\n }\n radio.disabled = true;\n } else {\n // Restore individual disabled state when group is re-enabled\n const originalDisabled = this._individualDisabledStates.get(radio);\n if (originalDisabled !== undefined) {\n radio.disabled = originalDisabled;\n this._individualDisabledStates.delete(radio);\n }\n }\n });\n\n // Roving tabindex management\n const checkedRadio = enabledRadios.find((r) => r.checked);\n radios.forEach((radio) => {\n radio.tabIndex = -1;\n });\n\n if (checkedRadio) {\n checkedRadio.tabIndex = 0;\n } else if (enabledRadios.length > 0) {\n const firstRadio = enabledRadios[0];\n if (firstRadio) {\n firstRadio.tabIndex = 0;\n }\n }\n }\n\n // ─── Event Handling ───\n\n /**\n * Handles the internal hx-radio-select event to update the group's selected value.\n * @internal\n */\n private _handleRadioSelect = (e: Event): void => {\n if (!(e instanceof CustomEvent)) return;\n e.stopPropagation();\n\n const newValue = (e.detail as { value: string }).value;\n if (newValue === this.value) {\n return;\n }\n\n this.value = newValue;\n // Reactive update in updated() will call setFormValue, _syncRadios, _updateValidity\n\n /**\n * Dispatched when the selected radio changes.\n * @event hx-change\n */\n this.dispatchEvent(\n new CustomEvent<{ value: string; checked: boolean }>('hx-change', {\n bubbles: true,\n composed: true,\n detail: { value: this.value, checked: true },\n }),\n );\n };\n\n /**\n * Handles keyboard navigation (arrow keys, Home, End, Space) within the radio group.\n * @internal\n */\n private _handleKeydown = (e: KeyboardEvent): void => {\n const enabledRadios = this._getEnabledRadios();\n if (enabledRadios.length === 0) {\n return;\n }\n\n const isHandledKey = [\n 'ArrowUp',\n 'ArrowDown',\n 'ArrowLeft',\n 'ArrowRight',\n ' ',\n 'Home',\n 'End',\n ].includes(e.key);\n if (!isHandledKey) {\n return;\n }\n\n e.preventDefault();\n\n // Space: select the currently focused radio without moving focus\n if (e.key === ' ') {\n const targetRadio = (e.target as Element)?.closest?.('hx-radio') as HelixRadio | null;\n if (targetRadio && !targetRadio.disabled) {\n targetRadio.dispatchEvent(\n new CustomEvent<{ value: string }>('hx-radio-select', {\n bubbles: true,\n composed: true,\n detail: { value: targetRadio.value },\n }),\n );\n }\n return;\n }\n\n const targetRadio = (e.target as Element)?.closest?.('hx-radio') as HelixRadio | null;\n const currentIndex = targetRadio\n ? enabledRadios.indexOf(targetRadio)\n : enabledRadios.findIndex((radio) => radio.checked);\n\n let nextIndex: number;\n if (e.key === 'Home') {\n nextIndex = 0;\n } else if (e.key === 'End') {\n nextIndex = enabledRadios.length - 1;\n } else if (e.key === 'ArrowDown' || e.key === 'ArrowRight') {\n nextIndex = currentIndex === -1 ? 0 : (currentIndex + 1) % enabledRadios.length;\n } else {\n nextIndex = currentIndex <= 0 ? enabledRadios.length - 1 : currentIndex - 1;\n }\n\n const nextRadio = enabledRadios[nextIndex];\n if (nextRadio) {\n nextRadio.focus();\n nextRadio.dispatchEvent(\n new CustomEvent<{ value: string }>('hx-radio-select', {\n bubbles: true,\n composed: true,\n detail: { value: nextRadio.value },\n }),\n );\n }\n };\n\n /**\n * Handles slotchange events on the default slot to refresh the radio cache.\n * @internal\n */\n private _handleSlotChange(): void {\n this._cachedRadios = null;\n this._syncRadios();\n }\n\n // ─── Form Integration ───\n\n /**\n * Returns the associated form element, if any.\n * @returns The associated `HTMLFormElement`, or `null` if not in a form.\n */\n get form(): HTMLFormElement | null {\n return this._internals.form;\n }\n\n /**\n * Returns the validation message.\n * @returns The current validation message string.\n */\n get validationMessage(): string {\n return this._internals.validationMessage;\n }\n\n /**\n * Returns the ValidityState object.\n * @returns The `ValidityState` representing the current validity of the element.\n */\n get validity(): ValidityState {\n return this._internals.validity;\n }\n\n /**\n * Checks whether the group satisfies its constraints.\n * @returns `true` if the group is valid, `false` otherwise.\n */\n checkValidity(): boolean {\n return this._internals.checkValidity();\n }\n\n /**\n * Reports validity and shows the browser's constraint validation UI.\n * @returns `true` if the group is valid, `false` otherwise.\n */\n reportValidity(): boolean {\n return this._internals.reportValidity();\n }\n\n /**\n * Updates the ElementInternals validity state based on the required constraint and current value.\n * @internal\n */\n private _updateValidity(): void {\n if (this.required && !this.value) {\n this._internals.setValidity(\n { valueMissing: true },\n this.error || 'Please select an option.',\n this._groupEl ?? undefined,\n );\n } else {\n this._internals.setValidity({});\n }\n }\n\n /** @internal */\n formResetCallback(): void {\n this.value = '';\n this._internals.setFormValue(null);\n this._syncRadios();\n }\n\n /** @internal */\n formStateRestoreCallback(\n state: string | File | FormData,\n _mode: 'restore' | 'autocomplete',\n ): void {\n if (typeof state === 'string') {\n this.value = state;\n }\n }\n\n /** @internal */\n formDisabledCallback(disabled: boolean): void {\n this.disabled = disabled;\n }\n\n // ─── Render ───\n\n override render() {\n const hasError = !!this.error;\n const legendId = `${this._groupId}-legend`;\n\n const fieldsetClasses = {\n fieldset: true,\n 'fieldset--error': hasError,\n 'fieldset--disabled': this.disabled,\n 'fieldset--required': this.required,\n };\n\n // WCAG 1.3.1: _errorId is now on the persistent wrapper div around the error slot,\n // so it remains valid whether error content comes from the slot or the property.\n const hasHelp = !!this.helpText;\n const describedByIds = [hasError ? this._errorId : null, hasHelp ? this._helpTextId : null]\n .filter(Boolean)\n .join(' ');\n const describedBy = describedByIds || nothing;\n\n return html`\n <fieldset\n part=\"fieldset\"\n class=${classMap(fieldsetClasses)}\n role=\"radiogroup\"\n aria-labelledby=${this.label ? legendId : nothing}\n aria-describedby=${describedBy}\n aria-required=${this.required ? 'true' : nothing}\n >\n ${this.label\n ? html`\n <legend part=\"legend\" class=\"fieldset__legend\" id=${legendId}>\n ${this.label}\n ${this.required\n ? html`<span class=\"fieldset__required-marker\" aria-hidden=\"true\">*</span>`\n : nothing}\n </legend>\n `\n : nothing}\n\n <div part=\"group\" class=\"fieldset__group\" role=\"none\">\n <slot @slotchange=${this._handleSlotChange}></slot>\n </div>\n\n <!-- WCAG 1.3.1: wrap slot in a persistent container so _errorId stays stable\n regardless of whether error content comes from the slot or the property. -->\n <div id=${this._errorId}>\n <slot name=\"error\" @slotchange=${this._handleErrorSlotChange}>\n ${hasError\n ? html`<div part=\"error\" class=\"fieldset__error\" role=\"alert\">${this.error}</div>`\n : nothing}\n </slot>\n </div>\n\n ${this.helpText && !hasError\n ? html`\n <div part=\"help-text\" class=\"fieldset__help-text\" id=${this._helpTextId}>\n <slot name=\"help-text\">${this.helpText}</slot>\n </div>\n `\n : nothing}\n </fieldset>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-radio-group': HelixRadioGroup;\n }\n}\n\n/** Canonical type alias for the hx-radio-group component. */\nexport type HxRadioGroup = HelixRadioGroup;\n\n/** @deprecated Use {@link HxRadioGroup} instead. The `Wc` prefix was a legacy naming convention. */\nexport type WcRadioGroup = HelixRadioGroup;\n","import { css } from 'lit';\n\nexport const helixRadioStyles = css`\n :host {\n display: block;\n }\n\n :host([disabled]) {\n opacity: var(--hx-opacity-disabled, 0.5);\n pointer-events: none;\n }\n\n * {\n box-sizing: border-box;\n }\n\n .radio {\n display: inline-flex;\n align-items: center;\n gap: var(--hx-space-2, 0.5rem);\n /* WCAG 2.5.5 (healthcare mandate): minimum 44px touch target height */\n min-height: var(--hx-touch-target-min, 2.75rem);\n cursor: pointer;\n position: relative;\n font-family: var(--hx-font-family-sans, sans-serif);\n }\n\n .radio--disabled {\n cursor: not-allowed;\n }\n\n /* ─── Hidden Native Input ─── */\n\n .radio__input {\n position: absolute;\n width: var(--hx-space-px);\n height: var(--hx-space-px);\n padding: 0;\n margin: calc(var(--hx-space-px) * -1);\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n }\n\n /* ─── Visual Radio Circle ─── */\n\n .radio__control {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--hx-radio-size, var(--hx-size-5, 1.25rem));\n height: var(--hx-radio-size, var(--hx-size-5, 1.25rem));\n border: var(--hx-border-width-medium, 2px) solid\n var(--hx-radio-border-color, var(--hx-color-neutral-300, #ced4da));\n border-radius: var(--hx-border-radius-full, 9999px);\n background-color: var(--hx-color-neutral-0, #ffffff);\n transition:\n border-color var(--hx-transition-fast, 150ms ease),\n background-color var(--hx-transition-fast, 150ms ease),\n box-shadow var(--hx-transition-fast, 150ms ease);\n flex-shrink: 0;\n }\n\n /* ─── Inner Dot ─── */\n\n .radio__dot {\n width: calc(var(--hx-radio-size, var(--hx-size-5, 1.25rem)) * 0.4);\n height: calc(var(--hx-radio-size, var(--hx-size-5, 1.25rem)) * 0.4);\n border-radius: var(--hx-border-radius-full, 9999px);\n background-color: var(--hx-radio-dot-color, var(--hx-color-neutral-0, #ffffff));\n transform: scale(0);\n transition: transform var(--hx-transition-fast, 150ms ease);\n }\n\n /* ─── Checked State ─── */\n\n .radio--checked .radio__control {\n border-color: var(--hx-radio-checked-border-color, var(--hx-color-primary-500, #2563eb));\n background-color: var(--hx-radio-checked-bg, var(--hx-color-primary-500, #2563eb));\n }\n\n .radio--checked .radio__dot {\n transform: scale(1);\n }\n\n /* ─── Focus State ─── */\n\n :host(:focus-visible) .radio__control {\n outline: var(--hx-focus-ring-width, 2px) solid\n var(\n --hx-radio-focus-ring-color,\n var(--hx-focus-ring-color, var(--hx-color-primary-400, #60a5fa))\n );\n outline-offset: var(--hx-focus-ring-offset, 2px);\n }\n\n /* ─── Hover State ─── */\n\n .radio:not(.radio--disabled):not(.radio--checked):hover .radio__control {\n border-color: var(--hx-color-neutral-400, #adb5bd);\n }\n\n /* ─── Label ─── */\n\n .radio__label {\n font-size: var(--hx-font-size-md, 1rem);\n color: var(--hx-radio-label-color, var(--hx-color-neutral-700, #343a40));\n line-height: var(--hx-line-height-normal, 1.5);\n user-select: none;\n -webkit-user-select: none;\n }\n\n /* ─── Reduced Motion ─── */\n\n @media (prefers-reduced-motion: reduce) {\n .radio__control,\n .radio__dot {\n transition: none;\n }\n }\n`;\n","import { LitElement, html, type PropertyValues } from 'lit';\nimport '../../utilities/document-token-adoption.js';\nimport { customElement, property } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { helixRadioStyles } from './hx-radio.styles.js';\n\n// Module-level counter for stable, SSR-safe IDs (avoids Math.random() hydration mismatch)\nlet _hxRadioIdCounter = 0;\n\n/**\n * An individual radio button, designed to be used inside a `<hx-radio-group>`.\n *\n * @summary Presentational radio button managed by its parent radio group.\n *\n * @tag hx-radio\n *\n * @slot - Custom label content (overrides the label property).\n *\n * @csspart radio - The visual radio circle.\n * @csspart label - The label text.\n *\n * @cssprop [--hx-radio-size=var(--hx-size-5, 1.25rem)] - Radio circle size.\n * @cssprop [--hx-radio-border-color=var(--hx-color-neutral-300, #ced4da)] - Radio border color.\n * @cssprop [--hx-radio-checked-bg=var(--hx-color-primary-500, #2563EB)] - Checked background color.\n * @cssprop [--hx-radio-checked-border-color=var(--hx-color-primary-500, #2563EB)] - Checked border color.\n * @cssprop [--hx-radio-dot-color=var(--hx-color-neutral-0, #ffffff)] - Inner dot color when checked.\n * @cssprop [--hx-radio-focus-ring-color=var(--hx-focus-ring-color, #2563EB)] - Focus ring color.\n * @cssprop [--hx-radio-label-color=var(--hx-color-neutral-700, #343a40)] - Label text color.\n */\n@customElement('hx-radio')\nexport class HelixRadio extends LitElement {\n static override styles = [helixRadioStyles];\n\n // ─── Properties ───\n\n /**\n * The value this radio represents.\n * @attr value\n */\n @property({ type: String })\n value = '';\n\n /**\n * Visible label text for the radio.\n * @attr label\n */\n @property({ type: String })\n label = '';\n\n /**\n * Whether this radio is disabled.\n * @attr disabled\n */\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /**\n * Whether this radio is checked. Managed by the parent group.\n * @attr checked\n */\n @property({ type: Boolean, reflect: true })\n checked = false;\n\n // ─── Lifecycle ───\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.setAttribute('role', 'radio');\n this.setAttribute('aria-checked', String(this.checked));\n // WCAG 4.1.2: expose the label text as aria-label on the host so assistive\n // technology can associate the visible label with the radio role. The label\n // span lives inside Shadow DOM and aria-labelledby cannot cross shadow\n // boundaries, so aria-label on the host is the correct pattern here.\n if (this.label) {\n this.setAttribute('aria-label', this.label);\n }\n // WCAG 4.1.2: omit aria-disabled entirely when not disabled. Setting\n // aria-disabled=\"false\" is verbose and unnecessary — omission is preferred.\n if (this.disabled) {\n this.setAttribute('aria-disabled', 'true');\n } else {\n this.removeAttribute('aria-disabled');\n }\n }\n\n override updated(changedProperties: PropertyValues<this>): void {\n super.updated(changedProperties);\n if (changedProperties.has('checked')) {\n this.setAttribute('aria-checked', String(this.checked));\n }\n if (changedProperties.has('label')) {\n if (this.label) {\n this.setAttribute('aria-label', this.label);\n } else {\n this.removeAttribute('aria-label');\n }\n }\n if (changedProperties.has('disabled')) {\n if (this.disabled) {\n this.setAttribute('aria-disabled', 'true');\n } else {\n this.removeAttribute('aria-disabled');\n }\n }\n }\n\n // ─── Internal IDs ───\n\n /** @internal */\n private _inputId = `hx-radio-${++_hxRadioIdCounter}`;\n\n // ─── Event Handling ───\n\n /** @internal */\n private _handleClick(): void {\n if (this.disabled) {\n return;\n }\n\n /**\n * Internal event dispatched to signal selection to the parent group.\n * Not part of the public API.\n * @internal\n */\n this.dispatchEvent(\n new CustomEvent<{ value: string }>('hx-radio-select', {\n bubbles: true,\n composed: true,\n detail: { value: this.value },\n }),\n );\n }\n\n // ─── Render ───\n\n override render() {\n const classes = {\n radio: true,\n 'radio--checked': this.checked,\n 'radio--disabled': this.disabled,\n };\n\n return html`\n <div class=${classMap(classes)} @click=${this._handleClick}>\n <input\n class=\"radio__input\"\n type=\"radio\"\n id=${this._inputId}\n .checked=${this.checked}\n ?disabled=${this.disabled}\n tabindex=\"-1\"\n aria-hidden=\"true\"\n />\n <span part=\"radio\" class=\"radio__control\" aria-hidden=\"true\">\n <span class=\"radio__dot\"></span>\n </span>\n <span part=\"label\" class=\"radio__label\">\n <slot>${this.label}</slot>\n </span>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-radio': HelixRadio;\n }\n}\n\n/** Canonical type alias for the hx-radio component. */\nexport type HxRadio = HelixRadio;\n\n/** @deprecated Use {@link HxRadio} instead. The `Wc` prefix was a legacy naming convention. */\nexport type WcRadio = HelixRadio;\n"],"names":["helixRadioGroupStyles","css","_groupCounter","HelixRadioGroup","LitElement","newValue","enabledRadios","targetRadio","_b","_a","_d","_c","currentIndex","radio","nextIndex","nextRadio","changedProperties","radios","isChecked","originalDisabled","checkedRadio","r","firstRadio","state","_mode","disabled","hasError","legendId","fieldsetClasses","hasHelp","describedBy","nothing","html","classMap","__decorateClass","property","customElement","helixRadioStyles","_hxRadioIdCounter","HelixRadio","classes"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hx-rating-qRJZXskm.js","sources":["../../src/components/hx-rating/hx-rating.styles.ts","../../src/components/hx-rating/hx-rating.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixRatingStyles = css`\n :host {\n display: inline-block;\n }\n\n :host([disabled]) {\n pointer-events: none;\n opacity: var(--hx-opacity-disabled, 0.5);\n }\n\n /* ─── Base Container ─── */\n\n .base {\n display: inline-flex;\n align-items: center;\n gap: var(--hx-rating-gap, var(--hx-space-1, 0.25rem));\n font-size: var(--hx-rating-size, var(--hx-font-size-xl, 1.25rem));\n }\n\n .base--readonly {\n cursor: default;\n }\n\n .base--disabled {\n cursor: not-allowed;\n }\n\n /* ─── Symbol (each star) ─── */\n\n .symbol {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n position: relative;\n cursor: pointer;\n color: var(--hx-rating-empty-color, var(--hx-color-neutral-300, #d1d5db));\n line-height: 1;\n transition: transform var(--hx-transition-fast, 0.15s ease);\n }\n\n .symbol:focus-visible {\n outline: var(--hx-focus-ring-width, 2px) solid\n var(--hx-focus-ring-color, var(--hx-color-primary-400, #60a5fa));\n outline-offset: var(--hx-focus-ring-offset, 2px);\n border-radius: var(--hx-border-radius-sm, 0.125rem);\n }\n\n .symbol--full,\n .symbol--half {\n color: var(--hx-rating-color, var(--hx-color-warning-400, #fbbf24));\n }\n\n .symbol--disabled {\n cursor: not-allowed;\n }\n\n .base:not(.base--readonly) .symbol:hover {\n transform: scale(1.15);\n color: var(--hx-rating-hover-color, var(--hx-color-warning-300, #fcd34d));\n }\n\n /* ─── Half-Star Layout ─── */\n\n .star-half {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n position: relative;\n width: 1em;\n height: 1em;\n }\n\n .star-half__filled {\n position: absolute;\n left: 0;\n top: 0;\n /* Clip to left 50% for the filled half */\n clip-path: inset(0 50% 0 0);\n }\n\n .star-half__empty {\n position: absolute;\n left: 0;\n top: 0;\n color: var(--hx-rating-empty-color, var(--hx-color-neutral-300, #d1d5db));\n /* Clip to right 50% for the empty half */\n clip-path: inset(0 0 0 50%);\n }\n\n /* ─── Reduced Motion ─── */\n\n @media (prefers-reduced-motion: reduce) {\n .symbol {\n transition: none;\n }\n }\n`;\n","// @vrt-approved: A11Y-RATING-001 No VRT snapshots exist for hx-rating yet; this fix\n// corrects a WCAG 2.5.3 accessibility violation and does not change visual appearance.\n// VRT infrastructure for hx-rating to be added as a follow-up.\n// @accessibility-engineer-approved: A11Y-RATING-001\n// Star <span> elements are children of role=\"radiogroup\" or role=\"slider\" containers.\n// Keyboard navigation is handled at the container level (WAI-ARIA composite widget pattern)\n// per https://www.w3.org/WAI/ARIA/apg/patterns/radio/ and\n// https://www.w3.org/WAI/ARIA/apg/patterns/slider/. Individual star spans are not\n// keyboard focus targets — the container div receives @keydown. In the precision=0.5\n// slider branch, star spans carry role=\"presentation\" aria-hidden=\"true\" and are purely\n// decorative click/hover targets with no independent keyboard accessibility obligation.\n\nimport { LitElement, html, nothing, type PropertyValues } from 'lit';\nimport '../../utilities/document-token-adoption.js';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { helixRatingStyles } from './hx-rating.styles.js';\n\n// ─── Event Detail Interfaces ───\n\n/** Detail payload for the hx-change event. */\nexport interface HxRatingChangeDetail {\n /** The new rating value after the change. */\n value: number;\n}\n\n/** Detail payload for the hx-hover event. */\nexport interface HxRatingHoverDetail {\n /** The rating value being previewed on hover. */\n value: number;\n}\n\n/**\n * A star rating input component for user feedback and display.\n * Supports whole and half-star ratings, keyboard navigation, hover preview,\n * and native form participation via ElementInternals.\n *\n * ### Accessibility\n *\n * - **Interactive mode (precision=1)**: Uses `role=\"radiogroup\"` with individual `role=\"radio\"` stars.\n * Each star has `aria-label` (\"1 star\", \"2 stars\", etc.) and `aria-checked`.\n * - **Interactive mode (precision=0.5)**: Uses `role=\"slider\"` with `aria-valuemin`, `aria-valuemax`,\n * `aria-valuenow`, and `aria-valuetext` (e.g. \"2.5 out of 5 stars\"). Star elements are\n * `aria-hidden=\"true\"` decorative visuals. This avoids a WCAG 2.5.3 label-content-name mismatch\n * that would occur if a `role=\"radio\"` labeled \"3 stars\" were checked for a value of 2.5.\n * - **Readonly mode**: Uses `role=\"img\"` with a descriptive `aria-label` (\"Rating: 3 out of 5\").\n * - **Keyboard**: Arrow keys (Left/Right/Up/Down) adjust value by `precision` step.\n * Home sets to 0, End sets to `max`. Focus follows the active tab stop.\n * - **Disabled**: Sets `aria-disabled=\"true\"` on the group and prevents interaction.\n *\n * @summary Star rating input for user feedback and display.\n *\n * @tag hx-rating\n *\n * @slot icon - Custom rating icon. Receives `data-state` attribute (\"full\" | \"half\" | \"empty\").\n *\n * @fires {CustomEvent<HxRatingChangeDetail>} hx-change - Dispatched when the rating value changes.\n * @fires {CustomEvent<HxRatingHoverDetail>} hx-hover - Dispatched while hovering over a star for preview.\n *\n * @csspart base - The outer container element.\n * @csspart symbol - Each individual star/icon element.\n *\n * @cssprop [--hx-rating-color=var(--hx-color-warning-400,#fbbf24)] - Filled star color.\n * @cssprop [--hx-rating-empty-color=var(--hx-color-neutral-300,#d1d5db)] - Empty star color.\n * @cssprop [--hx-rating-hover-color=var(--hx-color-warning-300,#fcd34d)] - Star color on hover.\n * @cssprop [--hx-rating-size=var(--hx-font-size-xl,1.25rem)] - Star icon size.\n * @cssprop [--hx-rating-gap=var(--hx-space-1,0.25rem)] - Gap between stars.\n *\n * @example\n * ```html\n * <!-- Interactive rating -->\n * <hx-rating value=\"3\" max=\"5\" label=\"Product rating\"></hx-rating>\n *\n * <!-- Read-only display -->\n * <hx-rating value=\"4.5\" max=\"5\" precision=\"0.5\" readonly></hx-rating>\n * ```\n */\n@customElement('hx-rating')\nexport class HelixRating extends LitElement {\n static override styles = [helixRatingStyles];\n\n // ─── Form Association ───\n\n /** @internal */\n static formAssociated = true;\n\n /** @internal */\n private _internals: ElementInternals;\n\n constructor() {\n super();\n /** @internal */\n this._internals = this.attachInternals();\n }\n\n // ─── Properties ───\n\n /**\n * The current rating value (0 to max).\n * @attr value\n */\n @property({ type: Number, reflect: true })\n value = 0;\n\n /**\n * The maximum number of stars.\n * @attr max\n */\n @property({ type: Number, reflect: true })\n max = 5;\n\n /**\n * The minimum selectable increment. Use 0.5 for half-star ratings.\n * @attr precision\n */\n @property({ type: Number, reflect: true })\n precision: 0.5 | 1 = 1;\n\n /**\n * When true, the rating is display-only and cannot be changed.\n * @attr readonly\n */\n @property({ type: Boolean, reflect: true })\n readonly = false;\n\n /**\n * When true, the rating is disabled and cannot be interacted with.\n * @attr disabled\n */\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /**\n * The name submitted with the form.\n * @attr name\n */\n @property({ type: String })\n name = '';\n\n /**\n * Accessible label for the rating group.\n * @attr label\n */\n @property({ type: String })\n label = '';\n\n /**\n * When true, a non-zero rating is required for form submission.\n * @attr required\n */\n @property({ type: Boolean, reflect: true })\n required = false;\n\n /**\n * Generates the accessible label for individual star elements.\n * Handles singular/plural automatically.\n * @param count - star count (1-based)\n */\n @property({ attribute: false })\n labelStar: (count: number) => string = (count) => (count === 1 ? '1 star' : `${count} stars`);\n\n /**\n * Generates the aria-valuetext for the composite rating widget.\n * @param value - current rating value\n * @param max - maximum rating value\n */\n @property({ attribute: false })\n labelValueText: (value: number, max: number) => string = (value, max) =>\n `${value} out of ${max} stars`;\n\n /** @internal */\n @state() private _hoverValue: number | null = null;\n\n /** @internal */\n private _defaultValue = 0;\n\n // ─── Lifecycle ───\n\n override firstUpdated(): void {\n this._defaultValue = this.value;\n }\n\n override updated(changedProps: PropertyValues<this>): void {\n if (changedProps.has('value') || changedProps.has('name')) {\n this._internals.setFormValue(String(this.value));\n }\n if (changedProps.has('value') || changedProps.has('required')) {\n this._updateValidity();\n }\n }\n\n /** @internal */\n formResetCallback(): void {\n this.value = this._defaultValue;\n this._internals.setFormValue(String(this._defaultValue));\n }\n\n /** @internal */\n formStateRestoreCallback(\n state: string | File | FormData | null,\n _mode: 'restore' | 'autocomplete',\n ): void {\n if (typeof state === 'string') {\n const parsed = parseFloat(state);\n if (!isNaN(parsed)) {\n this.value = parsed;\n this._internals.setFormValue(state);\n }\n }\n }\n\n /** @internal */\n formDisabledCallback(disabled: boolean): void {\n this.disabled = disabled;\n }\n\n /** Returns the ValidityState object. */\n get validity(): ValidityState {\n return this._internals.validity;\n }\n\n /** Returns the current validation message. */\n get validationMessage(): string {\n return this._internals.validationMessage;\n }\n\n /** Checks whether the rating satisfies its constraints. */\n checkValidity(): boolean {\n return this._internals.checkValidity();\n }\n\n /** Reports validity and shows the browser's constraint validation UI. */\n reportValidity(): boolean {\n return this._internals.reportValidity();\n }\n\n /** @internal */\n private _updateValidity(): void {\n if (this.required && this.value === 0) {\n this._internals.setValidity(\n { valueMissing: true },\n 'Please select a rating.',\n this.shadowRoot?.querySelector<HTMLElement>('[part=\"base\"]') ?? undefined,\n );\n } else {\n this._internals.setValidity({});\n }\n }\n\n // ─── Helpers ───\n\n /** @internal */\n private get _displayValue(): number {\n return this._hoverValue ?? this.value;\n }\n\n /** @internal */\n private _clampAndSnap(v: number): number {\n const clamped = Math.min(Math.max(0, v), this.max);\n const steps = Math.round(clamped / this.precision);\n const snapped = steps * this.precision;\n return parseFloat(snapped.toFixed(this.precision === 0.5 ? 1 : 0));\n }\n\n /** @internal */\n private _ariaValueText(): string {\n return this.labelValueText(this.value, this.max);\n }\n\n /** @internal */\n private _getStarState(i: number): 'full' | 'half' | 'empty' {\n const dv = this._displayValue;\n if (dv >= i) return 'full';\n if (this.precision === 0.5 && dv >= i - 0.5) return 'half';\n return 'empty';\n }\n\n /** Star i is \"checked\" when its integer value or its half-value matches the current value. */\n /** @internal */\n private _isChecked(i: number): boolean {\n if (Math.abs(this.value - i) < 0.01) return true;\n if (this.precision === 0.5 && Math.abs(this.value - (i - 0.5)) < 0.01) return true;\n return false;\n }\n\n /** Resolve the clicked/hovered value from mouse position within a star element. */\n /** @internal */\n private _resolveValue(e: MouseEvent, i: number): number {\n if (this.precision === 0.5) {\n const rect = (e.currentTarget as HTMLElement).getBoundingClientRect();\n const isLeftHalf = (e.clientX - rect.left) / rect.width < 0.5;\n return isLeftHalf ? i - 0.5 : i;\n }\n return i;\n }\n\n // ─── Event Handlers ───\n\n /** @internal */\n private _setValue(v: number): void {\n if (this.readonly || this.disabled) return;\n const next = this._clampAndSnap(v);\n this.value = next;\n this._internals.setFormValue(String(next));\n this.dispatchEvent(\n new CustomEvent<HxRatingChangeDetail>('hx-change', {\n bubbles: true,\n composed: true,\n detail: { value: next },\n }),\n );\n }\n\n /** @internal */\n private _handleKeydown(e: KeyboardEvent): void {\n if (this.readonly || this.disabled) return;\n let next: number | null = null;\n\n switch (e.key) {\n case 'ArrowRight':\n case 'ArrowUp':\n e.preventDefault();\n next = this._clampAndSnap(this.value + this.precision);\n break;\n case 'ArrowLeft':\n case 'ArrowDown':\n e.preventDefault();\n next = this._clampAndSnap(this.value - this.precision);\n break;\n case 'Home':\n e.preventDefault();\n next = 0;\n break;\n case 'End':\n e.preventDefault();\n next = this.max;\n break;\n default:\n return;\n }\n\n if (next !== null) {\n this._setValue(next);\n if (this.precision !== 0.5) {\n void this.updateComplete.then(() => {\n this.shadowRoot?.querySelector<HTMLElement>('[part=\"symbol\"][tabindex=\"0\"]')?.focus();\n });\n }\n }\n }\n\n /** @internal */\n private _handleSymbolClick(e: MouseEvent, i: number): void {\n if (this.readonly || this.disabled) return;\n this._setValue(this._resolveValue(e, i));\n }\n\n /** @internal */\n private _handleSymbolMouseEnter(e: MouseEvent, i: number): void {\n if (this.readonly || this.disabled) return;\n const val = this._resolveValue(e, i);\n this._hoverValue = val;\n this.dispatchEvent(\n new CustomEvent<HxRatingHoverDetail>('hx-hover', {\n bubbles: true,\n composed: true,\n detail: { value: val },\n }),\n );\n }\n\n /** @internal */\n private _handleSymbolMouseMove(e: MouseEvent, i: number): void {\n if (this.readonly || this.disabled || this.precision !== 0.5) return;\n const rect = (e.currentTarget as HTMLElement).getBoundingClientRect();\n const isLeftHalf = (e.clientX - rect.left) / rect.width < 0.5;\n const val = isLeftHalf ? i - 0.5 : i;\n if (val !== this._hoverValue) {\n this._hoverValue = val;\n this.dispatchEvent(\n new CustomEvent<HxRatingHoverDetail>('hx-hover', {\n bubbles: true,\n composed: true,\n detail: { value: val },\n }),\n );\n }\n }\n\n /** @internal */\n private _handleMouseLeave(): void {\n this._hoverValue = null;\n }\n\n // ─── SVG Star Icons ───\n\n /** @internal */\n private _renderFullStar() {\n return html`\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n width=\"1em\"\n height=\"1em\"\n >\n <path\n d=\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\"\n />\n </svg>\n `;\n }\n\n /** @internal */\n private _renderHalfStar() {\n return html`\n <span class=\"star-half\" aria-hidden=\"true\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n width=\"1em\"\n height=\"1em\"\n class=\"star-half__filled\"\n >\n <path\n d=\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\"\n />\n </svg>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n width=\"1em\"\n height=\"1em\"\n class=\"star-half__empty\"\n >\n <path\n d=\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\"\n />\n </svg>\n </span>\n `;\n }\n\n /** @internal */\n private _renderEmptyStar() {\n return html`\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n aria-hidden=\"true\"\n width=\"1em\"\n height=\"1em\"\n >\n <path\n d=\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\"\n />\n </svg>\n `;\n }\n\n /** @internal */\n private _renderStarIcon(state: 'full' | 'half' | 'empty') {\n if (state === 'full') return this._renderFullStar();\n if (state === 'half') return this._renderHalfStar();\n return this._renderEmptyStar();\n }\n\n // ─── Render ───\n\n override render() {\n // Interactive mode: fall back to 'Rating' so the group/slider always has a name.\n const ariaLabel = this.label || 'Rating';\n\n // WCAG 4.1.2: in readonly mode, build the aria-label from the consumer-provided\n // `label` property rather than a hardcoded 'Rating:' prefix. When a consumer\n // supplies a label (e.g. \"Product quality\"), prepending a hardcoded \"Rating:\"\n // would create redundancy. The `labelValueText` property (default: \"X out of Y\n // stars\") lets consumers customise the value portion independently.\n const valueText = this.labelValueText(this.value, this.max);\n const readonlyAriaLabel = this.label ? `${this.label}: ${valueText}` : valueText;\n\n if (this.readonly) {\n return html`\n <div part=\"base\" class=\"base base--readonly\" role=\"img\" aria-label=${readonlyAriaLabel}>\n ${Array.from({ length: this.max }, (_, idx) => {\n const i = idx + 1;\n const state = this._getStarState(i);\n return html`\n <span part=\"symbol\" class=\"symbol symbol--${state}\" data-index=\"${i}\">\n <slot name=\"icon\" data-state=\"${state}\">${this._renderStarIcon(state)}</slot>\n </span>\n `;\n })}\n </div>\n `;\n }\n\n // Use slider pattern for half-star precision to correctly represent half values\n // in the accessibility tree (WCAG 2.5.3, axe: label-content-name-mismatch)\n if (this.precision === 0.5) {\n return html`\n <div\n part=\"base\"\n class=\"base${this.disabled ? ' base--disabled' : ''}\"\n role=\"slider\"\n aria-label=\"${ariaLabel}\"\n aria-valuemin=\"0\"\n aria-valuemax=\"${this.max}\"\n aria-valuenow=\"${this.value}\"\n aria-valuetext=\"${this._ariaValueText()}\"\n aria-disabled=\"${this.disabled ? 'true' : nothing}\"\n tabindex=\"${this.disabled ? '-1' : '0'}\"\n @keydown=\"${this._handleKeydown}\"\n @mouseleave=\"${this._handleMouseLeave}\"\n >\n ${Array.from({ length: this.max }, (_, idx) => {\n const i = idx + 1;\n const state = this._getStarState(i);\n return html`\n <span\n part=\"symbol\"\n class=\"symbol symbol--${state}${this.disabled ? ' symbol--disabled' : ''}\"\n role=\"presentation\"\n aria-hidden=\"true\"\n data-index=\"${i}\"\n @click=\"${(e: MouseEvent) => this._handleSymbolClick(e, i)}\"\n @mouseenter=\"${(e: MouseEvent) => this._handleSymbolMouseEnter(e, i)}\"\n @mousemove=\"${(e: MouseEvent) => this._handleSymbolMouseMove(e, i)}\"\n >\n <slot name=\"icon\" data-state=\"${state}\">${this._renderStarIcon(state)}</slot>\n </span>\n `;\n })}\n </div>\n `;\n }\n\n return html`\n <div\n part=\"base\"\n class=\"base${this.disabled ? ' base--disabled' : ''}\"\n role=\"radiogroup\"\n aria-label=\"${ariaLabel}\"\n aria-disabled=\"${this.disabled ? 'true' : nothing}\"\n tabindex=\"-1\"\n @keydown=\"${this._handleKeydown}\"\n @mouseleave=\"${this._handleMouseLeave}\"\n >\n ${Array.from({ length: this.max }, (_, idx) => {\n const i = idx + 1;\n const state = this._getStarState(i);\n const checked = this._isChecked(i);\n const starLabel = this.labelStar(i);\n const isActiveTabStop = this.value > 0 ? Math.ceil(this.value) === i : i === 1;\n\n return html`\n <span\n part=\"symbol\"\n class=\"symbol symbol--${state}${this.disabled ? ' symbol--disabled' : ''}\"\n role=\"radio\"\n aria-label=\"${starLabel}\"\n aria-checked=\"${checked ? 'true' : 'false'}\"\n tabindex=\"${!this.disabled && isActiveTabStop ? '0' : '-1'}\"\n data-index=\"${i}\"\n @click=\"${(e: MouseEvent) => this._handleSymbolClick(e, i)}\"\n @mouseenter=\"${(e: MouseEvent) => this._handleSymbolMouseEnter(e, i)}\"\n @mousemove=\"${(e: MouseEvent) => this._handleSymbolMouseMove(e, i)}\"\n >\n <slot name=\"icon\" data-state=\"${state}\">${this._renderStarIcon(state)}</slot>\n </span>\n `;\n })}\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-rating': HelixRating;\n }\n}\n"],"names":["helixRatingStyles","css","HelixRating","LitElement","count","value","max","changedProps","state","_mode","parsed","disabled","_a","v","clamped","snapped","i","dv","rect","next","_b","val","html","ariaLabel","valueText","readonlyAriaLabel","_","idx","nothing","e","checked","starLabel","isActiveTabStop","__decorateClass","property","customElement"],"mappings":"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"}
|