@helixui/library 3.3.1-next.115 → 3.3.1-next.118
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 +445 -276
- package/dist/components/hx-accordion/hx-accordion-item.d.ts +35 -0
- package/dist/components/hx-accordion/hx-accordion-item.d.ts.map +1 -1
- package/dist/components/hx-checkbox/hx-checkbox.d.ts +153 -1
- package/dist/components/hx-checkbox/hx-checkbox.d.ts.map +1 -1
- package/dist/components/hx-checkbox/hx-checkbox.styles.d.ts.map +1 -1
- package/dist/components/hx-checkbox/index.js +1 -1
- package/dist/components/hx-checkbox-group/hx-checkbox-group.d.ts +151 -2
- 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-color-picker/hx-color-picker.d.ts +163 -1
- package/dist/components/hx-color-picker/hx-color-picker.d.ts.map +1 -1
- package/dist/components/hx-color-picker/hx-color-picker.styles.d.ts.map +1 -1
- package/dist/components/hx-color-picker/index.js +1 -1
- package/dist/components/hx-combobox/hx-combobox.d.ts +311 -2
- package/dist/components/hx-combobox/hx-combobox.d.ts.map +1 -1
- package/dist/components/hx-combobox/index.js +1 -1
- package/dist/components/hx-date-picker/hx-date-picker.d.ts +182 -56
- package/dist/components/hx-date-picker/hx-date-picker.d.ts.map +1 -1
- package/dist/components/hx-date-picker/hx-date-picker.styles.d.ts.map +1 -1
- package/dist/components/hx-date-picker/index.js +1 -1
- package/dist/components/hx-dialog/hx-dialog.d.ts +240 -0
- package/dist/components/hx-dialog/hx-dialog.d.ts.map +1 -1
- package/dist/components/hx-dialog/index.js +1 -1
- package/dist/components/hx-dropdown/hx-dropdown.d.ts +80 -0
- package/dist/components/hx-dropdown/hx-dropdown.d.ts.map +1 -1
- package/dist/components/hx-dropdown/index.js +1 -1
- package/dist/components/hx-field/hx-field.d.ts +109 -0
- package/dist/components/hx-field/hx-field.d.ts.map +1 -1
- package/dist/components/hx-field/index.js +1 -1
- package/dist/components/hx-popover/hx-popover.d.ts +91 -0
- package/dist/components/hx-popover/hx-popover.d.ts.map +1 -1
- package/dist/components/hx-popover/index.js +1 -1
- package/dist/components/hx-radio-group/hx-radio-group.d.ts +152 -1
- package/dist/components/hx-radio-group/hx-radio-group.d.ts.map +1 -1
- package/dist/components/hx-radio-group/hx-radio.d.ts +14 -0
- package/dist/components/hx-radio-group/hx-radio.d.ts.map +1 -1
- package/dist/components/hx-radio-group/index.js +1 -1
- package/dist/components/hx-select/hx-select.d.ts +303 -2
- package/dist/components/hx-select/hx-select.d.ts.map +1 -1
- package/dist/components/hx-select/hx-select.styles.d.ts.map +1 -1
- package/dist/components/hx-select/index.js +1 -1
- package/dist/components/hx-side-nav/hx-nav-item.styles.d.ts.map +1 -1
- package/dist/components/hx-side-nav/index.js +1 -1
- package/dist/components/hx-switch/hx-switch.d.ts +78 -1
- package/dist/components/hx-switch/hx-switch.d.ts.map +1 -1
- package/dist/components/hx-switch/hx-switch.styles.d.ts.map +1 -1
- package/dist/components/hx-switch/index.js +1 -1
- package/dist/components/hx-toggle-button/hx-toggle-button.d.ts +110 -0
- package/dist/components/hx-toggle-button/hx-toggle-button.d.ts.map +1 -1
- package/dist/components/hx-toggle-button/hx-toggle-button.styles.d.ts.map +1 -1
- package/dist/components/hx-toggle-button/index.js +1 -1
- package/dist/components/hx-tooltip/hx-tooltip.d.ts +52 -0
- package/dist/components/hx-tooltip/hx-tooltip.d.ts.map +1 -1
- package/dist/components/hx-tooltip/index.js +1 -1
- package/dist/css/helix-all.css +98 -1
- package/dist/css/helix-forms.css +98 -1
- package/dist/css/hx-checkbox.css +18 -0
- package/dist/css/hx-color-picker.css +25 -0
- package/dist/css/hx-date-picker.css +2 -1
- package/dist/css/hx-select.css +19 -0
- package/dist/css/hx-switch.css +17 -0
- package/dist/css/hx-toggle-button.css +17 -0
- package/dist/css/index.css +1 -1
- package/dist/css/manifest.json +2 -1
- package/dist/index.js +15 -15
- package/dist/shared/aria-flatten-DY6v2vah.js +22 -0
- package/dist/shared/aria-flatten-DY6v2vah.js.map +1 -0
- package/dist/shared/aria-idref-Q0yiSR3p.js +104 -0
- package/dist/shared/aria-idref-Q0yiSR3p.js.map +1 -0
- package/dist/shared/hx-accordion-ZVzgDzTG.js.map +1 -1
- package/dist/shared/hx-checkbox-BdgoUeWi.js +696 -0
- package/dist/shared/hx-checkbox-BdgoUeWi.js.map +1 -0
- package/dist/shared/hx-checkbox-group-LWezHrvS.js +496 -0
- package/dist/shared/hx-checkbox-group-LWezHrvS.js.map +1 -0
- package/dist/shared/hx-color-picker-DVhZl88b.js +1221 -0
- package/dist/shared/hx-color-picker-DVhZl88b.js.map +1 -0
- package/dist/shared/hx-combobox-DvlezcDV.js +1359 -0
- package/dist/shared/hx-combobox-DvlezcDV.js.map +1 -0
- package/dist/shared/{hx-date-picker-2iRG1p74.js → hx-date-picker-N-0aG5XL.js} +542 -206
- package/dist/shared/hx-date-picker-N-0aG5XL.js.map +1 -0
- package/dist/shared/hx-dialog-DzB7VytW.js +717 -0
- package/dist/shared/hx-dialog-DzB7VytW.js.map +1 -0
- package/dist/shared/{hx-dropdown-LyaRc8Rf.js → hx-dropdown-DJWlF94E.js} +130 -77
- package/dist/shared/hx-dropdown-DJWlF94E.js.map +1 -0
- package/dist/shared/{hx-field-B3Qo8OLS.js → hx-field-zw0U1KVi.js} +99 -38
- package/dist/shared/hx-field-zw0U1KVi.js.map +1 -0
- package/dist/shared/{hx-nav-item-xqRPOCWX.js → hx-nav-item-CODtUlew.js} +13 -9
- package/dist/shared/{hx-nav-item-xqRPOCWX.js.map → hx-nav-item-CODtUlew.js.map} +1 -1
- package/dist/shared/{hx-popover-B-FP3-wW.js → hx-popover-CHxWY_cd.js} +123 -66
- package/dist/shared/hx-popover-CHxWY_cd.js.map +1 -0
- package/dist/shared/hx-radio-CeGzARNk.js +822 -0
- package/dist/shared/hx-radio-CeGzARNk.js.map +1 -0
- package/dist/shared/hx-select-DrcS-YRJ.js +1089 -0
- package/dist/shared/hx-select-DrcS-YRJ.js.map +1 -0
- package/dist/shared/hx-switch-BX_8uNUs.js +540 -0
- package/dist/shared/hx-switch-BX_8uNUs.js.map +1 -0
- package/dist/shared/{hx-toggle-button-iLiYrMbD.js → hx-toggle-button-Dcz9IlUm.js} +226 -65
- package/dist/shared/hx-toggle-button-Dcz9IlUm.js.map +1 -0
- package/dist/shared/{hx-tooltip-nYOv9OLu.js → hx-tooltip-DVqtKPCD.js} +68 -46
- package/dist/shared/hx-tooltip-DVqtKPCD.js.map +1 -0
- package/dist/utils/aria-flatten.d.ts +56 -0
- package/dist/utils/aria-flatten.d.ts.map +1 -0
- package/dist/utils/aria-idref.d.ts +127 -0
- package/dist/utils/aria-idref.d.ts.map +1 -0
- package/figma-inventory.json +64 -1
- package/package.json +2 -2
- package/dist/shared/hx-checkbox-D7xma9YH.js +0 -524
- package/dist/shared/hx-checkbox-D7xma9YH.js.map +0 -1
- package/dist/shared/hx-checkbox-group-C9n315Ju.js +0 -323
- package/dist/shared/hx-checkbox-group-C9n315Ju.js.map +0 -1
- package/dist/shared/hx-color-picker-uRc865FJ.js +0 -882
- package/dist/shared/hx-color-picker-uRc865FJ.js.map +0 -1
- package/dist/shared/hx-combobox-DDzqNKEW.js +0 -924
- package/dist/shared/hx-combobox-DDzqNKEW.js.map +0 -1
- package/dist/shared/hx-date-picker-2iRG1p74.js.map +0 -1
- package/dist/shared/hx-dialog-DRN_1-Y-.js +0 -514
- package/dist/shared/hx-dialog-DRN_1-Y-.js.map +0 -1
- package/dist/shared/hx-dropdown-LyaRc8Rf.js.map +0 -1
- package/dist/shared/hx-field-B3Qo8OLS.js.map +0 -1
- package/dist/shared/hx-popover-B-FP3-wW.js.map +0 -1
- package/dist/shared/hx-radio-CJvNU2yP.js +0 -621
- package/dist/shared/hx-radio-CJvNU2yP.js.map +0 -1
- package/dist/shared/hx-select-C8fEHQhC.js +0 -807
- package/dist/shared/hx-select-C8fEHQhC.js.map +0 -1
- package/dist/shared/hx-switch-BrZFaRue.js +0 -420
- package/dist/shared/hx-switch-BrZFaRue.js.map +0 -1
- package/dist/shared/hx-toggle-button-iLiYrMbD.js.map +0 -1
- package/dist/shared/hx-tooltip-nYOv9OLu.js.map +0 -1
|
@@ -2,6 +2,37 @@ import { HelixElement } from '../../base/index.js';
|
|
|
2
2
|
/**
|
|
3
3
|
* A tooltip that displays contextual help text on hover or focus.
|
|
4
4
|
*
|
|
5
|
+
* ## Architecture Note: Light-DOM Description Shim (group-4 round-1)
|
|
6
|
+
*
|
|
7
|
+
* `aria-describedby` IDREFs cannot resolve across the Shadow DOM boundary —
|
|
8
|
+
* the trigger lives in the consumer's light DOM and references a tooltip
|
|
9
|
+
* whose body is in this component's shadow root. The tooltip text must
|
|
10
|
+
* therefore be exposed in DOCUMENT scope.
|
|
11
|
+
*
|
|
12
|
+
* The shim is a single visually-hidden `<span>` appended to `document.body`
|
|
13
|
+
* with the `_tooltipId` as its `id`. The trigger's `aria-describedby` points
|
|
14
|
+
* at this span. The text content is mirrored from the slotted `content`
|
|
15
|
+
* slot on every relevant signal:
|
|
16
|
+
*
|
|
17
|
+
* 1. `firstUpdated` (initial wiring)
|
|
18
|
+
* 2. `slotchange` on the default slot AND the `content` slot (the slotted
|
|
19
|
+
* element list changes)
|
|
20
|
+
* 3. **Text-content mutations on the assigned `content` slot elements**
|
|
21
|
+
* (round-23 P2 pattern). Without this observer a framework that
|
|
22
|
+
* rewrites the slotted `<span slot="content">` `textContent` IN PLACE
|
|
23
|
+
* (Vue / React keyed text rerender) would leave the shim stale.
|
|
24
|
+
*
|
|
25
|
+
* Cleanup: `disconnectedCallback` removes the shim from `document.body`,
|
|
26
|
+
* disconnects the slot-text observer, and clears the timers. SSR is
|
|
27
|
+
* sidestepped by guarding `document` access — the shim is created lazily
|
|
28
|
+
* the first time `_setupTriggerAria()` runs in a browser environment.
|
|
29
|
+
*
|
|
30
|
+
* `role="tooltip"` is the correct APG role and is NEVER promoted to
|
|
31
|
+
* `role="dialog"` — APG explicitly forbids tooltips from holding focus and
|
|
32
|
+
* the tooltip body is not a focus target. No host-canonical `_internals`
|
|
33
|
+
* work is owed: the trigger is the announced surface, and it correctly
|
|
34
|
+
* references the tooltip via `aria-describedby`.
|
|
35
|
+
*
|
|
5
36
|
* @summary Contextual help text and abbreviations with smart positioning.
|
|
6
37
|
*
|
|
7
38
|
* @tag hx-tooltip
|
|
@@ -97,11 +128,32 @@ export declare class HelixTooltip extends HelixElement {
|
|
|
97
128
|
* @internal
|
|
98
129
|
*/
|
|
99
130
|
private _lightDomDescription;
|
|
131
|
+
/**
|
|
132
|
+
* Watches in-place text mutations on the elements assigned to the
|
|
133
|
+
* `<slot name="content">`. Without this observer, a framework that
|
|
134
|
+
* rewrites the slotted `<span slot="content">` `textContent` in place
|
|
135
|
+
* would leave the document-scope shim stale — the `slotchange` event
|
|
136
|
+
* does NOT fire on descendant text mutations.
|
|
137
|
+
*
|
|
138
|
+
* The observer is reinstalled on every `_setupTriggerAria()` call against
|
|
139
|
+
* the deduped current set of assigned elements; it is fully torn down in
|
|
140
|
+
* `disconnectedCallback` to prevent leaks on SSR teardown.
|
|
141
|
+
* @internal
|
|
142
|
+
*/
|
|
143
|
+
private _contentSlotTextObserver;
|
|
100
144
|
connectedCallback(): void;
|
|
101
145
|
disconnectedCallback(): void;
|
|
102
146
|
firstUpdated(): void;
|
|
103
147
|
/** @internal */
|
|
104
148
|
private _setupTriggerAria;
|
|
149
|
+
/**
|
|
150
|
+
* (Re-)installs the slotted-content text observer over the deduped union
|
|
151
|
+
* of assigned `content` slot elements. Disconnects any previous observer
|
|
152
|
+
* before re-attaching so observer count is bounded by component lifetime,
|
|
153
|
+
* not by `slotchange` event count.
|
|
154
|
+
* @internal
|
|
155
|
+
*/
|
|
156
|
+
private _installContentSlotTextObserver;
|
|
105
157
|
/** @internal */
|
|
106
158
|
private _scheduleShow;
|
|
107
159
|
/** @internal */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hx-tooltip.d.ts","sourceRoot":"","sources":["../../../src/components/hx-tooltip/hx-tooltip.ts"],"names":[],"mappings":"AACA,OAAO,4CAA4C,CAAC;AAGpD,OAAO,EAAE,YAAY,EAAmB,MAAM,qBAAqB,CAAC;AAMpE
|
|
1
|
+
{"version":3,"file":"hx-tooltip.d.ts","sourceRoot":"","sources":["../../../src/components/hx-tooltip/hx-tooltip.ts"],"names":[],"mappings":"AACA,OAAO,4CAA4C,CAAC;AAGpD,OAAO,EAAE,YAAY,EAAmB,MAAM,qBAAqB,CAAC;AAMpE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmFG;AAEH,qBACa,YAAa,SAAQ,YAAY;IAC5C,OAAgB,MAAM,4BAA6C;IAEnE;;;;;OAKG;IAEH,SAAS,EACL,KAAK,GACL,WAAW,GACX,SAAS,GACT,OAAO,GACP,aAAa,GACb,WAAW,GACX,QAAQ,GACR,cAAc,GACd,YAAY,GACZ,MAAM,GACN,YAAY,GACZ,UAAU,CAAS;IAEvB;;;OAGG;IAEH,SAAS,SAAO;IAEhB;;;OAGG;IAEH,SAAS,SAAO;IAEhB,gBAAgB;IACP,OAAO,CAAC,QAAQ,CAAS;IAElC,gBAAgB;IAChB,OAAO,CAAC,UAAU,CAA8C;IAChE,gBAAgB;IAChB,OAAO,CAAC,UAAU,CAA8C;IAEhE,gBAAgB;IAChB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAoB;IAE/C,gBAAgB;IACW,OAAO,CAAC,YAAY,CAA0B;IACzE,gBAAgB;IACe,OAAO,CAAC,YAAY,CAA0B;IAC7E,gBAAgB;IACW,OAAO,CAAC,eAAe,CAAsB;IACxE,gBAAgB;IACW,OAAO,CAAC,UAAU,CAAsB;IACnE,gBAAgB;IACS,OAAO,CAAC,QAAQ,CAAsB;IAE/D;;;;;;OAMG;IACH,OAAO,CAAC,oBAAoB,CAAgC;IAE5D;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,wBAAwB,CAAiC;IAIxD,iBAAiB,IAAI,IAAI;IAUzB,oBAAoB,IAAI,IAAI;IAa5B,YAAY,IAAI,IAAI;IAM7B,gBAAgB;IAChB,OAAO,CAAC,iBAAiB;IA0CzB;;;;;;OAMG;IACH,OAAO,CAAC,+BAA+B;IAsCvC,gBAAgB;IAChB,OAAO,CAAC,aAAa;IAOrB,gBAAgB;IAChB,OAAO,CAAC,aAAa;IAOrB,gBAAgB;YACF,KAAK;IAMnB,gBAAgB;IAChB,OAAO,CAAC,KAAK;IAIb,gBAAgB;IAChB,OAAO,CAAC,YAAY;IAapB,gBAAgB;YACF,eAAe;IA0C7B,gBAAgB;IAChB,OAAO,CAAC,cAAc,CAMpB;IAEF;;;;;;OAMG;IACH,OAAO,CAAC,wBAAwB;IAavB,MAAM;CAyBhB;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,YAAY,EAAE,YAAY,CAAC;KAC5B;CACF"}
|
package/dist/css/helix-all.css
CHANGED
|
@@ -2080,6 +2080,23 @@
|
|
|
2080
2080
|
|
|
2081
2081
|
/* ─── Focus Ring ─── */
|
|
2082
2082
|
|
|
2083
|
+
/*
|
|
2084
|
+
* Host-focus path: on the modern (IDL element-references) render branch the
|
|
2085
|
+
* host is the tabbable surface (tabindex=0) and the inner input is demoted
|
|
2086
|
+
* to tabindex=-1. Drive the focus ring from ':host(:focus-visible)' so
|
|
2087
|
+
* keyboard users still get a visible affordance. Codex round-11 P1.
|
|
2088
|
+
*/
|
|
2089
|
+
:host(:focus-visible) .checkbox__box {
|
|
2090
|
+
outline: var(--hx-checkbox-focus-ring-width, var(--hx-focus-ring-width, 2px)) solid
|
|
2091
|
+
var(--hx-checkbox-focus-ring-color, var(--hx-focus-ring-color, #0f7078));
|
|
2092
|
+
outline-offset: var(--hx-checkbox-focus-ring-offset, var(--hx-focus-ring-offset, 2px));
|
|
2093
|
+
}
|
|
2094
|
+
|
|
2095
|
+
/*
|
|
2096
|
+
* Fallback (no-IDL-ref) path: the host carries tabindex=-1 and the inner
|
|
2097
|
+
* input is the tab target. The native :focus-visible on the input drives
|
|
2098
|
+
* the same visual ring, scoped via the inner-state class.
|
|
2099
|
+
*/
|
|
2083
2100
|
.checkbox__input:focus-visible ~ .checkbox__box {
|
|
2084
2101
|
outline: var(--hx-checkbox-focus-ring-width, var(--hx-focus-ring-width, 2px)) solid
|
|
2085
2102
|
var(--hx-checkbox-focus-ring-color, var(--hx-focus-ring-color, #0f7078));
|
|
@@ -2234,6 +2251,7 @@
|
|
|
2234
2251
|
border: 2px solid ButtonText;
|
|
2235
2252
|
}
|
|
2236
2253
|
|
|
2254
|
+
:host(:focus-visible) .checkbox__box,
|
|
2237
2255
|
.checkbox__input:focus-visible ~ .checkbox__box {
|
|
2238
2256
|
outline: 3px solid Highlight;
|
|
2239
2257
|
outline-offset: 2px;
|
|
@@ -2900,6 +2918,31 @@
|
|
|
2900
2918
|
pointer-events: none;
|
|
2901
2919
|
opacity: var(--hx-opacity-disabled, 0.5);
|
|
2902
2920
|
}
|
|
2921
|
+
/* Slotted label / help / error blocks for cross-shadow naming. */
|
|
2922
|
+
.hx-color-picker__label {
|
|
2923
|
+
display: block;
|
|
2924
|
+
margin-bottom: var(--hx-space-1, 0.25rem);
|
|
2925
|
+
font-weight: var(--hx-font-weight-semibold, 600);
|
|
2926
|
+
color: var(--hx-color-neutral-900, #1a1a1a);
|
|
2927
|
+
}
|
|
2928
|
+
.hx-color-picker__label:empty {
|
|
2929
|
+
display: none;
|
|
2930
|
+
}
|
|
2931
|
+
.hx-color-picker__help {
|
|
2932
|
+
display: block;
|
|
2933
|
+
margin-top: var(--hx-space-1, 0.25rem);
|
|
2934
|
+
font-size: var(--hx-font-size-xs, 0.75rem);
|
|
2935
|
+
color: var(--hx-color-neutral-600, #525252);
|
|
2936
|
+
}
|
|
2937
|
+
.hx-color-picker__error {
|
|
2938
|
+
display: block;
|
|
2939
|
+
margin-top: var(--hx-space-1, 0.25rem);
|
|
2940
|
+
font-size: var(--hx-font-size-xs, 0.75rem);
|
|
2941
|
+
color: var(--hx-color-danger-700, #c43e3e);
|
|
2942
|
+
}
|
|
2943
|
+
[hidden] {
|
|
2944
|
+
display: none !important;
|
|
2945
|
+
}
|
|
2903
2946
|
.trigger {
|
|
2904
2947
|
display: inline-flex;
|
|
2905
2948
|
align-items: center;
|
|
@@ -4426,7 +4469,8 @@
|
|
|
4426
4469
|
Live region (screen reader announcements)
|
|
4427
4470
|
============================================================ */
|
|
4428
4471
|
|
|
4429
|
-
.calendar__live-region
|
|
4472
|
+
.calendar__live-region,
|
|
4473
|
+
.field__sr-only {
|
|
4430
4474
|
position: absolute;
|
|
4431
4475
|
width: 1px;
|
|
4432
4476
|
height: 1px;
|
|
@@ -8298,6 +8342,11 @@ export const helixGridItemStyles = css`
|
|
|
8298
8342
|
/* ─── 3-tier token cascade: component → semantic → hardcoded fallback ─── */
|
|
8299
8343
|
:host {
|
|
8300
8344
|
display: block;
|
|
8345
|
+
/* Round-3 finding 1: host is the canonical combobox surface, so it owns
|
|
8346
|
+
keyboard focus. Suppress the UA default outline; the custom focus ring
|
|
8347
|
+
is painted on the inner trigger via :host(:focus-visible)
|
|
8348
|
+
.field__trigger so visual feedback follows the host's focus state. */
|
|
8349
|
+
outline: none;
|
|
8301
8350
|
|
|
8302
8351
|
/* Background & foreground */
|
|
8303
8352
|
--_bg: var(--hx-select-bg, var(--hx-color-surface-default, #ffffff));
|
|
@@ -8374,6 +8423,12 @@ export const helixGridItemStyles = css`
|
|
|
8374
8423
|
}
|
|
8375
8424
|
|
|
8376
8425
|
.field__trigger {
|
|
8426
|
+
/* Round-3 finding 1 / CodeRabbit F1: trigger is a <button type="button">
|
|
8427
|
+
(labelable) so native <label for> click activation works for mouse
|
|
8428
|
+
users. Reset native button chrome before applying field styles. */
|
|
8429
|
+
appearance: none;
|
|
8430
|
+
-webkit-appearance: none;
|
|
8431
|
+
margin: 0;
|
|
8377
8432
|
display: flex;
|
|
8378
8433
|
align-items: center;
|
|
8379
8434
|
justify-content: space-between;
|
|
@@ -8384,6 +8439,7 @@ export const helixGridItemStyles = css`
|
|
|
8384
8439
|
border-radius: var(--_border-radius);
|
|
8385
8440
|
background-color: var(--_bg);
|
|
8386
8441
|
color: var(--_color);
|
|
8442
|
+
font: inherit;
|
|
8387
8443
|
font-family: inherit;
|
|
8388
8444
|
font-size: var(--hx-font-size-md, 1rem);
|
|
8389
8445
|
line-height: var(--hx-line-height-normal, 1.5);
|
|
@@ -8396,6 +8452,11 @@ export const helixGridItemStyles = css`
|
|
|
8396
8452
|
outline: none;
|
|
8397
8453
|
}
|
|
8398
8454
|
|
|
8455
|
+
/* Round-3 finding 1: host is the canonical focusable surface. Both the
|
|
8456
|
+
:host(:focus-visible) descendant selector AND the legacy
|
|
8457
|
+
.field__trigger:focus-visible (kept for forced-colors regression test
|
|
8458
|
+
parity) paint the focus ring on the visual trigger. */
|
|
8459
|
+
:host(:focus-visible) .field__trigger,
|
|
8399
8460
|
.field__trigger:focus-visible {
|
|
8400
8461
|
border-color: var(--_focus-ring-color);
|
|
8401
8462
|
box-shadow: 0 0 0 var(--hx-focus-ring-width, 2px)
|
|
@@ -8464,6 +8525,7 @@ export const helixGridItemStyles = css`
|
|
|
8464
8525
|
border-color: var(--_error-color);
|
|
8465
8526
|
}
|
|
8466
8527
|
|
|
8528
|
+
:host(:focus-visible) .field--error .field__trigger,
|
|
8467
8529
|
.field--error .field__trigger:focus-visible {
|
|
8468
8530
|
border-color: var(--_error-color);
|
|
8469
8531
|
box-shadow: 0 0 0 var(--hx-focus-ring-width, 2px)
|
|
@@ -8597,6 +8659,7 @@ export const helixGridItemStyles = css`
|
|
|
8597
8659
|
border: 2px solid ButtonText;
|
|
8598
8660
|
}
|
|
8599
8661
|
|
|
8662
|
+
:host(:focus-visible) .field__trigger,
|
|
8600
8663
|
.field__trigger:focus-visible {
|
|
8601
8664
|
outline: 3px solid Highlight;
|
|
8602
8665
|
outline-offset: 2px;
|
|
@@ -10544,6 +10607,22 @@ export const helixStructuredListRowStyles = css`
|
|
|
10544
10607
|
appearance: none;
|
|
10545
10608
|
}
|
|
10546
10609
|
|
|
10610
|
+
/*
|
|
10611
|
+
* Host-focus path: on the modern (IDL element-references) render branch the
|
|
10612
|
+
* host is the tabbable surface (tabindex=0) and the inner track button is
|
|
10613
|
+
* demoted to tabindex=-1. Drive the focus ring from ':host(:focus-visible)'
|
|
10614
|
+
* so keyboard users still see a visible affordance. Codex round-11 P1.
|
|
10615
|
+
*/
|
|
10616
|
+
:host(:focus-visible) .switch__track {
|
|
10617
|
+
outline: var(--hx-focus-ring-width, 2px) solid
|
|
10618
|
+
var(--hx-switch-focus-ring-color, var(--hx-focus-ring-color, #0f7078));
|
|
10619
|
+
outline-offset: var(--hx-focus-ring-offset, 2px);
|
|
10620
|
+
}
|
|
10621
|
+
|
|
10622
|
+
/*
|
|
10623
|
+
* Fallback (no-IDL-ref) path: the host carries tabindex=-1 and the inner
|
|
10624
|
+
* track button is the tab target. Native :focus-visible drives the ring.
|
|
10625
|
+
*/
|
|
10547
10626
|
.switch__track:focus-visible {
|
|
10548
10627
|
outline: var(--hx-focus-ring-width, 2px) solid
|
|
10549
10628
|
var(--hx-switch-focus-ring-color, var(--hx-focus-ring-color, #0f7078));
|
|
@@ -10681,6 +10760,7 @@ export const helixStructuredListRowStyles = css`
|
|
|
10681
10760
|
border: 2px solid ButtonText;
|
|
10682
10761
|
}
|
|
10683
10762
|
|
|
10763
|
+
:host(:focus-visible) .switch__track,
|
|
10684
10764
|
.switch__track:focus-visible {
|
|
10685
10765
|
outline: 3px solid Highlight;
|
|
10686
10766
|
outline-offset: 2px;
|
|
@@ -12483,6 +12563,22 @@ export const helixToastStackStyles = css`
|
|
|
12483
12563
|
-webkit-user-select: none;
|
|
12484
12564
|
}
|
|
12485
12565
|
|
|
12566
|
+
/*
|
|
12567
|
+
* Host-focus path: on the modern (IDL element-references) render branch the
|
|
12568
|
+
* host is the tabbable surface (tabindex=0) and the inner <button> is
|
|
12569
|
+
* demoted to tabindex=-1. Drive the focus ring from ':host(:focus-visible)'
|
|
12570
|
+
* so keyboard users still see a visible affordance. Codex round-11 P1.
|
|
12571
|
+
*/
|
|
12572
|
+
:host(:focus-visible) .button {
|
|
12573
|
+
outline: var(--hx-focus-ring-width, 2px) solid
|
|
12574
|
+
var(--hx-toggle-button-focus-ring-color, var(--hx-focus-ring-color, #0f7078));
|
|
12575
|
+
outline-offset: var(--hx-focus-ring-offset, 2px);
|
|
12576
|
+
}
|
|
12577
|
+
|
|
12578
|
+
/*
|
|
12579
|
+
* Fallback (no-IDL-ref) path: the host carries tabindex=-1 and the inner
|
|
12580
|
+
* <button> is the tab target. Native :focus-visible drives the ring.
|
|
12581
|
+
*/
|
|
12486
12582
|
.button:focus-visible {
|
|
12487
12583
|
outline: var(--hx-focus-ring-width, 2px) solid
|
|
12488
12584
|
var(--hx-toggle-button-focus-ring-color, var(--hx-focus-ring-color, #0f7078));
|
|
@@ -12681,6 +12777,7 @@ export const helixToastStackStyles = css`
|
|
|
12681
12777
|
border: 2px solid ButtonText;
|
|
12682
12778
|
}
|
|
12683
12779
|
|
|
12780
|
+
:host(:focus-visible) .button,
|
|
12684
12781
|
.button:focus-visible {
|
|
12685
12782
|
outline: 3px solid Highlight;
|
|
12686
12783
|
outline-offset: 2px;
|
package/dist/css/helix-forms.css
CHANGED
|
@@ -72,6 +72,23 @@
|
|
|
72
72
|
|
|
73
73
|
/* ─── Focus Ring ─── */
|
|
74
74
|
|
|
75
|
+
/*
|
|
76
|
+
* Host-focus path: on the modern (IDL element-references) render branch the
|
|
77
|
+
* host is the tabbable surface (tabindex=0) and the inner input is demoted
|
|
78
|
+
* to tabindex=-1. Drive the focus ring from ':host(:focus-visible)' so
|
|
79
|
+
* keyboard users still get a visible affordance. Codex round-11 P1.
|
|
80
|
+
*/
|
|
81
|
+
:host(:focus-visible) .checkbox__box {
|
|
82
|
+
outline: var(--hx-checkbox-focus-ring-width, var(--hx-focus-ring-width, 2px)) solid
|
|
83
|
+
var(--hx-checkbox-focus-ring-color, var(--hx-focus-ring-color, #0f7078));
|
|
84
|
+
outline-offset: var(--hx-checkbox-focus-ring-offset, var(--hx-focus-ring-offset, 2px));
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/*
|
|
88
|
+
* Fallback (no-IDL-ref) path: the host carries tabindex=-1 and the inner
|
|
89
|
+
* input is the tab target. The native :focus-visible on the input drives
|
|
90
|
+
* the same visual ring, scoped via the inner-state class.
|
|
91
|
+
*/
|
|
75
92
|
.checkbox__input:focus-visible ~ .checkbox__box {
|
|
76
93
|
outline: var(--hx-checkbox-focus-ring-width, var(--hx-focus-ring-width, 2px)) solid
|
|
77
94
|
var(--hx-checkbox-focus-ring-color, var(--hx-focus-ring-color, #0f7078));
|
|
@@ -226,6 +243,7 @@
|
|
|
226
243
|
border: 2px solid ButtonText;
|
|
227
244
|
}
|
|
228
245
|
|
|
246
|
+
:host(:focus-visible) .checkbox__box,
|
|
229
247
|
.checkbox__input:focus-visible ~ .checkbox__box {
|
|
230
248
|
outline: 3px solid Highlight;
|
|
231
249
|
outline-offset: 2px;
|
|
@@ -402,6 +420,31 @@
|
|
|
402
420
|
pointer-events: none;
|
|
403
421
|
opacity: var(--hx-opacity-disabled, 0.5);
|
|
404
422
|
}
|
|
423
|
+
/* Slotted label / help / error blocks for cross-shadow naming. */
|
|
424
|
+
.hx-color-picker__label {
|
|
425
|
+
display: block;
|
|
426
|
+
margin-bottom: var(--hx-space-1, 0.25rem);
|
|
427
|
+
font-weight: var(--hx-font-weight-semibold, 600);
|
|
428
|
+
color: var(--hx-color-neutral-900, #1a1a1a);
|
|
429
|
+
}
|
|
430
|
+
.hx-color-picker__label:empty {
|
|
431
|
+
display: none;
|
|
432
|
+
}
|
|
433
|
+
.hx-color-picker__help {
|
|
434
|
+
display: block;
|
|
435
|
+
margin-top: var(--hx-space-1, 0.25rem);
|
|
436
|
+
font-size: var(--hx-font-size-xs, 0.75rem);
|
|
437
|
+
color: var(--hx-color-neutral-600, #525252);
|
|
438
|
+
}
|
|
439
|
+
.hx-color-picker__error {
|
|
440
|
+
display: block;
|
|
441
|
+
margin-top: var(--hx-space-1, 0.25rem);
|
|
442
|
+
font-size: var(--hx-font-size-xs, 0.75rem);
|
|
443
|
+
color: var(--hx-color-danger-700, #c43e3e);
|
|
444
|
+
}
|
|
445
|
+
[hidden] {
|
|
446
|
+
display: none !important;
|
|
447
|
+
}
|
|
405
448
|
.trigger {
|
|
406
449
|
display: inline-flex;
|
|
407
450
|
align-items: center;
|
|
@@ -1398,7 +1441,8 @@
|
|
|
1398
1441
|
Live region (screen reader announcements)
|
|
1399
1442
|
============================================================ */
|
|
1400
1443
|
|
|
1401
|
-
.calendar__live-region
|
|
1444
|
+
.calendar__live-region,
|
|
1445
|
+
.field__sr-only {
|
|
1402
1446
|
position: absolute;
|
|
1403
1447
|
width: 1px;
|
|
1404
1448
|
height: 1px;
|
|
@@ -2615,6 +2659,11 @@
|
|
|
2615
2659
|
/* ─── 3-tier token cascade: component → semantic → hardcoded fallback ─── */
|
|
2616
2660
|
:host {
|
|
2617
2661
|
display: block;
|
|
2662
|
+
/* Round-3 finding 1: host is the canonical combobox surface, so it owns
|
|
2663
|
+
keyboard focus. Suppress the UA default outline; the custom focus ring
|
|
2664
|
+
is painted on the inner trigger via :host(:focus-visible)
|
|
2665
|
+
.field__trigger so visual feedback follows the host's focus state. */
|
|
2666
|
+
outline: none;
|
|
2618
2667
|
|
|
2619
2668
|
/* Background & foreground */
|
|
2620
2669
|
--_bg: var(--hx-select-bg, var(--hx-color-surface-default, #ffffff));
|
|
@@ -2691,6 +2740,12 @@
|
|
|
2691
2740
|
}
|
|
2692
2741
|
|
|
2693
2742
|
.field__trigger {
|
|
2743
|
+
/* Round-3 finding 1 / CodeRabbit F1: trigger is a <button type="button">
|
|
2744
|
+
(labelable) so native <label for> click activation works for mouse
|
|
2745
|
+
users. Reset native button chrome before applying field styles. */
|
|
2746
|
+
appearance: none;
|
|
2747
|
+
-webkit-appearance: none;
|
|
2748
|
+
margin: 0;
|
|
2694
2749
|
display: flex;
|
|
2695
2750
|
align-items: center;
|
|
2696
2751
|
justify-content: space-between;
|
|
@@ -2701,6 +2756,7 @@
|
|
|
2701
2756
|
border-radius: var(--_border-radius);
|
|
2702
2757
|
background-color: var(--_bg);
|
|
2703
2758
|
color: var(--_color);
|
|
2759
|
+
font: inherit;
|
|
2704
2760
|
font-family: inherit;
|
|
2705
2761
|
font-size: var(--hx-font-size-md, 1rem);
|
|
2706
2762
|
line-height: var(--hx-line-height-normal, 1.5);
|
|
@@ -2713,6 +2769,11 @@
|
|
|
2713
2769
|
outline: none;
|
|
2714
2770
|
}
|
|
2715
2771
|
|
|
2772
|
+
/* Round-3 finding 1: host is the canonical focusable surface. Both the
|
|
2773
|
+
:host(:focus-visible) descendant selector AND the legacy
|
|
2774
|
+
.field__trigger:focus-visible (kept for forced-colors regression test
|
|
2775
|
+
parity) paint the focus ring on the visual trigger. */
|
|
2776
|
+
:host(:focus-visible) .field__trigger,
|
|
2716
2777
|
.field__trigger:focus-visible {
|
|
2717
2778
|
border-color: var(--_focus-ring-color);
|
|
2718
2779
|
box-shadow: 0 0 0 var(--hx-focus-ring-width, 2px)
|
|
@@ -2781,6 +2842,7 @@
|
|
|
2781
2842
|
border-color: var(--_error-color);
|
|
2782
2843
|
}
|
|
2783
2844
|
|
|
2845
|
+
:host(:focus-visible) .field--error .field__trigger,
|
|
2784
2846
|
.field--error .field__trigger:focus-visible {
|
|
2785
2847
|
border-color: var(--_error-color);
|
|
2786
2848
|
box-shadow: 0 0 0 var(--hx-focus-ring-width, 2px)
|
|
@@ -2914,6 +2976,7 @@
|
|
|
2914
2976
|
border: 2px solid ButtonText;
|
|
2915
2977
|
}
|
|
2916
2978
|
|
|
2979
|
+
:host(:focus-visible) .field__trigger,
|
|
2917
2980
|
.field__trigger:focus-visible {
|
|
2918
2981
|
outline: 3px solid Highlight;
|
|
2919
2982
|
outline-offset: 2px;
|
|
@@ -3328,6 +3391,22 @@
|
|
|
3328
3391
|
appearance: none;
|
|
3329
3392
|
}
|
|
3330
3393
|
|
|
3394
|
+
/*
|
|
3395
|
+
* Host-focus path: on the modern (IDL element-references) render branch the
|
|
3396
|
+
* host is the tabbable surface (tabindex=0) and the inner track button is
|
|
3397
|
+
* demoted to tabindex=-1. Drive the focus ring from ':host(:focus-visible)'
|
|
3398
|
+
* so keyboard users still see a visible affordance. Codex round-11 P1.
|
|
3399
|
+
*/
|
|
3400
|
+
:host(:focus-visible) .switch__track {
|
|
3401
|
+
outline: var(--hx-focus-ring-width, 2px) solid
|
|
3402
|
+
var(--hx-switch-focus-ring-color, var(--hx-focus-ring-color, #0f7078));
|
|
3403
|
+
outline-offset: var(--hx-focus-ring-offset, 2px);
|
|
3404
|
+
}
|
|
3405
|
+
|
|
3406
|
+
/*
|
|
3407
|
+
* Fallback (no-IDL-ref) path: the host carries tabindex=-1 and the inner
|
|
3408
|
+
* track button is the tab target. Native :focus-visible drives the ring.
|
|
3409
|
+
*/
|
|
3331
3410
|
.switch__track:focus-visible {
|
|
3332
3411
|
outline: var(--hx-focus-ring-width, 2px) solid
|
|
3333
3412
|
var(--hx-switch-focus-ring-color, var(--hx-focus-ring-color, #0f7078));
|
|
@@ -3465,6 +3544,7 @@
|
|
|
3465
3544
|
border: 2px solid ButtonText;
|
|
3466
3545
|
}
|
|
3467
3546
|
|
|
3547
|
+
:host(:focus-visible) .switch__track,
|
|
3468
3548
|
.switch__track:focus-visible {
|
|
3469
3549
|
outline: 3px solid Highlight;
|
|
3470
3550
|
outline-offset: 2px;
|
|
@@ -4400,6 +4480,22 @@
|
|
|
4400
4480
|
-webkit-user-select: none;
|
|
4401
4481
|
}
|
|
4402
4482
|
|
|
4483
|
+
/*
|
|
4484
|
+
* Host-focus path: on the modern (IDL element-references) render branch the
|
|
4485
|
+
* host is the tabbable surface (tabindex=0) and the inner <button> is
|
|
4486
|
+
* demoted to tabindex=-1. Drive the focus ring from ':host(:focus-visible)'
|
|
4487
|
+
* so keyboard users still see a visible affordance. Codex round-11 P1.
|
|
4488
|
+
*/
|
|
4489
|
+
:host(:focus-visible) .button {
|
|
4490
|
+
outline: var(--hx-focus-ring-width, 2px) solid
|
|
4491
|
+
var(--hx-toggle-button-focus-ring-color, var(--hx-focus-ring-color, #0f7078));
|
|
4492
|
+
outline-offset: var(--hx-focus-ring-offset, 2px);
|
|
4493
|
+
}
|
|
4494
|
+
|
|
4495
|
+
/*
|
|
4496
|
+
* Fallback (no-IDL-ref) path: the host carries tabindex=-1 and the inner
|
|
4497
|
+
* <button> is the tab target. Native :focus-visible drives the ring.
|
|
4498
|
+
*/
|
|
4403
4499
|
.button:focus-visible {
|
|
4404
4500
|
outline: var(--hx-focus-ring-width, 2px) solid
|
|
4405
4501
|
var(--hx-toggle-button-focus-ring-color, var(--hx-focus-ring-color, #0f7078));
|
|
@@ -4598,6 +4694,7 @@
|
|
|
4598
4694
|
border: 2px solid ButtonText;
|
|
4599
4695
|
}
|
|
4600
4696
|
|
|
4697
|
+
:host(:focus-visible) .button,
|
|
4601
4698
|
.button:focus-visible {
|
|
4602
4699
|
outline: 3px solid Highlight;
|
|
4603
4700
|
outline-offset: 2px;
|
package/dist/css/hx-checkbox.css
CHANGED
|
@@ -70,6 +70,23 @@
|
|
|
70
70
|
|
|
71
71
|
/* ─── Focus Ring ─── */
|
|
72
72
|
|
|
73
|
+
/*
|
|
74
|
+
* Host-focus path: on the modern (IDL element-references) render branch the
|
|
75
|
+
* host is the tabbable surface (tabindex=0) and the inner input is demoted
|
|
76
|
+
* to tabindex=-1. Drive the focus ring from ':host(:focus-visible)' so
|
|
77
|
+
* keyboard users still get a visible affordance. Codex round-11 P1.
|
|
78
|
+
*/
|
|
79
|
+
:host(:focus-visible) .checkbox__box {
|
|
80
|
+
outline: var(--hx-checkbox-focus-ring-width, var(--hx-focus-ring-width, 2px)) solid
|
|
81
|
+
var(--hx-checkbox-focus-ring-color, var(--hx-focus-ring-color, #0f7078));
|
|
82
|
+
outline-offset: var(--hx-checkbox-focus-ring-offset, var(--hx-focus-ring-offset, 2px));
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/*
|
|
86
|
+
* Fallback (no-IDL-ref) path: the host carries tabindex=-1 and the inner
|
|
87
|
+
* input is the tab target. The native :focus-visible on the input drives
|
|
88
|
+
* the same visual ring, scoped via the inner-state class.
|
|
89
|
+
*/
|
|
73
90
|
.checkbox__input:focus-visible ~ .checkbox__box {
|
|
74
91
|
outline: var(--hx-checkbox-focus-ring-width, var(--hx-focus-ring-width, 2px)) solid
|
|
75
92
|
var(--hx-checkbox-focus-ring-color, var(--hx-focus-ring-color, #0f7078));
|
|
@@ -224,6 +241,7 @@
|
|
|
224
241
|
border: 2px solid ButtonText;
|
|
225
242
|
}
|
|
226
243
|
|
|
244
|
+
:host(:focus-visible) .checkbox__box,
|
|
227
245
|
.checkbox__input:focus-visible ~ .checkbox__box {
|
|
228
246
|
outline: 3px solid Highlight;
|
|
229
247
|
outline-offset: 2px;
|
|
@@ -9,6 +9,31 @@
|
|
|
9
9
|
pointer-events: none;
|
|
10
10
|
opacity: var(--hx-opacity-disabled, 0.5);
|
|
11
11
|
}
|
|
12
|
+
/* Slotted label / help / error blocks for cross-shadow naming. */
|
|
13
|
+
.hx-color-picker__label {
|
|
14
|
+
display: block;
|
|
15
|
+
margin-bottom: var(--hx-space-1, 0.25rem);
|
|
16
|
+
font-weight: var(--hx-font-weight-semibold, 600);
|
|
17
|
+
color: var(--hx-color-neutral-900, #1a1a1a);
|
|
18
|
+
}
|
|
19
|
+
.hx-color-picker__label:empty {
|
|
20
|
+
display: none;
|
|
21
|
+
}
|
|
22
|
+
.hx-color-picker__help {
|
|
23
|
+
display: block;
|
|
24
|
+
margin-top: var(--hx-space-1, 0.25rem);
|
|
25
|
+
font-size: var(--hx-font-size-xs, 0.75rem);
|
|
26
|
+
color: var(--hx-color-neutral-600, #525252);
|
|
27
|
+
}
|
|
28
|
+
.hx-color-picker__error {
|
|
29
|
+
display: block;
|
|
30
|
+
margin-top: var(--hx-space-1, 0.25rem);
|
|
31
|
+
font-size: var(--hx-font-size-xs, 0.75rem);
|
|
32
|
+
color: var(--hx-color-danger-700, #c43e3e);
|
|
33
|
+
}
|
|
34
|
+
[hidden] {
|
|
35
|
+
display: none !important;
|
|
36
|
+
}
|
|
12
37
|
.trigger {
|
|
13
38
|
display: inline-flex;
|
|
14
39
|
align-items: center;
|
|
@@ -335,7 +335,8 @@
|
|
|
335
335
|
Live region (screen reader announcements)
|
|
336
336
|
============================================================ */
|
|
337
337
|
|
|
338
|
-
.calendar__live-region
|
|
338
|
+
.calendar__live-region,
|
|
339
|
+
.field__sr-only {
|
|
339
340
|
position: absolute;
|
|
340
341
|
width: 1px;
|
|
341
342
|
height: 1px;
|
package/dist/css/hx-select.css
CHANGED
|
@@ -2,6 +2,11 @@
|
|
|
2
2
|
/* ─── 3-tier token cascade: component → semantic → hardcoded fallback ─── */
|
|
3
3
|
:host {
|
|
4
4
|
display: block;
|
|
5
|
+
/* Round-3 finding 1: host is the canonical combobox surface, so it owns
|
|
6
|
+
keyboard focus. Suppress the UA default outline; the custom focus ring
|
|
7
|
+
is painted on the inner trigger via :host(:focus-visible)
|
|
8
|
+
.field__trigger so visual feedback follows the host's focus state. */
|
|
9
|
+
outline: none;
|
|
5
10
|
|
|
6
11
|
/* Background & foreground */
|
|
7
12
|
--_bg: var(--hx-select-bg, var(--hx-color-surface-default, #ffffff));
|
|
@@ -78,6 +83,12 @@
|
|
|
78
83
|
}
|
|
79
84
|
|
|
80
85
|
.field__trigger {
|
|
86
|
+
/* Round-3 finding 1 / CodeRabbit F1: trigger is a <button type="button">
|
|
87
|
+
(labelable) so native <label for> click activation works for mouse
|
|
88
|
+
users. Reset native button chrome before applying field styles. */
|
|
89
|
+
appearance: none;
|
|
90
|
+
-webkit-appearance: none;
|
|
91
|
+
margin: 0;
|
|
81
92
|
display: flex;
|
|
82
93
|
align-items: center;
|
|
83
94
|
justify-content: space-between;
|
|
@@ -88,6 +99,7 @@
|
|
|
88
99
|
border-radius: var(--_border-radius);
|
|
89
100
|
background-color: var(--_bg);
|
|
90
101
|
color: var(--_color);
|
|
102
|
+
font: inherit;
|
|
91
103
|
font-family: inherit;
|
|
92
104
|
font-size: var(--hx-font-size-md, 1rem);
|
|
93
105
|
line-height: var(--hx-line-height-normal, 1.5);
|
|
@@ -100,6 +112,11 @@
|
|
|
100
112
|
outline: none;
|
|
101
113
|
}
|
|
102
114
|
|
|
115
|
+
/* Round-3 finding 1: host is the canonical focusable surface. Both the
|
|
116
|
+
:host(:focus-visible) descendant selector AND the legacy
|
|
117
|
+
.field__trigger:focus-visible (kept for forced-colors regression test
|
|
118
|
+
parity) paint the focus ring on the visual trigger. */
|
|
119
|
+
:host(:focus-visible) .field__trigger,
|
|
103
120
|
.field__trigger:focus-visible {
|
|
104
121
|
border-color: var(--_focus-ring-color);
|
|
105
122
|
box-shadow: 0 0 0 var(--hx-focus-ring-width, 2px)
|
|
@@ -168,6 +185,7 @@
|
|
|
168
185
|
border-color: var(--_error-color);
|
|
169
186
|
}
|
|
170
187
|
|
|
188
|
+
:host(:focus-visible) .field--error .field__trigger,
|
|
171
189
|
.field--error .field__trigger:focus-visible {
|
|
172
190
|
border-color: var(--_error-color);
|
|
173
191
|
box-shadow: 0 0 0 var(--hx-focus-ring-width, 2px)
|
|
@@ -301,6 +319,7 @@
|
|
|
301
319
|
border: 2px solid ButtonText;
|
|
302
320
|
}
|
|
303
321
|
|
|
322
|
+
:host(:focus-visible) .field__trigger,
|
|
304
323
|
.field__trigger:focus-visible {
|
|
305
324
|
outline: 3px solid Highlight;
|
|
306
325
|
outline-offset: 2px;
|
package/dist/css/hx-switch.css
CHANGED
|
@@ -49,6 +49,22 @@
|
|
|
49
49
|
appearance: none;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
+
/*
|
|
53
|
+
* Host-focus path: on the modern (IDL element-references) render branch the
|
|
54
|
+
* host is the tabbable surface (tabindex=0) and the inner track button is
|
|
55
|
+
* demoted to tabindex=-1. Drive the focus ring from ':host(:focus-visible)'
|
|
56
|
+
* so keyboard users still see a visible affordance. Codex round-11 P1.
|
|
57
|
+
*/
|
|
58
|
+
:host(:focus-visible) .switch__track {
|
|
59
|
+
outline: var(--hx-focus-ring-width, 2px) solid
|
|
60
|
+
var(--hx-switch-focus-ring-color, var(--hx-focus-ring-color, #0f7078));
|
|
61
|
+
outline-offset: var(--hx-focus-ring-offset, 2px);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/*
|
|
65
|
+
* Fallback (no-IDL-ref) path: the host carries tabindex=-1 and the inner
|
|
66
|
+
* track button is the tab target. Native :focus-visible drives the ring.
|
|
67
|
+
*/
|
|
52
68
|
.switch__track:focus-visible {
|
|
53
69
|
outline: var(--hx-focus-ring-width, 2px) solid
|
|
54
70
|
var(--hx-switch-focus-ring-color, var(--hx-focus-ring-color, #0f7078));
|
|
@@ -186,6 +202,7 @@
|
|
|
186
202
|
border: 2px solid ButtonText;
|
|
187
203
|
}
|
|
188
204
|
|
|
205
|
+
:host(:focus-visible) .switch__track,
|
|
189
206
|
.switch__track:focus-visible {
|
|
190
207
|
outline: 3px solid Highlight;
|
|
191
208
|
outline-offset: 2px;
|
|
@@ -34,6 +34,22 @@
|
|
|
34
34
|
-webkit-user-select: none;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
/*
|
|
38
|
+
* Host-focus path: on the modern (IDL element-references) render branch the
|
|
39
|
+
* host is the tabbable surface (tabindex=0) and the inner <button> is
|
|
40
|
+
* demoted to tabindex=-1. Drive the focus ring from ':host(:focus-visible)'
|
|
41
|
+
* so keyboard users still see a visible affordance. Codex round-11 P1.
|
|
42
|
+
*/
|
|
43
|
+
:host(:focus-visible) .button {
|
|
44
|
+
outline: var(--hx-focus-ring-width, 2px) solid
|
|
45
|
+
var(--hx-toggle-button-focus-ring-color, var(--hx-focus-ring-color, #0f7078));
|
|
46
|
+
outline-offset: var(--hx-focus-ring-offset, 2px);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/*
|
|
50
|
+
* Fallback (no-IDL-ref) path: the host carries tabindex=-1 and the inner
|
|
51
|
+
* <button> is the tab target. Native :focus-visible drives the ring.
|
|
52
|
+
*/
|
|
37
53
|
.button:focus-visible {
|
|
38
54
|
outline: var(--hx-focus-ring-width, 2px) solid
|
|
39
55
|
var(--hx-toggle-button-focus-ring-color, var(--hx-focus-ring-color, #0f7078));
|
|
@@ -232,6 +248,7 @@
|
|
|
232
248
|
border: 2px solid ButtonText;
|
|
233
249
|
}
|
|
234
250
|
|
|
251
|
+
:host(:focus-visible) .button,
|
|
235
252
|
.button:focus-visible {
|
|
236
253
|
outline: 3px solid Highlight;
|
|
237
254
|
outline-offset: 2px;
|
package/dist/css/index.css
CHANGED