@helixui/react 3.3.1 → 3.4.1

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.
Files changed (108) hide show
  1. package/dist/components/HxAccordionItem/HxAccordionItem.d.ts +35 -0
  2. package/dist/components/HxAccordionItem/HxAccordionItem.d.ts.map +1 -1
  3. package/dist/components/HxColorPicker/types.d.ts +16 -1
  4. package/dist/components/HxColorPicker/types.d.ts.map +1 -1
  5. package/dist/components/HxCombobox/types.d.ts +1 -1
  6. package/dist/components/HxCombobox/types.d.ts.map +1 -1
  7. package/dist/components/HxDatePicker/types.d.ts +4 -0
  8. package/dist/components/HxDatePicker/types.d.ts.map +1 -1
  9. package/dist/components/HxDialog/HxDialog.d.ts +78 -0
  10. package/dist/components/HxDialog/HxDialog.d.ts.map +1 -1
  11. package/dist/components/HxDrawer/HxDrawer.d.ts +53 -0
  12. package/dist/components/HxDrawer/HxDrawer.d.ts.map +1 -1
  13. package/dist/components/HxDropdown/HxDropdown.d.ts +45 -0
  14. package/dist/components/HxDropdown/HxDropdown.d.ts.map +1 -1
  15. package/dist/components/HxField/HxField.d.ts +20 -0
  16. package/dist/components/HxField/HxField.d.ts.map +1 -1
  17. package/dist/components/HxIconButton/types.d.ts +5 -0
  18. package/dist/components/HxIconButton/types.d.ts.map +1 -1
  19. package/dist/components/HxLink/types.d.ts +4 -0
  20. package/dist/components/HxLink/types.d.ts.map +1 -1
  21. package/dist/components/HxList/HxList.d.ts +6 -0
  22. package/dist/components/HxList/HxList.d.ts.map +1 -1
  23. package/dist/components/HxListItem/HxListItem.d.ts +8 -0
  24. package/dist/components/HxListItem/HxListItem.d.ts.map +1 -1
  25. package/dist/components/HxMenu/HxMenu.d.ts +15 -0
  26. package/dist/components/HxMenu/HxMenu.d.ts.map +1 -1
  27. package/dist/components/HxMenu/types.d.ts +4 -2
  28. package/dist/components/HxMenu/types.d.ts.map +1 -1
  29. package/dist/components/HxMenuDivider/HxMenuDivider.d.ts +7 -0
  30. package/dist/components/HxMenuDivider/HxMenuDivider.d.ts.map +1 -1
  31. package/dist/components/HxMenuItem/HxMenuItem.d.ts +15 -1
  32. package/dist/components/HxMenuItem/HxMenuItem.d.ts.map +1 -1
  33. package/dist/components/HxMeter/HxMeter.d.ts +10 -0
  34. package/dist/components/HxMeter/HxMeter.d.ts.map +1 -1
  35. package/dist/components/HxOverflowMenu/HxOverflowMenu.d.ts +19 -0
  36. package/dist/components/HxOverflowMenu/HxOverflowMenu.d.ts.map +1 -1
  37. package/dist/components/HxOverflowMenu/types.d.ts +3 -1
  38. package/dist/components/HxOverflowMenu/types.d.ts.map +1 -1
  39. package/dist/components/HxPopover/HxPopover.d.ts +40 -0
  40. package/dist/components/HxPopover/HxPopover.d.ts.map +1 -1
  41. package/dist/components/HxProgressBar/HxProgressBar.d.ts +12 -0
  42. package/dist/components/HxProgressBar/HxProgressBar.d.ts.map +1 -1
  43. package/dist/components/HxSelect/HxSelect.d.ts +1 -0
  44. package/dist/components/HxSelect/HxSelect.d.ts.map +1 -1
  45. package/dist/components/HxSelect/index.js +1 -1
  46. package/dist/components/HxSelect/types.d.ts +2 -0
  47. package/dist/components/HxSelect/types.d.ts.map +1 -1
  48. package/dist/components/HxSplitButton/HxSplitButton.d.ts +21 -0
  49. package/dist/components/HxSplitButton/HxSplitButton.d.ts.map +1 -1
  50. package/dist/components/HxSplitButton/types.d.ts +0 -8
  51. package/dist/components/HxSplitButton/types.d.ts.map +1 -1
  52. package/dist/components/HxStat/HxStat.d.ts +7 -0
  53. package/dist/components/HxStat/HxStat.d.ts.map +1 -1
  54. package/dist/components/HxTab/HxTab.d.ts +10 -0
  55. package/dist/components/HxTab/HxTab.d.ts.map +1 -1
  56. package/dist/components/HxTabPanel/HxTabPanel.d.ts +6 -0
  57. package/dist/components/HxTabPanel/HxTabPanel.d.ts.map +1 -1
  58. package/dist/components/HxTabs/HxTabs.d.ts +10 -0
  59. package/dist/components/HxTabs/HxTabs.d.ts.map +1 -1
  60. package/dist/components/HxTabs/types.d.ts +10 -3
  61. package/dist/components/HxTabs/types.d.ts.map +1 -1
  62. package/dist/components/HxTd/HxTd.d.ts +5 -0
  63. package/dist/components/HxTd/HxTd.d.ts.map +1 -1
  64. package/dist/components/HxTd/types.d.ts +7 -3
  65. package/dist/components/HxTd/types.d.ts.map +1 -1
  66. package/dist/components/HxTh/HxTh.d.ts +6 -0
  67. package/dist/components/HxTh/HxTh.d.ts.map +1 -1
  68. package/dist/components/HxTimePicker/types.d.ts +4 -0
  69. package/dist/components/HxTimePicker/types.d.ts.map +1 -1
  70. package/dist/components/HxTooltip/HxTooltip.d.ts +31 -0
  71. package/dist/components/HxTooltip/HxTooltip.d.ts.map +1 -1
  72. package/dist/components/HxTr/HxTr.d.ts +8 -0
  73. package/dist/components/HxTr/HxTr.d.ts.map +1 -1
  74. package/dist/components/HxTreeItem/HxTreeItem.d.ts +21 -0
  75. package/dist/components/HxTreeItem/HxTreeItem.d.ts.map +1 -1
  76. package/dist/components/HxTreeView/HxTreeView.d.ts +14 -4
  77. package/dist/components/HxTreeView/HxTreeView.d.ts.map +1 -1
  78. package/dist/components/HxTreeView/types.d.ts +5 -2
  79. package/dist/components/HxTreeView/types.d.ts.map +1 -1
  80. package/dist/index.js +1 -1
  81. package/dist/shared/HxAccordionItem-C26EIvJG.js.map +1 -1
  82. package/dist/shared/HxDialog-DMF3crTa.js.map +1 -1
  83. package/dist/shared/HxDrawer-Y1QnaHrU.js.map +1 -1
  84. package/dist/shared/HxDropdown-DJiYTVXP.js.map +1 -1
  85. package/dist/shared/HxField-CbrmkDYu.js.map +1 -1
  86. package/dist/shared/HxList-B35ueWrO.js.map +1 -1
  87. package/dist/shared/HxListItem-DegXnlK0.js.map +1 -1
  88. package/dist/shared/HxMenu-B1tRT8Lm.js.map +1 -1
  89. package/dist/shared/HxMenuDivider-RE1AMxqi.js.map +1 -1
  90. package/dist/shared/HxMenuItem-CLdUUCJS.js.map +1 -1
  91. package/dist/shared/HxMeter-C3R4U7cD.js.map +1 -1
  92. package/dist/shared/HxOverflowMenu-CdTWx4X5.js.map +1 -1
  93. package/dist/shared/HxPopover-D0zfUXPF.js.map +1 -1
  94. package/dist/shared/HxProgressBar-FupceIzI.js.map +1 -1
  95. package/dist/shared/{HxSelect-BEm8srcF.js → HxSelect-BAt_veRr.js} +3 -2
  96. package/dist/shared/{HxSelect-BEm8srcF.js.map → HxSelect-BAt_veRr.js.map} +1 -1
  97. package/dist/shared/HxSplitButton-BVNWYaAl.js.map +1 -1
  98. package/dist/shared/HxStat-C_colBF2.js.map +1 -1
  99. package/dist/shared/HxTab-Dhb27BDp.js.map +1 -1
  100. package/dist/shared/HxTabPanel-CmFKupoK.js.map +1 -1
  101. package/dist/shared/HxTabs-DIIy0X3K.js.map +1 -1
  102. package/dist/shared/HxTd-l5ZrD1Ai.js.map +1 -1
  103. package/dist/shared/HxTh-Bo7R_MVI.js.map +1 -1
  104. package/dist/shared/HxTooltip-DD8Uc78f.js.map +1 -1
  105. package/dist/shared/HxTr-CjhQyD3e.js.map +1 -1
  106. package/dist/shared/HxTreeItem-B2_rGgy6.js.map +1 -1
  107. package/dist/shared/HxTreeView-BKbPPPhF.js.map +1 -1
  108. package/package.json +2 -2
@@ -3,6 +3,41 @@ import { HxAccordionItemProps } from './types.js';
3
3
  export type { HxAccordionItemProps };
4
4
  /**
5
5
  * An individual accordion item with collapsible content.
6
+
7
+ ## Architecture Note: Slot Projection vs. Host-Canonical (group-4 round-1)
8
+
9
+ `hx-accordion-item` deliberately does NOT participate in the
10
+ host-canonical / `internals.ariaLabelledByElements` pattern used by every
11
+ other group-2/3/4 component. Rationale:
12
+
13
+ 1. The trigger label comes from `<slot name="trigger">` — consumer
14
+ light-DOM projected directly into the `<summary>` element. AT reads
15
+ the slot-projected text natively because slot projection preserves
16
+ accessible name (the `<summary>` IS the heading and consumes the
17
+ slotted text in its own accessible name computation).
18
+ 2. `aria-labelledby="${_uid}-trigger"` on the inner content region and
19
+ `aria-controls="${_uid}-content"` on the summary BOTH resolve
20
+ same-shadow-root, which works correctly across every AT — these
21
+ IDREFs never cross a shadow boundary.
22
+ 3. Pushing these ids through `internals.ariaLabelledByElements` would
23
+ either duplicate the wiring (heading announced twice) or break the
24
+ native `<details>/<summary>` toggle semantics (the host carrying
25
+ `role="heading"` would shadow the summary's own heading projection).
26
+
27
+ `role="heading"` on `<summary>` (with `aria-level=N`) is the APG-canonical
28
+ Accordion pattern. Per the APG note, `<summary>` MUST be a direct child
29
+ of `<details>` for the native toggle to function — wrapping it in an
30
+ `<h3>` would forfeit native disclosure. The role-on-summary approach is
31
+ the authoritative compromise. NVDA, JAWS, and VoiceOver all announce the
32
+ summary as a heading at the configured level when this pattern is used.
33
+
34
+ `aria-controls` on the summary points at the shadow-internal content
35
+ region; APG marks the relationship as implicit via the heading + region
36
+ structure, so AT not following the IDREF still announces correctly. The
37
+ IDREF is a hint, not a requirement — and because both ids are in the
38
+ same shadow root, it resolves cleanly when AT does follow it. This
39
+ matches the popover/dropdown intentional `aria-controls` omission for
40
+ the cross-shadow case (see those components' code comments).
6
41
  *
7
42
  * @example
8
43
  * ```tsx
@@ -1 +1 @@
1
- {"version":3,"file":"HxAccordionItem.d.ts","sourceRoot":"","sources":["../../../src/components/HxAccordionItem/HxAccordionItem.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,kBAAkB,EAAE,MAAM,0CAA0C,CAAC;AAE9E,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEvD,YAAY,EAAE,oBAAoB,EAAE,CAAC;AAErC;;;;;;;;;GASG;AACH,eAAO,MAAM,eAAe;;;EAS1B,CAAC;AAEH,eAAe,eAAe,CAAC"}
1
+ {"version":3,"file":"HxAccordionItem.d.ts","sourceRoot":"","sources":["../../../src/components/HxAccordionItem/HxAccordionItem.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,kBAAkB,EAAE,MAAM,0CAA0C,CAAC;AAE9E,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEvD,YAAY,EAAE,oBAAoB,EAAE,CAAC;AAErC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,eAAO,MAAM,eAAe;;;EAS1B,CAAC;AAEH,eAAe,eAAe,CAAC"}
@@ -42,7 +42,22 @@ export interface HxColorPickerProps {
42
42
  labelColorValue?: string;
43
43
  /** Accessible label for the color picker dialog/panel. */
44
44
  labelPicker?: string;
45
- /** Generates the accessible label for the trigger button. */
45
+ /** Visible label rendered above the trigger. When set this becomes the
46
+ announced name of the trigger surface unless a stronger source
47
+ (`aria-labelledby`, `aria-label`, or `accessible-label`) is supplied. */
48
+ label?: string | undefined;
49
+ /** Visually-hidden accessible name. Highest-priority self-naming source —
50
+ outranks `label`, slotted label content, and the generated trigger label,
51
+ but defers to consumer `aria-labelledby` (effective) and `aria-label`. */
52
+ accessibleLabel?: string | undefined;
53
+ /** Help text rendered below the trigger and joined into the host's
54
+ announced description channel. */
55
+ helpText?: string | undefined;
56
+ /** Error message. When non-empty, marks the trigger surface as `aria-invalid`
57
+ and joins the host's announced description channel via a live alert. */
58
+ error?: string | undefined;
59
+ /** Generates the accessible label for the trigger button when no other
60
+ naming source is provided. */
46
61
  labelTrigger?: string;
47
62
  /** Dispatched while dragging sliders or grid. */
48
63
  onHxInput?: (event: Event) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/HxColorPicker/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,MAAM,WAAW,kBAAkB;IACjC,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,qBAAqB;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oBAAoB;IACpB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,iDAAiD;IACjD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yCAAyC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wFAAwF;IACxF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;6BAGyB;IACzB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB;wDACoD;IACpD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,uCAAuC;IACvC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,8CAA8C;IAC9C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oEAAoE;IACpE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,sDAAsD;IACtD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+CAA+C;IAC/C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,8DAA8D;IAC9D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qDAAqD;IACrD,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,kDAAkD;IAClD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,0DAA0D;IAC1D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6DAA6D;IAC7D,YAAY,CAAC,EAAE,MAAM,CAAC;IAGtB,iDAAiD;IACjD,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACnC,4CAA4C;IAC5C,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CACrC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/HxColorPicker/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,MAAM,WAAW,kBAAkB;IACjC,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,qBAAqB;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oBAAoB;IACpB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,iDAAiD;IACjD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yCAAyC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wFAAwF;IACxF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;6BAGyB;IACzB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB;wDACoD;IACpD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,uCAAuC;IACvC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,8CAA8C;IAC9C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oEAAoE;IACpE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,sDAAsD;IACtD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+CAA+C;IAC/C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,8DAA8D;IAC9D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qDAAqD;IACrD,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,kDAAkD;IAClD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,0DAA0D;IAC1D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;0EAEsE;IACtE,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B;;2EAEuE;IACvE,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC;mCAC+B;IAC/B,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B;yEACqE;IACrE,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B;+BAC2B;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;IAGtB,iDAAiD;IACjD,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACnC,4CAA4C;IAC5C,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CACrC"}
@@ -40,7 +40,7 @@ export interface HxComboboxProps {
40
40
  inputs with associated labels delegate accessible naming via `<label>`
41
41
  association and `aria-labelledby`, not host-level ARIA delegation. The
42
42
  `accessible-label` attribute is a fallback for label-free usage. The value is forwarded to the
43
- internal input's `aria-label`. */
43
+ host's `internals.ariaLabel` on the modern path. */
44
44
  accessibleLabel?: string | null;
45
45
  /** Text shown when no options match the current filter. */
46
46
  labelNoOptions?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/HxCombobox/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,MAAM,WAAW,eAAe;IAC9B,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,qBAAqB;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oBAAoB;IACpB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,+CAA+C;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oEAAoE;IACpE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yCAAyC;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,wCAAwC;IACxC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,yCAAyC;IACzC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2EAA2E;IAC3E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oCAAoC;IACpC,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,gDAAgD;IAChD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qEAAqE;IACrE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,kEAAkE;IAClE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,iEAAiE;IACjE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;;;;mCAQ+B;IAC/B,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,2DAA2D;IAC3D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,qEAAqE;IACrE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,2EAA2E;IAC3E,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAG3B,yCAAyC;IACzC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAClC,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAClC,sDAAsD;IACtD,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACnC,qDAAqD;IACrD,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACnC,6CAA6C;IAC7C,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CACrC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/HxCombobox/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,MAAM,WAAW,eAAe;IAC9B,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,qBAAqB;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oBAAoB;IACpB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,+CAA+C;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oEAAoE;IACpE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yCAAyC;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,wCAAwC;IACxC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,yCAAyC;IACzC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2EAA2E;IAC3E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oCAAoC;IACpC,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,gDAAgD;IAChD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qEAAqE;IACrE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,kEAAkE;IAClE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,iEAAiE;IACjE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;;;;qDAQiD;IACjD,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,2DAA2D;IAC3D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,qEAAqE;IACrE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,2EAA2E;IAC3E,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAG3B,yCAAyC;IACzC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAClC,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAClC,sDAAsD;IACtD,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACnC,qDAAqD;IACrD,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACnC,6CAA6C;IAC7C,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CACrC"}
@@ -40,6 +40,10 @@ export interface HxDatePickerProps {
40
40
  previousMonthLabel?: string;
41
41
  /** Accessible label for the next month navigation button. */
42
42
  nextMonthLabel?: string;
43
+ /** Accessible name for screen readers, if different from the visible label.
44
+ Uses `accessible-label` attribute instead of `aria-label` to avoid
45
+ ARIAMixin shadowing on the host element. Highest-precedence naming source. */
46
+ accessibleLabel?: string | null;
43
47
  /** Emitted when the selected date changes. */
44
48
  onHxChange?: (event: Event) => void;
45
49
  }
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/HxDatePicker/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,MAAM,WAAW,iBAAiB;IAChC,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,qBAAqB;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oBAAoB;IACpB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,uDAAuD;IACvD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,sEAAsE;IACtE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yDAAyD;IACzD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,yDAAyD;IACzD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,8BAA8B;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yDAAyD;IACzD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qCAAqC;IACrC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,2EAA2E;IAC3E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kEAAkE;IAClE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2DAA2D;IAC3D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qEAAqE;IACrE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gDAAgD;IAChD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,oFAAoF;IACpF,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,kFAAkF;IAClF,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,iEAAiE;IACjE,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,6DAA6D;IAC7D,cAAc,CAAC,EAAE,MAAM,CAAC;IAGxB,8CAA8C;IAC9C,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CACrC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/HxDatePicker/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,MAAM,WAAW,iBAAiB;IAChC,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,qBAAqB;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oBAAoB;IACpB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,uDAAuD;IACvD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,sEAAsE;IACtE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yDAAyD;IACzD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,yDAAyD;IACzD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,8BAA8B;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yDAAyD;IACzD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qCAAqC;IACrC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,2EAA2E;IAC3E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kEAAkE;IAClE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2DAA2D;IAC3D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qEAAqE;IACrE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gDAAgD;IAChD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,oFAAoF;IACpF,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,kFAAkF;IAClF,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,iEAAiE;IACjE,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,6DAA6D;IAC7D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;+EAE2E;IAC3E,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAGhC,8CAA8C;IAC9C,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CACrC"}
@@ -5,6 +5,84 @@ export type { HxDialogProps };
5
5
  * A modal and non-modal dialog component built on the native HTML `<dialog>` element.
6
6
  Provides focus trapping, backdrop interaction, keyboard navigation, and full
7
7
  ARIA labelling for enterprise healthcare accessibility requirements.
8
+
9
+ ## Architecture Note: Host-Canonical ARIA (group-4a round-1, Path A — native-dialog adaptation)
10
+
11
+ Unlike `hx-drawer` (which uses an inner `<div role="dialog">` and can fully
12
+ host-canonicalize the role), `hx-dialog` is built on the native
13
+ `<dialog>` HTMLDialogElement. The native element has an **implicit
14
+ `role="dialog"`** baked in by the browser that **cannot be stripped**, so
15
+ full host-canonical role takeover would create nested-dialog announcements.
16
+
17
+ **Path A (adopted):** the host owns label / description projection via
18
+ `ElementInternals` (`internals.ariaLabelledByElements`,
19
+ `internals.ariaDescribedByElements`, `internals.ariaLabel`) but **does NOT**
20
+ set `internals.role`. The native inner `<dialog>` continues to be the
21
+ announced surface. Consumer light-DOM IDREFs project across the shadow
22
+ boundary via `internals.aria*Elements` on the host.
23
+
24
+ **Hybrid fallback (always-on belt-and-suspenders):** because some assistive
25
+ technologies may walk the native `<dialog>` first and ignore host
26
+ `internals.aria*Elements`, the resolved label / description text is **also**
27
+ serialized into `aria-label` / `aria-describedby` on the inner native
28
+ `<dialog>` element. Consumers therefore get name/description on every AT,
29
+ with the IDL-ref path providing live DOM-text-update tracking when the AT
30
+ honours it. This forfeits live-text tracking on the inner-dialog fallback
31
+ (the serialized text is recomputed on every sync, which is good enough since
32
+ mutation observers re-fire `_syncHostAriaSemantics` on consumer text edits).
33
+
34
+ Why we do NOT set `internals.role = 'alertdialog'` either: setting role on
35
+ the host while the native `<dialog>` keeps `role="dialog"` would announce
36
+ BOTH a host alertdialog AND an inner dialog. Instead, the alertdialog
37
+ variant continues to write `role="alertdialog"` directly on the inner
38
+ `<dialog>` element (the platform allows overriding the implicit `dialog`
39
+ role with the more specific `alertdialog`).
40
+
41
+ Naming precedence (W3C AccName 1.2 §4.3.1):
42
+
43
+ 1. Consumer `aria-labelledby` on the host — IDREFs resolved across the
44
+ shadow boundary via `resolveIdrefTokens` (closest scope first, then
45
+ ancestor shadow hosts, then owner document).
46
+ 2. Consumer `aria-label` on the host.
47
+ 3. `<slot name="header">` text content (multi-node aggregation per
48
+ AccName 1.2 §4.3.10 — decorative `aria-hidden` / `[hidden]` subtrees
49
+ contribute zero to the name).
50
+ 4. `heading` property — explicit author-provided heading text.
51
+ 5. Hard-coded literal `"Dialog"` (last-resort accessible name).
52
+
53
+ Description channel: the host's `internals.ariaDescribedByElements` carries
54
+ the resolved IDREF chain on the modern path. The inner native `<dialog>` ALSO
55
+ receives a serialized `aria-describedby` chain — when a consumer description
56
+ resolves, a synthesized in-shadow `<span id="${id}-consumer-desc">` is
57
+ appended to the existing `description` span (if any) and the inner
58
+ `<dialog>`'s `aria-describedby` references both same-root ids. `aria-description`
59
+ is intentionally NEVER written — W3C AccName ignores it whenever
60
+ `aria-describedby` is also present.
61
+
62
+ Slot mutation observers track:
63
+ 1. The header slot's text content (in-place i18n re-renders).
64
+ 2. Consumer-resolved external IDREF targets (so a consumer mutating
65
+ `<label id="x">Patient</label>` in place re-flows the name).
66
+ 3. Host attribute mutations (delegated to `installAriaIdrefMirror`,
67
+ which also catches late-inserted IDREF targets and id renames in
68
+ every relevant root).
69
+ 4. Authentic consumer `aria-describedby` retraction (oldValue !== null &&
70
+ newValue === null) via a dedicated `attributeOldValue: true` observer.
71
+
72
+ **First-paint slot state seeding intentionally omitted:** seeding
73
+ `_hasHeaderSlot` / `_headerSlotText` from `firstUpdated()` would schedule an
74
+ extra Lit re-render that subtly reorders the open-dialog promise chain
75
+ (`updateComplete.then(...) → showModal() → updateComplete.then(...) →
76
+ focus first focusable`). On Chromium, that reordering interleaves the
77
+ native dialog's modal activation with the focus-restore step and causes
78
+ focus-trap test failures. The slotchange handler runs one microtask later
79
+ and `_syncHostAriaSemantics()` from `updated()` picks up the resolved state
80
+ on the next paint — close enough that AT never observes the unnamed window.
81
+ Mirrors the same intentional decision documented in hx-drawer round-1.
82
+
83
+ Focus trap, ESC dismiss with `hx-cancel` BEFORE `hx-close`, focus-restore
84
+ via `_triggerElement`, and native `showModal()` semantics are unchanged
85
+ from the pre-host-canonical implementation.
8
86
  *
9
87
  * @example
10
88
  * ```tsx
@@ -1 +1 @@
1
- {"version":3,"file":"HxDialog.d.ts","sourceRoot":"","sources":["../../../src/components/HxDialog/HxDialog.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,WAAW,EAAE,MAAM,uCAAuC,CAAC;AAEpE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,YAAY,EAAE,aAAa,EAAE,CAAC;AAE9B;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,QAAQ;;;;EAUnB,CAAC;AAEH,eAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"HxDialog.d.ts","sourceRoot":"","sources":["../../../src/components/HxDialog/HxDialog.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,WAAW,EAAE,MAAM,uCAAuC,CAAC;AAEpE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,YAAY,EAAE,aAAa,EAAE,CAAC;AAE9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyFG;AACH,eAAO,MAAM,QAAQ;;;;EAUnB,CAAC;AAEH,eAAe,QAAQ,CAAC"}
@@ -6,6 +6,59 @@ export type { HxDrawerProps };
6
6
  Supports focus trapping, overlay backdrop, keyboard navigation, and full
7
7
  ARIA labelling for enterprise healthcare accessibility requirements.
8
8
 
9
+ ## Architecture Note: Host-Canonical ARIA (group-4 round-1, Path A)
10
+
11
+ The host carries the announced dialog semantics via `ElementInternals`:
12
+
13
+ - `internals.role = 'dialog'` (the host IS the dialog surface)
14
+ - `internals.ariaModal = 'true'` (modality declared on host)
15
+ - `internals.ariaLabelledByElements` / `internals.ariaDescribedByElements`
16
+ project consumer light-DOM IDREFs across the shadow boundary.
17
+ - `internals.ariaLabel` carries the resolved fallback name when no
18
+ IDREF chain or slotted title exists.
19
+
20
+ The inner `<div part="overlay">` no longer carries `role`, `aria-modal`,
21
+ `aria-labelledby`, or `aria-label` — those would create a nested-dialog
22
+ announcement above the host's canonical surface. Belt-and-suspenders
23
+ fallback: when the runtime does NOT expose IDL element references on
24
+ `ElementInternals` (older Firefox / Safari builds), the resolved label
25
+ text is text-flattened and written to the inner overlay's `aria-label`
26
+ so AT walking down from the host still finds an announceable name.
27
+
28
+ Naming precedence (W3C AccName 1.2 §4.3.1):
29
+
30
+ 1. Consumer `aria-labelledby` on the host — IDREFs resolved across the
31
+ shadow boundary via `resolveIdrefTokens` (same scope walk used by
32
+ every host-canonical hx-* control: own root → ancestor shadow hosts
33
+ → owner document → slot owners).
34
+ 2. Consumer `aria-label` on the host.
35
+ 3. `<slot name="label">` text content (multi-node aggregation per
36
+ AccName 1.2 §4.3.10 — decorative `aria-hidden` / `[hidden]` subtrees
37
+ contribute zero to the name).
38
+ 4. `label` property — explicit author fallback string.
39
+ 5. Hard-coded literal `"Drawer"` (last-resort accessible name).
40
+
41
+ Description channel: a synthesized `<span id="${id}-consumer-desc">` is
42
+ rendered inside the shadow root and updated to mirror consumer-resolved
43
+ description text. The host's `internals.ariaDescribedByElements` carries
44
+ the live element references on the modern path; the in-shadow span is the
45
+ fallback target for AT that does not walk IDL refs. `aria-description` is
46
+ intentionally NEVER written — the W3C AccName algorithm ignores it
47
+ whenever `aria-describedby` is also present.
48
+
49
+ Slot mutation observers track:
50
+ 1. The label slot's text content (in-place i18n re-renders).
51
+ 2. Consumer-resolved external IDREF targets (so a consumer mutating
52
+ `<label id="x">Patient</label>` in place re-flows the name).
53
+ 3. Host attribute mutations (delegated to `installAriaIdrefMirror`,
54
+ which also catches late-inserted IDREF targets and id renames in
55
+ every relevant root).
56
+
57
+ Focus trap, ESC dismiss, focus-restore, and the inert-outside-content
58
+ sibling-walk are unchanged from the pre-host-canonical implementation —
59
+ they operate against the shadow-internal panel which is still the focus
60
+ target for keyboard users.
61
+
9
62
  ## Architecture Note: Native `<dialog>` Migration
10
63
 
11
64
  This component currently uses `role="dialog"` + `aria-modal="true"` on a
@@ -1 +1 @@
1
- {"version":3,"file":"HxDrawer.d.ts","sourceRoot":"","sources":["../../../src/components/HxDrawer/HxDrawer.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,WAAW,EAAE,MAAM,uCAAuC,CAAC;AAEpE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,YAAY,EAAE,aAAa,EAAE,CAAC;AAE9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,eAAO,MAAM,QAAQ;;;;;;EAYnB,CAAC;AAEH,eAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"HxDrawer.d.ts","sourceRoot":"","sources":["../../../src/components/HxDrawer/HxDrawer.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,WAAW,EAAE,MAAM,uCAAuC,CAAC;AAEpE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,YAAY,EAAE,aAAa,EAAE,CAAC;AAE9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuFG;AACH,eAAO,MAAM,QAAQ;;;;;;EAYnB,CAAC;AAEH,eAAe,QAAQ,CAAC"}
@@ -3,6 +3,51 @@ import { HxDropdownProps } from './types.js';
3
3
  export type { HxDropdownProps };
4
4
  /**
5
5
  * A dropdown component — a button that opens a floating panel on click.
6
+
7
+ ## Architecture Note: Host-Attribute Label Mirror (group-4 round-1)
8
+
9
+ The announced surface is the inner `[part="panel"]` element, which carries
10
+ `role="menu"`. The host wraps a slotted trigger and the floating panel and
11
+ does NOT claim a role itself (apart from the round-35-style host
12
+ `aria-expanded` fallback used only when the trigger slot is empty).
13
+
14
+ Because the panel lives in shadow DOM and `ElementInternals` IDL refs on
15
+ the host project semantics OUTWARD (host → AT) rather than INWARD
16
+ (host → shadow descendant), we use the **host-attribute mirror** pattern:
17
+ resolve consumer `aria-labelledby` IDREFs against the host's composed-tree
18
+ roots, text-flatten via `flattenAccName`, and write the result to the
19
+ panel's `aria-label`. Host `aria-label` outranks the `label` property in
20
+ the same precedence used by every host-canonical hx-* control.
21
+
22
+ Naming precedence (W3C AccName 1.2 §4.3.1):
23
+ 1. Host `aria-labelledby` (resolved IDREFs, text-flattened)
24
+ 2. Host `aria-label`
25
+ 3. `label` property
26
+ 4. Hard-coded literal `"Menu"` (last-resort accessible name)
27
+
28
+ **Group 4b → Group 5b boundary:** Group 4b added the host-attribute
29
+ label mirror **only** — additive on top of the existing dropdown
30
+ behaviour. Group 5b (this commit) adds the composite-navigation
31
+ portion that 4b explicitly deferred:
32
+ - **Roving tabindex** inside the panel (`_applyRovingTabIndex` +
33
+ `_rovingIndex`). Only the focused item carries `tabindex=0`.
34
+ - **First-character typeahead** with 500ms timeout (`_handleTypeahead`)
35
+ matching `hx-menu`, `hx-overflow-menu`, `hx-split-button`.
36
+ - Submenu auto-handling is delegated to slotted `hx-menu` /
37
+ `hx-menu-item` (whose `hx-item-submenu-open` / `hx-item-submenu-close`
38
+ events are auto-handled by the parent `hx-menu` after Group 5b).
39
+
40
+ The panel's inner-div `role="menu"` is intentionally NOT migrated to
41
+ the host: the host wraps a slotted consumer trigger AND the panel,
42
+ so it cannot canonically carry the menu role. Slotted `hx-menu-item`
43
+ children carry `role="menuitem"` on their HOST after Group 5b's menu
44
+ migration, which fixes the cross-shadow walk concern from the
45
+ consumer's perspective.
46
+
47
+ `aria-controls` is intentionally omitted on the trigger: the panel lives
48
+ in shadow DOM and IDREF values cannot be resolved across shadow
49
+ boundaries by assistive technology (axe-core flags this as a critical
50
+ violation if attempted). See `_setupTriggerAria` for the inline note.
6
51
  *
7
52
  * @example
8
53
  * ```tsx
@@ -1 +1 @@
1
- {"version":3,"file":"HxDropdown.d.ts","sourceRoot":"","sources":["../../../src/components/HxDropdown/HxDropdown.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAExE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,YAAY,EAAE,eAAe,EAAE,CAAC;AAEhC;;;;;;;;;GASG;AACH,eAAO,MAAM,UAAU;;;;EAUrB,CAAC;AAEH,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"HxDropdown.d.ts","sourceRoot":"","sources":["../../../src/components/HxDropdown/HxDropdown.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAExE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,YAAY,EAAE,eAAe,EAAE,CAAC;AAEhC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AACH,eAAO,MAAM,UAAU;;;;EAUrB,CAAC;AAEH,eAAe,UAAU,CAAC"}
@@ -13,6 +13,26 @@ into its light DOM children for ARIA describedby linkage across the shadow
13
13
  DOM boundary. This span has `id="${fieldId}-desc"` and is removed on
14
14
  `disconnectedCallback`. This is an intentional, documented accessibility
15
15
  mechanism.
16
+
17
+ **`aria-label` ownership model:** When `label` is set and no shadow `<label>`
18
+ is rendered, hx-field writes `aria-label` to the slotted control and stamps
19
+ a `data-hx-owns-label="true"` ownership marker.
20
+
21
+ Consumers have two ways to keep their value safe from hx-field's writes:
22
+ (a) **Suspend** all ARIA bridging by setting `data-aria-managed` on the
23
+ control. While present, hx-field skips every aria-* mutation and
24
+ leaves any existing marker/snapshot in place — removing
25
+ `data-aria-managed` later may resume host ownership of an `aria-label`
26
+ value that still matches the snapshot.
27
+ (b) **Release** ownership permanently by overwriting `aria-label` to a
28
+ different value than the one hx-field last wrote. The mismatch
29
+ triggers `_releaseHostOwnedAriaLabel`, which strips the marker and
30
+ clears the snapshot, transferring ownership to the consumer.
31
+
32
+ **Limitation:** because release detection is snapshot-based, a consumer
33
+ rewrite to the *exact same value* hx-field last wrote is invisible. To
34
+ genuinely take ownership in that case the consumer must write a different
35
+ value (even briefly), or remove the `data-hx-owns-label` marker themselves.
16
36
  *
17
37
  * @example
18
38
  * ```tsx
@@ -1 +1 @@
1
- {"version":3,"file":"HxField.d.ts","sourceRoot":"","sources":["../../../src/components/HxField/HxField.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,UAAU,EAAE,MAAM,sCAAsC,CAAC;AAElE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,YAAY,EAAE,YAAY,EAAE,CAAC;AAE7B;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,OAAO,wDAMlB,CAAC;AAEH,eAAe,OAAO,CAAC"}
1
+ {"version":3,"file":"HxField.d.ts","sourceRoot":"","sources":["../../../src/components/HxField/HxField.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,UAAU,EAAE,MAAM,sCAAsC,CAAC;AAElE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,YAAY,EAAE,YAAY,EAAE,CAAC;AAE7B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,eAAO,MAAM,OAAO,wDAMlB,CAAC;AAEH,eAAe,OAAO,CAAC"}
@@ -19,6 +19,11 @@ export interface HxIconButtonProps {
19
19
  type?: 'button' | 'submit' | 'reset';
20
20
  /** Whether the button is disabled. */
21
21
  disabled?: boolean;
22
+ /** Whether the button is in a loading state. Shows the spinner, prevents
23
+ activation, and sets `aria-busy="true"` on the inner element. Does NOT
24
+ set the native `disabled` attribute (loading is transient; disabled is
25
+ persistent, and AT announces them differently). */
26
+ loading?: boolean;
22
27
  /** When set, renders an `<a>` element instead of a `<button>`. */
23
28
  href?: string | undefined;
24
29
  /** Name submitted with form data. Only applicable when rendering as a button. */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/HxIconButton/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,MAAM,WAAW,iBAAiB;IAChC,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,qBAAqB;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oBAAoB;IACpB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B;;2EAEuE;IACvE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0CAA0C;IAC1C,OAAO,CAAC,EAAE,SAAS,GAAG,WAAW,GAAG,UAAU,GAAG,QAAQ,GAAG,OAAO,CAAC;IACpE,0BAA0B;IAC1B,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B;sCACkC;IAClC,IAAI,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC;IACrC,sCAAsC;IACtC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,kEAAkE;IAClE,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,iFAAiF;IACjF,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,kFAAkF;IAClF,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAG3B,4DAA4D;IAC5D,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CACpC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/HxIconButton/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,MAAM,WAAW,iBAAiB;IAChC,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,qBAAqB;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oBAAoB;IACpB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B;;2EAEuE;IACvE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0CAA0C;IAC1C,OAAO,CAAC,EAAE,SAAS,GAAG,WAAW,GAAG,UAAU,GAAG,QAAQ,GAAG,OAAO,CAAC;IACpE,0BAA0B;IAC1B,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B;sCACkC;IAClC,IAAI,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC;IACrC,sCAAsC;IACtC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;oDAGgD;IAChD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,kEAAkE;IAClE,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,iFAAiF;IACjF,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,kFAAkF;IAClF,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAG3B,4DAA4D;IAC5D,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CACpC"}
@@ -24,6 +24,10 @@ export interface HxLinkProps {
24
24
  /** Relationship between the current document and the linked URL.
25
25
  Automatically set to "noopener noreferrer" when target="_blank". */
26
26
  rel?: string | undefined;
27
+ /** Localised announcement text appended (visually hidden) to the link's
28
+ accessible name when `target="_blank"`. Defaults to English. Override
29
+ for i18n contexts so AT users hear the new-tab notice in their locale. */
30
+ externalLabel?: string;
27
31
  /** Dispatched when the link is clicked and is not disabled. */
28
32
  onHxClick?: (event: Event) => void;
29
33
  }
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/HxLink/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,MAAM,WAAW,WAAW;IAC1B,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,qBAAqB;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oBAAoB;IACpB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,kCAAkC;IAClC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B;;0CAEsC;IACtC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,wCAAwC;IACxC,OAAO,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAC1C;;0CAEsC;IACtC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;iDAC6C;IAC7C,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B;qEACiE;IACjE,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAGzB,+DAA+D;IAC/D,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CACpC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/HxLink/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,MAAM,WAAW,WAAW;IAC1B,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,qBAAqB;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oBAAoB;IACpB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,kCAAkC;IAClC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B;;0CAEsC;IACtC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,wCAAwC;IACxC,OAAO,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAC1C;;0CAEsC;IACtC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;iDAC6C;IAC7C,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B;qEACiE;IACjE,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB;;2EAEuE;IACvE,aAAa,CAAC,EAAE,MAAM,CAAC;IAGvB,+DAA+D;IAC/D,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CACpC"}
@@ -3,6 +3,12 @@ import { HxListProps } from './types.js';
3
3
  export type { HxListProps };
4
4
  /**
5
5
  * A styled list container supporting plain, bulleted, numbered, description, and interactive variants.
6
+
7
+ Group 7 host-canonical: `role="list"` (or `role="listbox"` in interactive
8
+ mode) lives on the **host** via `_internals.role`, harmonizing with
9
+ `hx-structured-list` (the gold-standard exemplar for Group 7). The `<dl>`
10
+ description variant keeps native semantics — no host role assigned, since
11
+ `<dl>` IS the semantic surface and AT walks it directly.
6
12
  *
7
13
  * @example
8
14
  * ```tsx
@@ -1 +1 @@
1
- {"version":3,"file":"HxList.d.ts","sourceRoot":"","sources":["../../../src/components/HxList/HxList.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAC;AAEhE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,YAAY,EAAE,WAAW,EAAE,CAAC;AAE5B;;;;;;;;;GASG;AACH,eAAO,MAAM,MAAM;;EAQjB,CAAC;AAEH,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"HxList.d.ts","sourceRoot":"","sources":["../../../src/components/HxList/HxList.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAC;AAEhE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,YAAY,EAAE,WAAW,EAAE,CAAC;AAE5B;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,MAAM;;EAQjB,CAAC;AAEH,eAAe,MAAM,CAAC"}
@@ -3,6 +3,14 @@ import { HxListItemProps } from './types.js';
3
3
  export type { HxListItemProps };
4
4
  /**
5
5
  * A rich list item for use inside `hx-list`.
6
+
7
+ Group 7 host-canonical: `role="option"` (interactive listbox mode) is
8
+ mirrored onto the **host** via `_internals.role` AND the legacy
9
+ setAttribute('role',...) path. The dual-surface pattern preserves the
10
+ existing imperative host-attribute behaviour (so consumers querying
11
+ `host.getAttribute('role')` still work) while adding cross-shadow IDREF
12
+ wiring through `internals.ariaLabelledByElements` for engines that
13
+ support it.
6
14
  *
7
15
  * @example
8
16
  * ```tsx
@@ -1 +1 @@
1
- {"version":3,"file":"HxListItem.d.ts","sourceRoot":"","sources":["../../../src/components/HxListItem/HxListItem.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;AAEpE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,YAAY,EAAE,eAAe,EAAE,CAAC;AAEhC;;;;;;;;;GASG;AACH,eAAO,MAAM,UAAU;;EAQrB,CAAC;AAEH,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"HxListItem.d.ts","sourceRoot":"","sources":["../../../src/components/HxListItem/HxListItem.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;AAEpE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,YAAY,EAAE,eAAe,EAAE,CAAC;AAEhC;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,UAAU;;EAQrB,CAAC;AAEH,eAAe,UAAU,CAAC"}
@@ -4,6 +4,21 @@ export type { HxMenuProps };
4
4
  /**
5
5
  * A menu container that manages keyboard navigation over a list of menu items.
6
6
  Use with `hx-menu-item` and `hx-menu-divider`.
7
+
8
+ Group 5b host-canonical: `role="menu"` lives on the **host** via
9
+ `_internals.role`. The host carries the announced surface so AT walks
10
+ `<hx-menu>` (role=menu) → slotted `<hx-menu-item>` (role=menuitem on host)
11
+ directly without two layers of indirection. Consumer-supplied
12
+ `aria-label` / `aria-labelledby` on the host are resolved via the shared
13
+ IDREF mirror; cross-shadow naming uses `ariaLabelledByElements` (modern)
14
+ with a flattened-string fallback (legacy).
15
+
16
+ Submenu coordination: when an `hx-menu-item` emits `hx-item-submenu-open`
17
+ or `hx-item-submenu-close`, the parent menu auto-handles the toggle by
18
+ calling `setSubmenuOpen()` on the item — UNLESS the consumer has called
19
+ `event.preventDefault()` on the bubbled event, signaling that they own the
20
+ submenu lifecycle. This matches APG-mandated behaviour while leaving an
21
+ opt-out for advanced consumers.
7
22
  *
8
23
  * @example
9
24
  * ```tsx
@@ -1 +1 @@
1
- {"version":3,"file":"HxMenu.d.ts","sourceRoot":"","sources":["../../../src/components/HxMenu/HxMenu.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAC;AAEhE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,YAAY,EAAE,WAAW,EAAE,CAAC;AAE5B;;;;;;;;;;GAUG;AACH,eAAO,MAAM,MAAM;;;EASjB,CAAC;AAEH,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"HxMenu.d.ts","sourceRoot":"","sources":["../../../src/components/HxMenu/HxMenu.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAC;AAEhE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,YAAY,EAAE,WAAW,EAAE,CAAC;AAE5B;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,MAAM;;;EASjB,CAAC;AAEH,eAAe,MAAM,CAAC"}
@@ -6,8 +6,10 @@ export interface HxMenuProps {
6
6
  className?: string;
7
7
  /** Inline styles */
8
8
  style?: React.CSSProperties;
9
- /** Accessible label for the menu. Rendered as `aria-label` on the inner
10
- `role="menu"` element when set. */
9
+ /** Accessible label for the menu. Used as a fallback when no consumer-supplied
10
+ `aria-label` / `aria-labelledby` is present on the host. On the modern
11
+ host-canonical path this projects onto `internals.ariaLabel`; on the
12
+ legacy fallback path it appears as `aria-label` on the inner div. */
11
13
  label?: string;
12
14
  /** Dispatched when Escape is pressed. */
13
15
  onHxClose?: (event: Event) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/HxMenu/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,MAAM,WAAW,WAAW;IAC1B,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,qBAAqB;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oBAAoB;IACpB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B;oCACgC;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IAGf,yCAAyC;IACzC,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACnC,2CAA2C;IAC3C,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CACrC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/HxMenu/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,MAAM,WAAW,WAAW;IAC1B,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,qBAAqB;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oBAAoB;IACpB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B;;;sEAGkE;IAClE,KAAK,CAAC,EAAE,MAAM,CAAC;IAGf,yCAAyC;IACzC,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACnC,2CAA2C;IAC3C,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CACrC"}
@@ -3,6 +3,13 @@ import { HxMenuDividerProps } from './types.js';
3
3
  export type { HxMenuDividerProps };
4
4
  /**
5
5
  * A visual separator for grouping items within an `hx-menu`.
6
+
7
+ Group 5b host-canonical: `role="separator"` lives on the **host** via
8
+ `_internals.role` so the parent `<hx-menu>` (`role="menu"`) sees the
9
+ separator as a direct child. `aria-orientation` is mirrored onto the host
10
+ via `internals.ariaOrientation`. The inner div is presentational on the
11
+ modern path and stripped of its role; the legacy fallback keeps the
12
+ inner role for engines without ElementInternals IDL accessors.
6
13
  *
7
14
  * @example
8
15
  * ```tsx
@@ -1 +1 @@
1
- {"version":3,"file":"HxMenuDivider.d.ts","sourceRoot":"","sources":["../../../src/components/HxMenuDivider/HxMenuDivider.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AAEvE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErD,YAAY,EAAE,kBAAkB,EAAE,CAAC;AAEnC;;;;;;;;;GASG;AACH,eAAO,MAAM,aAAa,8DAMxB,CAAC;AAEH,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"HxMenuDivider.d.ts","sourceRoot":"","sources":["../../../src/components/HxMenuDivider/HxMenuDivider.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AAEvE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErD,YAAY,EAAE,kBAAkB,EAAE,CAAC;AAEnC;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,aAAa,8DAMxB,CAAC;AAEH,eAAe,aAAa,CAAC"}
@@ -4,7 +4,21 @@ export type { HxMenuItemProps };
4
4
  /**
5
5
  * A single interactive item for use inside `hx-menu`. Supports normal, checkbox,
6
6
  and radio types, loading state, prefix/suffix slots, and submenu nesting.
7
- Use `aria-label` on the parent `hx-menu` to provide an accessible name.
7
+
8
+ Group 5b host-canonical: `role="menuitem"` (or `menuitemcheckbox` /
9
+ `menuitemradio` based on `type`) lives on the **host** via
10
+ `_internals.role`. The roving tabindex is written to the host, so the host
11
+ is the focusable surface and lands directly under the parent `<hx-menu>`
12
+ (which carries `role="menu"`) in the AT walked tree. The inner element is
13
+ presentational on the modern path — no role, no aria-* attributes — and
14
+ carries only click/keyboard event handlers. Keyboard activation
15
+ (Enter/Space) is owned by the host's `keydown` handler.
16
+
17
+ Cross-shadow naming: consumer-supplied `aria-label` / `aria-labelledby` on
18
+ the host project to `internals.ariaLabel` / `internals.ariaLabelledByElements`
19
+ via the shared IDREF mirror. The slotted text content is used as the default
20
+ accessible name when no override is set (AT walks slotted children
21
+ automatically through the host's role).
8
22
  *
9
23
  * @example
10
24
  * ```tsx
@@ -1 +1 @@
1
- {"version":3,"file":"HxMenuItem.d.ts","sourceRoot":"","sources":["../../../src/components/HxMenuItem/HxMenuItem.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;AAEpE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,YAAY,EAAE,eAAe,EAAE,CAAC;AAEhC;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,UAAU;;;;EAUrB,CAAC;AAEH,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"HxMenuItem.d.ts","sourceRoot":"","sources":["../../../src/components/HxMenuItem/HxMenuItem.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;AAEpE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,YAAY,EAAE,eAAe,EAAE,CAAC;AAEhC;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,UAAU;;;;EAUrB,CAAC;AAEH,eAAe,UAAU,CAAC"}
@@ -5,6 +5,16 @@ export type { HxMeterProps };
5
5
  * A scalar measurement within a known range — e.g., disk usage, health score,
6
6
  or any numeric value with defined min/max bounds. Supports low/high/optimum
7
7
  threshold markers for semantic color feedback.
8
+
9
+ Group 7 host-canonical: `role="meter"` is mirrored onto the **host** via
10
+ `_internals.role` AND kept on the inner `[role="meter"]` element. The dual
11
+ surface is the hx-progress-ring pattern (Group 7 gold-standard exemplar):
12
+ the host carries the cross-shadow IDREF wiring (`ariaLabelledByElements`
13
+ resolves through the shared mirror) while the inner element keeps its
14
+ existing role/state surface so legacy AT and consumer queries continue to
15
+ work. AccName 1.2 §4.3.1 precedence is implemented uniformly: consumer
16
+ host `aria-labelledby` (flattened) > consumer host `aria-label` >
17
+ `label` property / slotted label > derived value-text fallback.
8
18
  *
9
19
  * @example
10
20
  * ```tsx
@@ -1 +1 @@
1
- {"version":3,"file":"HxMeter.d.ts","sourceRoot":"","sources":["../../../src/components/HxMeter/HxMeter.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,UAAU,EAAE,MAAM,sCAAsC,CAAC;AAElE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,YAAY,EAAE,YAAY,EAAE,CAAC;AAE7B;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,OAAO,wDAMlB,CAAC;AAEH,eAAe,OAAO,CAAC"}
1
+ {"version":3,"file":"HxMeter.d.ts","sourceRoot":"","sources":["../../../src/components/HxMeter/HxMeter.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,UAAU,EAAE,MAAM,sCAAsC,CAAC;AAElE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,YAAY,EAAE,YAAY,EAAE,CAAC;AAE7B;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,OAAO,wDAMlB,CAAC;AAEH,eAAe,OAAO,CAAC"}
@@ -4,6 +4,25 @@ export type { HxOverflowMenuProps };
4
4
  /**
5
5
  * An overflow menu (kebab/meatball menu) that reveals hidden actions via a
6
6
  floating panel. Composed from a trigger button and a slotted menu panel.
7
+
8
+ ## Architecture Note: Host-Attribute Trigger Label Mirror (group-5b)
9
+
10
+ The composite has TWO ARIA-bearing surfaces inside its shadow DOM: the
11
+ trigger button (`role` defaulted from `<button>`, with `aria-haspopup`,
12
+ `aria-expanded`, `aria-controls`) and the panel (`role="menu"` on the
13
+ inner div). The host wraps both — it cannot carry either canonical role
14
+ itself, so role placement remains on the inner elements.
15
+
16
+ What Group 5b adds:
17
+ - **Roving tabindex** on slotted menu items (only the focused item has
18
+ tabindex=0; arrow keys move focus and rewrite tabindex). Closing-Tab
19
+ path is preserved (Tab moves focus past the menu and closes it).
20
+ - **First-character typeahead** with 500ms timeout matching `hx-menu`.
21
+ - **Host-attribute label mirror**: consumer-supplied `aria-label` /
22
+ `aria-labelledby` on the host flow to the trigger button's
23
+ `aria-label` (the trigger is the announced surface of the disclosure
24
+ pattern; consumer override wins over the `label` property). The panel
25
+ continues to use `labelMenu` for its own slot label.
7
26
  *
8
27
  * @example
9
28
  * ```tsx
@@ -1 +1 @@
1
- {"version":3,"file":"HxOverflowMenu.d.ts","sourceRoot":"","sources":["../../../src/components/HxOverflowMenu/HxOverflowMenu.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,iBAAiB,EAAE,MAAM,8CAA8C,CAAC;AAEjF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtD,YAAY,EAAE,mBAAmB,EAAE,CAAC;AAEpC;;;;;;;;;;GAUG;AACH,eAAO,MAAM,cAAc;;;;EAUzB,CAAC;AAEH,eAAe,cAAc,CAAC"}
1
+ {"version":3,"file":"HxOverflowMenu.d.ts","sourceRoot":"","sources":["../../../src/components/HxOverflowMenu/HxOverflowMenu.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,iBAAiB,EAAE,MAAM,8CAA8C,CAAC;AAEjF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtD,YAAY,EAAE,mBAAmB,EAAE,CAAC;AAEpC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,eAAO,MAAM,cAAc;;;;EAUzB,CAAC;AAEH,eAAe,cAAc,CAAC"}