@helixui/library 0.3.1 → 0.3.2
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 +2330 -1860
- package/dist/components/hx-action-bar/hx-action-bar.d.ts +3 -1
- package/dist/components/hx-action-bar/hx-action-bar.d.ts.map +1 -1
- package/dist/components/hx-action-bar/index.js +1 -1
- package/dist/components/hx-badge/hx-badge.d.ts +8 -0
- 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 -0
- package/dist/components/hx-badge/index.d.ts.map +1 -1
- package/dist/components/hx-badge/index.js +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 +0 -25
- package/dist/components/hx-breadcrumb/hx-breadcrumb.d.ts.map +1 -1
- package/dist/components/hx-breadcrumb/index.js +1 -1
- package/dist/components/hx-button/hx-button.styles.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 +3 -1
- package/dist/components/hx-button-group/hx-button-group.d.ts.map +1 -1
- package/dist/components/hx-button-group/index.js +1 -1
- package/dist/components/hx-checkbox-group/hx-checkbox-group.d.ts +3 -1
- package/dist/components/hx-checkbox-group/hx-checkbox-group.d.ts.map +1 -1
- package/dist/components/hx-checkbox-group/index.js +1 -1
- package/dist/components/hx-container/hx-container.d.ts +12 -0
- 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 +1 -0
- 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 +7 -0
- package/dist/components/hx-copy-button/hx-copy-button.d.ts.map +1 -1
- package/dist/components/hx-drawer/hx-drawer.d.ts +1 -1
- package/dist/components/hx-drawer/index.js +1 -1
- package/dist/components/hx-icon-button/hx-icon-button.d.ts +87 -0
- package/dist/components/hx-icon-button/hx-icon-button.d.ts.map +1 -0
- package/dist/components/hx-icon-button/hx-icon-button.styles.d.ts +2 -0
- package/dist/components/hx-icon-button/hx-icon-button.styles.d.ts.map +1 -0
- package/dist/components/hx-icon-button/index.d.ts +2 -0
- package/dist/components/hx-icon-button/index.d.ts.map +1 -0
- package/dist/components/hx-icon-button/index.js +5 -0
- package/dist/components/hx-icon-button/index.js.map +1 -0
- package/dist/components/hx-image/index.js +1 -1
- package/dist/components/hx-number-input/hx-number-input.d.ts +2 -2
- package/dist/components/hx-number-input/hx-number-input.d.ts.map +1 -1
- package/dist/components/hx-pagination/hx-pagination.d.ts +2 -0
- 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-prose/index.js +1 -1
- package/dist/components/hx-radio-group/hx-radio-group.d.ts +31 -10
- package/dist/components/hx-radio-group/hx-radio-group.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.js +1 -1
- package/dist/components/hx-slider/hx-slider.d.ts +6 -4
- package/dist/components/hx-slider/hx-slider.d.ts.map +1 -1
- package/dist/components/hx-slider/index.js +1 -1
- package/dist/components/hx-spinner/hx-spinner.d.ts +12 -6
- package/dist/components/hx-spinner/hx-spinner.d.ts.map +1 -1
- package/dist/components/hx-spinner/index.d.ts +1 -0
- package/dist/components/hx-spinner/index.d.ts.map +1 -1
- package/dist/components/hx-stack/hx-stack.d.ts +20 -0
- package/dist/components/hx-stack/hx-stack.d.ts.map +1 -1
- package/dist/components/hx-stack/index.js +1 -1
- package/dist/components/hx-steps/hx-step.d.ts +8 -0
- package/dist/components/hx-steps/hx-step.d.ts.map +1 -1
- package/dist/components/hx-structured-list/index.js +1 -1
- package/dist/components/hx-switch/hx-switch.d.ts +2 -2
- package/dist/components/hx-switch/hx-switch.d.ts.map +1 -1
- package/dist/components/hx-tag/index.d.ts +3 -0
- package/dist/components/hx-tag/index.d.ts.map +1 -1
- package/dist/components/hx-text/hx-text.d.ts +0 -2
- package/dist/components/hx-text/hx-text.d.ts.map +1 -1
- package/dist/components/hx-textarea/hx-textarea.d.ts +7 -0
- package/dist/components/hx-textarea/hx-textarea.d.ts.map +1 -1
- package/dist/components/hx-textarea/index.js +1 -1
- package/dist/components/hx-theme/hx-theme.d.ts +4 -0
- package/dist/components/hx-theme/hx-theme.d.ts.map +1 -1
- package/dist/components/hx-theme/index.d.ts +3 -1
- package/dist/components/hx-theme/index.d.ts.map +1 -1
- package/dist/components/hx-toggle-button/hx-toggle-button.d.ts +2 -2
- package/dist/components/hx-toggle-button/hx-toggle-button.d.ts.map +1 -1
- package/dist/components/hx-toggle-button/index.js +1 -1
- package/dist/components/hx-tree-view/hx-tree-item.d.ts +29 -10
- 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 +22 -2
- 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 +6 -1
- package/dist/components/hx-tree-view/index.d.ts.map +1 -1
- package/dist/components/hx-tree-view/index.js +1 -1
- package/dist/index.d.ts +13 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +107 -105
- package/dist/index.js.map +1 -1
- package/dist/shared/{hx-action-bar-D43v5rA2.js → hx-action-bar-B4i9tBCP.js} +71 -61
- package/dist/shared/hx-action-bar-B4i9tBCP.js.map +1 -0
- package/dist/shared/{hx-badge-DYB1Pnym.js → hx-badge-CjT0d8NK.js} +9 -2
- package/dist/shared/hx-badge-CjT0d8NK.js.map +1 -0
- package/dist/shared/{hx-breadcrumb-item-TKRcrMYc.js → hx-breadcrumb-item-DtSxRZ_W.js} +25 -18
- package/dist/shared/hx-breadcrumb-item-DtSxRZ_W.js.map +1 -0
- package/dist/shared/{hx-button-SAbf4_jC.js → hx-button-CtiJsmOg.js} +31 -29
- package/dist/shared/hx-button-CtiJsmOg.js.map +1 -0
- package/dist/shared/{hx-button-group-DET_Pkxt.js → hx-button-group-BMV5qFs4.js} +19 -13
- package/dist/shared/{hx-button-group-DET_Pkxt.js.map → hx-button-group-BMV5qFs4.js.map} +1 -1
- package/dist/shared/{hx-checkbox-group-CIIijwmc.js → hx-checkbox-group-DTS9iT4b.js} +26 -20
- package/dist/shared/hx-checkbox-group-DTS9iT4b.js.map +1 -0
- package/dist/shared/{hx-container-BXZBaOGG.js → hx-container-DLUKnTi9.js} +9 -8
- package/dist/shared/hx-container-DLUKnTi9.js.map +1 -0
- package/dist/shared/hx-copy-button-BXL1xkxb.js.map +1 -1
- package/dist/shared/{hx-drawer-CenIAGuR.js → hx-drawer-bTF0nbrg.js} +2 -2
- package/dist/shared/hx-drawer-bTF0nbrg.js.map +1 -0
- package/dist/shared/hx-icon-button-C_fsUJW4.js +257 -0
- package/dist/shared/hx-icon-button-C_fsUJW4.js.map +1 -0
- package/dist/shared/{hx-image-CzkOEeO4.js → hx-image-xyb_tHCR.js} +2 -2
- package/dist/shared/hx-image-xyb_tHCR.js.map +1 -0
- package/dist/shared/hx-number-input-CS6_w1lT.js.map +1 -1
- package/dist/shared/hx-pagination-DNFgXQm3.js.map +1 -1
- package/dist/shared/{hx-prose-BUkZ8rB3.js → hx-prose-DZh2KrMb.js} +10 -7
- package/dist/shared/{hx-prose-BUkZ8rB3.js.map → hx-prose-DZh2KrMb.js.map} +1 -1
- package/dist/shared/{hx-radio-reSaVmIB.js → hx-radio-CGtFKls2.js} +42 -14
- package/dist/shared/hx-radio-CGtFKls2.js.map +1 -0
- package/dist/shared/{hx-slider-CzHOl3Ur.js → hx-slider-Duzmuid9.js} +12 -8
- package/dist/shared/hx-slider-Duzmuid9.js.map +1 -0
- package/dist/shared/hx-spinner-BOApJ-g9.js.map +1 -1
- package/dist/shared/{hx-stack-C3xUwi6-.js → hx-stack-CfoW7jU7.js} +21 -1
- package/dist/shared/{hx-stack-C3xUwi6-.js.map → hx-stack-CfoW7jU7.js.map} +1 -1
- package/dist/shared/hx-step-nMT0fHEn.js.map +1 -1
- package/dist/shared/{hx-structured-list-DKborM60.js → hx-structured-list-CMja1VXz.js} +5 -5
- package/dist/shared/{hx-structured-list-DKborM60.js.map → hx-structured-list-CMja1VXz.js.map} +1 -1
- package/dist/shared/hx-switch-BPvIcDpM.js.map +1 -1
- package/dist/shared/hx-text-NjKoQATI.js.map +1 -1
- package/dist/shared/{hx-textarea-BLcReynr.js → hx-textarea-B_nmxzhC.js} +12 -8
- package/dist/shared/hx-textarea-B_nmxzhC.js.map +1 -0
- package/dist/shared/hx-theme-6GDoUG8j.js.map +1 -1
- package/dist/shared/{hx-toggle-button---Z4zvmn.js → hx-toggle-button--xCXWRJW.js} +3 -3
- package/dist/shared/{hx-toggle-button---Z4zvmn.js.map → hx-toggle-button--xCXWRJW.js.map} +1 -1
- package/dist/shared/{hx-tree-item-CIo3ek2M.js → hx-tree-item-Cesh_du5.js} +170 -148
- package/dist/shared/hx-tree-item-Cesh_du5.js.map +1 -0
- package/package.json +7 -1
- package/dist/shared/hx-action-bar-D43v5rA2.js.map +0 -1
- package/dist/shared/hx-badge-DYB1Pnym.js.map +0 -1
- package/dist/shared/hx-breadcrumb-item-TKRcrMYc.js.map +0 -1
- package/dist/shared/hx-button-SAbf4_jC.js.map +0 -1
- package/dist/shared/hx-checkbox-group-CIIijwmc.js.map +0 -1
- package/dist/shared/hx-container-BXZBaOGG.js.map +0 -1
- package/dist/shared/hx-drawer-CenIAGuR.js.map +0 -1
- package/dist/shared/hx-image-CzkOEeO4.js.map +0 -1
- package/dist/shared/hx-radio-reSaVmIB.js.map +0 -1
- package/dist/shared/hx-slider-CzHOl3Ur.js.map +0 -1
- package/dist/shared/hx-textarea-BLcReynr.js.map +0 -1
- package/dist/shared/hx-tree-item-CIo3ek2M.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hx-step-nMT0fHEn.js","sources":["../../src/components/hx-steps/hx-steps.styles.ts","../../src/components/hx-steps/hx-steps.ts","../../src/components/hx-steps/hx-step.styles.ts","../../src/components/hx-steps/hx-step.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixStepsStyles = css`\n :host {\n display: block;\n\n /* ─── Size defaults (md) ─── */\n --hx-steps-indicator-size: 2rem;\n --hx-steps-indicator-font-size: var(--hx-font-size-sm, 0.875rem);\n --hx-steps-indicator-icon-size: 1rem;\n --hx-steps-label-font-size: var(--hx-font-size-sm, 0.875rem);\n --hx-steps-description-font-size: var(--hx-font-size-xs, 0.75rem);\n\n /* ─── Item layout defaults (horizontal) ─── */\n --hx-steps-item-flex: 1;\n --hx-steps-item-width: auto;\n }\n\n .steps {\n display: flex;\n flex-direction: row;\n align-items: flex-start;\n }\n\n /* ─── Orientation: vertical ─── */\n\n :host([orientation='vertical']) {\n --hx-steps-item-flex: initial;\n --hx-steps-item-width: 100%;\n }\n\n :host([orientation='vertical']) .steps {\n flex-direction: column;\n }\n\n /* ─── Size: sm ─── */\n\n :host([size='sm']) {\n --hx-steps-indicator-size: 1.5rem;\n --hx-steps-indicator-font-size: var(--hx-font-size-xs, 0.75rem);\n --hx-steps-indicator-icon-size: 0.75rem;\n --hx-steps-label-font-size: var(--hx-font-size-xs, 0.75rem);\n --hx-steps-description-font-size: var(--hx-font-size-xs, 0.75rem);\n }\n\n /* ─── Size: lg ─── */\n\n :host([size='lg']) {\n --hx-steps-indicator-size: 2.5rem;\n --hx-steps-indicator-font-size: var(--hx-font-size-md, 1rem);\n --hx-steps-indicator-icon-size: 1.25rem;\n --hx-steps-label-font-size: var(--hx-font-size-md, 1rem);\n --hx-steps-description-font-size: var(--hx-font-size-sm, 0.875rem);\n }\n`;\n","import { LitElement, html } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { tokenStyles } from '@helixui/tokens/lit';\nimport { helixStepsStyles } from './hx-steps.styles.js';\nimport type { HelixStep } from './hx-step.js';\n\n/**\n * A multi-step wizard / stepper progress indicator. Renders a sequence of\n * `<hx-step>` children as a horizontal or vertical step tracker with connector\n * lines and status-based styling.\n *\n * Provide an `aria-label` on `<hx-steps>` to describe the step process for assistive technology.\n *\n * @summary Multi-step progress indicator container.\n *\n * @tag hx-steps\n *\n * @slot - Default slot for `<hx-step>` elements.\n *\n * @fires {CustomEvent<{step: HelixStep, index: number}>} hx-step-click - Dispatched when\n * a step is clicked. Detail contains the clicked `step` element and its zero-based `index`.\n *\n * @csspart base - The inner wrapper element.\n *\n * @cssprop [--hx-steps-indicator-size=2rem] - Step indicator circle diameter.\n * @cssprop [--hx-steps-connector-color=var(--hx-color-neutral-200)] - Connector line color.\n * @cssprop [--hx-steps-label-color=var(--hx-color-neutral-600)] - Step label text color.\n * @cssprop [--hx-steps-description-color=var(--hx-color-neutral-500)] - Step description color.\n */\n@customElement('hx-steps')\nexport class HelixSteps extends LitElement {\n static override styles = [tokenStyles, helixStepsStyles];\n\n // ─── Public Properties ───\n\n /**\n * Layout orientation of the steps.\n * @attr orientation\n */\n @property({ type: String, reflect: true })\n orientation: 'horizontal' | 'vertical' = 'horizontal';\n\n /**\n * Size variant of the steps.\n * @attr size\n */\n @property({ type: String, reflect: true })\n size: 'sm' | 'md' | 'lg' = 'md';\n\n // ─── Lifecycle ───\n\n override connectedCallback(): void {\n super.connectedCallback();\n if (!this.hasAttribute('role')) {\n this.setAttribute('role', 'list');\n }\n this.addEventListener('hx-step-click-internal', this._handleStepClickInternal as EventListener);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener(\n 'hx-step-click-internal',\n this._handleStepClickInternal as EventListener,\n );\n }\n\n override firstUpdated(): void {\n this._syncChildren();\n }\n\n override updated(changedProperties: Map<string, unknown>): void {\n super.updated(changedProperties);\n if (changedProperties.has('orientation') || changedProperties.has('size')) {\n this._syncChildren();\n }\n }\n\n // ─── Child Sync ───\n\n /** @internal */\n private _getSteps(): HelixStep[] {\n return Array.from(this.querySelectorAll(':scope > hx-step')) as HelixStep[];\n }\n\n /** @internal */\n private _syncChildren(): void {\n const steps = this._getSteps();\n steps.forEach((step, i) => {\n step.orientation = this.orientation;\n step.size = this.size;\n step.index = i;\n });\n }\n\n // ─── Event Handling ───\n\n /** @internal */\n private _handleSlotChange = (): void => {\n this._syncChildren();\n };\n\n /** @internal */\n private _handleStepClickInternal = (e: Event): void => {\n e.stopPropagation();\n const steps = this._getSteps();\n const step = e\n .composedPath()\n .find(\n (el): el is HelixStep => el instanceof Element && el.tagName.toLowerCase() === 'hx-step',\n );\n if (!step) return;\n const index = steps.indexOf(step);\n\n /**\n * Dispatched when a step is clicked.\n * @event hx-step-click\n */\n this.dispatchEvent(\n new CustomEvent('hx-step-click', {\n bubbles: true,\n composed: true,\n detail: { step, index },\n }),\n );\n };\n\n // ─── Render ───\n\n override render() {\n return html`\n <div part=\"base\" class=\"steps\">\n <slot @slotchange=${this._handleSlotChange}></slot>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-steps': HelixSteps;\n }\n}\n","import { css } from 'lit';\n\nexport const helixStepStyles = css`\n :host {\n display: flex;\n flex: var(--hx-steps-item-flex, 1);\n width: var(--hx-steps-item-width, auto);\n min-width: 0;\n }\n\n /* ─── Visually Hidden (SR only) ─── */\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 /* ─── Step Wrapper ─── */\n\n .step {\n display: flex;\n flex-direction: column;\n align-items: center;\n width: 100%;\n cursor: pointer;\n }\n\n /* ─── Focus ─── */\n\n :host(:focus-visible) .step__indicator {\n outline: 2px solid var(--hx-color-primary-500);\n outline-offset: 2px;\n }\n\n /* ─── Track (indicator + connector) ─── */\n\n .step__track {\n display: flex;\n flex-direction: row;\n align-items: center;\n width: 100%;\n }\n\n /* ─── Indicator ─── */\n\n .step__indicator {\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n width: var(--hx-steps-indicator-size, 2rem);\n height: var(--hx-steps-indicator-size, 2rem);\n border-radius: var(--hx-border-radius-full, 9999px);\n border: 2px solid var(--hx-color-neutral-300);\n background-color: var(--hx-color-neutral-0);\n color: var(--hx-color-neutral-500);\n font-size: var(--hx-steps-indicator-font-size, var(--hx-font-size-sm));\n font-weight: var(--hx-font-weight-semibold);\n font-family: var(--hx-font-family-sans);\n transition:\n background-color var(--hx-transition-fast, 150ms ease),\n border-color var(--hx-transition-fast, 150ms ease),\n color var(--hx-transition-fast, 150ms ease);\n position: relative;\n z-index: 1;\n }\n\n .step__indicator svg {\n width: var(--hx-steps-indicator-icon-size, 1rem);\n height: var(--hx-steps-indicator-icon-size, 1rem);\n }\n\n /* ─── Connector ─── */\n\n .step__connector {\n flex: 1;\n height: var(--hx-steps-connector-thickness, var(--hx-border-width, 2px));\n min-width: 0;\n background-color: var(--hx-steps-connector-color, var(--hx-color-neutral-200));\n transition: background-color var(--hx-transition-fast, 150ms ease);\n }\n\n :host(:last-child) .step__connector {\n display: none;\n }\n\n /* ─── Label Area ─── */\n\n .step__label-area {\n text-align: center;\n margin-top: var(--hx-space-2, 0.5rem);\n width: 100%;\n padding: 0 var(--hx-space-1, 0.25rem);\n }\n\n .step__label {\n font-family: var(--hx-font-family-sans);\n font-size: var(--hx-steps-label-font-size, var(--hx-font-size-sm));\n font-weight: var(--hx-font-weight-medium);\n color: var(--hx-steps-label-color, var(--hx-color-neutral-600));\n line-height: var(--hx-line-height-tight, 1.25);\n }\n\n .step__description {\n font-family: var(--hx-font-family-sans);\n font-size: var(--hx-steps-description-font-size, var(--hx-font-size-xs));\n color: var(--hx-steps-description-color, var(--hx-color-neutral-500));\n margin-top: var(--hx-space-1, 0.25rem);\n line-height: var(--hx-line-height-normal, 1.5);\n }\n\n /* ─── Status: active ─── */\n\n /* Active: outlined indicator (in-progress) — visually distinct from complete (filled) */\n :host([status='active']) .step__indicator {\n border-color: var(--hx-color-primary-500);\n background-color: var(--hx-color-primary-500);\n color: var(--hx-color-neutral-0);\n }\n\n :host([status='active']) .step__label {\n color: var(--hx-color-primary-700);\n font-weight: var(--hx-font-weight-semibold);\n }\n\n /* ─── Status: complete ─── */\n\n /* Complete: filled indicator with darker shade — visually distinct from active */\n :host([status='complete']) .step__indicator {\n border-color: var(--hx-color-primary-700);\n background-color: var(--hx-color-primary-700);\n color: var(--hx-color-neutral-0);\n }\n\n :host([status='complete']) .step__connector {\n background-color: var(--hx-steps-connector-complete-color, var(--hx-color-primary-500));\n }\n\n :host([status='complete']) .step__label {\n color: var(--hx-color-neutral-700);\n }\n\n /* ─── Status: error ─── */\n\n :host([status='error']) .step__indicator {\n border-color: var(--hx-color-error-500);\n background-color: var(--hx-color-error-500);\n color: var(--hx-color-neutral-0);\n }\n\n :host([status='error']) .step__label {\n color: var(--hx-color-error-700);\n }\n\n /* ─── Status: disabled ─── */\n\n :host([disabled]) .step {\n cursor: not-allowed;\n opacity: 0.5;\n pointer-events: none;\n }\n\n :host([disabled]) .step__indicator {\n border-color: var(--hx-color-neutral-300);\n background-color: var(--hx-color-neutral-100);\n color: var(--hx-color-neutral-400);\n }\n\n /* ─── Vertical Layout ─── */\n\n :host([orientation='vertical']) {\n flex: initial;\n width: 100%;\n }\n\n :host([orientation='vertical']) .step {\n flex-direction: row;\n align-items: flex-start;\n gap: var(--hx-space-3, 0.75rem);\n }\n\n :host([orientation='vertical']) .step__track {\n flex-direction: column;\n align-items: center;\n width: auto;\n flex-shrink: 0;\n }\n\n :host([orientation='vertical']) .step__connector {\n width: var(--hx-steps-connector-thickness, var(--hx-border-width, 2px));\n height: auto;\n min-height: var(--hx-space-8, 2rem);\n flex: 1;\n }\n\n :host([orientation='vertical']) .step__label-area {\n text-align: left;\n margin-top: 0;\n padding-bottom: var(--hx-space-4, 1rem);\n padding-inline-start: 0;\n }\n\n :host([orientation='vertical']:last-child) .step__label-area {\n padding-bottom: 0;\n }\n\n /* ─── Dark Mode ─── */\n\n @media (prefers-color-scheme: dark) {\n .step__indicator {\n background-color: var(--hx-color-neutral-800);\n border-color: var(--hx-color-neutral-600);\n color: var(--hx-color-neutral-300);\n }\n\n .step__connector {\n background-color: var(--hx-color-neutral-700);\n }\n\n .step__label {\n color: var(--hx-color-neutral-300);\n }\n\n .step__description {\n color: var(--hx-color-neutral-400);\n }\n\n :host([status='active']) .step__label {\n color: var(--hx-color-primary-300);\n }\n\n :host([status='complete']) .step__label {\n color: var(--hx-color-neutral-200);\n }\n\n :host([status='error']) .step__label {\n color: var(--hx-color-error-300);\n }\n\n :host([disabled]) .step__indicator {\n background-color: var(--hx-color-neutral-900);\n border-color: var(--hx-color-neutral-700);\n color: var(--hx-color-neutral-600);\n }\n }\n`;\n","import { LitElement, html } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { tokenStyles } from '@helixui/tokens/lit';\nimport { helixStepStyles } from './hx-step.styles.js';\n\n/**\n * An individual step, designed to be used inside an `<hx-steps>` container.\n * Represents a single step in a multi-step wizard or progress indicator.\n *\n * @summary Individual step item within an `<hx-steps>` progress indicator.\n *\n * @tag hx-step\n *\n * @slot icon - Custom icon for the step indicator. Shown when status is `pending` or `active`.\n * @slot label - Step label text. Falls back to the `label` property.\n * @slot description - Step description text. Falls back to the `description` property.\n *\n * @csspart base - The outermost wrapper element.\n * @csspart indicator - The circular step indicator.\n * @csspart connector - The line connecting this step to the next.\n * @csspart label - The step label element.\n * @csspart description - The step description element.\n *\n * @cssprop [--hx-steps-indicator-size=2rem] - Indicator circle diameter.\n * @cssprop [--hx-steps-indicator-font-size=var(--hx-font-size-sm)] - Indicator text size.\n * @cssprop [--hx-steps-indicator-icon-size=1rem] - Indicator icon size.\n * @cssprop [--hx-steps-label-font-size=var(--hx-font-size-sm)] - Label font size.\n * @cssprop [--hx-steps-description-font-size=var(--hx-font-size-xs)] - Description font size.\n * @cssprop [--hx-steps-connector-color=var(--hx-color-neutral-200)] - Connector line color.\n * @cssprop [--hx-steps-connector-complete-color=var(--hx-color-primary-500)] - Connector color when step is complete.\n * @cssprop [--hx-steps-connector-thickness=var(--hx-border-width,2px)] - Connector line thickness.\n * @cssprop [--hx-steps-label-color=var(--hx-color-neutral-600)] - Label text color.\n * @cssprop [--hx-steps-description-color=var(--hx-color-neutral-500)] - Description text color.\n */\n@customElement('hx-step')\nexport class HelixStep extends LitElement {\n static override styles = [tokenStyles, helixStepStyles];\n\n // ─── Public Properties ───\n\n /**\n * The step label text.\n * @attr label\n */\n @property({ type: String, reflect: true })\n label = '';\n\n /**\n * Current status of the step.\n * @attr status\n */\n @property({ type: String, reflect: true })\n status: 'pending' | 'active' | 'complete' | 'error' = 'pending';\n\n /**\n * Optional description text shown below the label.\n * @attr description\n */\n @property({ type: String, reflect: true })\n description = '';\n\n /**\n * Whether the step is disabled and non-interactive.\n * @attr disabled\n */\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n // ─── Internal Properties (set by parent hx-steps) ───\n\n /**\n * Layout orientation. Set by the parent `<hx-steps>` container.\n * @internal\n */\n @property({ type: String, reflect: true })\n orientation: 'horizontal' | 'vertical' = 'horizontal';\n\n /**\n * Size variant. Set by the parent `<hx-steps>` container.\n * @internal\n */\n @property({ type: String, reflect: true })\n size: 'sm' | 'md' | 'lg' = 'md';\n\n /**\n * Zero-based index of this step. Set by the parent `<hx-steps>` container.\n * @internal\n */\n @property({ type: Number })\n index = 0;\n\n // ─── Lifecycle ───\n\n override connectedCallback(): void {\n super.connectedCallback();\n if (!this.hasAttribute('role')) {\n this.setAttribute('role', 'listitem');\n }\n this.setAttribute('tabindex', this.disabled ? '-1' : '0');\n this.addEventListener('keydown', this._handleKeydown);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener('keydown', this._handleKeydown);\n }\n\n override updated(changedProperties: Map<string, unknown>): void {\n super.updated(changedProperties);\n if (changedProperties.has('status')) {\n if (this.status === 'active') {\n this.setAttribute('aria-current', 'step');\n } else {\n this.removeAttribute('aria-current');\n }\n }\n if (changedProperties.has('disabled')) {\n if (this.disabled) {\n this.setAttribute('tabindex', '-1');\n this.setAttribute('aria-disabled', 'true');\n } else {\n this.setAttribute('tabindex', '0');\n this.removeAttribute('aria-disabled');\n }\n }\n }\n\n // ─── Event Handling ───\n\n /** @internal */\n private _handleKeydown = (event: KeyboardEvent): void => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n this._handleClick();\n }\n };\n\n /** @internal */\n private _handleClick(): void {\n if (this.disabled) {\n return;\n }\n\n /**\n * Internal event dispatched to signal step click to the parent container.\n * @internal\n */\n this.dispatchEvent(\n new CustomEvent('hx-step-click-internal', {\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n // ─── Render Helpers ───\n\n /** @internal */\n private _renderCheckmark() {\n return html`\n <svg\n aria-hidden=\"true\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <path d=\"M20 6L9 17l-5-5\" />\n </svg>\n <span class=\"sr-only\">Complete</span>\n `;\n }\n\n /** @internal */\n private _renderXMark() {\n return html`\n <svg\n aria-hidden=\"true\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2.5\"\n stroke-linecap=\"round\"\n >\n <path d=\"M18 6L6 18M6 6l12 12\" />\n </svg>\n <span class=\"sr-only\">Error</span>\n `;\n }\n\n /** @internal */\n private _renderIndicatorContent() {\n if (this.status === 'complete') {\n return this._renderCheckmark();\n }\n if (this.status === 'error') {\n return this._renderXMark();\n }\n return html`<slot name=\"icon\">${this.index + 1}</slot>`;\n }\n\n // ─── Render ───\n\n override render() {\n return html`\n <div part=\"base\" class=\"step\" @click=${this._handleClick}>\n <div class=\"step__track\">\n <div part=\"indicator\" class=\"step__indicator\">${this._renderIndicatorContent()}</div>\n <div part=\"connector\" class=\"step__connector\" aria-hidden=\"true\"></div>\n </div>\n <div class=\"step__label-area\">\n <div part=\"label\" class=\"step__label\">\n <slot name=\"label\">${this.label}</slot>\n </div>\n <div part=\"description\" class=\"step__description\">\n <slot name=\"description\">${this.description}</slot>\n </div>\n </div>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-step': HelixStep;\n }\n}\n"],"names":["helixStepsStyles","css","HelixSteps","LitElement","e","steps","step","el","index","changedProperties","i","html","tokenStyles","__decorateClass","property","customElement","helixStepStyles","HelixStep","event"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"hx-step-nMT0fHEn.js","sources":["../../src/components/hx-steps/hx-steps.styles.ts","../../src/components/hx-steps/hx-steps.ts","../../src/components/hx-steps/hx-step.styles.ts","../../src/components/hx-steps/hx-step.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixStepsStyles = css`\n :host {\n display: block;\n\n /* ─── Size defaults (md) ─── */\n --hx-steps-indicator-size: 2rem;\n --hx-steps-indicator-font-size: var(--hx-font-size-sm, 0.875rem);\n --hx-steps-indicator-icon-size: 1rem;\n --hx-steps-label-font-size: var(--hx-font-size-sm, 0.875rem);\n --hx-steps-description-font-size: var(--hx-font-size-xs, 0.75rem);\n\n /* ─── Item layout defaults (horizontal) ─── */\n --hx-steps-item-flex: 1;\n --hx-steps-item-width: auto;\n }\n\n .steps {\n display: flex;\n flex-direction: row;\n align-items: flex-start;\n }\n\n /* ─── Orientation: vertical ─── */\n\n :host([orientation='vertical']) {\n --hx-steps-item-flex: initial;\n --hx-steps-item-width: 100%;\n }\n\n :host([orientation='vertical']) .steps {\n flex-direction: column;\n }\n\n /* ─── Size: sm ─── */\n\n :host([size='sm']) {\n --hx-steps-indicator-size: 1.5rem;\n --hx-steps-indicator-font-size: var(--hx-font-size-xs, 0.75rem);\n --hx-steps-indicator-icon-size: 0.75rem;\n --hx-steps-label-font-size: var(--hx-font-size-xs, 0.75rem);\n --hx-steps-description-font-size: var(--hx-font-size-xs, 0.75rem);\n }\n\n /* ─── Size: lg ─── */\n\n :host([size='lg']) {\n --hx-steps-indicator-size: 2.5rem;\n --hx-steps-indicator-font-size: var(--hx-font-size-md, 1rem);\n --hx-steps-indicator-icon-size: 1.25rem;\n --hx-steps-label-font-size: var(--hx-font-size-md, 1rem);\n --hx-steps-description-font-size: var(--hx-font-size-sm, 0.875rem);\n }\n`;\n","import { LitElement, html } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { tokenStyles } from '@helixui/tokens/lit';\nimport { helixStepsStyles } from './hx-steps.styles.js';\nimport type { HelixStep } from './hx-step.js';\n\n/**\n * A multi-step wizard / stepper progress indicator. Renders a sequence of\n * `<hx-step>` children as a horizontal or vertical step tracker with connector\n * lines and status-based styling.\n *\n * Provide an `aria-label` on `<hx-steps>` to describe the step process for assistive technology.\n *\n * @summary Multi-step progress indicator container.\n *\n * @tag hx-steps\n *\n * @slot - Default slot for `<hx-step>` elements.\n *\n * @fires {CustomEvent<{step: HelixStep, index: number}>} hx-step-click - Dispatched when\n * a step is clicked. Detail contains the clicked `step` element and its zero-based `index`.\n *\n * @csspart base - The inner wrapper element.\n *\n * @cssprop [--hx-steps-indicator-size=2rem] - Step indicator circle diameter.\n * @cssprop [--hx-steps-connector-color=var(--hx-color-neutral-200)] - Connector line color.\n * @cssprop [--hx-steps-label-color=var(--hx-color-neutral-600)] - Step label text color.\n * @cssprop [--hx-steps-description-color=var(--hx-color-neutral-500)] - Step description color.\n */\n@customElement('hx-steps')\nexport class HelixSteps extends LitElement {\n static override styles = [tokenStyles, helixStepsStyles];\n\n // ─── Public Properties ───\n\n /**\n * Layout orientation of the steps.\n * @attr orientation\n */\n @property({ type: String, reflect: true })\n orientation: 'horizontal' | 'vertical' = 'horizontal';\n\n /**\n * Size variant of the steps.\n * @attr size\n */\n @property({ type: String, reflect: true })\n size: 'sm' | 'md' | 'lg' = 'md';\n\n // ─── Lifecycle ───\n\n override connectedCallback(): void {\n super.connectedCallback();\n if (!this.hasAttribute('role')) {\n this.setAttribute('role', 'list');\n }\n this.addEventListener('hx-step-click-internal', this._handleStepClickInternal as EventListener);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener(\n 'hx-step-click-internal',\n this._handleStepClickInternal as EventListener,\n );\n }\n\n override firstUpdated(): void {\n this._syncChildren();\n }\n\n override updated(changedProperties: Map<string, unknown>): void {\n super.updated(changedProperties);\n if (changedProperties.has('orientation') || changedProperties.has('size')) {\n this._syncChildren();\n }\n }\n\n // ─── Child Sync ───\n\n /** @internal */\n private _getSteps(): HelixStep[] {\n return Array.from(this.querySelectorAll(':scope > hx-step')) as HelixStep[];\n }\n\n /** @internal */\n private _syncChildren(): void {\n const steps = this._getSteps();\n steps.forEach((step, i) => {\n step.orientation = this.orientation;\n step.size = this.size;\n step.index = i;\n });\n }\n\n // ─── Event Handling ───\n\n /** @internal */\n private _handleSlotChange = (): void => {\n this._syncChildren();\n };\n\n /** @internal */\n private _handleStepClickInternal = (e: Event): void => {\n e.stopPropagation();\n const steps = this._getSteps();\n const step = e\n .composedPath()\n .find(\n (el): el is HelixStep => el instanceof Element && el.tagName.toLowerCase() === 'hx-step',\n );\n if (!step) return;\n const index = steps.indexOf(step);\n\n /**\n * Dispatched when a step is clicked.\n * @event hx-step-click\n */\n this.dispatchEvent(\n new CustomEvent('hx-step-click', {\n bubbles: true,\n composed: true,\n detail: { step, index },\n }),\n );\n };\n\n // ─── Render ───\n\n override render() {\n return html`\n <div part=\"base\" class=\"steps\">\n <slot @slotchange=${this._handleSlotChange}></slot>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-steps': HelixSteps;\n }\n}\n","import { css } from 'lit';\n\nexport const helixStepStyles = css`\n :host {\n display: flex;\n flex: var(--hx-steps-item-flex, 1);\n width: var(--hx-steps-item-width, auto);\n min-width: 0;\n }\n\n /* ─── Visually Hidden (SR only) ─── */\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 /* ─── Step Wrapper ─── */\n\n .step {\n display: flex;\n flex-direction: column;\n align-items: center;\n width: 100%;\n cursor: pointer;\n }\n\n /* ─── Focus ─── */\n\n :host(:focus-visible) .step__indicator {\n outline: 2px solid var(--hx-color-primary-500);\n outline-offset: 2px;\n }\n\n /* ─── Track (indicator + connector) ─── */\n\n .step__track {\n display: flex;\n flex-direction: row;\n align-items: center;\n width: 100%;\n }\n\n /* ─── Indicator ─── */\n\n .step__indicator {\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n width: var(--hx-steps-indicator-size, 2rem);\n height: var(--hx-steps-indicator-size, 2rem);\n border-radius: var(--hx-border-radius-full, 9999px);\n border: 2px solid var(--hx-color-neutral-300);\n background-color: var(--hx-color-neutral-0);\n color: var(--hx-color-neutral-500);\n font-size: var(--hx-steps-indicator-font-size, var(--hx-font-size-sm));\n font-weight: var(--hx-font-weight-semibold);\n font-family: var(--hx-font-family-sans);\n transition:\n background-color var(--hx-transition-fast, 150ms ease),\n border-color var(--hx-transition-fast, 150ms ease),\n color var(--hx-transition-fast, 150ms ease);\n position: relative;\n z-index: 1;\n }\n\n .step__indicator svg {\n width: var(--hx-steps-indicator-icon-size, 1rem);\n height: var(--hx-steps-indicator-icon-size, 1rem);\n }\n\n /* ─── Connector ─── */\n\n .step__connector {\n flex: 1;\n height: var(--hx-steps-connector-thickness, var(--hx-border-width, 2px));\n min-width: 0;\n background-color: var(--hx-steps-connector-color, var(--hx-color-neutral-200));\n transition: background-color var(--hx-transition-fast, 150ms ease);\n }\n\n :host(:last-child) .step__connector {\n display: none;\n }\n\n /* ─── Label Area ─── */\n\n .step__label-area {\n text-align: center;\n margin-top: var(--hx-space-2, 0.5rem);\n width: 100%;\n padding: 0 var(--hx-space-1, 0.25rem);\n }\n\n .step__label {\n font-family: var(--hx-font-family-sans);\n font-size: var(--hx-steps-label-font-size, var(--hx-font-size-sm));\n font-weight: var(--hx-font-weight-medium);\n color: var(--hx-steps-label-color, var(--hx-color-neutral-600));\n line-height: var(--hx-line-height-tight, 1.25);\n }\n\n .step__description {\n font-family: var(--hx-font-family-sans);\n font-size: var(--hx-steps-description-font-size, var(--hx-font-size-xs));\n color: var(--hx-steps-description-color, var(--hx-color-neutral-500));\n margin-top: var(--hx-space-1, 0.25rem);\n line-height: var(--hx-line-height-normal, 1.5);\n }\n\n /* ─── Status: active ─── */\n\n /* Active: outlined indicator (in-progress) — visually distinct from complete (filled) */\n :host([status='active']) .step__indicator {\n border-color: var(--hx-color-primary-500);\n background-color: var(--hx-color-primary-500);\n color: var(--hx-color-neutral-0);\n }\n\n :host([status='active']) .step__label {\n color: var(--hx-color-primary-700);\n font-weight: var(--hx-font-weight-semibold);\n }\n\n /* ─── Status: complete ─── */\n\n /* Complete: filled indicator with darker shade — visually distinct from active */\n :host([status='complete']) .step__indicator {\n border-color: var(--hx-color-primary-700);\n background-color: var(--hx-color-primary-700);\n color: var(--hx-color-neutral-0);\n }\n\n :host([status='complete']) .step__connector {\n background-color: var(--hx-steps-connector-complete-color, var(--hx-color-primary-500));\n }\n\n :host([status='complete']) .step__label {\n color: var(--hx-color-neutral-700);\n }\n\n /* ─── Status: error ─── */\n\n :host([status='error']) .step__indicator {\n border-color: var(--hx-color-error-500);\n background-color: var(--hx-color-error-500);\n color: var(--hx-color-neutral-0);\n }\n\n :host([status='error']) .step__label {\n color: var(--hx-color-error-700);\n }\n\n /* ─── Status: disabled ─── */\n\n :host([disabled]) .step {\n cursor: not-allowed;\n opacity: 0.5;\n pointer-events: none;\n }\n\n :host([disabled]) .step__indicator {\n border-color: var(--hx-color-neutral-300);\n background-color: var(--hx-color-neutral-100);\n color: var(--hx-color-neutral-400);\n }\n\n /* ─── Vertical Layout ─── */\n\n :host([orientation='vertical']) {\n flex: initial;\n width: 100%;\n }\n\n :host([orientation='vertical']) .step {\n flex-direction: row;\n align-items: flex-start;\n gap: var(--hx-space-3, 0.75rem);\n }\n\n :host([orientation='vertical']) .step__track {\n flex-direction: column;\n align-items: center;\n width: auto;\n flex-shrink: 0;\n }\n\n :host([orientation='vertical']) .step__connector {\n width: var(--hx-steps-connector-thickness, var(--hx-border-width, 2px));\n height: auto;\n min-height: var(--hx-space-8, 2rem);\n flex: 1;\n }\n\n :host([orientation='vertical']) .step__label-area {\n text-align: left;\n margin-top: 0;\n padding-bottom: var(--hx-space-4, 1rem);\n padding-inline-start: 0;\n }\n\n :host([orientation='vertical']:last-child) .step__label-area {\n padding-bottom: 0;\n }\n\n /* ─── Dark Mode ─── */\n\n @media (prefers-color-scheme: dark) {\n .step__indicator {\n background-color: var(--hx-color-neutral-800);\n border-color: var(--hx-color-neutral-600);\n color: var(--hx-color-neutral-300);\n }\n\n .step__connector {\n background-color: var(--hx-color-neutral-700);\n }\n\n .step__label {\n color: var(--hx-color-neutral-300);\n }\n\n .step__description {\n color: var(--hx-color-neutral-400);\n }\n\n :host([status='active']) .step__label {\n color: var(--hx-color-primary-300);\n }\n\n :host([status='complete']) .step__label {\n color: var(--hx-color-neutral-200);\n }\n\n :host([status='error']) .step__label {\n color: var(--hx-color-error-300);\n }\n\n :host([disabled]) .step__indicator {\n background-color: var(--hx-color-neutral-900);\n border-color: var(--hx-color-neutral-700);\n color: var(--hx-color-neutral-600);\n }\n }\n`;\n","import { LitElement, html } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { tokenStyles } from '@helixui/tokens/lit';\nimport { helixStepStyles } from './hx-step.styles.js';\n\n/**\n * An individual step, designed to be used inside an `<hx-steps>` container.\n * Represents a single step in a multi-step wizard or progress indicator.\n *\n * @summary Individual step item within an `<hx-steps>` progress indicator.\n *\n * @tag hx-step\n *\n * @slot icon - Custom icon for the step indicator. Shown when status is `pending` or `active`.\n * @slot label - Step label text. Falls back to the `label` property.\n * @slot description - Step description text. Falls back to the `description` property.\n *\n * @csspart base - The outermost wrapper element.\n * @csspart indicator - The circular step indicator.\n * @csspart connector - The line connecting this step to the next.\n * @csspart label - The step label element.\n * @csspart description - The step description element.\n *\n * @cssprop [--hx-steps-indicator-size=2rem] - Indicator circle diameter.\n * @cssprop [--hx-steps-indicator-font-size=var(--hx-font-size-sm)] - Indicator text size.\n * @cssprop [--hx-steps-indicator-icon-size=1rem] - Indicator icon size.\n * @cssprop [--hx-steps-label-font-size=var(--hx-font-size-sm)] - Label font size.\n * @cssprop [--hx-steps-description-font-size=var(--hx-font-size-xs)] - Description font size.\n * @cssprop [--hx-steps-connector-color=var(--hx-color-neutral-200)] - Connector line color.\n * @cssprop [--hx-steps-connector-complete-color=var(--hx-color-primary-500)] - Connector color when step is complete.\n * @cssprop [--hx-steps-connector-thickness=var(--hx-border-width,2px)] - Connector line thickness.\n * @cssprop [--hx-steps-label-color=var(--hx-color-neutral-600)] - Label text color.\n * @cssprop [--hx-steps-description-color=var(--hx-color-neutral-500)] - Description text color.\n */\n@customElement('hx-step')\nexport class HelixStep extends LitElement {\n static override styles = [tokenStyles, helixStepStyles];\n\n // ─── Public Properties ───\n\n /**\n * The step label text.\n * @attr label\n */\n @property({ type: String, reflect: true })\n label = '';\n\n /**\n * Current status of the step.\n * @attr status\n */\n @property({ type: String, reflect: true })\n status: 'pending' | 'active' | 'complete' | 'error' = 'pending';\n\n /**\n * Optional description text shown below the label.\n * @attr description\n */\n @property({ type: String, reflect: true })\n description = '';\n\n /**\n * Whether the step is disabled and non-interactive.\n * @attr disabled\n */\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n // ─── Internal Properties (set by parent hx-steps) ───\n\n /**\n * Layout orientation. Set by the parent `<hx-steps>` container.\n * Reflected as an attribute for CSS styling (`[orientation='vertical']` selector).\n * Do not set this attribute directly on `<hx-step>` — use the `orientation`\n * property on the parent `<hx-steps>` container instead. The parent will\n * propagate the value to all child steps via `_syncChildren()`.\n * @internal\n */\n @property({ type: String, reflect: true })\n orientation: 'horizontal' | 'vertical' = 'horizontal';\n\n /**\n * Size variant. Set by the parent `<hx-steps>` container.\n * Reflected as an attribute for CSS styling. Do not set this attribute\n * directly on `<hx-step>` — use the `size` property on the parent\n * `<hx-steps>` container instead. The parent will propagate the value\n * to all child steps via `_syncChildren()`.\n * @internal\n */\n @property({ type: String, reflect: true })\n size: 'sm' | 'md' | 'lg' = 'md';\n\n /**\n * Zero-based index of this step. Set by the parent `<hx-steps>` container.\n * @internal\n */\n @property({ type: Number })\n index = 0;\n\n // ─── Lifecycle ───\n\n override connectedCallback(): void {\n super.connectedCallback();\n if (!this.hasAttribute('role')) {\n this.setAttribute('role', 'listitem');\n }\n this.setAttribute('tabindex', this.disabled ? '-1' : '0');\n this.addEventListener('keydown', this._handleKeydown);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener('keydown', this._handleKeydown);\n }\n\n override updated(changedProperties: Map<string, unknown>): void {\n super.updated(changedProperties);\n if (changedProperties.has('status')) {\n if (this.status === 'active') {\n this.setAttribute('aria-current', 'step');\n } else {\n this.removeAttribute('aria-current');\n }\n }\n if (changedProperties.has('disabled')) {\n if (this.disabled) {\n this.setAttribute('tabindex', '-1');\n this.setAttribute('aria-disabled', 'true');\n } else {\n this.setAttribute('tabindex', '0');\n this.removeAttribute('aria-disabled');\n }\n }\n }\n\n // ─── Event Handling ───\n\n /** @internal */\n private _handleKeydown = (event: KeyboardEvent): void => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n this._handleClick();\n }\n };\n\n /** @internal */\n private _handleClick(): void {\n if (this.disabled) {\n return;\n }\n\n /**\n * Internal event dispatched to signal step click to the parent container.\n * @internal\n */\n this.dispatchEvent(\n new CustomEvent('hx-step-click-internal', {\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n // ─── Render Helpers ───\n\n /** @internal */\n private _renderCheckmark() {\n return html`\n <svg\n aria-hidden=\"true\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <path d=\"M20 6L9 17l-5-5\" />\n </svg>\n <span class=\"sr-only\">Complete</span>\n `;\n }\n\n /** @internal */\n private _renderXMark() {\n return html`\n <svg\n aria-hidden=\"true\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2.5\"\n stroke-linecap=\"round\"\n >\n <path d=\"M18 6L6 18M6 6l12 12\" />\n </svg>\n <span class=\"sr-only\">Error</span>\n `;\n }\n\n /** @internal */\n private _renderIndicatorContent() {\n if (this.status === 'complete') {\n return this._renderCheckmark();\n }\n if (this.status === 'error') {\n return this._renderXMark();\n }\n return html`<slot name=\"icon\">${this.index + 1}</slot>`;\n }\n\n // ─── Render ───\n\n override render() {\n return html`\n <div part=\"base\" class=\"step\" @click=${this._handleClick}>\n <div class=\"step__track\">\n <div part=\"indicator\" class=\"step__indicator\">${this._renderIndicatorContent()}</div>\n <div part=\"connector\" class=\"step__connector\" aria-hidden=\"true\"></div>\n </div>\n <div class=\"step__label-area\">\n <div part=\"label\" class=\"step__label\">\n <slot name=\"label\">${this.label}</slot>\n </div>\n <div part=\"description\" class=\"step__description\">\n <slot name=\"description\">${this.description}</slot>\n </div>\n </div>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-step': HelixStep;\n }\n}\n"],"names":["helixStepsStyles","css","HelixSteps","LitElement","e","steps","step","el","index","changedProperties","i","html","tokenStyles","__decorateClass","property","customElement","helixStepStyles","HelixStep","event"],"mappings":"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"}
|
|
@@ -86,7 +86,7 @@ let e = class extends u {
|
|
|
86
86
|
}
|
|
87
87
|
render() {
|
|
88
88
|
return v`
|
|
89
|
-
<div part="base" class="list">
|
|
89
|
+
<div part="base" class="list" role="list">
|
|
90
90
|
<slot></slot>
|
|
91
91
|
</div>
|
|
92
92
|
`;
|
|
@@ -108,11 +108,11 @@ e = t([
|
|
|
108
108
|
let d = class extends u {
|
|
109
109
|
render() {
|
|
110
110
|
return v`
|
|
111
|
-
<div part="base" class="row">
|
|
112
|
-
<div part="label" class="row__label"
|
|
111
|
+
<div part="base" class="row" role="listitem">
|
|
112
|
+
<div part="label" class="row__label">
|
|
113
113
|
<slot name="label"></slot>
|
|
114
114
|
</div>
|
|
115
|
-
<div part="value" class="row__value"
|
|
115
|
+
<div part="value" class="row__value">
|
|
116
116
|
<slot></slot>
|
|
117
117
|
<div part="actions" class="row__actions">
|
|
118
118
|
<slot name="actions"></slot>
|
|
@@ -130,4 +130,4 @@ export {
|
|
|
130
130
|
e as H,
|
|
131
131
|
d as a
|
|
132
132
|
};
|
|
133
|
-
//# sourceMappingURL=hx-structured-list-
|
|
133
|
+
//# sourceMappingURL=hx-structured-list-CMja1VXz.js.map
|
package/dist/shared/{hx-structured-list-DKborM60.js.map → hx-structured-list-CMja1VXz.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hx-structured-list-
|
|
1
|
+
{"version":3,"file":"hx-structured-list-CMja1VXz.js","sources":["../../src/components/hx-structured-list/hx-structured-list.styles.ts","../../src/components/hx-structured-list/hx-structured-list.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixStructuredListStyles = css`\n :host {\n display: block;\n --_border-color: var(--hx-structured-list-border-color, var(--hx-color-neutral-200, #e2e8f0));\n --_border-width: var(--hx-structured-list-border-width, var(--hx-border-width-thin, 1px));\n --_bg-stripe: var(--hx-structured-list-stripe-bg, var(--hx-color-neutral-50, #f8fafc));\n --_padding-block: var(--hx-structured-list-padding-block, var(--hx-space-4, 1rem));\n --_padding-inline: var(--hx-structured-list-padding-inline, var(--hx-space-4, 1rem));\n }\n\n :host([condensed]) {\n --_padding-block: var(--hx-structured-list-condensed-padding-block, var(--hx-space-2, 0.5rem));\n --_padding-inline: var(\n --hx-structured-list-condensed-padding-inline,\n var(--hx-space-3, 0.75rem)\n );\n }\n\n .list {\n display: block;\n margin: 0;\n padding: 0;\n list-style: none;\n }\n\n :host([bordered]) .list {\n border: var(--_border-width) solid var(--_border-color);\n border-radius: var(--hx-border-radius-md, 0.375rem);\n overflow: hidden;\n }\n\n :host([striped]) ::slotted(hx-structured-list-row:nth-of-type(even)) {\n background: var(--_bg-stripe);\n }\n`;\n\nexport const helixStructuredListRowStyles = css`\n :host {\n display: block;\n }\n\n .row {\n display: grid;\n grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);\n align-items: baseline;\n padding-block: var(--_padding-block, var(--hx-space-4, 1rem));\n padding-inline: var(--_padding-inline, var(--hx-space-4, 1rem));\n gap: var(--hx-space-4, 1rem);\n }\n\n :host(:not(:last-of-type)) .row {\n border-bottom: var(--_border-width, var(--hx-border-width-thin, 1px)) solid\n var(--_border-color, var(--hx-color-neutral-200, #e2e8f0));\n }\n\n .row__label {\n font-weight: var(--hx-font-weight-medium, 500);\n color: var(--hx-structured-list-label-color, var(--hx-color-neutral-700, #374151));\n font-size: var(--hx-font-size-sm, 0.875rem);\n }\n\n .row__value {\n color: var(--hx-structured-list-value-color, var(--hx-color-neutral-900, #111827));\n font-size: var(--hx-font-size-sm, 0.875rem);\n }\n\n .row__actions {\n display: flex;\n align-items: center;\n gap: var(--hx-space-2, 0.5rem);\n }\n\n .row__actions:empty {\n display: none;\n }\n`;\n","import { LitElement, html } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { tokenStyles } from '@helixui/tokens/lit';\nimport {\n helixStructuredListStyles,\n helixStructuredListRowStyles,\n} from './hx-structured-list.styles.js';\n\n/**\n * Container for structured key-value data display. Renders as a description\n * list for accessible term/definition semantics. Use `hx-structured-list-row`\n * as direct children.\n *\n * @summary Key-value data display container for detail and summary views.\n *\n * @tag hx-structured-list\n *\n * @slot - One or more `hx-structured-list-row` elements.\n *\n * @csspart base - The root list element.\n *\n * @cssprop [--hx-structured-list-border-color=var(--hx-color-neutral-200)] - Border color when bordered.\n * @cssprop [--hx-structured-list-border-width=var(--hx-border-width-thin)] - Border width when bordered.\n * @cssprop [--hx-structured-list-stripe-bg=var(--hx-color-neutral-50)] - Stripe background color.\n * @cssprop [--hx-structured-list-padding-block=var(--hx-space-4)] - Row block padding.\n * @cssprop [--hx-structured-list-padding-inline=var(--hx-space-4)] - Row inline padding.\n * @cssprop [--hx-structured-list-condensed-padding-block=var(--hx-space-2)] - Row block padding (condensed).\n * @cssprop [--hx-structured-list-condensed-padding-inline=var(--hx-space-3)] - Row inline padding (condensed).\n */\n@customElement('hx-structured-list')\nexport class HelixStructuredList extends LitElement {\n static override styles = [tokenStyles, helixStructuredListStyles];\n\n /**\n * Renders a border around the entire list.\n * @attr bordered\n */\n @property({ type: Boolean, reflect: true })\n bordered = false;\n\n /**\n * Reduces row padding for denser layouts.\n * @attr condensed\n */\n @property({ type: Boolean, reflect: true })\n condensed = false;\n\n /**\n * Alternates row background colors for easier scanning.\n * @attr striped\n */\n @property({ type: Boolean, reflect: true })\n striped = false;\n\n override render() {\n return html`\n <div part=\"base\" class=\"list\" role=\"list\">\n <slot></slot>\n </div>\n `;\n }\n}\n\n/**\n * A single row within an `hx-structured-list`. Renders a label/value pair\n * with an optional actions area.\n *\n * @summary A label-value row for use inside `hx-structured-list`.\n *\n * @tag hx-structured-list-row\n *\n * @slot label - The term or key label (`<dt>` semantics).\n * @slot - The value or definition (`<dd>` semantics).\n * @slot actions - Optional action controls (edit button, etc.).\n *\n * @csspart base - The root row element.\n * @csspart label - The label (`dt`) cell.\n * @csspart value - The value (`dd`) cell.\n * @csspart actions - The actions cell.\n *\n * @cssprop [--hx-structured-list-label-color=var(--hx-color-neutral-700)] - Label text color.\n * @cssprop [--hx-structured-list-value-color=var(--hx-color-neutral-900)] - Value text color.\n */\n@customElement('hx-structured-list-row')\nexport class HelixStructuredListRow extends LitElement {\n static override styles = [tokenStyles, helixStructuredListRowStyles];\n\n override render() {\n return html`\n <div part=\"base\" class=\"row\" role=\"listitem\">\n <div part=\"label\" class=\"row__label\">\n <slot name=\"label\"></slot>\n </div>\n <div part=\"value\" class=\"row__value\">\n <slot></slot>\n <div part=\"actions\" class=\"row__actions\">\n <slot name=\"actions\"></slot>\n </div>\n </div>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-structured-list': HelixStructuredList;\n 'hx-structured-list-row': HelixStructuredListRow;\n }\n}\n"],"names":["helixStructuredListStyles","css","helixStructuredListRowStyles","HelixStructuredList","LitElement","html","tokenStyles","__decorateClass","property","customElement","HelixStructuredListRow"],"mappings":";;;AAEO,MAAMA,IAA4BC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAoC5BC,IAA+BD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;ACRrC,IAAME,IAAN,cAAkCC,EAAW;AAAA,EAA7C,cAAA;AAAA,UAAA,GAAA,SAAA,GAQL,KAAA,WAAW,IAOX,KAAA,YAAY,IAOZ,KAAA,UAAU;AAAA,EAAA;AAAA,EAED,SAAS;AAChB,WAAOC;AAAA;AAAA;AAAA;AAAA;AAAA,EAKT;AACF;AA/BaF,EACK,SAAS,CAACG,GAAaN,CAAyB;AAOhEO,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,SAAS,SAAS,IAAM;AAAA,GAP/BL,EAQX,WAAA,YAAA,CAAA;AAOAI,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,SAAS,SAAS,IAAM;AAAA,GAd/BL,EAeX,WAAA,aAAA,CAAA;AAOAI,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,SAAS,SAAS,IAAM;AAAA,GArB/BL,EAsBX,WAAA,WAAA,CAAA;AAtBWA,IAANI,EAAA;AAAA,EADNE,EAAc,oBAAoB;AAAA,GACtBN,CAAA;AAsDN,IAAMO,IAAN,cAAqCN,EAAW;AAAA,EAG5C,SAAS;AAChB,WAAOC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaT;AACF;AAlBaK,EACK,SAAS,CAACJ,GAAaJ,CAA4B;AADxDQ,IAANH,EAAA;AAAA,EADNE,EAAc,wBAAwB;AAAA,GAC1BC,CAAA;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hx-switch-BPvIcDpM.js","sources":["../../src/components/hx-switch/hx-switch.styles.ts","../../src/components/hx-switch/hx-switch.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixSwitchStyles = 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 /* --- Layout --- */\n\n .switch {\n display: flex;\n flex-direction: column;\n gap: var(--hx-space-1, 0.25rem);\n font-family: var(--hx-font-family-sans, sans-serif);\n }\n\n .switch__control-row {\n display: flex;\n align-items: center;\n gap: var(--hx-space-2, 0.5rem);\n }\n\n /* --- Track --- */\n\n .switch__track {\n position: relative;\n display: inline-flex;\n align-items: center;\n flex-shrink: 0;\n border: none;\n padding: 0;\n border-radius: var(--hx-border-radius-full, 9999px);\n background-color: var(--hx-switch-track-bg, var(--hx-color-neutral-300, #ced4da));\n cursor: pointer;\n transition: background-color var(--hx-transition-fast, 150ms ease);\n outline: none;\n -webkit-appearance: none;\n appearance: none;\n }\n\n .switch__track:focus-visible {\n outline: var(--hx-focus-ring-width, 2px) solid\n var(--hx-switch-focus-ring-color, var(--hx-focus-ring-color, #2563eb));\n outline-offset: var(--hx-focus-ring-offset, 2px);\n }\n\n .switch--checked .switch__track {\n background-color: var(--hx-switch-track-checked-bg, var(--hx-color-primary-500, #2563eb));\n }\n\n /* --- Thumb --- */\n\n .switch__thumb {\n position: absolute;\n border-radius: var(--hx-border-radius-full, 9999px);\n background-color: var(--hx-switch-thumb-bg, var(--hx-color-neutral-0, #ffffff));\n box-shadow: var(--hx-switch-thumb-shadow, var(--hx-shadow-sm, 0 1px 2px 0 rgb(0 0 0 / 0.05)));\n transition: transform var(--hx-transition-fast, 150ms ease);\n }\n\n /* --- Size: sm (track 32x18, thumb 14px) --- */\n\n .switch--sm .switch__track {\n width: var(--hx-switch-track-width-sm, var(--hx-size-8, 2rem));\n height: var(--hx-switch-track-height-sm, var(--hx-size-4-5, 1.125rem));\n }\n\n .switch--sm .switch__thumb {\n width: var(--hx-switch-thumb-size-sm, var(--hx-size-3-5, 0.875rem));\n height: var(--hx-switch-thumb-size-sm, var(--hx-size-3-5, 0.875rem));\n top: 50%;\n left: var(--hx-switch-thumb-offset, var(--hx-space-0-5, 0.125rem));\n transform: translateY(-50%);\n }\n\n .switch--sm.switch--checked .switch__thumb {\n transform: translateY(-50%)\n translateX(var(--hx-switch-thumb-size-sm, var(--hx-size-3-5, 0.875rem)));\n }\n\n /* --- Size: md (track 40x22, thumb 18px) --- */\n\n .switch--md .switch__track {\n width: var(--hx-switch-track-width-md, var(--hx-size-10, 2.5rem));\n height: var(--hx-switch-track-height-md, var(--hx-size-5-5, 1.375rem));\n }\n\n .switch--md .switch__thumb {\n width: var(--hx-switch-thumb-size-md, var(--hx-size-4-5, 1.125rem));\n height: var(--hx-switch-thumb-size-md, var(--hx-size-4-5, 1.125rem));\n top: 50%;\n left: var(--hx-switch-thumb-offset, var(--hx-space-0-5, 0.125rem));\n transform: translateY(-50%);\n }\n\n .switch--md.switch--checked .switch__thumb {\n transform: translateY(-50%)\n translateX(var(--hx-switch-thumb-size-md, var(--hx-size-4-5, 1.125rem)));\n }\n\n /* --- Size: lg (track 48x26, thumb 22px) --- */\n\n .switch--lg .switch__track {\n width: var(--hx-switch-track-width-lg, var(--hx-size-12, 3rem));\n height: var(--hx-switch-track-height-lg, var(--hx-size-6-5, 1.625rem));\n }\n\n .switch--lg .switch__thumb {\n width: var(--hx-switch-thumb-size-lg, var(--hx-size-5-5, 1.375rem));\n height: var(--hx-switch-thumb-size-lg, var(--hx-size-5-5, 1.375rem));\n top: 50%;\n left: var(--hx-switch-thumb-offset, var(--hx-space-0-5, 0.125rem));\n transform: translateY(-50%);\n }\n\n .switch--lg.switch--checked .switch__thumb {\n transform: translateY(-50%)\n translateX(var(--hx-switch-thumb-size-lg, var(--hx-size-5-5, 1.375rem)));\n }\n\n /* --- Label --- */\n\n .switch__label {\n font-size: var(--hx-font-size-sm, 0.875rem);\n font-weight: var(--hx-font-weight-medium, 500);\n color: var(--hx-switch-label-color, var(--hx-color-neutral-700, #343a40));\n line-height: var(--hx-line-height-normal, 1.5);\n cursor: pointer;\n user-select: none;\n -webkit-user-select: none;\n }\n\n .switch__required-marker {\n color: var(--hx-switch-error-color, var(--hx-color-error-text, #b91c1c));\n font-weight: var(--hx-font-weight-bold, 700);\n }\n\n /* --- Help Text & Error --- */\n\n .switch__help-text {\n font-size: var(--hx-font-size-xs, 0.75rem);\n color: var(--hx-switch-help-text-color, var(--hx-color-neutral-500, #6c757d));\n line-height: var(--hx-line-height-normal, 1.5);\n }\n\n .switch__error {\n font-size: var(--hx-font-size-xs, 0.75rem);\n color: var(--hx-switch-error-color, var(--hx-color-error-text, #b91c1c));\n line-height: var(--hx-line-height-normal, 1.5);\n }\n\n /* --- Reduced Motion --- */\n\n @media (prefers-reduced-motion: reduce) {\n .switch__track,\n .switch__thumb {\n transition: none;\n }\n }\n`;\n","import { LitElement, html, nothing } from 'lit';\nimport { customElement, property, query, state } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { tokenStyles } from '@helixui/tokens/lit';\nimport { helixSwitchStyles } from './hx-switch.styles.js';\n\n/**\n * A toggle switch component for on/off states.\n *\n * Uses `role=\"switch\"` with `aria-checked` to convey toggle state.\n * Supports keyboard activation via Space key (per ARIA APG switch pattern).\n * Label association is handled through `aria-labelledby`, and\n * error/help text are linked via `aria-describedby`.\n *\n * @summary Form-associated toggle switch with label, error, and help text.\n *\n * @tag hx-switch\n *\n * @slot - Custom label content (overrides the label property).\n * @slot error - Custom error content (overrides the error property).\n * @slot help-text - Custom help text content (overrides the helpText property).\n *\n * @fires {CustomEvent<{checked: boolean, value: string}>} hx-change - Dispatched when the switch is toggled.\n *\n * @csspart switch - The switch container (track + thumb wrapper).\n * @csspart track - The track background element.\n * @csspart thumb - The sliding thumb element.\n * @csspart label - The label text element.\n * @csspart help-text - The help text container.\n * @csspart error - The error message container.\n *\n * @cssprop [--hx-switch-track-bg=var(--hx-color-neutral-300)] - Track background color.\n * @cssprop [--hx-switch-track-checked-bg=var(--hx-color-primary-500)] - Track background when checked.\n * @cssprop [--hx-switch-thumb-bg=var(--hx-color-neutral-0)] - Thumb background color.\n * @cssprop [--hx-switch-thumb-shadow=var(--hx-shadow-sm)] - Thumb box shadow.\n * @cssprop [--hx-switch-focus-ring-color=var(--hx-focus-ring-color)] - Focus ring color.\n * @cssprop [--hx-switch-label-color=var(--hx-color-neutral-700)] - Label text color.\n * @cssprop [--hx-switch-error-color=var(--hx-color-error-500)] - Error message color.\n * @cssprop [--hx-switch-help-text-color=var(--hx-color-neutral-500)] - Help text color.\n */\n@customElement('hx-switch')\nexport class HelixSwitch extends LitElement {\n static override styles = [tokenStyles, helixSwitchStyles];\n\n /** Monotonic counter for deterministic, unique IDs across instances. */\n private static _instanceCounter = 0;\n\n // ─── Form Association ───\n\n /** Enables the element to participate in form submission and validation. */\n static formAssociated = true;\n\n /** ElementInternals instance for form association, validation, and ARIA. */\n private _internals: ElementInternals;\n\n constructor() {\n super();\n this._internals = this.attachInternals();\n }\n\n // ─── Properties ───\n\n /**\n * Whether the switch is toggled on.\n * @attr checked\n */\n @property({ type: Boolean, reflect: true })\n checked = false;\n\n /**\n * Whether the switch is disabled.\n * @attr disabled\n */\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /**\n * Whether the switch is required for form submission.\n * @attr required\n */\n @property({ type: Boolean, reflect: true })\n required = false;\n\n /**\n * The name of the switch, used for form submission.\n * @attr name\n */\n @property({ type: String })\n name = '';\n\n /**\n * The value submitted when the switch is checked.\n * @attr value\n */\n @property({ type: String })\n value = 'on';\n\n /**\n * The visible label text for the switch.\n * @attr label\n */\n @property({ type: String })\n label = '';\n\n /**\n * Size variant of the switch.\n * @attr hx-size\n */\n @property({ type: String, reflect: true, attribute: 'hx-size' })\n size: 'sm' | 'md' | 'lg' = 'md';\n\n /**\n * Error message to display. When set, the switch enters an error state.\n * @attr error\n */\n @property({ type: String })\n error = '';\n\n /**\n * Help text displayed below the switch for guidance.\n * @attr help-text\n */\n @property({ type: String, attribute: 'help-text' })\n helpText = '';\n\n // ─── Lifecycle ───\n\n override updated(changedProperties: Map<string, unknown>): void {\n super.updated(changedProperties);\n if (changedProperties.has('checked') || changedProperties.has('value')) {\n this._internals.setFormValue(this.checked ? this.value : null);\n this._updateValidity();\n }\n if (changedProperties.has('required')) {\n this._updateValidity();\n }\n }\n\n // ─── Form Integration ───\n\n /** Returns the associated form element, if any. */\n get form(): HTMLFormElement | null {\n return this._internals.form;\n }\n\n /** Returns the validation message. */\n get validationMessage(): string {\n return this._internals.validationMessage;\n }\n\n /** Returns the ValidityState object. */\n get validity(): ValidityState {\n return this._internals.validity;\n }\n\n /** Checks whether the switch 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 /** Recalculates and sets the validity state based on required and checked. */\n private _updateValidity(): void {\n if (this.required && !this.checked) {\n this._internals.setValidity(\n { valueMissing: true },\n this.error || 'This field is required.',\n this._trackEl ?? undefined,\n );\n } else {\n this._internals.setValidity({});\n }\n }\n\n /** Called by the form when it resets. */\n formResetCallback(): void {\n this.checked = false;\n this._internals.setFormValue(null);\n }\n\n /** Called when the form restores state (e.g., back/forward navigation). */\n formStateRestoreCallback(state: File | string | null, _mode: 'restore' | 'autocomplete'): void {\n if (typeof state === 'string') {\n this.checked = state === this.value;\n }\n }\n\n /** Reference to the native button element acting as the switch track. */\n @query('.switch__track')\n private _trackEl!: HTMLButtonElement | null;\n\n /** Whether the error slot has assigned content. */\n @state() private _hasErrorSlot = false;\n\n /** Whether the default slot has assigned content (slotted label). */\n @state() private _hasDefaultSlot = false;\n\n // ─── Slot Handlers ───\n\n /** Updates _hasErrorSlot when error slot content changes. */\n private _handleErrorSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n this._hasErrorSlot = slot.assignedNodes({ flatten: true }).length > 0;\n }\n\n /** Updates _hasDefaultSlot when default slot content changes. */\n private _handleDefaultSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n this._hasDefaultSlot = slot.assignedNodes({ flatten: true }).length > 0;\n }\n\n // ─── Event Handling ───\n\n /** Toggles checked state and dispatches hx-change event. */\n private _toggle(): void {\n if (this.disabled) return;\n this.checked = !this.checked;\n\n this.dispatchEvent(\n new CustomEvent('hx-change', {\n bubbles: true,\n composed: true,\n detail: { checked: this.checked, value: this.value },\n }),\n );\n }\n\n /** Handles click events on the track. */\n private _handleClick(): void {\n this._toggle();\n }\n\n /** Handles keydown events — Space toggles the switch per ARIA APG. */\n private _handleKeyDown(e: KeyboardEvent): void {\n if (e.key === ' ') {\n e.preventDefault();\n this._toggle();\n }\n }\n\n // ─── Public Methods ───\n\n /** Moves focus to the switch track element. */\n override focus(options?: FocusOptions): void {\n this._trackEl?.focus(options);\n }\n\n // ─── Render ───\n\n /** Unique ID for this switch instance, used for ARIA associations. */\n private _switchId = `hx-switch-${++HelixSwitch._instanceCounter}`;\n /** ID for the label element, referenced by aria-labelledby. */\n private _labelId = `${this._switchId}-label`;\n /** ID for the help text element, referenced by aria-describedby. */\n private _helpTextId = `${this._switchId}-help`;\n /** ID for the error element, referenced by aria-describedby. */\n private _errorId = `${this._switchId}-error`;\n\n override render() {\n const hasError = !!this.error;\n const hasLabel = !!this.label || this._hasDefaultSlot;\n\n const containerClasses = {\n switch: true,\n 'switch--checked': this.checked,\n 'switch--disabled': this.disabled,\n 'switch--required': this.required,\n 'switch--error': hasError,\n [`switch--${this.size}`]: true,\n };\n\n const describedBy =\n [\n hasError || this._hasErrorSlot ? this._errorId : null,\n this.helpText && !hasError ? this._helpTextId : null,\n ]\n .filter(Boolean)\n .join(' ') || undefined;\n\n return html`\n <div part=\"switch\" class=${classMap(containerClasses)}>\n <div class=\"switch__control-row\">\n <button\n part=\"track\"\n class=\"switch__track\"\n type=\"button\"\n role=\"switch\"\n aria-checked=${this.checked ? 'true' : 'false'}\n aria-labelledby=${ifDefined(hasLabel ? this._labelId : undefined)}\n aria-describedby=${ifDefined(describedBy)}\n aria-invalid=${hasError ? 'true' : nothing}\n aria-required=${this.required ? 'true' : nothing}\n ?disabled=${this.disabled}\n @click=${this._handleClick}\n @keydown=${this._handleKeyDown}\n >\n <span part=\"thumb\" class=\"switch__thumb\"></span>\n </button>\n\n <span part=\"label\" class=\"switch__label\" id=${this._labelId} @click=${this._handleClick}>\n <slot @slotchange=${this._handleDefaultSlotChange}>${this.label}</slot>${this.required\n ? html`<span class=\"switch__required-marker\" aria-hidden=\"true\">*</span>`\n : nothing}\n </span>\n </div>\n\n <slot name=\"error\" @slotchange=${this._handleErrorSlotChange}>\n ${hasError\n ? html`<div part=\"error\" class=\"switch__error\" id=${this._errorId} role=\"alert\">\n ${this.error}\n </div>`\n : nothing}\n </slot>\n\n ${this.helpText && !hasError\n ? html`\n <div part=\"help-text\" class=\"switch__help-text\" id=${this._helpTextId}>\n <slot name=\"help-text\">${this.helpText}</slot>\n </div>\n `\n : nothing}\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-switch': HelixSwitch;\n }\n}\n\n/** @deprecated Use HxSwitch instead. */\nexport type WcSwitch = HelixSwitch;\nexport type HxSwitch = HelixSwitch;\n"],"names":["helixSwitchStyles","css","HelixSwitch","LitElement","changedProperties","state","_mode","e","slot","options","_a","hasError","hasLabel","containerClasses","describedBy","html","classMap","ifDefined","nothing","tokenStyles","__decorateClass","property","query","customElement"],"mappings":";;;;;AAEO,MAAMA,IAAoBC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;ACwC1B,IAAMC,IAAN,cAA0BC,EAAW;AAAA,EAc1C,cAAc;AACZ,UAAA,GAWF,KAAA,UAAU,IAOV,KAAA,WAAW,IAOX,KAAA,WAAW,IAOX,KAAA,OAAO,IAOP,KAAA,QAAQ,MAOR,KAAA,QAAQ,IAOR,KAAA,OAA2B,MAO3B,KAAA,QAAQ,IAOR,KAAA,WAAW,IAyEF,KAAQ,gBAAgB,IAGxB,KAAQ,kBAAkB,IAuDnC,KAAQ,YAAY,aAAa,EAAED,EAAY,gBAAgB,IAE/D,KAAQ,WAAW,GAAG,KAAK,SAAS,UAEpC,KAAQ,cAAc,GAAG,KAAK,SAAS,SAEvC,KAAQ,WAAW,GAAG,KAAK,SAAS,UA3MlC,KAAK,aAAa,KAAK,gBAAA;AAAA,EACzB;AAAA;AAAA,EAqES,QAAQE,GAA+C;AAC9D,UAAM,QAAQA,CAAiB,IAC3BA,EAAkB,IAAI,SAAS,KAAKA,EAAkB,IAAI,OAAO,OACnE,KAAK,WAAW,aAAa,KAAK,UAAU,KAAK,QAAQ,IAAI,GAC7D,KAAK,gBAAA,IAEHA,EAAkB,IAAI,UAAU,KAClC,KAAK,gBAAA;AAAA,EAET;AAAA;AAAA;AAAA,EAKA,IAAI,OAA+B;AACjC,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA;AAAA,EAGA,IAAI,oBAA4B;AAC9B,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA;AAAA,EAGA,IAAI,WAA0B;AAC5B,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA;AAAA,EAGA,gBAAyB;AACvB,WAAO,KAAK,WAAW,cAAA;AAAA,EACzB;AAAA;AAAA,EAGA,iBAA0B;AACxB,WAAO,KAAK,WAAW,eAAA;AAAA,EACzB;AAAA;AAAA,EAGQ,kBAAwB;AAC9B,IAAI,KAAK,YAAY,CAAC,KAAK,UACzB,KAAK,WAAW;AAAA,MACd,EAAE,cAAc,GAAA;AAAA,MAChB,KAAK,SAAS;AAAA,MACd,KAAK,YAAY;AAAA,IAAA,IAGnB,KAAK,WAAW,YAAY,EAAE;AAAA,EAElC;AAAA;AAAA,EAGA,oBAA0B;AACxB,SAAK,UAAU,IACf,KAAK,WAAW,aAAa,IAAI;AAAA,EACnC;AAAA;AAAA,EAGA,yBAAyBC,GAA6BC,GAAyC;AAC7F,IAAI,OAAOD,KAAU,aACnB,KAAK,UAAUA,MAAU,KAAK;AAAA,EAElC;AAAA;AAAA;AAAA,EAeQ,uBAAuBE,GAAgB;AAC7C,UAAMC,IAAOD,EAAE;AACf,SAAK,gBAAgBC,EAAK,cAAc,EAAE,SAAS,GAAA,CAAM,EAAE,SAAS;AAAA,EACtE;AAAA;AAAA,EAGQ,yBAAyBD,GAAgB;AAC/C,UAAMC,IAAOD,EAAE;AACf,SAAK,kBAAkBC,EAAK,cAAc,EAAE,SAAS,GAAA,CAAM,EAAE,SAAS;AAAA,EACxE;AAAA;AAAA;AAAA,EAKQ,UAAgB;AACtB,IAAI,KAAK,aACT,KAAK,UAAU,CAAC,KAAK,SAErB,KAAK;AAAA,MACH,IAAI,YAAY,aAAa;AAAA,QAC3B,SAAS;AAAA,QACT,UAAU;AAAA,QACV,QAAQ,EAAE,SAAS,KAAK,SAAS,OAAO,KAAK,MAAA;AAAA,MAAM,CACpD;AAAA,IAAA;AAAA,EAEL;AAAA;AAAA,EAGQ,eAAqB;AAC3B,SAAK,QAAA;AAAA,EACP;AAAA;AAAA,EAGQ,eAAeD,GAAwB;AAC7C,IAAIA,EAAE,QAAQ,QACZA,EAAE,eAAA,GACF,KAAK,QAAA;AAAA,EAET;AAAA;AAAA;AAAA,EAKS,MAAME,GAA8B;;AAC3C,KAAAC,IAAA,KAAK,aAAL,QAAAA,EAAe,MAAMD;AAAA,EACvB;AAAA,EAaS,SAAS;AAChB,UAAME,IAAW,CAAC,CAAC,KAAK,OAClBC,IAAW,CAAC,CAAC,KAAK,SAAS,KAAK,iBAEhCC,IAAmB;AAAA,MACvB,QAAQ;AAAA,MACR,mBAAmB,KAAK;AAAA,MACxB,oBAAoB,KAAK;AAAA,MACzB,oBAAoB,KAAK;AAAA,MACzB,iBAAiBF;AAAA,MACjB,CAAC,WAAW,KAAK,IAAI,EAAE,GAAG;AAAA,IAAA,GAGtBG,IACJ;AAAA,MACEH,KAAY,KAAK,gBAAgB,KAAK,WAAW;AAAA,MACjD,KAAK,YAAY,CAACA,IAAW,KAAK,cAAc;AAAA,IAAA,EAE/C,OAAO,OAAO,EACd,KAAK,GAAG,KAAK;AAElB,WAAOI;AAAA,iCACsBC,EAASH,CAAgB,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,2BAOhC,KAAK,UAAU,SAAS,OAAO;AAAA,8BAC5BI,EAAUL,IAAW,KAAK,WAAW,MAAS,CAAC;AAAA,+BAC9CK,EAAUH,CAAW,CAAC;AAAA,2BAC1BH,IAAW,SAASO,CAAO;AAAA,4BAC1B,KAAK,WAAW,SAASA,CAAO;AAAA,wBACpC,KAAK,QAAQ;AAAA,qBAChB,KAAK,YAAY;AAAA,uBACf,KAAK,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA,wDAKc,KAAK,QAAQ,WAAW,KAAK,YAAY;AAAA,gCACjE,KAAK,wBAAwB,IAAI,KAAK,KAAK,UAAU,KAAK,WAC1EH,uEACAG,CAAO;AAAA;AAAA;AAAA;AAAA,yCAIkB,KAAK,sBAAsB;AAAA,YACxDP,IACEI,+CAAkD,KAAK,QAAQ;AAAA,kBAC3D,KAAK,KAAK;AAAA,wBAEdG,CAAO;AAAA;AAAA;AAAA,UAGX,KAAK,YAAY,CAACP,IAChBI;AAAA,mEACuD,KAAK,WAAW;AAAA,yCAC1C,KAAK,QAAQ;AAAA;AAAA,gBAG1CG,CAAO;AAAA;AAAA;AAAA,EAGjB;AACF;AA/RahB,EACK,SAAS,CAACiB,GAAanB,CAAiB;AAD7CE,EAII,mBAAmB;AAJvBA,EASJ,iBAAiB;AAiBxBkB,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,SAAS,SAAS,IAAM;AAAA,GAzB/BnB,EA0BX,WAAA,WAAA,CAAA;AAOAkB,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,SAAS,SAAS,IAAM;AAAA,GAhC/BnB,EAiCX,WAAA,YAAA,CAAA;AAOAkB,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,SAAS,SAAS,IAAM;AAAA,GAvC/BnB,EAwCX,WAAA,YAAA,CAAA;AAOAkB,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GA9CfnB,EA+CX,WAAA,QAAA,CAAA;AAOAkB,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GArDfnB,EAsDX,WAAA,SAAA,CAAA;AAOAkB,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GA5DfnB,EA6DX,WAAA,SAAA,CAAA;AAOAkB,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,QAAQ,SAAS,IAAM,WAAW,WAAW;AAAA,GAnEpDnB,EAoEX,WAAA,QAAA,CAAA;AAOAkB,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GA1EfnB,EA2EX,WAAA,SAAA,CAAA;AAOAkB,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,QAAQ,WAAW,aAAa;AAAA,GAjFvCnB,EAkFX,WAAA,YAAA,CAAA;AAsEQkB,EAAA;AAAA,EADPE,EAAM,gBAAgB;AAAA,GAvJZpB,EAwJH,WAAA,YAAA,CAAA;AAGSkB,EAAA;AAAA,EAAhBf,EAAA;AAAM,GA3JIH,EA2JM,WAAA,iBAAA,CAAA;AAGAkB,EAAA;AAAA,EAAhBf,EAAA;AAAM,GA9JIH,EA8JM,WAAA,mBAAA,CAAA;AA9JNA,IAANkB,EAAA;AAAA,EADNG,EAAc,WAAW;AAAA,GACbrB,CAAA;"}
|
|
1
|
+
{"version":3,"file":"hx-switch-BPvIcDpM.js","sources":["../../src/components/hx-switch/hx-switch.styles.ts","../../src/components/hx-switch/hx-switch.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixSwitchStyles = 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 /* --- Layout --- */\n\n .switch {\n display: flex;\n flex-direction: column;\n gap: var(--hx-space-1, 0.25rem);\n font-family: var(--hx-font-family-sans, sans-serif);\n }\n\n .switch__control-row {\n display: flex;\n align-items: center;\n gap: var(--hx-space-2, 0.5rem);\n }\n\n /* --- Track --- */\n\n .switch__track {\n position: relative;\n display: inline-flex;\n align-items: center;\n flex-shrink: 0;\n border: none;\n padding: 0;\n border-radius: var(--hx-border-radius-full, 9999px);\n background-color: var(--hx-switch-track-bg, var(--hx-color-neutral-300, #ced4da));\n cursor: pointer;\n transition: background-color var(--hx-transition-fast, 150ms ease);\n outline: none;\n -webkit-appearance: none;\n appearance: none;\n }\n\n .switch__track:focus-visible {\n outline: var(--hx-focus-ring-width, 2px) solid\n var(--hx-switch-focus-ring-color, var(--hx-focus-ring-color, #2563eb));\n outline-offset: var(--hx-focus-ring-offset, 2px);\n }\n\n .switch--checked .switch__track {\n background-color: var(--hx-switch-track-checked-bg, var(--hx-color-primary-500, #2563eb));\n }\n\n /* --- Thumb --- */\n\n .switch__thumb {\n position: absolute;\n border-radius: var(--hx-border-radius-full, 9999px);\n background-color: var(--hx-switch-thumb-bg, var(--hx-color-neutral-0, #ffffff));\n box-shadow: var(--hx-switch-thumb-shadow, var(--hx-shadow-sm, 0 1px 2px 0 rgb(0 0 0 / 0.05)));\n transition: transform var(--hx-transition-fast, 150ms ease);\n }\n\n /* --- Size: sm (track 32x18, thumb 14px) --- */\n\n .switch--sm .switch__track {\n width: var(--hx-switch-track-width-sm, var(--hx-size-8, 2rem));\n height: var(--hx-switch-track-height-sm, var(--hx-size-4-5, 1.125rem));\n }\n\n .switch--sm .switch__thumb {\n width: var(--hx-switch-thumb-size-sm, var(--hx-size-3-5, 0.875rem));\n height: var(--hx-switch-thumb-size-sm, var(--hx-size-3-5, 0.875rem));\n top: 50%;\n left: var(--hx-switch-thumb-offset, var(--hx-space-0-5, 0.125rem));\n transform: translateY(-50%);\n }\n\n .switch--sm.switch--checked .switch__thumb {\n transform: translateY(-50%)\n translateX(var(--hx-switch-thumb-size-sm, var(--hx-size-3-5, 0.875rem)));\n }\n\n /* --- Size: md (track 40x22, thumb 18px) --- */\n\n .switch--md .switch__track {\n width: var(--hx-switch-track-width-md, var(--hx-size-10, 2.5rem));\n height: var(--hx-switch-track-height-md, var(--hx-size-5-5, 1.375rem));\n }\n\n .switch--md .switch__thumb {\n width: var(--hx-switch-thumb-size-md, var(--hx-size-4-5, 1.125rem));\n height: var(--hx-switch-thumb-size-md, var(--hx-size-4-5, 1.125rem));\n top: 50%;\n left: var(--hx-switch-thumb-offset, var(--hx-space-0-5, 0.125rem));\n transform: translateY(-50%);\n }\n\n .switch--md.switch--checked .switch__thumb {\n transform: translateY(-50%)\n translateX(var(--hx-switch-thumb-size-md, var(--hx-size-4-5, 1.125rem)));\n }\n\n /* --- Size: lg (track 48x26, thumb 22px) --- */\n\n .switch--lg .switch__track {\n width: var(--hx-switch-track-width-lg, var(--hx-size-12, 3rem));\n height: var(--hx-switch-track-height-lg, var(--hx-size-6-5, 1.625rem));\n }\n\n .switch--lg .switch__thumb {\n width: var(--hx-switch-thumb-size-lg, var(--hx-size-5-5, 1.375rem));\n height: var(--hx-switch-thumb-size-lg, var(--hx-size-5-5, 1.375rem));\n top: 50%;\n left: var(--hx-switch-thumb-offset, var(--hx-space-0-5, 0.125rem));\n transform: translateY(-50%);\n }\n\n .switch--lg.switch--checked .switch__thumb {\n transform: translateY(-50%)\n translateX(var(--hx-switch-thumb-size-lg, var(--hx-size-5-5, 1.375rem)));\n }\n\n /* --- Label --- */\n\n .switch__label {\n font-size: var(--hx-font-size-sm, 0.875rem);\n font-weight: var(--hx-font-weight-medium, 500);\n color: var(--hx-switch-label-color, var(--hx-color-neutral-700, #343a40));\n line-height: var(--hx-line-height-normal, 1.5);\n cursor: pointer;\n user-select: none;\n -webkit-user-select: none;\n }\n\n .switch__required-marker {\n color: var(--hx-switch-error-color, var(--hx-color-error-text, #b91c1c));\n font-weight: var(--hx-font-weight-bold, 700);\n }\n\n /* --- Help Text & Error --- */\n\n .switch__help-text {\n font-size: var(--hx-font-size-xs, 0.75rem);\n color: var(--hx-switch-help-text-color, var(--hx-color-neutral-500, #6c757d));\n line-height: var(--hx-line-height-normal, 1.5);\n }\n\n .switch__error {\n font-size: var(--hx-font-size-xs, 0.75rem);\n color: var(--hx-switch-error-color, var(--hx-color-error-text, #b91c1c));\n line-height: var(--hx-line-height-normal, 1.5);\n }\n\n /* --- Reduced Motion --- */\n\n @media (prefers-reduced-motion: reduce) {\n .switch__track,\n .switch__thumb {\n transition: none;\n }\n }\n`;\n","import { LitElement, html, nothing, type PropertyValues } from 'lit';\nimport { customElement, property, query, state } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { tokenStyles } from '@helixui/tokens/lit';\nimport { helixSwitchStyles } from './hx-switch.styles.js';\n\n/**\n * A toggle switch component for on/off states.\n *\n * Uses `role=\"switch\"` with `aria-checked` to convey toggle state.\n * Supports keyboard activation via Space key (per ARIA APG switch pattern).\n * Label association is handled through `aria-labelledby`, and\n * error/help text are linked via `aria-describedby`.\n *\n * @summary Form-associated toggle switch with label, error, and help text.\n *\n * @tag hx-switch\n *\n * @slot - Custom label content (overrides the label property).\n * @slot error - Custom error content (overrides the error property).\n * @slot help-text - Custom help text content (overrides the helpText property).\n *\n * @fires {CustomEvent<{checked: boolean, value: string}>} hx-change - Dispatched when the switch is toggled.\n *\n * @csspart switch - The switch container (track + thumb wrapper).\n * @csspart track - The track background element.\n * @csspart thumb - The sliding thumb element.\n * @csspart label - The label text element.\n * @csspart help-text - The help text container.\n * @csspart error - The error message container.\n *\n * @cssprop [--hx-switch-track-bg=var(--hx-color-neutral-300)] - Track background color.\n * @cssprop [--hx-switch-track-checked-bg=var(--hx-color-primary-500)] - Track background when checked.\n * @cssprop [--hx-switch-thumb-bg=var(--hx-color-neutral-0)] - Thumb background color.\n * @cssprop [--hx-switch-thumb-shadow=var(--hx-shadow-sm)] - Thumb box shadow.\n * @cssprop [--hx-switch-focus-ring-color=var(--hx-focus-ring-color)] - Focus ring color.\n * @cssprop [--hx-switch-label-color=var(--hx-color-neutral-700)] - Label text color.\n * @cssprop [--hx-switch-error-color=var(--hx-color-error-500)] - Error message color.\n * @cssprop [--hx-switch-help-text-color=var(--hx-color-neutral-500)] - Help text color.\n */\n@customElement('hx-switch')\nexport class HelixSwitch extends LitElement {\n static override styles = [tokenStyles, helixSwitchStyles];\n\n /** Monotonic counter for deterministic, unique IDs across instances. */\n private static _instanceCounter = 0;\n\n // ─── Form Association ───\n\n /** Enables the element to participate in form submission and validation. */\n static formAssociated = true;\n\n /** ElementInternals instance for form association, validation, and ARIA. */\n private _internals: ElementInternals;\n\n constructor() {\n super();\n this._internals = this.attachInternals();\n }\n\n // ─── Properties ───\n\n /**\n * Whether the switch is toggled on.\n * @attr checked\n */\n @property({ type: Boolean, reflect: true })\n checked = false;\n\n /**\n * Whether the switch is disabled.\n * @attr disabled\n */\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /**\n * Whether the switch is required for form submission.\n * @attr required\n */\n @property({ type: Boolean, reflect: true })\n required = false;\n\n /**\n * The name of the switch, used for form submission.\n * @attr name\n */\n @property({ type: String })\n name = '';\n\n /**\n * The value submitted when the switch is checked.\n * @attr value\n */\n @property({ type: String })\n value = 'on';\n\n /**\n * The visible label text for the switch.\n * @attr label\n */\n @property({ type: String })\n label = '';\n\n /**\n * Size variant of the switch.\n * @attr hx-size\n */\n @property({ type: String, reflect: true, attribute: 'hx-size' })\n size: 'sm' | 'md' | 'lg' = 'md';\n\n /**\n * Error message to display. When set, the switch enters an error state.\n * @attr error\n */\n @property({ type: String })\n error = '';\n\n /**\n * Help text displayed below the switch for guidance.\n * @attr help-text\n */\n @property({ type: String, attribute: 'help-text' })\n helpText = '';\n\n // ─── Lifecycle ───\n\n override updated(changedProperties: PropertyValues<this>): void {\n super.updated(changedProperties);\n if (changedProperties.has('checked') || changedProperties.has('value')) {\n this._internals.setFormValue(this.checked ? this.value : null);\n this._updateValidity();\n }\n if (changedProperties.has('required')) {\n this._updateValidity();\n }\n }\n\n // ─── Form Integration ───\n\n /** Returns the associated form element, if any. */\n get form(): HTMLFormElement | null {\n return this._internals.form;\n }\n\n /** Returns the validation message. */\n get validationMessage(): string {\n return this._internals.validationMessage;\n }\n\n /** Returns the ValidityState object. */\n get validity(): ValidityState {\n return this._internals.validity;\n }\n\n /** Checks whether the switch 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 /** Recalculates and sets the validity state based on required and checked. */\n private _updateValidity(): void {\n if (this.required && !this.checked) {\n this._internals.setValidity(\n { valueMissing: true },\n this.error || 'This field is required.',\n this._trackEl ?? undefined,\n );\n } else {\n this._internals.setValidity({});\n }\n }\n\n /** Called by the form when it resets. */\n formResetCallback(): void {\n this.checked = false;\n this._internals.setFormValue(null);\n }\n\n /** Called when the form restores state (e.g., back/forward navigation). */\n formStateRestoreCallback(state: File | string | null, _mode: 'restore' | 'autocomplete'): void {\n if (typeof state === 'string') {\n this.checked = state === this.value;\n }\n }\n\n /** Reference to the native button element acting as the switch track. */\n @query('.switch__track')\n private _trackEl!: HTMLButtonElement | null;\n\n /** Whether the error slot has assigned content. */\n @state() private _hasErrorSlot = false;\n\n /** Whether the default slot has assigned content (slotted label). */\n @state() private _hasDefaultSlot = false;\n\n // ─── Slot Handlers ───\n\n /** Updates _hasErrorSlot when error slot content changes. */\n private _handleErrorSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n this._hasErrorSlot = slot.assignedNodes({ flatten: true }).length > 0;\n }\n\n /** Updates _hasDefaultSlot when default slot content changes. */\n private _handleDefaultSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n this._hasDefaultSlot = slot.assignedNodes({ flatten: true }).length > 0;\n }\n\n // ─── Event Handling ───\n\n /** Toggles checked state and dispatches hx-change event. */\n private _toggle(): void {\n if (this.disabled) return;\n this.checked = !this.checked;\n\n this.dispatchEvent(\n new CustomEvent('hx-change', {\n bubbles: true,\n composed: true,\n detail: { checked: this.checked, value: this.value },\n }),\n );\n }\n\n /** Handles click events on the track. */\n private _handleClick(): void {\n this._toggle();\n }\n\n /** Handles keydown events — Space toggles the switch per ARIA APG. */\n private _handleKeyDown(e: KeyboardEvent): void {\n if (e.key === ' ') {\n e.preventDefault();\n this._toggle();\n }\n }\n\n // ─── Public Methods ───\n\n /** Moves focus to the switch track element. */\n override focus(options?: FocusOptions): void {\n this._trackEl?.focus(options);\n }\n\n // ─── Render ───\n\n /** Unique ID for this switch instance, used for ARIA associations. */\n private _switchId = `hx-switch-${++HelixSwitch._instanceCounter}`;\n /** ID for the label element, referenced by aria-labelledby. */\n private _labelId = `${this._switchId}-label`;\n /** ID for the help text element, referenced by aria-describedby. */\n private _helpTextId = `${this._switchId}-help`;\n /** ID for the error element, referenced by aria-describedby. */\n private _errorId = `${this._switchId}-error`;\n\n override render() {\n const hasError = !!this.error;\n const hasLabel = !!this.label || this._hasDefaultSlot;\n\n const containerClasses = {\n switch: true,\n 'switch--checked': this.checked,\n 'switch--disabled': this.disabled,\n 'switch--required': this.required,\n 'switch--error': hasError,\n [`switch--${this.size}`]: true,\n };\n\n const describedBy =\n [\n hasError || this._hasErrorSlot ? this._errorId : null,\n this.helpText && !hasError ? this._helpTextId : null,\n ]\n .filter(Boolean)\n .join(' ') || undefined;\n\n return html`\n <div part=\"switch\" class=${classMap(containerClasses)}>\n <div class=\"switch__control-row\">\n <button\n part=\"track\"\n class=\"switch__track\"\n type=\"button\"\n role=\"switch\"\n aria-checked=${this.checked ? 'true' : 'false'}\n aria-labelledby=${ifDefined(hasLabel ? this._labelId : undefined)}\n aria-describedby=${ifDefined(describedBy)}\n aria-invalid=${hasError ? 'true' : nothing}\n aria-required=${this.required ? 'true' : nothing}\n ?disabled=${this.disabled}\n @click=${this._handleClick}\n @keydown=${this._handleKeyDown}\n >\n <span part=\"thumb\" class=\"switch__thumb\"></span>\n </button>\n\n <span part=\"label\" class=\"switch__label\" id=${this._labelId} @click=${this._handleClick}>\n <slot @slotchange=${this._handleDefaultSlotChange}>${this.label}</slot>${this.required\n ? html`<span class=\"switch__required-marker\" aria-hidden=\"true\">*</span>`\n : nothing}\n </span>\n </div>\n\n <slot name=\"error\" @slotchange=${this._handleErrorSlotChange}>\n ${hasError\n ? html`<div part=\"error\" class=\"switch__error\" id=${this._errorId} role=\"alert\">\n ${this.error}\n </div>`\n : nothing}\n </slot>\n\n ${this.helpText && !hasError\n ? html`\n <div part=\"help-text\" class=\"switch__help-text\" id=${this._helpTextId}>\n <slot name=\"help-text\">${this.helpText}</slot>\n </div>\n `\n : nothing}\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-switch': HelixSwitch;\n }\n}\n\n/** @deprecated Use HxSwitch instead. */\nexport type WcSwitch = HelixSwitch;\nexport type HxSwitch = HelixSwitch;\n"],"names":["helixSwitchStyles","css","HelixSwitch","LitElement","changedProperties","state","_mode","e","slot","options","_a","hasError","hasLabel","containerClasses","describedBy","html","classMap","ifDefined","nothing","tokenStyles","__decorateClass","property","query","customElement"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hx-text-NjKoQATI.js","sources":["../../src/components/hx-text/hx-text.styles.ts","../../src/components/hx-text/hx-text.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixTextStyles = css`\n :host {\n display: inline;\n }\n\n /* ─── Base ─── */\n\n .text {\n display: inline;\n font-family: var(--hx-font-family-sans, sans-serif);\n font-size: var(--hx-text-font-size);\n font-weight: var(--hx-text-font-weight);\n line-height: var(--hx-text-line-height);\n letter-spacing: var(--hx-text-letter-spacing);\n color: var(--hx-text-color);\n margin: 0;\n padding: 0;\n }\n\n /* ─── Variants ─── */\n\n .text--body {\n --hx-text-font-size: var(--hx-font-size-md, 1rem);\n --hx-text-font-weight: var(--hx-font-weight-regular, 400);\n --hx-text-line-height: var(--hx-line-height-normal, 1.5);\n --hx-text-letter-spacing: var(--hx-letter-spacing-normal, 0);\n }\n\n .text--body-sm {\n --hx-text-font-size: var(--hx-font-size-sm, 0.875rem);\n --hx-text-font-weight: var(--hx-font-weight-regular, 400);\n --hx-text-line-height: var(--hx-line-height-normal, 1.5);\n --hx-text-letter-spacing: var(--hx-letter-spacing-normal, 0);\n }\n\n .text--body-lg {\n --hx-text-font-size: var(--hx-font-size-lg, 1.125rem);\n --hx-text-font-weight: var(--hx-font-weight-regular, 400);\n --hx-text-line-height: var(--hx-line-height-normal, 1.5);\n --hx-text-letter-spacing: var(--hx-letter-spacing-normal, 0);\n }\n\n .text--label {\n --hx-text-font-size: var(--hx-font-size-md, 1rem);\n --hx-text-font-weight: var(--hx-font-weight-medium, 500);\n --hx-text-line-height: var(--hx-line-height-tight, 1.25);\n --hx-text-letter-spacing: var(--hx-letter-spacing-normal, 0);\n }\n\n .text--label-sm {\n --hx-text-font-size: var(--hx-font-size-sm, 0.875rem);\n --hx-text-font-weight: var(--hx-font-weight-medium, 500);\n --hx-text-line-height: var(--hx-line-height-tight, 1.25);\n --hx-text-letter-spacing: var(--hx-letter-spacing-normal, 0);\n }\n\n .text--caption {\n --hx-text-font-size: var(--hx-font-size-xs, 0.75rem);\n --hx-text-font-weight: var(--hx-font-weight-regular, 400);\n --hx-text-line-height: var(--hx-line-height-normal, 1.5);\n --hx-text-letter-spacing: var(--hx-letter-spacing-normal, 0);\n }\n\n .text--code {\n --hx-text-font-size: var(--hx-font-size-sm, 0.875rem);\n --hx-text-font-weight: var(--hx-font-weight-regular, 400);\n --hx-text-line-height: var(--hx-line-height-normal, 1.5);\n --hx-text-letter-spacing: var(--hx-letter-spacing-normal, 0);\n font-family: var(--hx-font-family-mono, monospace);\n }\n\n .text--overline {\n --hx-text-font-size: var(--hx-font-size-xs, 0.75rem);\n --hx-text-font-weight: var(--hx-font-weight-semibold, 600);\n --hx-text-line-height: var(--hx-line-height-tight, 1.25);\n --hx-text-letter-spacing: var(--hx-letter-spacing-wide, 0.05em);\n text-transform: uppercase;\n }\n\n /* ─── Colors ─── */\n\n .text--color-default {\n --hx-text-color: var(--hx-color-neutral-900, #0f172a);\n }\n\n .text--color-subtle {\n --hx-text-color: var(--hx-color-neutral-500, #64748b);\n }\n\n .text--color-disabled {\n --hx-text-color: var(--hx-color-neutral-400, #94a3b8);\n }\n\n .text--color-inverse {\n --hx-text-color: var(--hx-color-neutral-0, #ffffff);\n }\n\n .text--color-danger {\n --hx-text-color: var(--hx-color-error-600, #dc2626);\n }\n\n .text--color-success {\n --hx-text-color: var(--hx-color-success-600, #16a34a);\n }\n\n .text--color-warning {\n --hx-text-color: var(--hx-color-warning-600, #d97706);\n }\n\n /* ─── Weight Overrides ─── */\n\n .text--weight-regular {\n --hx-text-font-weight: var(--hx-font-weight-regular, 400);\n }\n\n .text--weight-medium {\n --hx-text-font-weight: var(--hx-font-weight-medium, 500);\n }\n\n .text--weight-semibold {\n --hx-text-font-weight: var(--hx-font-weight-semibold, 600);\n }\n\n .text--weight-bold {\n --hx-text-font-weight: var(--hx-font-weight-bold, 700);\n }\n\n /* ─── Truncation ─── */\n\n .text--truncate {\n display: block;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .text--clamp {\n display: -webkit-box;\n -webkit-box-orient: vertical;\n overflow: hidden;\n }\n\n :host([truncate]) {\n display: block;\n }\n\n :host([lines]:not([lines='0'])) {\n display: block;\n }\n`;\n","import { LitElement } from 'lit';\nimport { html as staticHtml, unsafeStatic } from 'lit/static-html.js';\nimport { customElement, property } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { styleMap } from 'lit/directives/style-map.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { tokenStyles } from '@helixui/tokens/lit';\nimport { helixTextStyles } from './hx-text.styles.js';\n\n/**\n * A semantic typography wrapper that applies consistent text styles using design tokens.\n *\n * @summary Presentational text wrapper for consistent typography across variants, weights, and colors.\n *\n * @tag hx-text\n *\n * @slot - Default slot for text content.\n *\n * @csspart base - The inner element (tag determined by the `as` property).\n *\n * @cssprop [--hx-text-font-size] - Font size (set per variant).\n * @cssprop [--hx-text-font-weight] - Font weight (overridden by weight prop).\n * @cssprop [--hx-text-line-height] - Line height (set per variant).\n * @cssprop [--hx-text-letter-spacing] - Letter spacing (set per variant).\n * @cssprop [--hx-text-color] - Text color (set per color prop).\n *\n * @example\n * <!-- Drupal/Twig usage (CDN):\n * <hx-text variant=\"body\" color=\"default\">Patient name here</hx-text>\n * <hx-text variant=\"label\" weight=\"semibold\">Date of Birth</hx-text>\n * <hx-text variant=\"caption\" color=\"subtle\">Last reviewed on 2026-03-05</hx-text>\n * <!-- Truncate (boolean attr — omit to disable, include to enable): -->\n * <hx-text truncate>Long patient note that gets clipped</hx-text>\n * <!-- Multi-line clamp (numeric attr): -->\n * <hx-text lines=\"3\">Paragraph of clinical notes...</hx-text>\n * <!-- Semantic element override: -->\n * <hx-text as=\"p\" variant=\"body\">Paragraph-level content.</hx-text>\n * <hx-text as=\"strong\" variant=\"label\">Bold label</hx-text>\n * -->\n */\n@customElement('hx-text')\nexport class HelixText extends LitElement {\n static override styles = [tokenStyles, helixTextStyles];\n\n /**\n * Typography variant controlling font size, line height, and letter spacing.\n *\n * Note: The public variant set (body / body-sm / body-lg / label / label-sm / caption / code /\n * overline) intentionally extends the original audit spec (body / lead / small / caption /\n * overline). `lead` and `small` were replaced with the more granular `body-lg`, `body-sm`,\n * `label`, `label-sm`, and `code` variants to better serve healthcare UI density requirements.\n * There are no `lead` or `small` variants — consumers must use `body-lg` and `body-sm`\n * respectively.\n *\n * @attr variant\n */\n @property({ type: String, reflect: true })\n variant: 'body' | 'body-sm' | 'body-lg' | 'label' | 'label-sm' | 'caption' | 'code' | 'overline' =\n 'body';\n\n /**\n * Font weight override. When unset, the variant's default weight is used.\n * @attr weight\n */\n @property({ type: String, reflect: true })\n weight: 'regular' | 'medium' | 'semibold' | 'bold' | undefined = undefined;\n\n /**\n * Semantic color intent.\n * @attr color\n */\n @property({ type: String, reflect: true })\n color: 'default' | 'subtle' | 'disabled' | 'inverse' | 'danger' | 'success' | 'warning' =\n 'default';\n\n /**\n * When true, clips text to a single line with an ellipsis overflow.\n * @attr truncate\n */\n @property({ type: Boolean, reflect: true })\n truncate = false;\n\n /**\n * Maximum number of lines to display before clamping with ellipsis.\n * When set, overrides `truncate`. Set to 0 to disable.\n * @attr lines\n */\n @property({ type: Number, reflect: true })\n lines = 0;\n\n /**\n * The HTML element to render as the inner base element.\n * Use to produce semantically appropriate markup (e.g., `p`, `strong`, `em`).\n * Defaults to `span` for inline usage.\n *\n * In Drupal Twig: `<hx-text as=\"p\" variant=\"body\">...</hx-text>`\n *\n * @attr as\n */\n @property({ type: String, reflect: true })\n as: 'span' | 'p' | 'strong' | 'em' | 'div' = 'span';\n\n /** Validates `as` against the allowed element list to prevent injection. */\n private get _safeTag(): string {\n const allowed = new Set(['span', 'p', 'strong', 'em', 'div']);\n return allowed.has(this.as) ? this.as : 'span';\n }\n\n override render() {\n const effectiveLines = Math.max(0, this.lines);\n const isTruncated = this.truncate && effectiveLines === 0;\n const isClamped = effectiveLines > 0;\n const classes = {\n text: true,\n [`text--${this.variant}`]: true,\n [`text--color-${this.color}`]: true,\n [`text--weight-${this.weight}`]: this.weight !== undefined,\n 'text--truncate': isTruncated,\n 'text--clamp': isClamped,\n };\n\n const inlineStyles = isClamped ? { '-webkit-line-clamp': String(effectiveLines) } : {};\n\n const titleText = isTruncated || isClamped ? this.textContent?.trim() : undefined;\n\n const tag = unsafeStatic(this._safeTag);\n\n return staticHtml`\n <${tag}\n part=\"base\"\n class=${classMap(classes)}\n style=${styleMap(inlineStyles)}\n title=${ifDefined(titleText || undefined)}\n >\n <slot></slot>\n </${tag}>\n `;\n }\n}\n\n/** @deprecated Use `HelixText` directly. Kept for backward compatibility. */\nexport type WcText = HelixText;\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-text': HelixText;\n }\n}\n"],"names":["helixTextStyles","css","HelixText","LitElement","effectiveLines","isTruncated","isClamped","classes","inlineStyles","titleText","_a","tag","unsafeStatic","staticHtml","classMap","styleMap","ifDefined","tokenStyles","__decorateClass","property","customElement"],"mappings":";;;;;;;AAEO,MAAMA,IAAkBC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;ACuCxB,IAAMC,IAAN,cAAwBC,EAAW;AAAA,EAAnC,cAAA;AAAA,UAAA,GAAA,SAAA,GAgBL,KAAA,UACE,QAOF,KAAA,SAAiE,QAOjE,KAAA,QACE,WAOF,KAAA,WAAW,IAQX,KAAA,QAAQ,GAYR,KAAA,KAA6C;AAAA,EAAA;AAAA;AAAA,EAG7C,IAAY,WAAmB;AAE7B,gCADoB,IAAI,CAAC,QAAQ,KAAK,UAAU,MAAM,KAAK,CAAC,GAC7C,IAAI,KAAK,EAAE,IAAI,KAAK,KAAK;AAAA,EAC1C;AAAA,EAES,SAAS;;AAChB,UAAMC,IAAiB,KAAK,IAAI,GAAG,KAAK,KAAK,GACvCC,IAAc,KAAK,YAAYD,MAAmB,GAClDE,IAAYF,IAAiB,GAC7BG,IAAU;AAAA,MACd,MAAM;AAAA,MACN,CAAC,SAAS,KAAK,OAAO,EAAE,GAAG;AAAA,MAC3B,CAAC,eAAe,KAAK,KAAK,EAAE,GAAG;AAAA,MAC/B,CAAC,gBAAgB,KAAK,MAAM,EAAE,GAAG,KAAK,WAAW;AAAA,MACjD,kBAAkBF;AAAA,MAClB,eAAeC;AAAA,IAAA,GAGXE,IAAeF,IAAY,EAAE,sBAAsB,OAAOF,CAAc,EAAA,IAAM,CAAA,GAE9EK,IAAYJ,KAAeC,KAAYI,IAAA,KAAK,gBAAL,gBAAAA,EAAkB,SAAS,QAElEC,IAAMC,EAAa,KAAK,QAAQ;AAEtC,WAAOC;AAAAA,SACFF,CAAG;AAAA;AAAA,gBAEIG,EAASP,CAAO,CAAC;AAAA,gBACjBQ,EAASP,CAAY,CAAC;AAAA,gBACtBQ,EAAUP,KAAa,MAAS,CAAC;AAAA;AAAA;AAAA,UAGvCE,CAAG;AAAA;AAAA,EAEX;AACF;AAjGaT,EACK,SAAS,CAACe,GAAajB,CAAe;AAetDkB,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,QAAQ,SAAS,IAAM;AAAA,GAf9BjB,EAgBX,WAAA,WAAA,CAAA;AAQAgB,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,QAAQ,SAAS,IAAM;AAAA,GAvB9BjB,EAwBX,WAAA,UAAA,CAAA;AAOAgB,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,QAAQ,SAAS,IAAM;AAAA,GA9B9BjB,EA+BX,WAAA,SAAA,CAAA;AAQAgB,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,SAAS,SAAS,IAAM;AAAA,GAtC/BjB,EAuCX,WAAA,YAAA,CAAA;AAQAgB,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,QAAQ,SAAS,IAAM;AAAA,GA9C9BjB,EA+CX,WAAA,SAAA,CAAA;AAYAgB,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,QAAQ,SAAS,IAAM;AAAA,GA1D9BjB,EA2DX,WAAA,MAAA,CAAA;AA3DWA,IAANgB,EAAA;AAAA,EADNE,EAAc,SAAS;AAAA,GACXlB,CAAA;"}
|
|
1
|
+
{"version":3,"file":"hx-text-NjKoQATI.js","sources":["../../src/components/hx-text/hx-text.styles.ts","../../src/components/hx-text/hx-text.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixTextStyles = css`\n :host {\n display: inline;\n }\n\n /* ─── Base ─── */\n\n .text {\n display: inline;\n font-family: var(--hx-font-family-sans, sans-serif);\n font-size: var(--hx-text-font-size);\n font-weight: var(--hx-text-font-weight);\n line-height: var(--hx-text-line-height);\n letter-spacing: var(--hx-text-letter-spacing);\n color: var(--hx-text-color);\n margin: 0;\n padding: 0;\n }\n\n /* ─── Variants ─── */\n\n .text--body {\n --hx-text-font-size: var(--hx-font-size-md, 1rem);\n --hx-text-font-weight: var(--hx-font-weight-regular, 400);\n --hx-text-line-height: var(--hx-line-height-normal, 1.5);\n --hx-text-letter-spacing: var(--hx-letter-spacing-normal, 0);\n }\n\n .text--body-sm {\n --hx-text-font-size: var(--hx-font-size-sm, 0.875rem);\n --hx-text-font-weight: var(--hx-font-weight-regular, 400);\n --hx-text-line-height: var(--hx-line-height-normal, 1.5);\n --hx-text-letter-spacing: var(--hx-letter-spacing-normal, 0);\n }\n\n .text--body-lg {\n --hx-text-font-size: var(--hx-font-size-lg, 1.125rem);\n --hx-text-font-weight: var(--hx-font-weight-regular, 400);\n --hx-text-line-height: var(--hx-line-height-normal, 1.5);\n --hx-text-letter-spacing: var(--hx-letter-spacing-normal, 0);\n }\n\n .text--label {\n --hx-text-font-size: var(--hx-font-size-md, 1rem);\n --hx-text-font-weight: var(--hx-font-weight-medium, 500);\n --hx-text-line-height: var(--hx-line-height-tight, 1.25);\n --hx-text-letter-spacing: var(--hx-letter-spacing-normal, 0);\n }\n\n .text--label-sm {\n --hx-text-font-size: var(--hx-font-size-sm, 0.875rem);\n --hx-text-font-weight: var(--hx-font-weight-medium, 500);\n --hx-text-line-height: var(--hx-line-height-tight, 1.25);\n --hx-text-letter-spacing: var(--hx-letter-spacing-normal, 0);\n }\n\n .text--caption {\n --hx-text-font-size: var(--hx-font-size-xs, 0.75rem);\n --hx-text-font-weight: var(--hx-font-weight-regular, 400);\n --hx-text-line-height: var(--hx-line-height-normal, 1.5);\n --hx-text-letter-spacing: var(--hx-letter-spacing-normal, 0);\n }\n\n .text--code {\n --hx-text-font-size: var(--hx-font-size-sm, 0.875rem);\n --hx-text-font-weight: var(--hx-font-weight-regular, 400);\n --hx-text-line-height: var(--hx-line-height-normal, 1.5);\n --hx-text-letter-spacing: var(--hx-letter-spacing-normal, 0);\n font-family: var(--hx-font-family-mono, monospace);\n }\n\n .text--overline {\n --hx-text-font-size: var(--hx-font-size-xs, 0.75rem);\n --hx-text-font-weight: var(--hx-font-weight-semibold, 600);\n --hx-text-line-height: var(--hx-line-height-tight, 1.25);\n --hx-text-letter-spacing: var(--hx-letter-spacing-wide, 0.05em);\n text-transform: uppercase;\n }\n\n /* ─── Colors ─── */\n\n .text--color-default {\n --hx-text-color: var(--hx-color-neutral-900, #0f172a);\n }\n\n .text--color-subtle {\n --hx-text-color: var(--hx-color-neutral-500, #64748b);\n }\n\n .text--color-disabled {\n --hx-text-color: var(--hx-color-neutral-400, #94a3b8);\n }\n\n .text--color-inverse {\n --hx-text-color: var(--hx-color-neutral-0, #ffffff);\n }\n\n .text--color-danger {\n --hx-text-color: var(--hx-color-error-600, #dc2626);\n }\n\n .text--color-success {\n --hx-text-color: var(--hx-color-success-600, #16a34a);\n }\n\n .text--color-warning {\n --hx-text-color: var(--hx-color-warning-600, #d97706);\n }\n\n /* ─── Weight Overrides ─── */\n\n .text--weight-regular {\n --hx-text-font-weight: var(--hx-font-weight-regular, 400);\n }\n\n .text--weight-medium {\n --hx-text-font-weight: var(--hx-font-weight-medium, 500);\n }\n\n .text--weight-semibold {\n --hx-text-font-weight: var(--hx-font-weight-semibold, 600);\n }\n\n .text--weight-bold {\n --hx-text-font-weight: var(--hx-font-weight-bold, 700);\n }\n\n /* ─── Truncation ─── */\n\n .text--truncate {\n display: block;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .text--clamp {\n display: -webkit-box;\n -webkit-box-orient: vertical;\n overflow: hidden;\n }\n\n :host([truncate]) {\n display: block;\n }\n\n :host([lines]:not([lines='0'])) {\n display: block;\n }\n`;\n","import { LitElement } from 'lit';\nimport { html as staticHtml, unsafeStatic } from 'lit/static-html.js';\nimport { customElement, property } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { styleMap } from 'lit/directives/style-map.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { tokenStyles } from '@helixui/tokens/lit';\nimport { helixTextStyles } from './hx-text.styles.js';\n\n/**\n * A semantic typography wrapper that applies consistent text styles using design tokens.\n *\n * @summary Presentational text wrapper for consistent typography across variants, weights, and colors.\n *\n * @tag hx-text\n *\n * @slot - Default slot for text content.\n *\n * @csspart base - The inner element (tag determined by the `as` property).\n *\n * @cssprop [--hx-text-font-size] - Font size (set per variant).\n * @cssprop [--hx-text-font-weight] - Font weight (overridden by weight prop).\n * @cssprop [--hx-text-line-height] - Line height (set per variant).\n * @cssprop [--hx-text-letter-spacing] - Letter spacing (set per variant).\n * @cssprop [--hx-text-color] - Text color (set per color prop).\n *\n * @example\n * <!-- Drupal/Twig usage (CDN):\n * <hx-text variant=\"body\" color=\"default\">Patient name here</hx-text>\n * <hx-text variant=\"label\" weight=\"semibold\">Date of Birth</hx-text>\n * <hx-text variant=\"caption\" color=\"subtle\">Last reviewed on 2026-03-05</hx-text>\n * <!-- Truncate (boolean attr — omit to disable, include to enable): -->\n * <hx-text truncate>Long patient note that gets clipped</hx-text>\n * <!-- Multi-line clamp (numeric attr): -->\n * <hx-text lines=\"3\">Paragraph of clinical notes...</hx-text>\n * <!-- Semantic element override: -->\n * <hx-text as=\"p\" variant=\"body\">Paragraph-level content.</hx-text>\n * <hx-text as=\"strong\" variant=\"label\">Bold label</hx-text>\n * -->\n */\n@customElement('hx-text')\nexport class HelixText extends LitElement {\n static override styles = [tokenStyles, helixTextStyles];\n\n /**\n * Typography variant controlling font size, line height, and letter spacing.\n *\n * Note: The public variant set (body / body-sm / body-lg / label / label-sm / caption / code /\n * overline) intentionally extends the original audit spec (body / lead / small / caption /\n * overline). `lead` and `small` were replaced with the more granular `body-lg`, `body-sm`,\n * `label`, `label-sm`, and `code` variants to better serve healthcare UI density requirements.\n * There are no `lead` or `small` variants — consumers must use `body-lg` and `body-sm`\n * respectively.\n *\n * @attr variant\n */\n @property({ type: String, reflect: true })\n variant: 'body' | 'body-sm' | 'body-lg' | 'label' | 'label-sm' | 'caption' | 'code' | 'overline' =\n 'body';\n\n /**\n * Font weight override. When unset, the variant's default weight is used.\n * @attr weight\n */\n @property({ type: String, reflect: true })\n weight: 'regular' | 'medium' | 'semibold' | 'bold' | undefined = undefined;\n\n /**\n * Semantic color intent.\n * @attr color\n */\n @property({ type: String, reflect: true })\n color: 'default' | 'subtle' | 'disabled' | 'inverse' | 'danger' | 'success' | 'warning' =\n 'default';\n\n /**\n * When true, clips text to a single line with an ellipsis overflow.\n * @attr truncate\n */\n @property({ type: Boolean, reflect: true })\n truncate = false;\n\n /**\n * Maximum number of lines to display before clamping with ellipsis.\n * When set, overrides `truncate`. Set to 0 to disable.\n * @attr lines\n */\n @property({ type: Number, reflect: true })\n lines = 0;\n\n /**\n * The HTML element to render as the inner base element.\n * Use to produce semantically appropriate markup (e.g., `p`, `strong`, `em`).\n * Defaults to `span` for inline usage.\n *\n * In Drupal Twig: `<hx-text as=\"p\" variant=\"body\">...</hx-text>`\n *\n * @attr as\n */\n @property({ type: String, reflect: true })\n as: 'span' | 'p' | 'strong' | 'em' | 'div' = 'span';\n\n /** Validates `as` against the allowed element list to prevent injection. */\n private get _safeTag(): string {\n const allowed = new Set(['span', 'p', 'strong', 'em', 'div']);\n return allowed.has(this.as) ? this.as : 'span';\n }\n\n override render() {\n const effectiveLines = Math.max(0, this.lines);\n const isTruncated = this.truncate && effectiveLines === 0;\n const isClamped = effectiveLines > 0;\n const classes = {\n text: true,\n [`text--${this.variant}`]: true,\n [`text--color-${this.color}`]: true,\n [`text--weight-${this.weight}`]: this.weight !== undefined,\n 'text--truncate': isTruncated,\n 'text--clamp': isClamped,\n };\n\n const inlineStyles = isClamped ? { '-webkit-line-clamp': String(effectiveLines) } : {};\n\n const titleText = isTruncated || isClamped ? this.textContent?.trim() : undefined;\n\n const tag = unsafeStatic(this._safeTag);\n\n return staticHtml`\n <${tag}\n part=\"base\"\n class=${classMap(classes)}\n style=${styleMap(inlineStyles)}\n title=${ifDefined(titleText || undefined)}\n >\n <slot></slot>\n </${tag}>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-text': HelixText;\n }\n}\n"],"names":["helixTextStyles","css","HelixText","LitElement","effectiveLines","isTruncated","isClamped","classes","inlineStyles","titleText","_a","tag","unsafeStatic","staticHtml","classMap","styleMap","ifDefined","tokenStyles","__decorateClass","property","customElement"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { css as c, LitElement as f, nothing as d, html as o } from "lit";
|
|
2
|
-
import { property as i, query as v, state as
|
|
2
|
+
import { property as i, query as v, state as x, customElement as _ } from "lit/decorators.js";
|
|
3
3
|
import { classMap as g } from "lit/directives/class-map.js";
|
|
4
4
|
import { ifDefined as h } from "lit/directives/if-defined.js";
|
|
5
5
|
import { live as b } from "lit/directives/live.js";
|
|
@@ -160,13 +160,13 @@ const y = c`
|
|
|
160
160
|
}
|
|
161
161
|
`;
|
|
162
162
|
var w = Object.defineProperty, $ = Object.getOwnPropertyDescriptor, a = (e, t, l, n) => {
|
|
163
|
-
for (var s = n > 1 ? void 0 : n ? $(t, l) : t, p = e.length - 1,
|
|
164
|
-
(
|
|
163
|
+
for (var s = n > 1 ? void 0 : n ? $(t, l) : t, p = e.length - 1, u; p >= 0; p--)
|
|
164
|
+
(u = e[p]) && (s = (n ? u(t, l, s) : u(s)) || s);
|
|
165
165
|
return n && s && w(t, l, s), s;
|
|
166
166
|
};
|
|
167
167
|
let S = 0, r = class extends f {
|
|
168
168
|
constructor() {
|
|
169
|
-
super(), this.label = "", this.placeholder = "", this.value = "", this.required = !1, this.disabled = !1, this.error = "", this.helpText = "", this.name = "", this.rows = 4, this.resize = "vertical", this.showCount = !1, this.ariaLabel = null, this._hasLabelSlot = !1, this._hasErrorSlot = !1, this._hasHelpTextSlot = !1, this._textareaId = `hx-textarea-${++S}`, this._helpTextId = `${this._textareaId}-help`, this._errorId = `${this._textareaId}-error`, this._counterId = `${this._textareaId}-counter`, this._internals = this.attachInternals();
|
|
169
|
+
super(), this.label = "", this.placeholder = "", this.value = "", this.required = !1, this.disabled = !1, this.error = "", this.helpText = "", this.name = "", this.rows = 4, this.readonly = !1, this.resize = "vertical", this.showCount = !1, this.ariaLabel = null, this._hasLabelSlot = !1, this._hasErrorSlot = !1, this._hasHelpTextSlot = !1, this._textareaId = `hx-textarea-${++S}`, this._helpTextId = `${this._textareaId}-help`, this._errorId = `${this._textareaId}-error`, this._counterId = `${this._textareaId}-counter`, this._internals = this.attachInternals();
|
|
170
170
|
}
|
|
171
171
|
/** @internal */
|
|
172
172
|
_handleLabelSlotChange(e) {
|
|
@@ -317,6 +317,7 @@ let S = 0, r = class extends f {
|
|
|
317
317
|
placeholder=${h(this.placeholder || void 0)}
|
|
318
318
|
?required=${this.required}
|
|
319
319
|
?disabled=${this.disabled}
|
|
320
|
+
?readonly=${this.readonly}
|
|
320
321
|
rows=${this.rows}
|
|
321
322
|
minlength=${h(this.minlength)}
|
|
322
323
|
maxlength=${h(this.maxlength)}
|
|
@@ -384,6 +385,9 @@ a([
|
|
|
384
385
|
a([
|
|
385
386
|
i({ type: Number, attribute: "maxlength" })
|
|
386
387
|
], r.prototype, "maxlength", 2);
|
|
388
|
+
a([
|
|
389
|
+
i({ type: Boolean, reflect: !0 })
|
|
390
|
+
], r.prototype, "readonly", 2);
|
|
387
391
|
a([
|
|
388
392
|
i({ type: String, reflect: !0 })
|
|
389
393
|
], r.prototype, "resize", 2);
|
|
@@ -397,13 +401,13 @@ a([
|
|
|
397
401
|
v(".field__textarea")
|
|
398
402
|
], r.prototype, "_textarea", 2);
|
|
399
403
|
a([
|
|
400
|
-
|
|
404
|
+
x()
|
|
401
405
|
], r.prototype, "_hasLabelSlot", 2);
|
|
402
406
|
a([
|
|
403
|
-
|
|
407
|
+
x()
|
|
404
408
|
], r.prototype, "_hasErrorSlot", 2);
|
|
405
409
|
a([
|
|
406
|
-
|
|
410
|
+
x()
|
|
407
411
|
], r.prototype, "_hasHelpTextSlot", 2);
|
|
408
412
|
r = a([
|
|
409
413
|
_("hx-textarea")
|
|
@@ -411,4 +415,4 @@ r = a([
|
|
|
411
415
|
export {
|
|
412
416
|
r as H
|
|
413
417
|
};
|
|
414
|
-
//# sourceMappingURL=hx-textarea-
|
|
418
|
+
//# sourceMappingURL=hx-textarea-B_nmxzhC.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hx-textarea-B_nmxzhC.js","sources":["../../src/components/hx-textarea/hx-textarea.styles.ts","../../src/components/hx-textarea/hx-textarea.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixTextareaStyles = 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 .field {\n display: flex;\n flex-direction: column;\n gap: var(--hx-space-1, 0.25rem);\n font-family: var(--hx-input-font-family, var(--hx-font-family-sans, sans-serif));\n }\n\n /* --- Label --- */\n\n .field__label-wrapper {\n display: contents;\n }\n\n .field__label {\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-input-label-color, var(--hx-color-neutral-700, #343a40));\n line-height: var(--hx-line-height-normal, 1.5);\n }\n\n .field__required-marker {\n color: var(--hx-input-error-color, var(--hx-color-error-text, #b91c1c));\n font-weight: var(--hx-font-weight-bold, 700);\n }\n\n /* --- Textarea Wrapper --- */\n\n .field__textarea-wrapper {\n display: flex;\n flex-direction: column;\n border: var(--hx-border-width-thin, 1px) solid\n var(--hx-input-border-color, var(--hx-color-neutral-300, #ced4da));\n border-radius: var(--hx-input-border-radius, var(--hx-border-radius-md, 0.375rem));\n background-color: var(--hx-input-bg, var(--hx-color-neutral-0, #ffffff));\n transition:\n border-color var(--hx-transition-fast, 150ms ease),\n box-shadow var(--hx-transition-fast, 150ms ease);\n overflow: hidden;\n }\n\n .field__textarea-wrapper:focus-within {\n border-color: var(--hx-input-focus-ring-color, var(--hx-focus-ring-color, #2563eb));\n /* Solid fallback for browsers without color-mix() (Chrome < 111, Safari < 16.2) — WCAG 1.4.11 */\n box-shadow: 0 0 0 var(--hx-focus-ring-width, 2px)\n rgba(37, 99, 235, var(--hx-focus-ring-opacity, 0.25));\n box-shadow: 0 0 0 var(--hx-focus-ring-width, 2px)\n color-mix(\n in srgb,\n var(--hx-input-focus-ring-color, var(--hx-focus-ring-color, #2563eb))\n calc(var(--hx-focus-ring-opacity, 0.25) * 100%),\n transparent\n );\n }\n\n /* --- Error State --- */\n\n .field--error .field__textarea-wrapper {\n border-color: var(--hx-input-error-color, var(--hx-color-error-500, #dc3545));\n }\n\n .field--error .field__textarea-wrapper:focus-within {\n border-color: var(--hx-input-error-color, var(--hx-color-error-500, #dc3545));\n /* Solid fallback for browsers without color-mix() — WCAG 1.4.11 */\n box-shadow: 0 0 0 var(--hx-focus-ring-width, 2px)\n rgba(220, 53, 69, var(--hx-focus-ring-opacity, 0.25));\n box-shadow: 0 0 0 var(--hx-focus-ring-width, 2px)\n color-mix(\n in srgb,\n var(--hx-input-error-color, var(--hx-color-error-500, #dc3545))\n calc(var(--hx-focus-ring-opacity, 0.25) * 100%),\n transparent\n );\n }\n\n /* --- Native Textarea --- */\n\n .field__textarea {\n border: none;\n outline: none;\n background: transparent;\n padding: var(--hx-space-2, 0.5rem) var(--hx-space-3, 0.75rem);\n font-family: inherit;\n font-size: var(--hx-font-size-md, 1rem);\n color: var(--hx-input-color, var(--hx-color-neutral-800, #212529));\n line-height: var(--hx-line-height-normal, 1.5);\n min-height: var(--hx-textarea-min-height, var(--hx-size-20, 5rem));\n width: 100%;\n resize: vertical;\n }\n\n .field__textarea::placeholder {\n color: var(--hx-color-neutral-400, #adb5bd);\n }\n\n .field__textarea:disabled {\n cursor: not-allowed;\n }\n\n /* --- Resize Variants --- */\n\n :host([resize='none']) .field__textarea {\n resize: none;\n }\n\n /* resize: vertical is the base default — no override needed for [resize='vertical'] */\n\n :host([resize='both']) .field__textarea {\n resize: both;\n }\n\n :host([resize='auto']) .field__textarea {\n resize: none;\n overflow: hidden;\n }\n\n /* --- Character Counter --- */\n\n .field__counter {\n font-size: var(--hx-font-size-xs, 0.75rem);\n color: var(--hx-color-neutral-500, #6c757d);\n line-height: var(--hx-line-height-normal, 1.5);\n text-align: right;\n }\n\n /* --- Help Text & Error Messages --- */\n\n .field__help-text {\n font-size: var(--hx-font-size-xs, 0.75rem);\n color: var(--hx-color-neutral-500, #6c757d);\n line-height: var(--hx-line-height-normal, 1.5);\n }\n\n .field__error {\n font-size: var(--hx-font-size-xs, 0.75rem);\n color: var(--hx-input-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 } from 'lit';\nimport { customElement, property, query, state } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { live } from 'lit/directives/live.js';\nimport { tokenStyles } from '@helixui/tokens/lit';\nimport { helixTextareaStyles } from './hx-textarea.styles.js';\n\n// Module-level counter for stable, SSR-safe IDs (avoids Math.random() hydration mismatch)\nlet _hxTextareaIdCounter = 0;\n\n/**\n * A multi-line text area component with label, validation, and form association.\n *\n * Uses `aria-invalid` to convey error state and `aria-describedby` to link\n * error/help text to the textarea. Label association is handled through\n * `aria-labelledby` (for slotted labels) or the standard `<label for>` pattern.\n * Supports `aria-label` for cases where a visible label is not present.\n * Validation errors are announced via `role=\"alert\"` (assertive live region).\n *\n * @summary Form-associated textarea with built-in label, error, help text, character counter, and auto-resize.\n *\n * @tag hx-textarea\n *\n * @slot label - Custom label content (overrides the label property). Use for Drupal Form API rendered labels.\n * @slot help-text - Custom help text content (overrides the helpText property).\n * @slot error - Custom error content (overrides the error property). Use for Drupal Form API rendered errors.\n *\n * @fires {CustomEvent<{value: string}>} hx-input - Dispatched on every keystroke as the user types.\n * @fires {CustomEvent<{value: string}>} hx-change - Dispatched when the textarea loses focus after its value changed.\n *\n * @csspart field - The outer field container.\n * @csspart label - The label element.\n * @csspart textarea-wrapper - The wrapper around the textarea.\n * @csspart textarea - The native textarea element.\n * @csspart counter - The character count display.\n * @csspart help-text - The help text container.\n * @csspart error - The error message container.\n *\n * @cssprop [--hx-input-bg=var(--hx-color-neutral-0)] - Input background color.\n * @cssprop [--hx-input-color=var(--hx-color-neutral-800)] - Input text color.\n * @cssprop [--hx-input-border-color=var(--hx-color-neutral-300)] - Input border color.\n * @cssprop [--hx-input-border-radius=var(--hx-border-radius-md)] - Input border radius.\n * @cssprop [--hx-input-font-family=var(--hx-font-family-sans)] - Input font family.\n * @cssprop [--hx-input-focus-ring-color=var(--hx-focus-ring-color)] - Focus ring color.\n * @cssprop [--hx-input-error-color=var(--hx-color-error-500)] - Error state color.\n * @cssprop [--hx-input-label-color=var(--hx-color-neutral-700)] - Label text color.\n * @cssprop [--hx-textarea-min-height=var(--hx-size-20, 5rem)] - Minimum textarea height.\n */\n@customElement('hx-textarea')\nexport class HelixTextarea extends LitElement {\n static override styles = [tokenStyles, helixTextareaStyles];\n\n // ─── Form Association ───\n\n /** Enables the element to participate in form submission and validation. */\n static formAssociated = true;\n\n /** ElementInternals instance for form association, validation, and ARIA. */\n private _internals: ElementInternals;\n\n constructor() {\n super();\n this._internals = this.attachInternals();\n }\n\n // ─── Properties ───\n\n /**\n * The visible label text for the textarea.\n * @attr label\n */\n @property({ type: String })\n label = '';\n\n /**\n * Placeholder text shown when the textarea is empty.\n * @attr placeholder\n */\n @property({ type: String })\n placeholder = '';\n\n /**\n * The current value of the textarea.\n * @attr value\n */\n @property({ type: String })\n value = '';\n\n /**\n * Whether the textarea is required for form submission.\n * @attr required\n */\n @property({ type: Boolean, reflect: true })\n required = false;\n\n /**\n * Whether the textarea 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 textarea enters an error state.\n * @attr error\n */\n @property({ type: String })\n error = '';\n\n /**\n * Help text displayed below the textarea for guidance.\n * @attr help-text\n */\n @property({ type: String, attribute: 'help-text' })\n helpText = '';\n\n /**\n * The name of the textarea, used for form submission.\n * @attr name\n */\n @property({ type: String })\n name = '';\n\n /**\n * The number of visible text rows. Must be a positive integer (minimum 1).\n * Invalid values are clamped to the nearest valid value.\n * @attr rows\n */\n @property({ type: Number })\n rows = 4;\n\n /**\n * Minimum number of characters required.\n * @attr minlength\n */\n @property({ type: Number, attribute: 'minlength' })\n minlength: number | undefined;\n\n /**\n * Maximum number of characters allowed.\n * @attr maxlength\n */\n @property({ type: Number, attribute: 'maxlength' })\n maxlength: number | undefined;\n\n /**\n * Whether the textarea is read-only. Read-only fields are visible but\n * cannot be edited by the user. Common in healthcare for displaying\n * non-editable patient data inline with editable fields.\n * @attr readonly\n */\n @property({ type: Boolean, reflect: true })\n readonly = false;\n\n /**\n * Controls how the textarea can be resized. Use 'auto' for auto-grow behavior.\n * @attr resize\n */\n @property({ type: String, reflect: true })\n resize: 'none' | 'vertical' | 'both' | 'auto' = 'vertical';\n\n /**\n * Whether to show a character count below the textarea.\n * @attr show-count\n */\n @property({ type: Boolean, attribute: 'show-count' })\n showCount = false;\n\n /**\n * Accessible name for screen readers, if different from the visible label.\n * @attr aria-label\n */\n @property({ type: String, attribute: 'aria-label' })\n override ariaLabel: string | null = null;\n\n // ─── Internal References ───\n\n /** @internal */\n @query('.field__textarea')\n private _textarea: HTMLTextAreaElement | undefined;\n\n // ─── Slot Tracking ───\n\n /** @internal */\n @state() private _hasLabelSlot = false;\n /** @internal */\n @state() private _hasErrorSlot = false;\n /** @internal */\n @state() private _hasHelpTextSlot = false;\n\n /** @internal */\n private _handleLabelSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n this._hasLabelSlot = slot.assignedElements().length > 0;\n if (this._hasLabelSlot) {\n const slottedLabel = slot.assignedElements()[0];\n if (slottedLabel && !slottedLabel.id) {\n slottedLabel.id = `${this._textareaId}-slotted-label`;\n }\n }\n }\n\n /** @internal */\n private _handleErrorSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n this._hasErrorSlot = slot.assignedElements().length > 0;\n }\n\n /** @internal */\n private _handleHelpTextSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n this._hasHelpTextSlot = slot.assignedElements().length > 0;\n }\n\n // ─── Lifecycle ───\n\n override updated(changedProperties: Map<string, unknown>): void {\n super.updated(changedProperties);\n if (changedProperties.has('rows')) {\n const clamped = Math.max(1, Math.round(this.rows));\n if (clamped !== this.rows) {\n this.rows = clamped;\n }\n }\n if (changedProperties.has('value')) {\n this._internals.setFormValue(this.value);\n }\n if (\n changedProperties.has('value') ||\n changedProperties.has('required') ||\n changedProperties.has('minlength') ||\n changedProperties.has('maxlength')\n ) {\n this._updateValidity();\n }\n // Auto-grow: respond to programmatic value changes\n if (changedProperties.has('value') && this.resize === 'auto' && this._textarea) {\n this._textarea.style.height = 'auto';\n this._textarea.style.height = `${this._textarea.scrollHeight}px`;\n }\n }\n\n // ─── Form Integration ───\n\n /** Returns the associated form element, if any. */\n get form(): HTMLFormElement | null {\n return this._internals.form;\n }\n\n /** Returns the validation message. */\n get validationMessage(): string {\n return this._internals.validationMessage;\n }\n\n /** Returns the ValidityState object. */\n get validity(): ValidityState {\n return this._internals.validity;\n }\n\n /** Checks whether the textarea 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 const anchor = this._textarea ?? undefined;\n if (this.required && !this.value) {\n this._internals.setValidity(\n { valueMissing: true },\n this.error || 'This field is required.',\n anchor,\n );\n } else if (\n this.minlength !== undefined &&\n this.value.length > 0 &&\n this.value.length < this.minlength\n ) {\n this._internals.setValidity(\n { tooShort: true },\n this.error || `Value must be at least ${this.minlength} characters.`,\n anchor,\n );\n } else if (this.maxlength !== undefined && this.value.length > this.maxlength) {\n this._internals.setValidity(\n { tooLong: true },\n this.error || `Value must be ${this.maxlength} characters or fewer.`,\n anchor,\n );\n } else {\n this._internals.setValidity({});\n }\n }\n\n /** Called by the browser when the owning form is reset. */\n formResetCallback(): void {\n this.value = '';\n this._internals.setFormValue('');\n }\n\n /** Called by the browser to restore form state (e.g., back/forward navigation). */\n formStateRestoreCallback(state: string): void {\n this.value = state;\n }\n\n // ─── Event Handling ───\n\n /** @internal */\n private _handleInput(e: Event): void {\n const target = e.target as HTMLTextAreaElement;\n this.value = target.value;\n // Note: setFormValue is called in updated() via the value change — no double-call here (P1-06 fix)\n\n // Auto-grow: reset height then set to scrollHeight\n if (this.resize === 'auto') {\n target.style.height = 'auto';\n target.style.height = `${target.scrollHeight}px`;\n }\n\n /**\n * Dispatched on every keystroke as the user types.\n * @event hx-input\n */\n this.dispatchEvent(\n new CustomEvent('hx-input', {\n bubbles: true,\n composed: true,\n detail: { value: this.value },\n }),\n );\n }\n\n /** @internal */\n private _handleChange(e: Event): void {\n const target = e.target as HTMLTextAreaElement;\n this.value = target.value;\n this._internals.setFormValue(this.value);\n this._updateValidity();\n\n /**\n * Dispatched when the textarea loses focus after its value changed.\n * @event hx-change\n */\n this.dispatchEvent(\n new CustomEvent('hx-change', {\n bubbles: true,\n composed: true,\n detail: { value: this.value },\n }),\n );\n }\n\n // ─── Public Methods ───\n\n /** Moves focus to the textarea element. */\n override focus(options?: FocusOptions): void {\n this._textarea?.focus(options);\n }\n\n /** Selects all text in the textarea. */\n select(): void {\n this._textarea?.select();\n }\n\n // ─── Render ───\n\n /** @internal */\n private _textareaId = `hx-textarea-${++_hxTextareaIdCounter}`;\n /** @internal */\n private _helpTextId = `${this._textareaId}-help`;\n /** @internal */\n private _errorId = `${this._textareaId}-error`;\n /** @internal */\n private _counterId = `${this._textareaId}-counter`;\n\n /** @internal */\n private _renderCounter() {\n if (!this.showCount) return nothing;\n\n const count = this.value.length;\n const display = this.maxlength !== undefined ? `${count} / ${this.maxlength}` : `${count}`;\n\n return html`\n <div part=\"counter\" class=\"field__counter\" id=${this._counterId} aria-live=\"polite\">\n ${display}\n </div>\n `;\n }\n\n override render() {\n const hasError = !!this.error || this._hasErrorSlot;\n\n const fieldClasses = {\n field: true,\n 'field--error': hasError,\n 'field--disabled': this.disabled,\n 'field--required': this.required,\n };\n\n // P0-02 fix: help text container renders when slot is used OR property is set\n const hasHelpText = (!!this.helpText || this._hasHelpTextSlot) && !hasError;\n\n const describedBy =\n [\n hasError ? this._errorId : null,\n hasHelpText ? this._helpTextId : null,\n this.showCount ? this._counterId : null,\n ]\n .filter(Boolean)\n .join(' ') || undefined;\n\n return html`\n <div part=\"field\" class=${classMap(fieldClasses)}>\n <div class=\"field__label-wrapper\">\n <slot name=\"label\" @slotchange=${this._handleLabelSlotChange}>\n ${this.label\n ? html`\n <label part=\"label\" class=\"field__label\" for=${this._textareaId}>\n ${this.label}\n ${this.required\n ? html`<span class=\"field__required-marker\" aria-hidden=\"true\">*</span>`\n : nothing}\n </label>\n `\n : nothing}\n </slot>\n </div>\n\n <div part=\"textarea-wrapper\" class=\"field__textarea-wrapper\">\n <textarea\n part=\"textarea\"\n class=\"field__textarea\"\n id=${this._textareaId}\n .value=${live(this.value)}\n placeholder=${ifDefined(this.placeholder || undefined)}\n ?required=${this.required}\n ?disabled=${this.disabled}\n ?readonly=${this.readonly}\n rows=${this.rows}\n minlength=${ifDefined(this.minlength)}\n maxlength=${ifDefined(this.maxlength)}\n name=${ifDefined(this.name || undefined)}\n aria-label=${ifDefined(this.ariaLabel ?? undefined)}\n aria-labelledby=${ifDefined(\n this._hasLabelSlot ? `${this._textareaId}-slotted-label` : undefined,\n )}\n aria-invalid=${hasError ? 'true' : nothing}\n aria-describedby=${ifDefined(describedBy)}\n @input=${this._handleInput}\n @change=${this._handleChange}\n ></textarea>\n </div>\n\n ${this._renderCounter()}\n ${hasError\n ? html`\n <div part=\"error\" class=\"field__error\" id=${this._errorId} role=\"alert\">\n <slot name=\"error\" @slotchange=${this._handleErrorSlotChange}>${this.error}</slot>\n </div>\n `\n : html`<slot name=\"error\" @slotchange=${this._handleErrorSlotChange}></slot>`}\n ${hasHelpText\n ? html`\n <div part=\"help-text\" class=\"field__help-text\" id=${this._helpTextId}>\n <slot name=\"help-text\" @slotchange=${this._handleHelpTextSlotChange}>\n ${this.helpText}\n </slot>\n </div>\n `\n : html`<slot name=\"help-text\" @slotchange=${this._handleHelpTextSlotChange}></slot>`}\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-textarea': HelixTextarea;\n }\n}\n\nexport type WcTextarea = HelixTextarea;\n"],"names":["helixTextareaStyles","css","_hxTextareaIdCounter","HelixTextarea","LitElement","slot","slottedLabel","changedProperties","clamped","anchor","state","target","options","_a","nothing","count","display","html","hasError","fieldClasses","hasHelpText","describedBy","classMap","live","ifDefined","tokenStyles","__decorateClass","property","query","customElement"],"mappings":"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"}
|