@heartlandone/vega 2.95.0 → 2.96.0

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 (181) hide show
  1. package/dist/cjs/{app-globals-76815382.js → app-globals-38afea36.js} +7 -7
  2. package/dist/cjs/{code-block-493c7ce7.js → code-block-4126dc3b.js} +1501 -55
  3. package/dist/cjs/{component-value-history-controller-slimmer.abstract-ab21fcbf.js → component-value-history-controller-slimmer.abstract-38ba956e.js} +2 -2
  4. package/dist/cjs/{content-state-fc34a814.js → content-state-50e8a03c.js} +142 -580
  5. package/dist/cjs/{element-appender-slimmer-1d6323c2.js → element-appender-slimmer-7773fdab.js} +115 -0
  6. package/dist/cjs/{image-annotation-action-7c4cd316.js → image-annotation-action-89363de8.js} +2 -2
  7. package/dist/cjs/{image-extension-30a7c10f.js → image-extension-c881c454.js} +2 -2
  8. package/dist/cjs/index.cjs.js +10 -10
  9. package/dist/cjs/{link-extension-92a63cb7.js → link-extension-b7f99a52.js} +2 -2
  10. package/dist/cjs/loader.cjs.js +7 -7
  11. package/dist/cjs/{public-rules-9e1ea1d9.js → public-rules-72894208.js} +3 -3
  12. package/dist/cjs/{range-30219330.js → range-95d41dea.js} +1 -1
  13. package/dist/cjs/{rich-text-editor-required-rule-23bf7485.js → rich-text-editor-required-rule-4d6d2493.js} +1 -1
  14. package/dist/cjs/{split-cell-operation-43752212.js → split-cell-operation-70be116d.js} +2 -2
  15. package/dist/cjs/{token-extension-d123d9d0.js → token-extension-eb828948.js} +35 -11
  16. package/dist/cjs/vega-code-block.cjs.entry.js +3 -3
  17. package/dist/cjs/vega-date-picker_2.cjs.entry.js +1 -1
  18. package/dist/cjs/vega-dropdown_5.cjs.entry.js +27 -4
  19. package/dist/cjs/vega-env-manager-23b8b23c.js +2 -2
  20. package/dist/cjs/vega-popover_2.cjs.entry.js +1 -1
  21. package/dist/cjs/vega-rich-text-content.cjs.entry.js +58 -9
  22. package/dist/cjs/vega-rich-text-editor_4.cjs.entry.js +608 -90
  23. package/dist/cjs/vega-rich-text-table-properties_3.cjs.entry.js +3 -3
  24. package/dist/cjs/vega-section-title.cjs.entry.js +896 -14
  25. package/dist/cjs/vega-time-picker_2.cjs.entry.js +1 -1
  26. package/dist/cjs/vega-tooltip_2.cjs.entry.js +1 -1
  27. package/dist/cjs/vega.cjs.js +7 -7
  28. package/dist/collection/components/vega-combo-box/vega-combo-box.js +2 -2
  29. package/dist/collection/components/vega-dropdown/vega-dropdown.js +30 -7
  30. package/dist/collection/components/vega-input-select/vega-input-select.js +2 -2
  31. package/dist/collection/components/vega-rich-text-content/vega-rich-text-content.css +4 -0
  32. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/block-delete-node-content-strategy.js +29 -0
  33. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/block-delete-text-or-decorator-node-strategy.js +10 -1
  34. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/block-transform-to-list-strategy.js +8 -3
  35. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-annotation-strategy.abstract.js +60 -0
  36. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-item-replace-nest-list-strategy.js +36 -4
  37. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-items-strategy.abstract.js +27 -0
  38. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-nest-items-strategy.js +74 -0
  39. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-remove-list-item-strategy.js +81 -1
  40. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-transform-selection.js +30 -0
  41. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-transform-to-list-strategy.js +160 -9
  42. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-transform-to-paragraph-strategy.js +376 -10
  43. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-unnest-items-strategy.js +104 -0
  44. package/dist/collection/components/vega-rich-text-editor/dto/actions/modify-content-action.abstract.js +2 -0
  45. package/dist/collection/components/vega-rich-text-editor/dto/actions/nest-list-items-action.js +12 -0
  46. package/dist/collection/components/vega-rich-text-editor/dto/actions/unnest-list-items-action.js +12 -0
  47. package/dist/collection/components/vega-rich-text-editor/dto/annotations/list-annotation.js +12 -0
  48. package/dist/collection/components/vega-rich-text-editor/dto/blocks/list-block.js +10 -1
  49. package/dist/collection/components/vega-rich-text-editor/dto/blocks/list-item-block.js +11 -3
  50. package/dist/collection/components/vega-rich-text-editor/dto/content-state.js +7 -1
  51. package/dist/collection/components/vega-rich-text-editor/dto/filter-styles-strategies/list-block/list-block-filter-styles-strategy.js +8 -4
  52. package/dist/collection/components/vega-rich-text-editor/dto/renderers/blocks/list-block-renderer.js +34 -1
  53. package/dist/collection/components/vega-rich-text-editor/dto/renderers/blocks/list-item-block-renderer.js +20 -3
  54. package/dist/collection/components/vega-rich-text-editor/extensions/table/annotation-handler/table-annotation-handler-base.js +25 -1
  55. package/dist/collection/components/vega-rich-text-editor/slimmers/controllers/helper/element-to-dto-strategy/li-to-rte-list-item-block-strategy.js +2 -0
  56. package/dist/collection/components/vega-rich-text-editor/slimmers/controllers/helper/input-event-handler/abstract-delete-content-handler.js +29 -0
  57. package/dist/collection/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/bullets-numbers-toolbar-button-slimmer.js +30 -1
  58. package/dist/collection/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/helper/abstract-list-keyboard-handler.js +204 -0
  59. package/dist/collection/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/helper/list-shift-tab-outdent-handler.js +42 -0
  60. package/dist/collection/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/helper/list-tab-indent-handler.js +34 -0
  61. package/dist/collection/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/list-keyboard-slimmer.js +180 -0
  62. package/dist/collection/components/vega-section-title/slimmers/a11y-tree/build-section-title-a11y-tree.js +54 -0
  63. package/dist/collection/components/vega-section-title/slimmers/renderers/vega-section-title-renderer.js +4 -4
  64. package/dist/collection/components/vega-section-title/vega-section-title.js +18 -2
  65. package/dist/collection/helpers/a11y-tree/a11y-node-dto.js +210 -0
  66. package/dist/collection/helpers/a11y-tree/a11y-tree-applier.js +189 -0
  67. package/dist/collection/helpers/a11y-tree/a11y-tree.types.js +48 -0
  68. package/dist/collection/helpers/a11y-tree/strategies/baseline-strategy.js +78 -0
  69. package/dist/collection/helpers/a11y-tree/strategies/firefox-nvda-strategy.js +56 -0
  70. package/dist/collection/helpers/a11y-tree/strategies/webkit-voiceover-strategy.js +140 -0
  71. package/dist/collection/helpers/a11y-tree/strategy-resolver.js +172 -0
  72. package/dist/collection/helpers/slimmers/a11y-tree-slimmer.js +54 -0
  73. package/dist/collection/helpers/slimmers/element-appender/element-appender-slimmer.js +29 -0
  74. package/dist/collection/helpers/slimmers/element-appender/visibility-modifiers/clip-on-scroll-modifier.js +70 -0
  75. package/dist/collection/helpers/slimmers/element-appender/visibility-modifiers/visibility-modifier.interface.js +1 -0
  76. package/dist/collection/helpers/ui/element-appender.js +16 -0
  77. package/dist/esm/{app-globals-eafcc7a1.js → app-globals-d7b651c1.js} +7 -7
  78. package/dist/esm/{code-block-e12588fe.js → code-block-0a88b481.js} +1495 -51
  79. package/dist/esm/{component-value-history-controller-slimmer.abstract-4e8eb313.js → component-value-history-controller-slimmer.abstract-6846edfa.js} +2 -2
  80. package/dist/esm/{content-state-8032467a.js → content-state-79ca99e5.js} +105 -541
  81. package/dist/esm/{element-appender-slimmer-7fcb944b.js → element-appender-slimmer-73ad10ae.js} +115 -0
  82. package/dist/esm/{image-annotation-action-08a20d5e.js → image-annotation-action-bb299ef1.js} +2 -2
  83. package/dist/esm/{image-extension-b6c7e4a7.js → image-extension-48a96f98.js} +2 -2
  84. package/dist/esm/index.js +8 -8
  85. package/dist/esm/{link-extension-97fcb8fb.js → link-extension-09534514.js} +2 -2
  86. package/dist/esm/loader.js +7 -7
  87. package/dist/esm/{public-rules-c06f0d2a.js → public-rules-5eb03ef0.js} +3 -3
  88. package/dist/esm/{range-e999837f.js → range-d4deb7df.js} +1 -1
  89. package/dist/esm/{rich-text-editor-required-rule-71f8ee98.js → rich-text-editor-required-rule-5bbbce23.js} +1 -1
  90. package/dist/esm/{split-cell-operation-359f8082.js → split-cell-operation-7f3058ad.js} +2 -2
  91. package/dist/esm/{token-extension-f5bf9c21.js → token-extension-40c32bcc.js} +30 -6
  92. package/dist/esm/vega-code-block.entry.js +3 -3
  93. package/dist/esm/vega-date-picker_2.entry.js +1 -1
  94. package/dist/esm/vega-dropdown_5.entry.js +27 -4
  95. package/dist/esm/vega-env-manager-8f8dc473.js +2 -2
  96. package/dist/esm/vega-popover_2.entry.js +1 -1
  97. package/dist/esm/vega-rich-text-content.entry.js +58 -9
  98. package/dist/esm/vega-rich-text-editor_4.entry.js +604 -86
  99. package/dist/esm/vega-rich-text-table-properties_3.entry.js +3 -3
  100. package/dist/esm/vega-section-title.entry.js +897 -15
  101. package/dist/esm/vega-time-picker_2.entry.js +1 -1
  102. package/dist/esm/vega-tooltip_2.entry.js +1 -1
  103. package/dist/esm/vega.js +7 -7
  104. package/dist/sri/vega-sri-manifest.json +94 -94
  105. package/dist/types/components/vega-combo-box/vega-combo-box.d.ts +6 -6
  106. package/dist/types/components/vega-dropdown/types.d.ts +2 -2
  107. package/dist/types/components/vega-dropdown/vega-dropdown.d.ts +32 -9
  108. package/dist/types/components/vega-input-select/vega-input-select.d.ts +6 -6
  109. package/dist/types/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-annotation-strategy.abstract.d.ts +36 -0
  110. package/dist/types/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-item-replace-nest-list-strategy.d.ts +14 -2
  111. package/dist/types/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-items-strategy.abstract.d.ts +22 -0
  112. package/dist/types/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-nest-items-strategy.d.ts +21 -0
  113. package/dist/types/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-remove-list-item-strategy.d.ts +14 -0
  114. package/dist/types/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-transform-selection.d.ts +15 -0
  115. package/dist/types/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-transform-to-list-strategy.d.ts +30 -3
  116. package/dist/types/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-transform-to-paragraph-strategy.d.ts +99 -3
  117. package/dist/types/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-unnest-items-strategy.d.ts +22 -0
  118. package/dist/types/components/vega-rich-text-editor/dto/actions/modify-content-action.abstract.d.ts +2 -0
  119. package/dist/types/components/vega-rich-text-editor/dto/actions/nest-list-items-action.d.ts +11 -0
  120. package/dist/types/components/vega-rich-text-editor/dto/actions/unnest-list-items-action.d.ts +11 -0
  121. package/dist/types/components/vega-rich-text-editor/dto/annotations/list-annotation.d.ts +8 -0
  122. package/dist/types/components/vega-rich-text-editor/dto/blocks/list-block.d.ts +6 -1
  123. package/dist/types/components/vega-rich-text-editor/dto/blocks/list-item-block.d.ts +5 -1
  124. package/dist/types/components/vega-rich-text-editor/dto/content-state.d.ts +2 -2
  125. package/dist/types/components/vega-rich-text-editor/dto/renderers/blocks/list-block-renderer.d.ts +2 -0
  126. package/dist/types/components/vega-rich-text-editor/dto/renderers/blocks/list-item-block-renderer.d.ts +8 -0
  127. package/dist/types/components/vega-rich-text-editor/extensions/table/annotation-handler/table-annotation-handler-base.d.ts +18 -0
  128. package/dist/types/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/bullets-numbers-toolbar-button-slimmer.d.ts +8 -0
  129. package/dist/types/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/helper/abstract-list-keyboard-handler.d.ts +99 -0
  130. package/dist/types/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/helper/list-shift-tab-outdent-handler.d.ts +15 -0
  131. package/dist/types/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/helper/list-tab-indent-handler.d.ts +15 -0
  132. package/dist/types/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/list-keyboard-slimmer.d.ts +73 -0
  133. package/dist/types/components/vega-section-title/slimmers/a11y-tree/build-section-title-a11y-tree.d.ts +41 -0
  134. package/dist/types/components/vega-section-title/vega-section-title.d.ts +9 -0
  135. package/dist/types/components.d.ts +10 -10
  136. package/dist/types/helpers/a11y-tree/a11y-node-dto.d.ts +173 -0
  137. package/dist/types/helpers/a11y-tree/a11y-tree-applier.d.ts +28 -0
  138. package/dist/types/helpers/a11y-tree/a11y-tree.types.d.ts +137 -0
  139. package/dist/types/helpers/a11y-tree/strategies/baseline-strategy.d.ts +18 -0
  140. package/dist/types/helpers/a11y-tree/strategies/firefox-nvda-strategy.d.ts +16 -0
  141. package/dist/types/helpers/a11y-tree/strategies/webkit-voiceover-strategy.d.ts +23 -0
  142. package/dist/types/helpers/a11y-tree/strategy-resolver.d.ts +59 -0
  143. package/dist/types/helpers/slimmers/a11y-tree-slimmer.d.ts +49 -0
  144. package/dist/types/helpers/slimmers/element-appender/element-appender-slimmer.d.ts +9 -0
  145. package/dist/types/helpers/slimmers/element-appender/visibility-modifiers/clip-on-scroll-modifier.d.ts +37 -0
  146. package/dist/types/helpers/slimmers/element-appender/visibility-modifiers/visibility-modifier.interface.d.ts +56 -0
  147. package/dist/types/helpers/ui/element-appender.d.ts +7 -0
  148. package/dist/vega/index.esm.js +1 -1
  149. package/dist/vega/{p-9c39f90b.entry.js → p-1dfbc542.entry.js} +1 -1
  150. package/dist/vega/{p-e235020b.entry.js → p-22cc174e.entry.js} +1 -1
  151. package/dist/vega/{p-b187b82d.entry.js → p-2df5d59b.entry.js} +1 -1
  152. package/dist/vega/{p-f7e459cd.js → p-312d8205.js} +1 -1
  153. package/dist/vega/{p-a7209700.js → p-3345d903.js} +1 -1
  154. package/dist/vega/{p-02355de8.js → p-3c23ec90.js} +1 -1
  155. package/dist/vega/p-55e0014a.js +3 -0
  156. package/dist/vega/p-5f377954.js +1 -1
  157. package/dist/vega/p-65fee02f.entry.js +1 -0
  158. package/dist/vega/p-6a51d720.js +1 -0
  159. package/dist/vega/{p-fe24b459.js → p-6c7b6d45.js} +1 -1
  160. package/dist/vega/{p-579cdeae.js → p-84b7a775.js} +1 -1
  161. package/dist/vega/{p-df828d90.entry.js → p-96da7d30.entry.js} +1 -1
  162. package/dist/vega/{p-88be9ec5.js → p-9d3f69cb.js} +1 -1
  163. package/dist/vega/{p-8a001caa.js → p-9f11b579.js} +1 -1
  164. package/dist/vega/{p-ba2b9663.entry.js → p-acaff62d.entry.js} +1 -1
  165. package/dist/vega/p-b63319e9.entry.js +1 -0
  166. package/dist/vega/{p-c079c935.entry.js → p-b660f38c.entry.js} +1 -1
  167. package/dist/vega/p-b8ffa42f.entry.js +1 -0
  168. package/dist/vega/{p-4fe40b76.js → p-c4564904.js} +1 -1
  169. package/dist/vega/p-d9158512.js +1 -0
  170. package/dist/vega/p-e62d41ee.js +1 -0
  171. package/dist/vega/{p-9f7154d2.js → p-ec5dee32.js} +1 -1
  172. package/dist/vega/{p-05d04c07.entry.js → p-f29d9707.entry.js} +1 -1
  173. package/dist/vega/vega.esm.js +1 -1
  174. package/package.json +3 -2
  175. package/dist/vega/p-0be4df0a.js +0 -1
  176. package/dist/vega/p-38c9d782.js +0 -1
  177. package/dist/vega/p-513bc0d9.js +0 -1
  178. package/dist/vega/p-8d4b85e7.entry.js +0 -1
  179. package/dist/vega/p-c5d3b008.entry.js +0 -1
  180. package/dist/vega/p-d25ca0c3.entry.js +0 -1
  181. package/dist/vega/p-f4da615a.js +0 -3
@@ -0,0 +1,15 @@
1
+ import { Nullable } from '../../../../../../../types/general';
2
+ import { RTEBlock } from '../../../../../dto/blocks/block.abstract';
3
+ import { RTETextNode } from '../../../../../dto/nodes/text-node';
4
+ import { AbstractListKeyboardHandler } from './abstract-list-keyboard-handler';
5
+ /**
6
+ * Handles Tab key list indentation.
7
+ * Normalizes the selection, applies a command-style gate on the first
8
+ * eligible segment, then nests each qualifying segment.
9
+ */
10
+ export declare class ListTabIndentHandler extends AbstractListKeyboardHandler {
11
+ /**
12
+ * @inheritDoc
13
+ */
14
+ execute(selectedBlocks: RTEBlock[]): Array<Nullable<[RTETextNode, RTETextNode]>> | null;
15
+ }
@@ -0,0 +1,73 @@
1
+ import { VegaSlimmer } from '../../../../../../vega-slimmer/vega-slimmer-core';
2
+ import { BulletsNumbersToolbarButtonSlimmer } from './bullets-numbers-toolbar-button-slimmer';
3
+ /**
4
+ * Handles list keyboard shortcuts (Tab/Shift+Tab) for list tooling.
5
+ */
6
+ export declare class ListKeyboardSlimmer extends VegaSlimmer {
7
+ protected readonly selectionController: BulletsNumbersToolbarButtonSlimmer['selectionController'];
8
+ protected readonly valueController: BulletsNumbersToolbarButtonSlimmer['valueController'];
9
+ protected readonly value: BulletsNumbersToolbarButtonSlimmer['value'];
10
+ protected readonly toolbarItems: BulletsNumbersToolbarButtonSlimmer['toolbarItems'];
11
+ protected readonly vegaRichTextEditorRenderer: BulletsNumbersToolbarButtonSlimmer['vegaRichTextEditorRenderer'];
12
+ private boundEditableElement;
13
+ private isKeyboardListenerBound;
14
+ private readonly listTabIndentHandler;
15
+ private readonly listShiftTabOutdentHandler;
16
+ /**
17
+ * @inheritDoc
18
+ */
19
+ disconnectedCallback(): void;
20
+ /**
21
+ * @inheritDoc
22
+ */
23
+ componentDidLoad(): void;
24
+ /**
25
+ * Re-sync keyboard listener when toolbarItems prop changes at runtime,
26
+ * ensuring list shortcuts are bound/unbound as tools are added/removed.
27
+ */
28
+ watchToolbarItems(): void;
29
+ /**
30
+ * Synchronize the DOM keydown listener with the configured toolbar items.
31
+ */
32
+ private syncListKeyboardListener;
33
+ /**
34
+ * Determine whether any list keyboard controls are enabled in the toolbar.
35
+ *
36
+ * @returns {boolean} True when any list toolbar item is configured.
37
+ */
38
+ private hasListToolbarConfigured;
39
+ /**
40
+ * Attach the keydown listener to the current editable element when available.
41
+ * Handles element ref changes by rebinding when the target element differs.
42
+ */
43
+ private addListKeyboardListener;
44
+ /**
45
+ * Detach the keydown listener from the previously bound editable element.
46
+ */
47
+ private removeListKeyboardListener;
48
+ /**
49
+ * Handle Tab and Shift+Tab list keyboard interactions.
50
+ *
51
+ * @param {KeyboardEvent} e - Keyboard event to process.
52
+ * @returns {void}
53
+ */
54
+ private handleListKeyboardAction;
55
+ /**
56
+ * Check whether the Tab event includes modifiers other than Shift.
57
+ *
58
+ * @param {KeyboardEvent} e - Keyboard event to inspect.
59
+ * @returns {boolean} True when non-shift modifier keys are pressed.
60
+ */
61
+ private hasNonShiftModifierForTab;
62
+ /**
63
+ * Restore the logical selection after a list keyboard action completes.
64
+ *
65
+ * @param {Array<Nullable<[RTETextNode, RTETextNode]>>} selectionBoundaries - Boundaries produced by the handler.
66
+ * @param {Nullable<RTETextNode>} preferredStartNode - Preferred start node from prior selection.
67
+ * @param {Nullable<RTETextNode>} preferredEndNode - Preferred end node from prior selection.
68
+ * @param {number} startOffset - Preferred start offset.
69
+ * @param {number} endOffset - Preferred end offset.
70
+ * @returns {void}
71
+ */
72
+ private restoreListSelection;
73
+ }
@@ -0,0 +1,41 @@
1
+ import { A11yNode } from '../../../../helpers/a11y-tree/a11y-tree.types';
2
+ interface BuildArgs {
3
+ titleText: string;
4
+ icon?: string;
5
+ iconAlign?: 'left' | 'right';
6
+ headingLevel?: 1 | 2 | 3 | 4 | 5 | 6;
7
+ }
8
+ /**
9
+ * Build the semantic A11y Tree for a `vega-section-title` instance.
10
+ *
11
+ * The structure uses a presentation wrapper so the container is transparent to
12
+ * assistive technology — the heading is the semantic anchor:
13
+ *
14
+ * ```
15
+ * presentation "st-root" (role=none — AT-transparent wrapper)
16
+ * ├── heading "st-heading" (titleText, level=2 by default)
17
+ * └── icon "st-icon" (decorative — only when an icon prop is set)
18
+ * ```
19
+ *
20
+ * Description text is not wired into the A11y tree. It is exposed as plain
21
+ * visible text in the component's shadow DOM, read by screen readers via normal
22
+ * linear traversal. This avoids three VoiceOver regressions introduced when the
23
+ * container carried `role="group"` with `aria-label` + `aria-describedby`:
24
+ *
25
+ * - Bug 1 (Safari): webkit folded the description into the heading `aria-label`,
26
+ * so focusing the H2 announced both title AND description together.
27
+ * - Bug 2 (Chrome, no description): `role="group"` created an extra navigation
28
+ * boundary and announced the title twice (group label + heading).
29
+ * - Bug 3 (Chrome, with description): description read twice — once via the
30
+ * hidden `aria-describedby` span on the group, once via the visible div.
31
+ *
32
+ * **No inline ARIA / no double projection**: this function must NOT set
33
+ * `aria-*` or `role` attributes directly on the component. The A11y Tree
34
+ * slimmer (`A11yTreeSlimmer`) calls `applyA11yTree()` on every render to
35
+ * project the semantic intent through the chosen strategy.
36
+ *
37
+ * @param {BuildArgs} args - Section-title fields used to author the semantic tree.
38
+ * @returns {A11yNode} The semantic A11y Tree root for the section title.
39
+ */
40
+ export declare function buildSectionTitleA11yTree(args: BuildArgs): A11yNode;
41
+ export {};
@@ -4,6 +4,7 @@ import { IconAlignType } from '../../types/ui.type';
4
4
  import { TextColorsTokenType } from '../../types/design-token.type';
5
5
  import { VegaSectionTitleSizeType } from './types';
6
6
  import { VegaComponentUsageRuntimeMetricsSlimmer } from '../../helpers/slimmers/component-usage-runtime-metrics';
7
+ import { A11yTreeSlimmer } from '../../helpers/slimmers/a11y-tree-slimmer';
7
8
  /**
8
9
  * @vegaVersion 2.1.0
9
10
  */
@@ -11,6 +12,14 @@ export declare class VegaSectionTitle {
11
12
  protected readonly globalSlimmers: GlobalSlimmers;
12
13
  protected readonly renderer: VegaSectionTitleRenderer;
13
14
  protected vegaComponentUsageRuntimeMetricsSlimmer: VegaComponentUsageRuntimeMetricsSlimmer<HTMLVegaSectionTitleElement>;
15
+ /**
16
+ * Projects the component's semantic accessibility intent onto the shadow
17
+ * DOM via the A11y Tree foundation. Replaces the previous inline `role` /
18
+ * `aria-label` on the host element so ARIA is authored once, in
19
+ * `buildSectionTitleA11yTree`, and projected through the browser-engine
20
+ * strategy layer (no double projection).
21
+ */
22
+ protected readonly a11yTreeSlimmer: A11yTreeSlimmer<HTMLVegaSectionTitleElement>;
14
23
  host: HTMLVegaSectionTitleElement;
15
24
  /**
16
25
  * Specifies the text content of the title displayed
@@ -1684,8 +1684,8 @@ export namespace Components {
1684
1684
  */
1685
1685
  "isLoading": boolean;
1686
1686
  /**
1687
- * Determines whether the dropdown position is calculated relative to the screen.
1688
- * @VegaWarning - It will overrides the positionRelativeTo and matchContainerHeight properties, rendering them ineffective. - Currently, when set to true, the position calculation may be inaccurate if the popover is placed inside a scrollable container within a shadowRoot (e.g., inside a vega-modal with scrollable content).
1687
+ * Determines whether the dropdown uses viewport-based positioning (`position: fixed`) or container-based positioning (`position: absolute`). **Technical Implementation:** - When `false` (default): The dropdown content box renders with `position: absolute` and its coordinates are calculated relative to the nearest positioned ancestor. Combined with `positionRelativeTo`, you can specify which ancestor to measure from, which ensures the menu scrolls together with that ancestor. - When `true`: The dropdown content box renders with `position: fixed` and its coordinates are calculated from the viewport. The menu is visually anchored to the trigger element via JavaScript and moves with it on scroll, even though it is not part of the document flow. `positionRelativeTo` has no effect in this mode. When to set `isScreenPosition` to `true`: - Dropdowns that need to break out of container constraints (non-Shadow-DOM only): When you want the dropdown to appear outside its container's boundaries (e.g., to avoid being clipped by a parent's `overflow: hidden` or small dimensions), viewport-based positioning allows it to render freely. This only works for regular (non-Shadow-DOM) containers. Shadow DOM boundaries cannot be escaped with `position: fixed`. - Dropdowns in fixed or sticky positioned containers: When the dropdown trigger is inside a fixed or sticky positioned container, viewport-based positioning ensures correct alignment. When to keep `isScreenPosition` as `false` (default): - Simple layouts where the dropdown and its trigger are not inside scrollable containers - When you want the dropdown to scroll naturally with its container (using `position: absolute`) - When you need `positionRelativeTo` to control which ancestor the dropdown is positioned relative to - When `matchContainerHeight` is needed (this property is overridden when `isScreenPosition` is `true`)
1688
+ * @VegaWarning - Setting this to `true` override the `positionRelativeTo` and `matchContainerHeight` properties, rendering them ineffective. - Currently, when set to `true`, the position calculation may be inaccurate if the popover is placed inside a scrollable container within a shadowRoot (e.g., inside a vega-modal with scrollable content).
1689
1689
  * @vegaVersion 2.36.0
1690
1690
  */
1691
1691
  "isScreenPosition": boolean;
@@ -7853,7 +7853,7 @@ declare namespace LocalJSX {
7853
7853
  */
7854
7854
  "onCreate"?: (event: VegaComboBoxCustomEvent<string>) => void;
7855
7855
  /**
7856
- * An event emitter notifying that the Select All option in the dropdown has been clicked. The event's `detail` property is `true` when all items become selected, and `false` when Select All is cleared.
7856
+ * An event emitter only fired when the Select All checkbox in the dropdown has been clicked. The event's `detail` property is `true` when the Select All checkbox is clicked to select all items, and `false` when the Select All checkbox is clicked to clear all selected items.
7857
7857
  * @eventSemantics namespace:native
7858
7858
  * @vegaVersion 2.95.0
7859
7859
  */
@@ -7875,7 +7875,7 @@ declare namespace LocalJSX {
7875
7875
  */
7876
7876
  "onVegaCreate"?: (event: VegaComboBoxCustomEvent<string>) => void;
7877
7877
  /**
7878
- * An event emitter notifying that the Select All option in the dropdown has been clicked. The event's `detail` property is `true` when all items become selected, and `false` when Select All is cleared.
7878
+ * An event emitter only fired when the Select All checkbox in the dropdown has been clicked. The event's `detail` property is `true` when the Select All checkbox is clicked to select all items, and `false` when the Select All checkbox is clicked to clear all selected items.
7879
7879
  * @vegaVersion 2.95.0
7880
7880
  */
7881
7881
  "onVegaDropdownSelectAllClick"?: (event: VegaComboBoxCustomEvent<boolean>) => void;
@@ -8309,8 +8309,8 @@ declare namespace LocalJSX {
8309
8309
  */
8310
8310
  "isLoading"?: boolean;
8311
8311
  /**
8312
- * Determines whether the dropdown position is calculated relative to the screen.
8313
- * @VegaWarning - It will overrides the positionRelativeTo and matchContainerHeight properties, rendering them ineffective. - Currently, when set to true, the position calculation may be inaccurate if the popover is placed inside a scrollable container within a shadowRoot (e.g., inside a vega-modal with scrollable content).
8312
+ * Determines whether the dropdown uses viewport-based positioning (`position: fixed`) or container-based positioning (`position: absolute`). **Technical Implementation:** - When `false` (default): The dropdown content box renders with `position: absolute` and its coordinates are calculated relative to the nearest positioned ancestor. Combined with `positionRelativeTo`, you can specify which ancestor to measure from, which ensures the menu scrolls together with that ancestor. - When `true`: The dropdown content box renders with `position: fixed` and its coordinates are calculated from the viewport. The menu is visually anchored to the trigger element via JavaScript and moves with it on scroll, even though it is not part of the document flow. `positionRelativeTo` has no effect in this mode. When to set `isScreenPosition` to `true`: - Dropdowns that need to break out of container constraints (non-Shadow-DOM only): When you want the dropdown to appear outside its container's boundaries (e.g., to avoid being clipped by a parent's `overflow: hidden` or small dimensions), viewport-based positioning allows it to render freely. This only works for regular (non-Shadow-DOM) containers. Shadow DOM boundaries cannot be escaped with `position: fixed`. - Dropdowns in fixed or sticky positioned containers: When the dropdown trigger is inside a fixed or sticky positioned container, viewport-based positioning ensures correct alignment. When to keep `isScreenPosition` as `false` (default): - Simple layouts where the dropdown and its trigger are not inside scrollable containers - When you want the dropdown to scroll naturally with its container (using `position: absolute`) - When you need `positionRelativeTo` to control which ancestor the dropdown is positioned relative to - When `matchContainerHeight` is needed (this property is overridden when `isScreenPosition` is `true`)
8313
+ * @VegaWarning - Setting this to `true` override the `positionRelativeTo` and `matchContainerHeight` properties, rendering them ineffective. - Currently, when set to `true`, the position calculation may be inaccurate if the popover is placed inside a scrollable container within a shadowRoot (e.g., inside a vega-modal with scrollable content).
8314
8314
  * @vegaVersion 2.36.0
8315
8315
  */
8316
8316
  "isScreenPosition"?: boolean;
@@ -8375,7 +8375,7 @@ declare namespace LocalJSX {
8375
8375
  */
8376
8376
  "onDropdownSearch"?: (event: VegaDropdownCustomEvent<string>) => void;
8377
8377
  /**
8378
- * An event emitter notifying that the Select All option has been clicked. The event's `detail` property is `true` when all items become selected, and `false` when Select All is cleared.
8378
+ * An event emitter only fired when the Select All checkbox has been clicked. The event's `detail` property is `true` when the Select All checkbox is clicked to select all items, and `false` when the Select All checkbox is clicked to clear all selected items.
8379
8379
  * @eventSemantics namespace:native
8380
8380
  * @vegaVersion 2.93.0
8381
8381
  */
@@ -8409,7 +8409,7 @@ declare namespace LocalJSX {
8409
8409
  */
8410
8410
  "onVegaDropdownClick"?: (event: VegaDropdownCustomEvent<string>) => void;
8411
8411
  /**
8412
- * An event emitter notifying that the Select All option has been clicked. The event's `detail` property is `true` when all items become selected, and `false` when Select All is cleared.
8412
+ * An event emitter only fired when the Select All checkbox has been clicked. The event's `detail` property is `true` when the Select All checkbox is clicked to select all items, and `false` when the Select All checkbox is clicked to clear all selected items.
8413
8413
  * @vegaVersion 2.93.0
8414
8414
  */
8415
8415
  "onVegaDropdownSelectAllClick"?: (event: VegaDropdownCustomEvent<boolean>) => void;
@@ -9952,7 +9952,7 @@ declare namespace LocalJSX {
9952
9952
  */
9953
9953
  "onChange"?: (event: VegaInputSelectCustomEvent<SelectValueType<SelectType>>) => void;
9954
9954
  /**
9955
- * An event emitter notifying that the Select All option in the dropdown has been clicked. The event's `detail` property is `true` when all items become selected, and `false` when Select All is cleared.
9955
+ * An event emitter only fired when the Select All checkbox in the dropdown has been clicked. The event's `detail` property is `true` when the Select All checkbox is clicked to select all items, and `false` when the Select All checkbox is clicked to clear all selected items.
9956
9956
  * @eventSemantics namespace:native
9957
9957
  * @vegaVersion 2.95.0
9958
9958
  */
@@ -9981,7 +9981,7 @@ declare namespace LocalJSX {
9981
9981
  */
9982
9982
  "onVegaChange"?: (event: VegaInputSelectCustomEvent<SelectValueType<SelectType>>) => void;
9983
9983
  /**
9984
- * An event emitter notifying that the Select All option in the dropdown has been clicked. The event's `detail` property is `true` when all items become selected, and `false` when Select All is cleared.
9984
+ * An event emitter only fired when the Select All checkbox in the dropdown has been clicked. The event's `detail` property is `true` when the Select All checkbox is clicked to select all items, and `false` when the Select All checkbox is clicked to clear all selected items.
9985
9985
  * @vegaVersion 2.95.0
9986
9986
  */
9987
9987
  "onVegaDropdownSelectAllClick"?: (event: VegaInputSelectCustomEvent<boolean>) => void;
@@ -0,0 +1,173 @@
1
+ import { A11yNode, A11ySemanticKind } from './a11y-tree.types';
2
+ /**
3
+ * Semantic DTO layer for the A11y Tree.
4
+ *
5
+ * Authoring an A11y Tree with raw `A11yNode` literals asks the developer to
6
+ * think in ARIA terms (`role: 'group'`, `decorative: true`, etc.). The DTO
7
+ * classes here provide a higher-level vocabulary that names the *content's
8
+ * meaning* — "this is a container", "this is a heading", "this is a
9
+ * decorative icon" — and lets the strategy layer translate intent into ARIA.
10
+ *
11
+ * ## Design (Visitor / Strategy + typed semantic DTOs)
12
+ *
13
+ * - DTOs are *type-holders for semantic intent*. They do NOT contain ARIA
14
+ * generation logic themselves.
15
+ * - Each DTO compiles to an `A11yNode` whose `kind` field carries the
16
+ * semantic discriminator. Strategies can then dispatch on `kind`
17
+ * (preferred) or fall back to `role` (for plain `A11yNode` authors).
18
+ * - This keeps strategies pure and independently testable, while letting
19
+ * authors write:
20
+ *
21
+ * ```ts
22
+ * new A11yContainerNode('st-root', { label, description })
23
+ * .childrenWith(
24
+ * new A11yHeadingNode('st-heading', { level: 2, label }),
25
+ * new A11yIconNode('st-icon'),
26
+ * );
27
+ * ```
28
+ *
29
+ * instead of hand-shaping `{ role: 'group', label, description, … }`.
30
+ *
31
+ * ## Migration path
32
+ *
33
+ * Phase 1 (this file): DTOs are an additive layer on top of `A11yNode`.
34
+ * Existing strategies continue to work unchanged because each DTO emits
35
+ * a fully-populated `A11yNode` with `role` set correctly.
36
+ *
37
+ * Phase 2 (follow-up): strategies grow `compileNode(node)` methods that
38
+ * dispatch on `node.kind` for cases where semantic intent is richer than
39
+ * `role` alone can express.
40
+ */
41
+ /**
42
+ * Base class for all semantic DTO nodes. Provides the `childrenWith()`
43
+ * composition helper and the abstract `toA11yNode()` contract.
44
+ */
45
+ export declare abstract class A11yNodeDto {
46
+ protected childDtos: A11yNodeDto[];
47
+ abstract readonly kind: A11ySemanticKind;
48
+ /**
49
+ * Declare the semantic children of this node in reading order.
50
+ *
51
+ * @param {...A11yNodeDto} children - Semantic child DTOs in reading order.
52
+ * @returns {this} `this`, for fluent chaining.
53
+ */
54
+ childrenWith(...children: A11yNodeDto[]): this;
55
+ /**
56
+ * Compile the declared child DTOs into their `A11yNode` representations.
57
+ *
58
+ * @returns {A11yNode[] | undefined} The compiled children, or `undefined` when none.
59
+ */
60
+ protected compileChildren(): A11yNode[] | undefined;
61
+ /** Compile this DTO (and its subtree) into an `A11yNode`. */
62
+ abstract toA11yNode(): A11yNode;
63
+ }
64
+ /**
65
+ * A generic container that groups related content. Maps to `role="group"`
66
+ * by default; strategies may upgrade to `role="region"` when a description
67
+ * is present and the platform benefits (e.g. Firefox+NVDA landmark
68
+ * navigation — see `firefox-nvda-strategy.ts`).
69
+ */
70
+ export declare class A11yContainerNode extends A11yNodeDto {
71
+ readonly id: string;
72
+ readonly opts: {
73
+ label?: string;
74
+ description?: string;
75
+ };
76
+ readonly kind: A11ySemanticKind;
77
+ constructor(id: string, opts?: {
78
+ label?: string;
79
+ description?: string;
80
+ });
81
+ /**
82
+ * Compile this DTO into its `A11yNode` representation.
83
+ *
84
+ * @returns {A11yNode} The compiled semantic node.
85
+ */
86
+ toA11yNode(): A11yNode;
87
+ }
88
+ /**
89
+ * A navigable / discoverable section (landmark). Always renders as
90
+ * `role="region"` so it appears in AT landmark navigation.
91
+ */
92
+ export declare class A11yLandmarkNode extends A11yNodeDto {
93
+ readonly id: string;
94
+ readonly opts: {
95
+ label?: string;
96
+ description?: string;
97
+ };
98
+ readonly kind: A11ySemanticKind;
99
+ constructor(id: string, opts?: {
100
+ label?: string;
101
+ description?: string;
102
+ });
103
+ /**
104
+ * Compile this DTO into its `A11yNode` representation.
105
+ *
106
+ * @returns {A11yNode} The compiled semantic node.
107
+ */
108
+ toA11yNode(): A11yNode;
109
+ }
110
+ /**
111
+ * A heading at the given level (1–6, defaults to 2).
112
+ *
113
+ * Use this instead of a raw `{ role: 'heading', level: 2 }` literal to
114
+ * benefit from the default-level guard and the `kind` discriminator.
115
+ */
116
+ export declare class A11yHeadingNode extends A11yNodeDto {
117
+ readonly id: string;
118
+ readonly opts: {
119
+ level?: 1 | 2 | 3 | 4 | 5 | 6;
120
+ label?: string;
121
+ };
122
+ readonly kind: A11ySemanticKind;
123
+ constructor(id: string, opts?: {
124
+ level?: 1 | 2 | 3 | 4 | 5 | 6;
125
+ label?: string;
126
+ });
127
+ /**
128
+ * Compile this DTO into its `A11yNode` representation.
129
+ *
130
+ * @returns {A11yNode} The compiled semantic node.
131
+ */
132
+ toA11yNode(): A11yNode;
133
+ }
134
+ /**
135
+ * A purely decorative icon. `decorative` is always `true` so authors never
136
+ * have to remember the flag — that is the whole point of this DTO class.
137
+ *
138
+ * Produces `aria-hidden="true"` via the baseline strategy; webkit-voiceover
139
+ * additionally sets `role="none"` as a belt-and-suspenders guard.
140
+ */
141
+ export declare class A11yIconNode extends A11yNodeDto {
142
+ readonly id: string;
143
+ readonly kind: A11ySemanticKind;
144
+ constructor(id: string);
145
+ /**
146
+ * Compile this DTO into its `A11yNode` representation.
147
+ *
148
+ * @returns {A11yNode} The compiled semantic node.
149
+ */
150
+ toA11yNode(): A11yNode;
151
+ }
152
+ /**
153
+ * An informative image that requires an accessible label (alt text).
154
+ *
155
+ * Produces `role="img"` + `aria-label` via the baseline strategy.
156
+ * Contrast with `A11yIconNode` which is always decorative.
157
+ */
158
+ export declare class A11yImageNode extends A11yNodeDto {
159
+ readonly id: string;
160
+ readonly opts: {
161
+ label: string;
162
+ };
163
+ readonly kind: A11ySemanticKind;
164
+ constructor(id: string, opts: {
165
+ label: string;
166
+ });
167
+ /**
168
+ * Compile this DTO into its `A11yNode` representation.
169
+ *
170
+ * @returns {A11yNode} The compiled semantic node.
171
+ */
172
+ toA11yNode(): A11yNode;
173
+ }
@@ -0,0 +1,28 @@
1
+ import { A11yNode } from './a11y-tree.types';
2
+ /**
3
+ * Applies an A11y Tree to a shadow root by:
4
+ *
5
+ * 1. Resolving the `A11yTreeStrategy` that best matches the current
6
+ * browser engine / AT environment.
7
+ * 2. Compiling the semantic tree into a flat list of `AriaPatch`
8
+ * instructions.
9
+ * 3. Clearing any previously managed ARIA attributes (`data-a11y-managed`).
10
+ * 4. Applying each patch to the `data-a11y-id` target node in the shadow.
11
+ * 5. Materialising one visually-hidden description `<span>` per patch that
12
+ * references `aria-describedby` and whose node carries description text.
13
+ * 6. Stamping `data-a11y-strategy-applied` on the host for observability.
14
+ *
15
+ * This is the generic, component-agnostic projection step. Components
16
+ * interact with it indirectly through `A11yTreeSlimmer`.
17
+ *
18
+ * @param {A11yNode} root - The root `A11yNode` of the semantic tree.
19
+ * @param {HTMLElement} host - The component's host element. Must have a `shadowRoot`.
20
+ * If `shadowRoot` is null (e.g. light-DOM component or early call before first
21
+ * render), the function returns immediately without throwing.
22
+ * @example
23
+ * ```ts
24
+ * // Called once per render from A11yTreeSlimmer.projectA11yTree():
25
+ * applyA11yTree(buildSectionTitleA11yTree({ titleText, description }), this.host);
26
+ * ```
27
+ */
28
+ export declare function applyA11yTree(root: A11yNode, host: HTMLElement): void;
@@ -0,0 +1,137 @@
1
+ /**
2
+ * A11y Tree — generic type definitions.
3
+ *
4
+ * The A11y Tree is a browser-agnostic description of the *semantic* a11y
5
+ * structure of a component. Each node captures the intent (role, label,
6
+ * description, level, etc.) and a stable `id` that the strategy layer
7
+ * can use to project ARIA attributes onto the real DOM.
8
+ *
9
+ * ## Architecture overview
10
+ *
11
+ * ```
12
+ * Component (TSX)
13
+ * ↓ builds semantic tree via DTO helpers (a11y-node-dto.ts)
14
+ * A11yNode tree (this file)
15
+ * ↓ compiled by an A11yTreeStrategy
16
+ * AriaPatch[]
17
+ * ↓ applied by a11y-tree-applier.ts
18
+ * Shadow DOM (ARIA attributes on data-a11y-id elements)
19
+ * ```
20
+ *
21
+ * The A11y Tree is NOT rendered itself. It is consumed by an
22
+ * `A11yTreeStrategy` that decides, per browser/AT, which ARIA attributes
23
+ * to attach to which DOM nodes.
24
+ *
25
+ * ## Browser-engine strategy contract
26
+ *
27
+ * Assistive technology (AT) cannot be detected from JavaScript (by design,
28
+ * for user privacy). The strategy resolver therefore branches on *browser
29
+ * engine* as a coarse proxy for the most likely AT pairing:
30
+ *
31
+ * | Engine | Assumed AT | Confidence |
32
+ * |-----------|-------------------|---------------------|
33
+ * | WebKit | VoiceOver (macOS/iOS) | medium on Apple, low elsewhere |
34
+ * | Gecko | NVDA (Windows), Orca (Linux) | medium on Win, low elsewhere |
35
+ * | Chromium | JAWS / NVDA / TalkBack | high on non-Apple, medium on Apple |
36
+ *
37
+ * **Confidence semantics** (see `A11yStrategyConfidence`):
38
+ * - `high` — direct signal (explicit override or confirmed UA).
39
+ * - `medium` — plausible proxy; AT pairing is an assumption that covers the
40
+ * majority of users on that engine+platform combination.
41
+ * - `low` — unknown UA or atypical engine/platform combo; dev-mode warning
42
+ * fires once per (strategy, reason) tuple via `resolveStrategy`.
43
+ *
44
+ * Consumers who know the AT environment (e.g. automated tests, a storybook
45
+ * knob) can pin a strategy explicitly via `data-a11y-strategy` on the host
46
+ * element — this is always treated as `high` confidence.
47
+ */
48
+ export declare type A11yRole = 'heading' | 'group' | 'region' | 'img' | 'presentation' | 'none';
49
+ /**
50
+ * Semantic kind — describes *what the content is*, independent of which
51
+ * ARIA attribute it ultimately produces. Strategies may dispatch on `kind`
52
+ * for fine-grained control beyond what `role` can express.
53
+ *
54
+ * Authoritative definition: `a11y-node-dto.ts`. Re-exported here so tree
55
+ * literal authors can type-check without importing the DTO module.
56
+ */
57
+ export declare type A11ySemanticKind = 'container' | 'landmark' | 'heading' | 'icon' | 'image' | 'button' | 'live';
58
+ /**
59
+ * A single node in the semantic A11y Tree.
60
+ *
61
+ * Nodes are authored via the DTO helpers in `a11y-node-dto.ts` to avoid
62
+ * hand-shaping ARIA field names. Raw literals are still accepted by all
63
+ * APIs for backwards compatibility and quick inline use.
64
+ */
65
+ export interface A11yNode {
66
+ /** Stable identifier; DOM nodes opt in via `data-a11y-id`. */
67
+ id: string;
68
+ /** Semantic role for this node. */
69
+ role: A11yRole;
70
+ /**
71
+ * Optional semantic discriminator emitted by the DTO layer.
72
+ * Strategies that need to distinguish intent beyond `role`
73
+ * (e.g. landmark vs plain container) dispatch on this first
74
+ * and fall back to `role` when absent.
75
+ */
76
+ kind?: A11ySemanticKind;
77
+ /** Visible text label (used for aria-label / aria-labelledby). */
78
+ label?: string;
79
+ /** Supplementary description (used for aria-describedby). */
80
+ description?: string;
81
+ /** Heading level (1–6) when role === 'heading'. */
82
+ level?: 1 | 2 | 3 | 4 | 5 | 6;
83
+ /** Whether this node is purely decorative. */
84
+ decorative?: boolean;
85
+ /** Child semantic nodes. */
86
+ children?: A11yNode[];
87
+ }
88
+ /**
89
+ * A flat instruction emitted by the strategy: "on the DOM node carrying
90
+ * `data-a11y-id=<targetId>`, set this attribute to this value".
91
+ *
92
+ * `value === null` means the attribute should be removed.
93
+ */
94
+ export interface AriaPatch {
95
+ targetId: string;
96
+ attribute: string;
97
+ value: string | null;
98
+ }
99
+ /**
100
+ * Strategy contract. Each strategy encapsulates the per-browser/AT quirks
101
+ * needed to project an `A11yNode` tree onto real ARIA attributes.
102
+ *
103
+ * Strategies MUST be pure functions of the tree: same input → same output.
104
+ * Side effects (DOM manipulation) belong in `a11y-tree-applier.ts`.
105
+ */
106
+ export interface A11yTreeStrategy {
107
+ /** Machine-readable name, used for `data-a11y-strategy` lookups. */
108
+ name: string;
109
+ /** Convert a semantic A11y tree into a flat list of ARIA patches. */
110
+ compile(root: A11yNode): AriaPatch[];
111
+ }
112
+ /**
113
+ * Confidence level for the strategy-resolver's UA→AT mapping.
114
+ *
115
+ * - `high` : we observed a direct signal (explicit override, or a
116
+ * UA the resolver has confirmed test coverage for).
117
+ * - `medium` : UA pattern is a known proxy but the AT pairing is an
118
+ * assumption (e.g. Firefox → NVDA on Windows; users on
119
+ * Linux running Orca will also match this branch).
120
+ * - `low` : we are falling back to baseline because we could not
121
+ * recognise the UA at all.
122
+ *
123
+ * Low-confidence matches surface a dev-mode console warning (rate-limited
124
+ * per strategy+reason tuple) so product teams know when to pin a strategy
125
+ * explicitly via `data-a11y-strategy`.
126
+ */
127
+ export declare type A11yStrategyConfidence = 'high' | 'medium' | 'low';
128
+ /**
129
+ * Full resolution result including the strategy, how confident we are,
130
+ * and a human-readable reason string for dev warnings.
131
+ */
132
+ export interface A11yStrategyResolution {
133
+ strategy: A11yTreeStrategy;
134
+ confidence: A11yStrategyConfidence;
135
+ /** Human-readable reason — surfaced in dev warnings. */
136
+ reason: string;
137
+ }
@@ -0,0 +1,18 @@
1
+ import { A11yTreeStrategy } from '../a11y-tree.types';
2
+ /**
3
+ * Baseline strategy: spec-compliant ARIA, works on evergreen Chromium,
4
+ * Firefox, and Safari with their default AT pairings (NVDA, Orca,
5
+ * VoiceOver-macOS). Used as the default when no engine-specific override
6
+ * matches.
7
+ *
8
+ * ## Mapping rules
9
+ *
10
+ * | Node role | ARIA output |
11
+ * |---------------|----------------------------------------------------|
12
+ * | heading | `role="heading"` + `aria-level` |
13
+ * | group/region | `role` + `aria-label` (if present) + `aria-describedby` (if description) |
14
+ * | img (decorative) | `aria-hidden="true"` |
15
+ * | img (labelled) | `role="img"` + `aria-label` |
16
+ * | presentation/none | `role="presentation"` |
17
+ */
18
+ export declare const baselineStrategy: A11yTreeStrategy;
@@ -0,0 +1,16 @@
1
+ import { A11yTreeStrategy } from '../a11y-tree.types';
2
+ /**
3
+ * Firefox + NVDA strategy.
4
+ *
5
+ * Firefox/NVDA generally handles spec-compliant ARIA correctly. The one
6
+ * known quirk for the Vega component family:
7
+ *
8
+ * **NVDA browse-mode may skip `aria-describedby` on `role="group"`.**
9
+ * When a group container carries a description, NVDA in browse (reading)
10
+ * mode sometimes does not announce it. Workaround: promote the container to
11
+ * `role="region"`, which is part of the landmark navigation set and is
12
+ * reliably announced by NVDA when encountered during linear reading.
13
+ *
14
+ * All other node types fall back to baseline behaviour.
15
+ */
16
+ export declare const firefoxNvdaStrategy: A11yTreeStrategy;
@@ -0,0 +1,23 @@
1
+ import { A11yTreeStrategy } from '../a11y-tree.types';
2
+ /**
3
+ * WebKit + VoiceOver strategy.
4
+ *
5
+ * Applies on top of the baseline to work around two known VoiceOver quirks:
6
+ *
7
+ * **Quirk #1 — `aria-describedby` on non-focusable containers is skipped.**
8
+ * VoiceOver on Safari often does not read `aria-describedby` on non-focusable
9
+ * `role="group"` (A11yContainerNode) or `role="region"` (A11yLandmarkNode)
10
+ * containers. Workaround: fold the description text directly into the
11
+ * heading's `aria-label` (joined with `. `) so it is read together with the
12
+ * title, and remove the orphaned `aria-describedby` patch.
13
+ *
14
+ * **Quirk #2 — Decorative `<vega-icon>` announced twice.**
15
+ * Safari occasionally announces a decorative icon twice when only
16
+ * `aria-hidden` is set on the host. We additionally set `role="none"` as a
17
+ * belt-and-suspenders guard that suppresses the extra announcement.
18
+ *
19
+ * These adjustments are applied as a *diff* on top of the baseline patch
20
+ * list — the A11y Tree itself is unchanged. Other node types fall back to
21
+ * baseline behaviour.
22
+ */
23
+ export declare const webkitVoiceOverStrategy: A11yTreeStrategy;