@heartlandone/vega 2.94.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 (381) hide show
  1. package/dist/cjs/{app-globals-d05c3410.js → app-globals-38afea36.js} +7 -7
  2. package/dist/cjs/{child-nodes-event-prevent-slimmer-e67ee84c.js → child-nodes-event-prevent-slimmer-e0ac8467.js} +1 -1
  3. package/dist/cjs/{code-block-493c7ce7.js → code-block-4126dc3b.js} +1501 -55
  4. package/dist/cjs/{component-value-history-controller-slimmer.abstract-ab21fcbf.js → component-value-history-controller-slimmer.abstract-38ba956e.js} +2 -2
  5. package/dist/cjs/{content-state-fc34a814.js → content-state-50e8a03c.js} +142 -580
  6. package/dist/cjs/{element-appender-slimmer-1d6323c2.js → element-appender-slimmer-7773fdab.js} +115 -0
  7. package/dist/cjs/{event-emit-slimmer-d234a619.js → event-emit-slimmer-34aa195e.js} +1 -1
  8. package/dist/cjs/{image-annotation-action-7c4cd316.js → image-annotation-action-89363de8.js} +2 -2
  9. package/dist/cjs/{image-extension-30a7c10f.js → image-extension-c881c454.js} +2 -2
  10. package/dist/cjs/index.cjs.js +11 -11
  11. package/dist/cjs/{internal-vega-event-manager-13c4012b.js → internal-vega-event-manager-7003c84a.js} +10 -2
  12. package/dist/cjs/{link-extension-92a63cb7.js → link-extension-b7f99a52.js} +2 -2
  13. package/dist/cjs/loader.cjs.js +9 -9
  14. package/dist/cjs/{public-rules-9e1ea1d9.js → public-rules-72894208.js} +3 -3
  15. package/dist/cjs/{range-30219330.js → range-95d41dea.js} +1 -1
  16. package/dist/cjs/{rich-text-editor-required-rule-23bf7485.js → rich-text-editor-required-rule-4d6d2493.js} +1 -1
  17. package/dist/cjs/shared-backdrop-manager-71e54fdb.js +199 -0
  18. package/dist/cjs/{split-cell-operation-43752212.js → split-cell-operation-70be116d.js} +2 -2
  19. package/dist/cjs/{token-extension-ea891d54.js → token-extension-eb828948.js} +36 -12
  20. package/dist/cjs/vega-accordion.cjs.entry.js +2 -2
  21. package/dist/cjs/vega-app-footer.cjs.entry.js +2 -2
  22. package/dist/cjs/vega-app-header-button.cjs.entry.js +3 -3
  23. package/dist/cjs/vega-banner.cjs.entry.js +2 -2
  24. package/dist/cjs/vega-breadcrumb.cjs.entry.js +3 -3
  25. package/dist/cjs/vega-button-circle.cjs.entry.js +3 -3
  26. package/dist/cjs/vega-button-group_2.cjs.entry.js +3 -3
  27. package/dist/cjs/vega-button-link.cjs.entry.js +3 -3
  28. package/dist/cjs/vega-button.cjs.entry.js +3 -3
  29. package/dist/cjs/vega-calendar_5.cjs.entry.js +3 -3
  30. package/dist/cjs/vega-carousel.cjs.entry.js +2 -2
  31. package/dist/cjs/vega-checkbox_2.cjs.entry.js +3 -3
  32. package/dist/cjs/vega-chip.cjs.entry.js +3 -3
  33. package/dist/cjs/vega-code-block.cjs.entry.js +6 -6
  34. package/dist/cjs/vega-color-picker.cjs.entry.js +2 -2
  35. package/dist/cjs/vega-color-swatch-picker.cjs.entry.js +3 -3
  36. package/dist/cjs/vega-color-swatch.cjs.entry.js +2 -2
  37. package/dist/cjs/vega-combo-box.cjs.entry.js +22 -4
  38. package/dist/cjs/vega-date-picker_2.cjs.entry.js +4 -4
  39. package/dist/cjs/vega-dialog_2.cjs.entry.js +160 -70
  40. package/dist/cjs/vega-dropdown_5.cjs.entry.js +41 -13
  41. package/dist/cjs/vega-env-manager-23b8b23c.js +2 -2
  42. package/dist/cjs/vega-field-label.cjs.entry.js +2 -2
  43. package/dist/cjs/vega-file-uploader.cjs.entry.js +2 -2
  44. package/dist/cjs/vega-form.cjs.entry.js +3 -3
  45. package/dist/cjs/vega-image-uploader.cjs.entry.js +3 -3
  46. package/dist/cjs/vega-input-credit-card.cjs.entry.js +3 -3
  47. package/dist/cjs/vega-input-numeric.cjs.entry.js +3 -3
  48. package/dist/cjs/vega-input-passcode.cjs.entry.js +3 -3
  49. package/dist/cjs/vega-input-phone-number.cjs.entry.js +3 -3
  50. package/dist/cjs/vega-input-range.cjs.entry.js +3 -3
  51. package/dist/cjs/vega-input-select.cjs.entry.js +54 -5
  52. package/dist/cjs/vega-input.cjs.entry.js +2 -2
  53. package/dist/cjs/vega-item-toggle.cjs.entry.js +2 -2
  54. package/dist/cjs/vega-left-nav_5.cjs.entry.js +32 -193
  55. package/dist/cjs/vega-pagination-page-selector-mobile.cjs.entry.js +2 -2
  56. package/dist/cjs/vega-pagination.cjs.entry.js +3 -3
  57. package/dist/cjs/vega-popover_2.cjs.entry.js +3 -3
  58. package/dist/cjs/vega-progress-tracker_2.cjs.entry.js +13 -3
  59. package/dist/cjs/vega-radio_2.cjs.entry.js +3 -3
  60. package/dist/cjs/vega-rich-text-content.cjs.entry.js +58 -9
  61. package/dist/cjs/vega-rich-text-editor_4.cjs.entry.js +611 -93
  62. package/dist/cjs/vega-rich-text-find-replace-panel.cjs.entry.js +2 -2
  63. package/dist/cjs/vega-rich-text-special-characters-panel.cjs.entry.js +2 -2
  64. package/dist/cjs/vega-rich-text-table-properties_3.cjs.entry.js +5 -5
  65. package/dist/cjs/vega-section-title.cjs.entry.js +896 -14
  66. package/dist/cjs/vega-segment-control.cjs.entry.js +2 -2
  67. package/dist/cjs/vega-selection-chip_2.cjs.entry.js +3 -3
  68. package/dist/cjs/vega-selection-tile_2.cjs.entry.js +3 -3
  69. package/dist/cjs/vega-sidenav_3.cjs.entry.js +2 -2
  70. package/dist/cjs/vega-signature-capture.cjs.entry.js +2 -2
  71. package/dist/cjs/vega-stepper.cjs.entry.js +3 -3
  72. package/dist/cjs/vega-tab-group_2.cjs.entry.js +3 -3
  73. package/dist/cjs/vega-table_11.cjs.entry.js +3 -3
  74. package/dist/cjs/vega-textarea.cjs.entry.js +3 -3
  75. package/dist/cjs/vega-time-picker_2.cjs.entry.js +4 -4
  76. package/dist/cjs/vega-toggle-switch.cjs.entry.js +2 -2
  77. package/dist/cjs/vega-tooltip_2.cjs.entry.js +1 -1
  78. package/dist/cjs/vega.cjs.js +9 -9
  79. package/dist/collection/components/vega-combo-box/slimmers/renderers/vega-combo-box-dropdown-renderer.js +5 -1
  80. package/dist/collection/components/vega-combo-box/vega-combo-box.js +52 -1
  81. package/dist/collection/components/vega-dialog/vega-dialog.js +1 -1
  82. package/dist/collection/components/vega-dropdown/slimmers/controllers/vega-dropdown-render-mode-controller.js +7 -6
  83. package/dist/collection/components/vega-dropdown/vega-dropdown.js +36 -8
  84. package/dist/collection/components/vega-input-select/slimmers/controllers/vega-input-select-dropdown-controller.js +11 -1
  85. package/dist/collection/components/vega-input-select/slimmers/controllers/vega-input-select-items-slot-controler.js +23 -2
  86. package/dist/collection/components/vega-input-select/slimmers/renderers/vega-input-select-dropdown-renderer.js +4 -0
  87. package/dist/collection/components/vega-input-select/vega-input-select.js +53 -2
  88. package/dist/collection/components/vega-modal/slimmers/controllers/vega-modal-backdrop-manager.js +141 -0
  89. package/dist/collection/components/vega-modal/slimmers/controllers/vega-modal-open-state-controller.js +10 -17
  90. package/dist/collection/components/vega-modal/slimmers/controllers/vega-modal-z-index-controller.js +2 -2
  91. package/dist/collection/components/vega-modal/slimmers/renderers/vega-modal-renderer.js +3 -2
  92. package/dist/collection/components/vega-modal/vega-modal.js +77 -8
  93. package/dist/collection/components/vega-progress-tracker/slimmers/controllers/vega-progress-tracker-current-steps-controller.js +7 -0
  94. package/dist/collection/components/vega-progress-tracker/vega-progress-tracker.js +6 -0
  95. package/dist/collection/components/vega-rich-text-content/vega-rich-text-content.css +4 -0
  96. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/block-delete-node-content-strategy.js +29 -0
  97. 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
  98. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/block-transform-to-list-strategy.js +8 -3
  99. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-annotation-strategy.abstract.js +60 -0
  100. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-item-replace-nest-list-strategy.js +36 -4
  101. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-items-strategy.abstract.js +27 -0
  102. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-nest-items-strategy.js +74 -0
  103. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-remove-list-item-strategy.js +81 -1
  104. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-transform-selection.js +30 -0
  105. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-transform-to-list-strategy.js +160 -9
  106. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-transform-to-paragraph-strategy.js +376 -10
  107. package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-unnest-items-strategy.js +104 -0
  108. package/dist/collection/components/vega-rich-text-editor/dto/actions/modify-content-action.abstract.js +2 -0
  109. package/dist/collection/components/vega-rich-text-editor/dto/actions/nest-list-items-action.js +12 -0
  110. package/dist/collection/components/vega-rich-text-editor/dto/actions/unnest-list-items-action.js +12 -0
  111. package/dist/collection/components/vega-rich-text-editor/dto/annotations/list-annotation.js +12 -0
  112. package/dist/collection/components/vega-rich-text-editor/dto/blocks/list-block.js +10 -1
  113. package/dist/collection/components/vega-rich-text-editor/dto/blocks/list-item-block.js +11 -3
  114. package/dist/collection/components/vega-rich-text-editor/dto/content-state.js +7 -1
  115. package/dist/collection/components/vega-rich-text-editor/dto/filter-styles-strategies/list-block/list-block-filter-styles-strategy.js +8 -4
  116. package/dist/collection/components/vega-rich-text-editor/dto/renderers/blocks/list-block-renderer.js +34 -1
  117. package/dist/collection/components/vega-rich-text-editor/dto/renderers/blocks/list-item-block-renderer.js +20 -3
  118. package/dist/collection/components/vega-rich-text-editor/extensions/table/annotation-handler/table-annotation-handler-base.js +25 -1
  119. 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
  120. package/dist/collection/components/vega-rich-text-editor/slimmers/controllers/helper/input-event-handler/abstract-delete-content-handler.js +29 -0
  121. package/dist/collection/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/bullets-numbers-toolbar-button-slimmer.js +30 -1
  122. package/dist/collection/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/helper/abstract-list-keyboard-handler.js +204 -0
  123. package/dist/collection/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/helper/list-shift-tab-outdent-handler.js +42 -0
  124. package/dist/collection/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/helper/list-tab-indent-handler.js +34 -0
  125. package/dist/collection/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/list-keyboard-slimmer.js +180 -0
  126. package/dist/collection/components/vega-section-title/slimmers/a11y-tree/build-section-title-a11y-tree.js +54 -0
  127. package/dist/collection/components/vega-section-title/slimmers/renderers/vega-section-title-renderer.js +4 -4
  128. package/dist/collection/components/vega-section-title/vega-section-title.js +18 -2
  129. package/dist/collection/helpers/a11y-tree/a11y-node-dto.js +210 -0
  130. package/dist/collection/helpers/a11y-tree/a11y-tree-applier.js +189 -0
  131. package/dist/collection/helpers/a11y-tree/a11y-tree.types.js +48 -0
  132. package/dist/collection/helpers/a11y-tree/strategies/baseline-strategy.js +78 -0
  133. package/dist/collection/helpers/a11y-tree/strategies/firefox-nvda-strategy.js +56 -0
  134. package/dist/collection/helpers/a11y-tree/strategies/webkit-voiceover-strategy.js +140 -0
  135. package/dist/collection/helpers/a11y-tree/strategy-resolver.js +172 -0
  136. package/dist/collection/helpers/backdrop/shared-backdrop-manager.js +32 -1
  137. package/dist/collection/helpers/event-manager/event-id/component-event-id-map.js +11 -3
  138. package/dist/collection/helpers/slimmers/a11y-tree-slimmer.js +54 -0
  139. package/dist/collection/helpers/slimmers/element-appender/element-appender-slimmer.js +29 -0
  140. package/dist/collection/helpers/slimmers/element-appender/visibility-modifiers/clip-on-scroll-modifier.js +70 -0
  141. package/dist/collection/helpers/slimmers/element-appender/visibility-modifiers/visibility-modifier.interface.js +1 -0
  142. package/dist/collection/helpers/ui/element-appender.js +16 -0
  143. package/dist/esm/{app-globals-f2336686.js → app-globals-d7b651c1.js} +7 -7
  144. package/dist/esm/{child-nodes-event-prevent-slimmer-96c14f5a.js → child-nodes-event-prevent-slimmer-82626871.js} +1 -1
  145. package/dist/esm/{code-block-e12588fe.js → code-block-0a88b481.js} +1495 -51
  146. package/dist/esm/{component-value-history-controller-slimmer.abstract-4e8eb313.js → component-value-history-controller-slimmer.abstract-6846edfa.js} +2 -2
  147. package/dist/esm/{content-state-8032467a.js → content-state-79ca99e5.js} +105 -541
  148. package/dist/esm/{element-appender-slimmer-7fcb944b.js → element-appender-slimmer-73ad10ae.js} +115 -0
  149. package/dist/esm/{event-emit-slimmer-db4a82e0.js → event-emit-slimmer-2452278f.js} +1 -1
  150. package/dist/esm/{image-annotation-action-b3b6c308.js → image-annotation-action-bb299ef1.js} +3 -3
  151. package/dist/esm/{image-extension-b6c7e4a7.js → image-extension-48a96f98.js} +2 -2
  152. package/dist/esm/index.js +10 -10
  153. package/dist/esm/{internal-vega-event-manager-48690e5b.js → internal-vega-event-manager-2ecc9186.js} +11 -3
  154. package/dist/esm/{link-extension-97fcb8fb.js → link-extension-09534514.js} +2 -2
  155. package/dist/esm/loader.js +10 -10
  156. package/dist/esm/{public-rules-c06f0d2a.js → public-rules-5eb03ef0.js} +3 -3
  157. package/dist/esm/{range-e999837f.js → range-d4deb7df.js} +1 -1
  158. package/dist/esm/{rich-text-editor-required-rule-71f8ee98.js → rich-text-editor-required-rule-5bbbce23.js} +1 -1
  159. package/dist/esm/shared-backdrop-manager-a7c63838.js +197 -0
  160. package/dist/esm/{split-cell-operation-359f8082.js → split-cell-operation-7f3058ad.js} +2 -2
  161. package/dist/esm/{token-extension-9896879b.js → token-extension-40c32bcc.js} +32 -8
  162. package/dist/esm/vega-accordion.entry.js +3 -3
  163. package/dist/esm/vega-app-footer.entry.js +3 -3
  164. package/dist/esm/vega-app-header-button.entry.js +4 -4
  165. package/dist/esm/vega-banner.entry.js +3 -3
  166. package/dist/esm/vega-breadcrumb.entry.js +4 -4
  167. package/dist/esm/vega-button-circle.entry.js +4 -4
  168. package/dist/esm/vega-button-group_2.entry.js +4 -4
  169. package/dist/esm/vega-button-link.entry.js +4 -4
  170. package/dist/esm/vega-button.entry.js +4 -4
  171. package/dist/esm/vega-calendar_5.entry.js +4 -4
  172. package/dist/esm/vega-carousel.entry.js +3 -3
  173. package/dist/esm/vega-checkbox_2.entry.js +4 -4
  174. package/dist/esm/vega-chip.entry.js +4 -4
  175. package/dist/esm/vega-code-block.entry.js +7 -7
  176. package/dist/esm/vega-color-picker.entry.js +3 -3
  177. package/dist/esm/vega-color-swatch-picker.entry.js +4 -4
  178. package/dist/esm/vega-color-swatch.entry.js +3 -3
  179. package/dist/esm/vega-combo-box.entry.js +23 -5
  180. package/dist/esm/vega-date-picker_2.entry.js +5 -5
  181. package/dist/esm/vega-dialog_2.entry.js +161 -71
  182. package/dist/esm/vega-dropdown_5.entry.js +42 -14
  183. package/dist/esm/vega-env-manager-8f8dc473.js +2 -2
  184. package/dist/esm/{vega-event-id-270fe47e.js → vega-event-id-f55f6977.js} +1 -1
  185. package/dist/esm/vega-field-label.entry.js +3 -3
  186. package/dist/esm/vega-file-uploader.entry.js +3 -3
  187. package/dist/esm/vega-form.entry.js +4 -4
  188. package/dist/esm/vega-image-uploader.entry.js +4 -4
  189. package/dist/esm/vega-input-credit-card.entry.js +4 -4
  190. package/dist/esm/vega-input-numeric.entry.js +4 -4
  191. package/dist/esm/vega-input-passcode.entry.js +4 -4
  192. package/dist/esm/vega-input-phone-number.entry.js +4 -4
  193. package/dist/esm/vega-input-range.entry.js +4 -4
  194. package/dist/esm/vega-input-select.entry.js +55 -6
  195. package/dist/esm/vega-input.entry.js +3 -3
  196. package/dist/esm/vega-item-toggle.entry.js +3 -3
  197. package/dist/esm/vega-left-nav_5.entry.js +32 -193
  198. package/dist/esm/vega-page-notification_2.entry.js +1 -1
  199. package/dist/esm/vega-pagination-page-selector-mobile.entry.js +3 -3
  200. package/dist/esm/vega-pagination-page-size-selector-mobile.entry.js +1 -1
  201. package/dist/esm/vega-pagination.entry.js +4 -4
  202. package/dist/esm/vega-popover_2.entry.js +4 -4
  203. package/dist/esm/vega-progress-tracker_2.entry.js +14 -4
  204. package/dist/esm/vega-radio_2.entry.js +4 -4
  205. package/dist/esm/vega-rich-text-content.entry.js +59 -10
  206. package/dist/esm/vega-rich-text-editor_4.entry.js +608 -90
  207. package/dist/esm/vega-rich-text-find-replace-panel.entry.js +3 -3
  208. package/dist/esm/vega-rich-text-special-characters-panel.entry.js +3 -3
  209. package/dist/esm/vega-rich-text-table-properties_3.entry.js +6 -6
  210. package/dist/esm/vega-section-title.entry.js +897 -15
  211. package/dist/esm/vega-segment-control.entry.js +3 -3
  212. package/dist/esm/vega-selection-chip_2.entry.js +4 -4
  213. package/dist/esm/vega-selection-tile_2.entry.js +4 -4
  214. package/dist/esm/vega-sidenav_3.entry.js +3 -3
  215. package/dist/esm/vega-signature-capture.entry.js +3 -3
  216. package/dist/esm/vega-stepper.entry.js +4 -4
  217. package/dist/esm/vega-tab-group_2.entry.js +4 -4
  218. package/dist/esm/vega-table_11.entry.js +4 -4
  219. package/dist/esm/vega-textarea.entry.js +4 -4
  220. package/dist/esm/vega-time-picker_2.entry.js +5 -5
  221. package/dist/esm/vega-toggle-switch.entry.js +3 -3
  222. package/dist/esm/vega-tooltip_2.entry.js +1 -1
  223. package/dist/esm/vega.js +10 -10
  224. package/dist/sri/vega-sri-manifest.json +272 -268
  225. package/dist/types/components/vega-combo-box/slimmers/renderers/vega-combo-box-dropdown-renderer.d.ts +1 -0
  226. package/dist/types/components/vega-combo-box/vega-combo-box.d.ts +21 -0
  227. package/dist/types/components/vega-dropdown/slimmers/controllers/vega-dropdown-render-mode-controller.d.ts +2 -1
  228. package/dist/types/components/vega-dropdown/types.d.ts +2 -2
  229. package/dist/types/components/vega-dropdown/vega-dropdown.d.ts +36 -9
  230. package/dist/types/components/vega-input-select/slimmers/controllers/vega-input-select-dropdown-controller.d.ts +2 -0
  231. package/dist/types/components/vega-input-select/slimmers/controllers/vega-input-select-items-slot-controler.d.ts +10 -0
  232. package/dist/types/components/vega-input-select/types.d.ts +1 -0
  233. package/dist/types/components/vega-input-select/vega-input-select.d.ts +21 -0
  234. package/dist/types/components/vega-modal/slimmers/controllers/vega-modal-backdrop-manager.d.ts +66 -0
  235. package/dist/types/components/vega-modal/slimmers/controllers/vega-modal-open-state-controller.d.ts +1 -5
  236. package/dist/types/components/vega-modal/slimmers/controllers/vega-modal-z-index-controller.d.ts +1 -1
  237. package/dist/types/components/vega-modal/slimmers/renderers/vega-modal-renderer.d.ts +1 -1
  238. package/dist/types/components/vega-modal/vega-modal.d.ts +34 -6
  239. package/dist/types/components/vega-progress-tracker/slimmers/controllers/vega-progress-tracker-current-steps-controller.d.ts +2 -0
  240. package/dist/types/components/vega-progress-tracker/vega-progress-tracker.d.ts +1 -0
  241. package/dist/types/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-annotation-strategy.abstract.d.ts +36 -0
  242. 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
  243. package/dist/types/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-items-strategy.abstract.d.ts +22 -0
  244. package/dist/types/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-nest-items-strategy.d.ts +21 -0
  245. package/dist/types/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-remove-list-item-strategy.d.ts +14 -0
  246. package/dist/types/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-transform-selection.d.ts +15 -0
  247. package/dist/types/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-transform-to-list-strategy.d.ts +30 -3
  248. package/dist/types/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-transform-to-paragraph-strategy.d.ts +99 -3
  249. package/dist/types/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-unnest-items-strategy.d.ts +22 -0
  250. package/dist/types/components/vega-rich-text-editor/dto/actions/modify-content-action.abstract.d.ts +2 -0
  251. package/dist/types/components/vega-rich-text-editor/dto/actions/nest-list-items-action.d.ts +11 -0
  252. package/dist/types/components/vega-rich-text-editor/dto/actions/unnest-list-items-action.d.ts +11 -0
  253. package/dist/types/components/vega-rich-text-editor/dto/annotations/list-annotation.d.ts +8 -0
  254. package/dist/types/components/vega-rich-text-editor/dto/blocks/list-block.d.ts +6 -1
  255. package/dist/types/components/vega-rich-text-editor/dto/blocks/list-item-block.d.ts +5 -1
  256. package/dist/types/components/vega-rich-text-editor/dto/content-state.d.ts +2 -2
  257. package/dist/types/components/vega-rich-text-editor/dto/renderers/blocks/list-block-renderer.d.ts +2 -0
  258. package/dist/types/components/vega-rich-text-editor/dto/renderers/blocks/list-item-block-renderer.d.ts +8 -0
  259. package/dist/types/components/vega-rich-text-editor/extensions/table/annotation-handler/table-annotation-handler-base.d.ts +18 -0
  260. package/dist/types/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/bullets-numbers-toolbar-button-slimmer.d.ts +8 -0
  261. package/dist/types/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/helper/abstract-list-keyboard-handler.d.ts +99 -0
  262. package/dist/types/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/helper/list-shift-tab-outdent-handler.d.ts +15 -0
  263. package/dist/types/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/helper/list-tab-indent-handler.d.ts +15 -0
  264. package/dist/types/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/list-keyboard-slimmer.d.ts +73 -0
  265. package/dist/types/components/vega-section-title/slimmers/a11y-tree/build-section-title-a11y-tree.d.ts +41 -0
  266. package/dist/types/components/vega-section-title/vega-section-title.d.ts +9 -0
  267. package/dist/types/components.d.ts +42 -8
  268. package/dist/types/helpers/a11y-tree/a11y-node-dto.d.ts +173 -0
  269. package/dist/types/helpers/a11y-tree/a11y-tree-applier.d.ts +28 -0
  270. package/dist/types/helpers/a11y-tree/a11y-tree.types.d.ts +137 -0
  271. package/dist/types/helpers/a11y-tree/strategies/baseline-strategy.d.ts +18 -0
  272. package/dist/types/helpers/a11y-tree/strategies/firefox-nvda-strategy.d.ts +16 -0
  273. package/dist/types/helpers/a11y-tree/strategies/webkit-voiceover-strategy.d.ts +23 -0
  274. package/dist/types/helpers/a11y-tree/strategy-resolver.d.ts +59 -0
  275. package/dist/types/helpers/backdrop/shared-backdrop-manager.d.ts +16 -0
  276. package/dist/types/helpers/slimmers/a11y-tree-slimmer.d.ts +49 -0
  277. package/dist/types/helpers/slimmers/element-appender/element-appender-slimmer.d.ts +9 -0
  278. package/dist/types/helpers/slimmers/element-appender/visibility-modifiers/clip-on-scroll-modifier.d.ts +37 -0
  279. package/dist/types/helpers/slimmers/element-appender/visibility-modifiers/visibility-modifier.interface.d.ts +56 -0
  280. package/dist/types/helpers/ui/element-appender.d.ts +7 -0
  281. package/dist/vega/index.esm.js +1 -1
  282. package/dist/vega/{p-3e8baeac.entry.js → p-0512308f.entry.js} +1 -1
  283. package/dist/vega/{p-46fe3154.entry.js → p-1d8312d3.entry.js} +1 -1
  284. package/dist/vega/{p-f5d7b89f.entry.js → p-1dfbc542.entry.js} +1 -1
  285. package/dist/vega/{p-fbd3be00.entry.js → p-200c8914.entry.js} +1 -1
  286. package/dist/vega/{p-e235020b.entry.js → p-22cc174e.entry.js} +1 -1
  287. package/dist/vega/{p-b1ff70bf.js → p-2c737fc8.js} +1 -1
  288. package/dist/vega/{p-782eb312.entry.js → p-2d77ae73.entry.js} +1 -1
  289. package/dist/vega/{p-cb90163a.entry.js → p-2d8d4d5b.entry.js} +1 -1
  290. package/dist/vega/{p-f651df3b.entry.js → p-2df5d59b.entry.js} +1 -1
  291. package/dist/vega/p-31216140.js +1 -0
  292. package/dist/vega/{p-f7e459cd.js → p-312d8205.js} +1 -1
  293. package/dist/vega/{p-a7209700.js → p-3345d903.js} +1 -1
  294. package/dist/vega/{p-44439ecc.entry.js → p-36d2df7a.entry.js} +1 -1
  295. package/dist/vega/{p-02355de8.js → p-3c23ec90.js} +1 -1
  296. package/dist/vega/{p-2bf17505.entry.js → p-3d6f761a.entry.js} +1 -1
  297. package/dist/vega/p-4151f53a.entry.js +1 -0
  298. package/dist/vega/{p-a057285e.entry.js → p-49e1cf4d.entry.js} +1 -1
  299. package/dist/vega/{p-698fbd73.js → p-5447a8e8.js} +1 -1
  300. package/dist/vega/p-55e0014a.js +3 -0
  301. package/dist/vega/{p-45e8424a.entry.js → p-56d19601.entry.js} +1 -1
  302. package/dist/vega/{p-addbca58.entry.js → p-5924adae.entry.js} +1 -1
  303. package/dist/vega/{p-9dca874d.entry.js → p-5e4517eb.entry.js} +1 -1
  304. package/dist/vega/p-5f377954.js +1 -1
  305. package/dist/vega/p-65fee02f.entry.js +1 -0
  306. package/dist/vega/{p-140616fe.js → p-66647244.js} +1 -1
  307. package/dist/vega/{p-62d6e063.entry.js → p-6680ba17.entry.js} +1 -1
  308. package/dist/vega/p-6a51d720.js +1 -0
  309. package/dist/vega/{p-fe24b459.js → p-6c7b6d45.js} +1 -1
  310. package/dist/vega/{p-288d65ad.entry.js → p-6fcec7c7.entry.js} +1 -1
  311. package/dist/vega/{p-d08ffdf1.entry.js → p-74f86ff9.entry.js} +1 -1
  312. package/dist/vega/{p-6ad7144a.entry.js → p-775ecfad.entry.js} +1 -1
  313. package/dist/vega/{p-6f70a10f.entry.js → p-7950f3e2.entry.js} +1 -1
  314. package/dist/vega/{p-f246f125.entry.js → p-80b7945a.entry.js} +1 -1
  315. package/dist/vega/p-8354cff0.entry.js +1 -0
  316. package/dist/vega/{p-5db61a12.entry.js → p-841b3281.entry.js} +1 -1
  317. package/dist/vega/{p-579cdeae.js → p-84b7a775.js} +1 -1
  318. package/dist/vega/p-87e5cb56.entry.js +1 -0
  319. package/dist/vega/p-8c30a60d.js +1 -0
  320. package/dist/vega/{p-f8a29127.entry.js → p-8d96f0e8.entry.js} +1 -1
  321. package/dist/vega/{p-95913e3c.entry.js → p-91303402.entry.js} +1 -1
  322. package/dist/vega/p-96da7d30.entry.js +1 -0
  323. package/dist/vega/{p-51b68d25.js → p-9d3f69cb.js} +1 -1
  324. package/dist/vega/{p-ed103a1a.entry.js → p-9d96d83f.entry.js} +1 -1
  325. package/dist/vega/{p-6dfe2407.js → p-9f11b579.js} +1 -1
  326. package/dist/vega/p-9f201152.entry.js +1 -0
  327. package/dist/vega/{p-48ee3e24.entry.js → p-a775825e.entry.js} +1 -1
  328. package/dist/vega/{p-9d18ba7f.entry.js → p-acaff62d.entry.js} +1 -1
  329. package/dist/vega/{p-b8f8e480.entry.js → p-ae146458.entry.js} +1 -1
  330. package/dist/vega/{p-e8ee70c5.entry.js → p-b3a2ce06.entry.js} +1 -1
  331. package/dist/vega/{p-5107277d.entry.js → p-b4c26035.entry.js} +1 -1
  332. package/dist/vega/p-b63319e9.entry.js +1 -0
  333. package/dist/vega/{p-c9daabe1.entry.js → p-b660f38c.entry.js} +1 -1
  334. package/dist/vega/{p-8c083255.entry.js → p-b8c13ac9.entry.js} +1 -1
  335. package/dist/vega/p-b8ffa42f.entry.js +1 -0
  336. package/dist/vega/{p-7b57a845.entry.js → p-b9e72de2.entry.js} +1 -1
  337. package/dist/vega/{p-0af32f31.entry.js → p-bb60e381.entry.js} +1 -1
  338. package/dist/vega/p-bbad318e.entry.js +1 -0
  339. package/dist/vega/p-c0e42c03.entry.js +1 -0
  340. package/dist/vega/{p-c67b9aba.entry.js → p-c41f5684.entry.js} +1 -1
  341. package/dist/vega/{p-4fe40b76.js → p-c4564904.js} +1 -1
  342. package/dist/vega/{p-341a6b32.entry.js → p-c54b5a8f.entry.js} +1 -1
  343. package/dist/vega/p-cd1e976c.entry.js +1 -0
  344. package/dist/vega/p-d9158512.js +1 -0
  345. package/dist/vega/{p-2dc5edd0.entry.js → p-db11134b.entry.js} +1 -1
  346. package/dist/vega/{p-14559974.entry.js → p-e1737c8e.entry.js} +1 -1
  347. package/dist/vega/{p-0b311599.entry.js → p-e1b57e8f.entry.js} +1 -1
  348. package/dist/vega/{p-9f38448c.entry.js → p-e5ff77f7.entry.js} +1 -1
  349. package/dist/vega/p-e62d41ee.js +1 -0
  350. package/dist/vega/{p-6f01a71a.entry.js → p-ebe32b25.entry.js} +1 -1
  351. package/dist/vega/p-ec162599.entry.js +1 -0
  352. package/dist/vega/{p-9f7154d2.js → p-ec5dee32.js} +1 -1
  353. package/dist/vega/{p-d3a36d19.entry.js → p-ec64cc59.entry.js} +1 -1
  354. package/dist/vega/p-f29d9707.entry.js +1 -0
  355. package/dist/vega/{p-5df2d6a1.entry.js → p-f78944d7.entry.js} +1 -1
  356. package/dist/vega/{p-c9c6daa6.entry.js → p-f9bfee81.entry.js} +1 -1
  357. package/dist/vega/{p-26c7fe8b.entry.js → p-fa65956c.entry.js} +1 -1
  358. package/dist/vega/{p-f96d0503.entry.js → p-fc7e4c8a.entry.js} +1 -1
  359. package/dist/vega/{p-b39d4a88.entry.js → p-fd23c365.entry.js} +1 -1
  360. package/dist/vega/vega.esm.js +1 -1
  361. package/package.json +3 -2
  362. package/dist/collection/components/vega-modal/slimmers/controllers/vega-modal-backdrop-controller.js +0 -73
  363. package/dist/types/components/vega-modal/slimmers/controllers/vega-modal-backdrop-controller.d.ts +0 -27
  364. package/dist/vega/p-0b9c7c79.entry.js +0 -1
  365. package/dist/vega/p-0be4df0a.js +0 -1
  366. package/dist/vega/p-2364be92.entry.js +0 -1
  367. package/dist/vega/p-270697c0.entry.js +0 -1
  368. package/dist/vega/p-282b37cb.js +0 -1
  369. package/dist/vega/p-38c9d782.js +0 -1
  370. package/dist/vega/p-52c6a399.entry.js +0 -1
  371. package/dist/vega/p-73f2c3c0.entry.js +0 -1
  372. package/dist/vega/p-762ea523.entry.js +0 -1
  373. package/dist/vega/p-7a88a3d3.entry.js +0 -1
  374. package/dist/vega/p-83a16285.entry.js +0 -1
  375. package/dist/vega/p-91287214.entry.js +0 -1
  376. package/dist/vega/p-c66d2a1e.js +0 -1
  377. package/dist/vega/p-cad5222a.entry.js +0 -1
  378. package/dist/vega/p-d25ca0c3.entry.js +0 -1
  379. package/dist/vega/p-f05a193e.entry.js +0 -1
  380. package/dist/vega/p-f4da615a.js +0 -3
  381. package/dist/vega/p-f906a7bc.entry.js +0 -1
@@ -1,9 +1,10 @@
1
1
  import { h, r as registerInstance, H as Host, g as getElement } from './index-090d31ca.js';
2
2
  import { s as sanitizeVegaComponent } from './component-7d906393.js';
3
- import { c as MapToComponentField, V as VegaSlimmer, I as InjectVegaSlimmer } from './global-slimmer-registry-17c4efd4.js';
3
+ import { c as MapToComponentField, V as VegaSlimmer, M as MapToComponentMethod, I as InjectVegaSlimmer } from './global-slimmer-registry-17c4efd4.js';
4
4
  import { V as VegaComponentUsageRuntimeMetricsSlimmer, I as InjectVegaGlobalSlimmer } from './component-usage-runtime-metrics-4b1afd04.js';
5
+ import { t as tryGetDocument } from './try-get-document-bef0f526.js';
5
6
 
6
- var __decorate$1 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
7
+ var __decorate$2 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
7
8
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
8
9
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
9
10
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
@@ -11,13 +12,13 @@ var __decorate$1 = (undefined && undefined.__decorate) || function (decorators,
11
12
  };
12
13
  class VegaSectionTitleRenderer extends VegaSlimmer {
13
14
  render() {
14
- return (h("vega-flex", { "aria-hidden": "true", "align-items": "start", "justify-content": "start", gap: "size-8", class: this.size === 'small' ? 'section-title-small' : undefined },
15
+ return (h("vega-flex", { "data-a11y-id": "st-root", "align-items": "start", "justify-content": "start", gap: "size-8", class: this.size === 'small' ? 'section-title-small' : undefined },
15
16
  this.renderPrefixIcon(),
16
17
  this.renderText()));
17
18
  }
18
19
  renderPrefixIcon() {
19
20
  return (this.icon &&
20
- this.iconAlign === 'left' && h("div", { class: "section-title-icon-container" }, this.renderIcon()));
21
+ this.iconAlign === 'left' && (h("div", { "data-a11y-id": "st-icon", class: "section-title-icon-container" }, this.renderIcon())));
21
22
  }
22
23
  renderText() {
23
24
  return (h("vega-flex", { class: "vega-flex-grow", direction: "col", "align-items": "start", "justify-content": "start", gap: "size-4" },
@@ -26,7 +27,7 @@ class VegaSectionTitleRenderer extends VegaSlimmer {
26
27
  }
27
28
  renderTitle() {
28
29
  return (h("div", { class: "section-title-text vega-flex-grow" },
29
- h("span", null, this.titleText),
30
+ h("span", { "data-a11y-id": "st-heading" }, this.titleText),
30
31
  this.renderSuffixIcon()));
31
32
  }
32
33
  renderDescription() {
@@ -34,34 +35,901 @@ class VegaSectionTitleRenderer extends VegaSlimmer {
34
35
  }
35
36
  renderSuffixIcon() {
36
37
  return (this.icon &&
37
- this.iconAlign === 'right' && h("div", { class: "right-icon-container" }, this.renderIcon()));
38
+ this.iconAlign === 'right' && (h("div", { "data-a11y-id": "st-icon", class: "right-icon-container" }, this.renderIcon())));
38
39
  }
39
40
  renderIcon() {
40
41
  return (h("vega-icon", { icon: this.icon, color: this.iconColor, size: this.size === 'small' ? 'size-16' : 'size-20', class: "vega-flex-shrink-0" }));
41
42
  }
42
43
  }
43
- __decorate$1([
44
+ __decorate$2([
44
45
  MapToComponentField()
45
46
  ], VegaSectionTitleRenderer.prototype, "host", void 0);
46
- __decorate$1([
47
+ __decorate$2([
47
48
  MapToComponentField()
48
49
  ], VegaSectionTitleRenderer.prototype, "titleText", void 0);
49
- __decorate$1([
50
+ __decorate$2([
50
51
  MapToComponentField()
51
52
  ], VegaSectionTitleRenderer.prototype, "description", void 0);
52
- __decorate$1([
53
+ __decorate$2([
53
54
  MapToComponentField()
54
55
  ], VegaSectionTitleRenderer.prototype, "icon", void 0);
55
- __decorate$1([
56
+ __decorate$2([
56
57
  MapToComponentField()
57
58
  ], VegaSectionTitleRenderer.prototype, "iconAlign", void 0);
58
- __decorate$1([
59
+ __decorate$2([
59
60
  MapToComponentField()
60
61
  ], VegaSectionTitleRenderer.prototype, "iconColor", void 0);
61
- __decorate$1([
62
+ __decorate$2([
62
63
  MapToComponentField()
63
64
  ], VegaSectionTitleRenderer.prototype, "size", void 0);
64
65
 
66
+ /**
67
+ * Baseline strategy: spec-compliant ARIA, works on evergreen Chromium,
68
+ * Firefox, and Safari with their default AT pairings (NVDA, Orca,
69
+ * VoiceOver-macOS). Used as the default when no engine-specific override
70
+ * matches.
71
+ *
72
+ * ## Mapping rules
73
+ *
74
+ * | Node role | ARIA output |
75
+ * |---------------|----------------------------------------------------|
76
+ * | heading | `role="heading"` + `aria-level` |
77
+ * | group/region | `role` + `aria-label` (if present) + `aria-describedby` (if description) |
78
+ * | img (decorative) | `aria-hidden="true"` |
79
+ * | img (labelled) | `role="img"` + `aria-label` |
80
+ * | presentation/none | `role="presentation"` |
81
+ */
82
+ const baselineStrategy = {
83
+ name: 'baseline',
84
+ /**
85
+ * Compile the semantic tree into spec-compliant ARIA patches.
86
+ *
87
+ * @param {A11yNode} root - Root of the semantic A11y Tree to compile.
88
+ * @returns {AriaPatch[]} Flat list of ARIA attribute patches to apply.
89
+ */
90
+ compile(root) {
91
+ const patches = [];
92
+ walk(root, patches);
93
+ return patches;
94
+ },
95
+ };
96
+ /**
97
+ * Recursively translate a node and its children into ARIA patches.
98
+ *
99
+ * @param {A11yNode} node - Current node being translated.
100
+ * @param {AriaPatch[]} patches - Accumulator the produced patches are pushed onto.
101
+ */
102
+ function walk(node, patches) {
103
+ var _a, _b;
104
+ switch (node.role) {
105
+ case 'heading':
106
+ patches.push({ targetId: node.id, attribute: 'role', value: 'heading' });
107
+ patches.push({
108
+ targetId: node.id,
109
+ attribute: 'aria-level',
110
+ value: String((_a = node.level) !== null && _a !== void 0 ? _a : 2),
111
+ });
112
+ break;
113
+ case 'group':
114
+ case 'region':
115
+ patches.push({ targetId: node.id, attribute: 'role', value: node.role });
116
+ if (node.label) {
117
+ patches.push({ targetId: node.id, attribute: 'aria-label', value: node.label });
118
+ }
119
+ if (node.description) {
120
+ // Baseline AT: describedby works reliably on group/region.
121
+ patches.push({
122
+ targetId: node.id,
123
+ attribute: 'aria-describedby',
124
+ value: `${node.id}__desc`,
125
+ });
126
+ }
127
+ break;
128
+ case 'img':
129
+ if (node.decorative) {
130
+ patches.push({ targetId: node.id, attribute: 'aria-hidden', value: 'true' });
131
+ }
132
+ else if (node.label) {
133
+ patches.push({ targetId: node.id, attribute: 'role', value: 'img' });
134
+ patches.push({ targetId: node.id, attribute: 'aria-label', value: node.label });
135
+ }
136
+ break;
137
+ case 'presentation':
138
+ case 'none':
139
+ patches.push({ targetId: node.id, attribute: 'role', value: 'presentation' });
140
+ break;
141
+ }
142
+ (_b = node.children) === null || _b === void 0 ? void 0 : _b.forEach((c) => walk(c, patches));
143
+ }
144
+
145
+ /**
146
+ * Firefox + NVDA strategy.
147
+ *
148
+ * Firefox/NVDA generally handles spec-compliant ARIA correctly. The one
149
+ * known quirk for the Vega component family:
150
+ *
151
+ * **NVDA browse-mode may skip `aria-describedby` on `role="group"`.**
152
+ * When a group container carries a description, NVDA in browse (reading)
153
+ * mode sometimes does not announce it. Workaround: promote the container to
154
+ * `role="region"`, which is part of the landmark navigation set and is
155
+ * reliably announced by NVDA when encountered during linear reading.
156
+ *
157
+ * All other node types fall back to baseline behaviour.
158
+ */
159
+ const firefoxNvdaStrategy = {
160
+ name: 'firefox-nvda',
161
+ /**
162
+ * Compile ARIA patches, applying the NVDA group-description workaround.
163
+ *
164
+ * @param {A11yNode} root - Root of the semantic A11y Tree to compile.
165
+ * @returns {AriaPatch[]} ARIA patches with group promoted to region when needed.
166
+ */
167
+ compile(root) {
168
+ const patches = baselineStrategy.compile(root);
169
+ // Promote all described groups to region (not just the first one).
170
+ for (const group of collectDescribedGroups(root)) {
171
+ for (const p of patches) {
172
+ if (p.targetId === group.id && p.attribute === 'role' && p.value === 'group') {
173
+ p.value = 'region';
174
+ }
175
+ }
176
+ }
177
+ return patches;
178
+ },
179
+ };
180
+ /**
181
+ * Collect every `group` node in the tree that carries a description,
182
+ * in depth-first order. Includes nested described groups.
183
+ *
184
+ * @param {A11yNode} node - Node to search from.
185
+ * @returns {A11yNode[]} All described group nodes, including nested ones.
186
+ */
187
+ function collectDescribedGroups(node) {
188
+ var _a;
189
+ const out = [];
190
+ // Check if this node is a described group
191
+ if (node.role === 'group' && node.description) {
192
+ out.push(node);
193
+ }
194
+ // Always recurse into children to find nested described groups
195
+ for (const c of (_a = node.children) !== null && _a !== void 0 ? _a : []) {
196
+ out.push(...collectDescribedGroups(c));
197
+ }
198
+ return out;
199
+ }
200
+
201
+ /**
202
+ * WebKit + VoiceOver strategy.
203
+ *
204
+ * Applies on top of the baseline to work around two known VoiceOver quirks:
205
+ *
206
+ * **Quirk #1 — `aria-describedby` on non-focusable containers is skipped.**
207
+ * VoiceOver on Safari often does not read `aria-describedby` on non-focusable
208
+ * `role="group"` (A11yContainerNode) or `role="region"` (A11yLandmarkNode)
209
+ * containers. Workaround: fold the description text directly into the
210
+ * heading's `aria-label` (joined with `. `) so it is read together with the
211
+ * title, and remove the orphaned `aria-describedby` patch.
212
+ *
213
+ * **Quirk #2 — Decorative `<vega-icon>` announced twice.**
214
+ * Safari occasionally announces a decorative icon twice when only
215
+ * `aria-hidden` is set on the host. We additionally set `role="none"` as a
216
+ * belt-and-suspenders guard that suppresses the extra announcement.
217
+ *
218
+ * These adjustments are applied as a *diff* on top of the baseline patch
219
+ * list — the A11y Tree itself is unchanged. Other node types fall back to
220
+ * baseline behaviour.
221
+ */
222
+ const webkitVoiceOverStrategy = {
223
+ name: 'webkit-voiceover',
224
+ /**
225
+ * Compile ARIA patches, applying the two VoiceOver workarounds.
226
+ *
227
+ * @param {A11yNode} root - Root of the semantic A11y Tree to compile.
228
+ * @returns {AriaPatch[]} ARIA patches adjusted for WebKit + VoiceOver.
229
+ */
230
+ compile(root) {
231
+ var _a;
232
+ const patches = baselineStrategy.compile(root);
233
+ // Quirk #1: fold each described container's description into its heading's
234
+ // aria-label. The non-focusable-container quirk affects both role="group"
235
+ // (A11yContainerNode) and role="region" (A11yLandmarkNode). Generalized to
236
+ // iterate every described container so components with multiple described
237
+ // groups/regions all get folded correctly instead of only the first pair.
238
+ for (const container of collectDescribedContainers(root)) {
239
+ // Use the first heading owned by this container (not crossing nested
240
+ // described-container boundaries), or fall back to the container itself.
241
+ const heading = (_a = findOwnedHeading(container)) !== null && _a !== void 0 ? _a : container;
242
+ const combined = [heading.label, container.description].filter(Boolean).join('. ');
243
+ // Emit an explicit removal patch (value: null) for the container's
244
+ // aria-describedby. VoiceOver double-announces the description when it
245
+ // is both folded into the heading label AND referenced via
246
+ // aria-describedby, so we untrack the attribute declaratively (rather
247
+ // than silently dropping the patch) to keep re-render cleanup correct.
248
+ //
249
+ // When folding onto the container itself (no owned heading found), also
250
+ // update the existing aria-label patch in-place so we do not produce a
251
+ // duplicate patch that would leave the old value visible to consumers
252
+ // using Array.find().
253
+ const foldingOntoContainer = heading.id === container.id;
254
+ for (const p of patches) {
255
+ if (p.targetId === container.id && p.attribute === 'aria-describedby') {
256
+ p.value = null;
257
+ }
258
+ if (foldingOntoContainer && p.targetId === container.id && p.attribute === 'aria-label') {
259
+ p.value = combined;
260
+ }
261
+ }
262
+ if (!foldingOntoContainer) {
263
+ patches.push({ targetId: heading.id, attribute: 'aria-label', value: combined });
264
+ }
265
+ }
266
+ // Quirk #2: harden decorative icons with role="none".
267
+ walkIcons(root, (n) => {
268
+ if (n.decorative) {
269
+ patches.push({ targetId: n.id, attribute: 'role', value: 'none' });
270
+ }
271
+ });
272
+ return patches;
273
+ },
274
+ };
275
+ /**
276
+ * Find the first heading node owned directly by a described container,
277
+ * stopping at nested described-container boundaries.
278
+ *
279
+ * A heading "owned" by a container is one that lives in that container's
280
+ * direct subtree but NOT inside a nested described group/region. Those inner
281
+ * headings belong to the inner container's own fold pass, so crossing their
282
+ * boundary would cause the outer container's description to overwrite the
283
+ * inner heading's aria-label and then be lost when the inner pass runs.
284
+ *
285
+ * If no owned heading is found, the caller falls back to the container itself
286
+ * (the `?? container` in compile()), folding the description onto the
287
+ * container's own aria-label.
288
+ *
289
+ * @param {A11yNode} node - The container to search within.
290
+ * @returns {A11yNode | undefined} First heading owned by this container, if any.
291
+ */
292
+ function findOwnedHeading(node) {
293
+ var _a;
294
+ for (const c of (_a = node.children) !== null && _a !== void 0 ? _a : []) {
295
+ // Stop at nested described-container boundaries — their headings belong
296
+ // to those containers' own fold passes, not this one.
297
+ if ((c.role === 'group' || c.role === 'region') && c.description) {
298
+ continue;
299
+ }
300
+ if (c.role === 'heading')
301
+ return c;
302
+ const hit = findOwnedHeading(c);
303
+ if (hit)
304
+ return hit;
305
+ }
306
+ return undefined;
307
+ }
308
+ /**
309
+ * Visit every image node in the tree, invoking the callback on each.
310
+ *
311
+ * @param {A11yNode} node - Node to walk from.
312
+ * @param {(n: A11yNode) => void} fn - Callback invoked for each image node.
313
+ */
314
+ function walkIcons(node, fn) {
315
+ var _a;
316
+ if (node.role === 'img')
317
+ fn(node);
318
+ (_a = node.children) === null || _a === void 0 ? void 0 : _a.forEach((c) => walkIcons(c, fn));
319
+ }
320
+ /**
321
+ * Collect every `group` or `region` node in the tree that carries a
322
+ * description, in depth-first order. Includes nested described containers.
323
+ *
324
+ * @param {A11yNode} node - Node to search from.
325
+ * @returns {A11yNode[]} All described container nodes, including nested ones.
326
+ */
327
+ function collectDescribedContainers(node) {
328
+ var _a;
329
+ const out = [];
330
+ // Check if this node is a described container
331
+ if ((node.role === 'group' || node.role === 'region') && node.description) {
332
+ out.push(node);
333
+ }
334
+ // Always recurse into children to find nested described containers
335
+ for (const c of (_a = node.children) !== null && _a !== void 0 ? _a : []) {
336
+ out.push(...collectDescribedContainers(c));
337
+ }
338
+ return out;
339
+ }
340
+
341
+ /**
342
+ * All registered strategies. The resolver picks from this list; callers that
343
+ * need exhaustive enumeration (e.g. tests, Storybook knobs) can import this
344
+ * constant directly.
345
+ */
346
+ const ALL_A11Y_STRATEGIES = [
347
+ baselineStrategy,
348
+ webkitVoiceOverStrategy,
349
+ firefoxNvdaStrategy,
350
+ ];
351
+ /**
352
+ * Picks an `A11yTreeStrategy` from the runtime environment and returns the
353
+ * full `A11yStrategyResolution` including confidence and a reason string.
354
+ *
355
+ * ## Browser-engine detection
356
+ *
357
+ * AT cannot be detected from JS (user privacy). We branch on *browser engine*
358
+ * as a coarse proxy for the most likely AT pairing on each platform:
359
+ *
360
+ * | Engine | Assumed AT | Confidence |
361
+ * |-----------|------------------------------|-------------------------|
362
+ * | WebKit | VoiceOver (macOS/iOS) | medium on Apple, low elsewhere |
363
+ * | Gecko | NVDA (Win), Orca (Linux) | medium on Win32, low elsewhere |
364
+ * | Chromium | JAWS / NVDA / TalkBack | high on non-Apple, medium on Apple |
365
+ *
366
+ * An explicit `data-a11y-strategy` attribute on the host element is always
367
+ * treated as `high` confidence (known override). If the override value does
368
+ * not match any registered strategy name, the resolver falls back to baseline
369
+ * with `low` confidence and logs an actionable warning.
370
+ *
371
+ * @param {HTMLElement} [host] - The component host element. When provided, its
372
+ * `data-a11y-strategy` attribute is checked first.
373
+ * @returns {A11yStrategyResolution} The resolved strategy with confidence and reason.
374
+ */
375
+ function resolveStrategyDetailed(host) {
376
+ var _a, _b;
377
+ // Explicit override takes precedence over UA detection.
378
+ const override = (_a = host === null || host === void 0 ? void 0 : host.getAttribute('data-a11y-strategy')) !== null && _a !== void 0 ? _a : null;
379
+ if (override) {
380
+ const found = ALL_A11Y_STRATEGIES.find((s) => s.name === override);
381
+ if (found) {
382
+ return {
383
+ strategy: found,
384
+ confidence: 'high',
385
+ reason: `explicit override via data-a11y-strategy="${override}"`,
386
+ };
387
+ }
388
+ // Unknown override name — warn and fall back to baseline.
389
+ return {
390
+ strategy: baselineStrategy,
391
+ confidence: 'low',
392
+ reason: `unknown data-a11y-strategy="${override}"; known strategies: ${ALL_A11Y_STRATEGIES.map((s) => s.name).join(', ')}. Falling back to baseline.`,
393
+ };
394
+ }
395
+ // Read the runtime navigator explicitly from `globalThis` (not the bare
396
+ // `navigator` identifier, which build tooling may substitute). Delegate the
397
+ // pure UA→strategy mapping to `resolveStrategyFromEnv` so it can be unit
398
+ // tested deterministically without mocking globals.
399
+ const nav = globalThis.navigator;
400
+ return resolveStrategyFromEnv(nav === null || nav === void 0 ? void 0 : nav.userAgent, (_b = nav === null || nav === void 0 ? void 0 : nav.platform) !== null && _b !== void 0 ? _b : '');
401
+ }
402
+ /**
403
+ * Pure UA→strategy mapping. Separated from `resolveStrategyDetailed` so the
404
+ * browser-engine detection table can be unit tested deterministically by
405
+ * passing explicit `userAgent` / `platform` values instead of mocking the
406
+ * global `navigator` (which build/test tooling may sandbox).
407
+ *
408
+ * @param {string | undefined} userAgent - The `navigator.userAgent` string, or
409
+ * `undefined` for an SSR / non-browser environment.
410
+ * @param {string} platform - The `navigator.platform` string (empty string when
411
+ * unavailable).
412
+ * @returns {A11yStrategyResolution} The resolved strategy with confidence and reason.
413
+ */
414
+ function resolveStrategyFromEnv(userAgent, platform) {
415
+ // SSR / non-browser environment: no UA available.
416
+ if (userAgent === undefined) {
417
+ return {
418
+ strategy: baselineStrategy,
419
+ confidence: 'medium',
420
+ reason: 'no navigator (SSR or non-browser environment); baseline assumed',
421
+ };
422
+ }
423
+ const ua = userAgent;
424
+ // Order matters: Safari UA contains "Safari" but Chrome UA also does.
425
+ if (/\bFirefox\//.test(ua)) {
426
+ // Firefox + NVDA is the canonical pairing on Windows; on other
427
+ // platforms (macOS VoiceOver, Linux Orca, Windows JAWS) this is a
428
+ // probabilistic guess.
429
+ const isWindows = /Win/i.test(platform);
430
+ return {
431
+ strategy: firefoxNvdaStrategy,
432
+ confidence: isWindows ? 'medium' : 'low',
433
+ reason: isWindows
434
+ ? 'Firefox on Windows — assumed NVDA (most common pairing on Win32)'
435
+ : 'Firefox on non-Windows platform — AT pairing is a guess (may be Orca, VoiceOver, or JAWS)',
436
+ };
437
+ }
438
+ if (/^((?!chrome|android).)*safari/i.test(ua)) {
439
+ const isApple = /Mac|iPhone|iPad|iPod/i.test(platform);
440
+ return {
441
+ strategy: webkitVoiceOverStrategy,
442
+ confidence: isApple ? 'medium' : 'low',
443
+ reason: isApple
444
+ ? 'WebKit on Apple platform — assumed VoiceOver'
445
+ : 'WebKit on non-Apple platform — AT pairing is a guess',
446
+ };
447
+ }
448
+ // Chromium (Edge/Chrome). On macOS, Chromium routes through VoiceOver's
449
+ // accessibility tree; baseline covers most users but VoiceOver quirks may
450
+ // surface. Surfaced as medium confidence so the override path stays
451
+ // discoverable.
452
+ const onApple = /Mac|iPhone|iPad|iPod/i.test(platform);
453
+ return {
454
+ strategy: baselineStrategy,
455
+ confidence: onApple ? 'medium' : 'high',
456
+ reason: onApple
457
+ ? 'Chromium on Apple platform — VoiceOver may diverge from Chromium baseline'
458
+ : 'Chromium on non-Apple platform — baseline is the expected AT mapping',
459
+ };
460
+ }
461
+ /**
462
+ * Convenience wrapper for callers that only need the resolved strategy.
463
+ * Equivalent to `resolveStrategyDetailed(host).strategy` but additionally
464
+ * emits a **dev-mode console warning** for `low`-confidence resolutions,
465
+ * pointing engineers at the `data-a11y-strategy` override mechanism.
466
+ *
467
+ * The warning is rate-limited per `(strategyName, reason)` tuple to avoid
468
+ * log spam on every render cycle.
469
+ *
470
+ * @param {HTMLElement} [host] - The component host element (optional). Used for
471
+ * the `data-a11y-strategy` override check.
472
+ * @returns {A11yTreeStrategy} The resolved strategy.
473
+ */
474
+ function resolveStrategy(host) {
475
+ const resolution = resolveStrategyDetailed(host);
476
+ if (resolution.confidence === 'low') {
477
+ warnOnce(resolution.strategy.name, resolution.reason);
478
+ }
479
+ return resolution.strategy;
480
+ }
481
+ const warnedKeys = new Set();
482
+ /**
483
+ * Emit a console.warn once per (strategy, reason) tuple. Suppressed in
484
+ * production builds and when `console` is unavailable (SSR).
485
+ *
486
+ * @param {string} strategyName - Name of the resolved strategy.
487
+ * @param {string} reason - Human-readable reason for the resolution.
488
+ * @internal
489
+ */
490
+ function warnOnce(strategyName, reason) {
491
+ var _a, _b;
492
+ if (typeof console === 'undefined')
493
+ return;
494
+ // Only warn in dev mode. Production builds set NODE_ENV=production;
495
+ // the guard below also handles minified bundles where `process` may
496
+ // be undefined.
497
+ const env = (_b = (_a = globalThis.process) === null || _a === void 0 ? void 0 : _a.env) === null || _b === void 0 ? void 0 : _b.NODE_ENV;
498
+ if (env === 'production')
499
+ return;
500
+ const key = `${strategyName}::${reason}`;
501
+ if (warnedKeys.has(key))
502
+ return;
503
+ warnedKeys.add(key);
504
+ console.warn(`[vega a11y-tree] Low-confidence strategy resolution: using "${strategyName}". ` +
505
+ `Reason: ${reason}. ` +
506
+ `Pin via data-a11y-strategy="<strategy-name>" to silence this warning ` +
507
+ `when you know the correct AT pairing. ` +
508
+ `Known strategies: ${ALL_A11Y_STRATEGIES.map((s) => s.name).join(', ')}.`);
509
+ }
510
+
511
+ /**
512
+ * Applies an A11y Tree to a shadow root by:
513
+ *
514
+ * 1. Resolving the `A11yTreeStrategy` that best matches the current
515
+ * browser engine / AT environment.
516
+ * 2. Compiling the semantic tree into a flat list of `AriaPatch`
517
+ * instructions.
518
+ * 3. Clearing any previously managed ARIA attributes (`data-a11y-managed`).
519
+ * 4. Applying each patch to the `data-a11y-id` target node in the shadow.
520
+ * 5. Materialising one visually-hidden description `<span>` per patch that
521
+ * references `aria-describedby` and whose node carries description text.
522
+ * 6. Stamping `data-a11y-strategy-applied` on the host for observability.
523
+ *
524
+ * This is the generic, component-agnostic projection step. Components
525
+ * interact with it indirectly through `A11yTreeSlimmer`.
526
+ *
527
+ * @param {A11yNode} root - The root `A11yNode` of the semantic tree.
528
+ * @param {HTMLElement} host - The component's host element. Must have a `shadowRoot`.
529
+ * If `shadowRoot` is null (e.g. light-DOM component or early call before first
530
+ * render), the function returns immediately without throwing.
531
+ * @example
532
+ * ```ts
533
+ * // Called once per render from A11yTreeSlimmer.projectA11yTree():
534
+ * applyA11yTree(buildSectionTitleA11yTree({ titleText, description }), this.host);
535
+ * ```
536
+ */
537
+ function applyA11yTree(root, host) {
538
+ const shadow = host.shadowRoot;
539
+ if (!shadow)
540
+ return;
541
+ const strategy = resolveStrategy(host);
542
+ const patches = strategy.compile(root);
543
+ clearPreviousPatches(shadow);
544
+ for (const patch of patches) {
545
+ applyPatch(shadow, patch);
546
+ }
547
+ // Materialise a visually-hidden description node when any patch
548
+ // references aria-describedby. This node is what the AT reads via
549
+ // the describedby relationship.
550
+ maybeRenderDescriptionNode(root, shadow, patches);
551
+ host.setAttribute('data-a11y-strategy-applied', strategy.name);
552
+ }
553
+ /**
554
+ * Remove all ARIA attributes that were set by a previous `applyA11yTree`
555
+ * call. The `data-a11y-managed` attribute on each node acts as a manifest
556
+ * of which attributes were set so we can clean up exactly those — and only
557
+ * those — without disturbing hand-authored ARIA.
558
+ *
559
+ * @param {ShadowRoot} shadow - The shadow root to clean previously managed ARIA from.
560
+ */
561
+ function clearPreviousPatches(shadow) {
562
+ shadow.querySelectorAll('[data-a11y-managed]').forEach((el) => {
563
+ var _a;
564
+ /* istanbul ignore next -- the [data-a11y-managed] selector guarantees the attribute is present, so the `?? ''` fallback is unreachable defensive code */
565
+ const attrs = ((_a = el.getAttribute('data-a11y-managed')) !== null && _a !== void 0 ? _a : '').split(' ').filter(Boolean);
566
+ attrs.forEach((a) => el.removeAttribute(a));
567
+ el.removeAttribute('data-a11y-managed');
568
+ });
569
+ }
570
+ /**
571
+ * Apply a single `AriaPatch` to the matching `data-a11y-id` element.
572
+ * Records every attribute written in `data-a11y-managed` so
573
+ * `clearPreviousPatches` can undo it on the next render.
574
+ *
575
+ * When `patch.value === null` the attribute is removed instead of set.
576
+ *
577
+ * @param {ShadowRoot} shadow - The shadow root containing the target element.
578
+ * @param {AriaPatch} patch - The ARIA patch to apply.
579
+ */
580
+ function applyPatch(shadow, patch) {
581
+ var _a;
582
+ const target = shadow.querySelector(`[data-a11y-id="${patch.targetId}"]`);
583
+ if (!target)
584
+ return;
585
+ if (patch.value === null) {
586
+ target.removeAttribute(patch.attribute);
587
+ }
588
+ else {
589
+ target.setAttribute(patch.attribute, patch.value);
590
+ }
591
+ // Track which attributes we wrote so we can clean them up later.
592
+ const prev = (_a = target.getAttribute('data-a11y-managed')) !== null && _a !== void 0 ? _a : '';
593
+ if (!prev.split(' ').includes(patch.attribute)) {
594
+ target.setAttribute('data-a11y-managed', (prev + ' ' + patch.attribute).trim());
595
+ }
596
+ }
597
+ /**
598
+ * Materialise a visually-hidden `<span>` description node for every strategy
599
+ * patch that references `aria-describedby`. Each `<span>` carries the
600
+ * description text so assistive technology can read it via the describedby
601
+ * relationship.
602
+ *
603
+ * Spans are created once and reused on subsequent renders; their text content
604
+ * is updated in place. Spans whose `aria-describedby` reference is dropped on
605
+ * a later render are pruned by `pruneStaleDescriptionNodes`.
606
+ *
607
+ * Visually-hidden styles follow the `.sr-only` pattern (not `display:none`
608
+ * which would suppress AT reading).
609
+ *
610
+ * @param {A11yNode} root - The root of the semantic tree (source of description text).
611
+ * @param {ShadowRoot} shadow - The shadow root to append/update description nodes in.
612
+ * @param {AriaPatch[]} patches - The compiled patch list to scan for `aria-describedby`.
613
+ */
614
+ function maybeRenderDescriptionNode(root, shadow, patches) {
615
+ // Collect every aria-describedby patch that has a live string target id —
616
+ // one hidden span is required per described node.
617
+ const describedByPatches = patches.filter((p) => p.attribute === 'aria-describedby' && typeof p.value === 'string');
618
+ const keepIds = new Set(describedByPatches.map((p) => p.value));
619
+ // Remove any previously-materialised description spans that are no longer
620
+ // referenced by a live aria-describedby patch — e.g. the `description` prop
621
+ // was cleared, or the description moved to a different node. Without this,
622
+ // orphaned visually-hidden spans linger in the shadow DOM and are still
623
+ // announced by AT during linear (non-describedby) traversal.
624
+ pruneStaleDescriptionNodes(shadow, keepIds);
625
+ for (const patch of describedByPatches) {
626
+ const node = findById(root, patch.targetId);
627
+ /* istanbul ignore next -- describedby patches are only emitted for nodes that carry a description, so this guard is unreachable defensive code */
628
+ if (!(node === null || node === void 0 ? void 0 : node.description))
629
+ continue;
630
+ ensureDescriptionSpan(shadow, patch.value, node.description);
631
+ }
632
+ }
633
+ /**
634
+ * Create (or update in place) a visually-hidden `<span>` carrying description
635
+ * text for a single `aria-describedby` reference.
636
+ *
637
+ * @param {ShadowRoot} shadow - The shadow root to append/update the span in.
638
+ * @param {string} id - The span id, matching the `aria-describedby` value.
639
+ * @param {string} text - The description text to expose to AT.
640
+ */
641
+ function ensureDescriptionSpan(shadow, id, text) {
642
+ let descEl = shadow.getElementById(id);
643
+ if (!descEl) {
644
+ const doc = tryGetDocument();
645
+ /* istanbul ignore next -- document is always present in the browser render path */
646
+ if (!doc)
647
+ return;
648
+ descEl = doc.createElement('span');
649
+ descEl.id = id;
650
+ // Stamp the span so pruneStaleDescriptionNodes can find and clean it up
651
+ // on a later render when it is no longer referenced.
652
+ descEl.setAttribute('data-a11y-desc', '');
653
+ descEl.style.position = 'absolute';
654
+ descEl.style.width = '1px';
655
+ descEl.style.height = '1px';
656
+ descEl.style.overflow = 'hidden';
657
+ // `clip` is kept for legacy engines; `clip-path` + `white-space: nowrap`
658
+ // cover modern engines and prevent a 1px phantom scrollbar.
659
+ descEl.style.clip = 'rect(0 0 0 0)';
660
+ descEl.style.clipPath = 'inset(50%)';
661
+ descEl.style.whiteSpace = 'nowrap';
662
+ shadow.appendChild(descEl);
663
+ }
664
+ descEl.textContent = text;
665
+ }
666
+ /**
667
+ * Remove visually-hidden description `<span>`s (stamped `data-a11y-desc`)
668
+ * that are no longer referenced by a live `aria-describedby` patch.
669
+ *
670
+ * @param {ShadowRoot} shadow - The shadow root to prune stale description nodes from.
671
+ * @param {Set<string>} keepIds - Ids of spans still referenced this render; all
672
+ * other stamped spans are removed.
673
+ */
674
+ function pruneStaleDescriptionNodes(shadow, keepIds) {
675
+ shadow.querySelectorAll('[data-a11y-desc]').forEach((el) => {
676
+ if (!keepIds.has(el.id))
677
+ el.remove();
678
+ });
679
+ }
680
+ /**
681
+ * Depth-first search for a node by `id`.
682
+ *
683
+ * @param {A11yNode} node - Node to search from.
684
+ * @param {string} id - The `id` to find.
685
+ * @returns {A11yNode | undefined} The matching node, or `undefined` when not found.
686
+ */
687
+ function findById(node, id) {
688
+ var _a;
689
+ if (node.id === id)
690
+ return node;
691
+ for (const c of (_a = node.children) !== null && _a !== void 0 ? _a : []) {
692
+ const hit = findById(c, id);
693
+ if (hit)
694
+ return hit;
695
+ }
696
+ return undefined;
697
+ }
698
+
699
+ var __decorate$1 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
700
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
701
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
702
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
703
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
704
+ };
705
+ /**
706
+ * Generic A11y Tree slimmer.
707
+ *
708
+ * Hooks `componentDidRender` and projects the component's semantic A11y
709
+ * Tree onto its shadow DOM using the strategy resolved for the current
710
+ * browser engine.
711
+ *
712
+ * ## Opt-in steps for a component
713
+ *
714
+ * 1. Tag render targets with `data-a11y-id="<stable-id>"` in the renderer.
715
+ * 2. Author a `build<Component>A11yTree(host)` function (see
716
+ * `a11y-node-dto.ts` for the DTO helpers that make this ergonomic).
717
+ * 3. Inject this slimmer with `@InjectVegaSlimmer()`:
718
+ *
719
+ * ```ts
720
+ * @InjectVegaSlimmer()
721
+ * protected a11yTreeSlimmer = new A11yTreeSlimmer<HTMLVegaFooElement>(
722
+ * host => buildFooA11yTree({ title: host.title, description: host.description }),
723
+ * );
724
+ * ```
725
+ *
726
+ * The slimmer handles strategy selection, patch application, and cleanup
727
+ * on every subsequent render.
728
+ *
729
+ * @template T - The concrete `HTMLElement` subtype for the component host.
730
+ */
731
+ class A11yTreeSlimmer extends VegaSlimmer {
732
+ constructor(buildA11yTree) {
733
+ super();
734
+ this.buildA11yTree = buildA11yTree;
735
+ }
736
+ /**
737
+ * Called by Stencil after each render. Projects the semantic A11y Tree
738
+ * onto the shadow DOM via the resolved browser-engine strategy.
739
+ */
740
+ projectA11yTree() {
741
+ const tree = this.buildA11yTree(this.host);
742
+ applyA11yTree(tree, this.host);
743
+ }
744
+ }
745
+ __decorate$1([
746
+ MapToComponentField()
747
+ ], A11yTreeSlimmer.prototype, "host", void 0);
748
+ __decorate$1([
749
+ MapToComponentMethod('componentDidRender')
750
+ ], A11yTreeSlimmer.prototype, "projectA11yTree", null);
751
+
752
+ /**
753
+ * Semantic DTO layer for the A11y Tree.
754
+ *
755
+ * Authoring an A11y Tree with raw `A11yNode` literals asks the developer to
756
+ * think in ARIA terms (`role: 'group'`, `decorative: true`, etc.). The DTO
757
+ * classes here provide a higher-level vocabulary that names the *content's
758
+ * meaning* — "this is a container", "this is a heading", "this is a
759
+ * decorative icon" — and lets the strategy layer translate intent into ARIA.
760
+ *
761
+ * ## Design (Visitor / Strategy + typed semantic DTOs)
762
+ *
763
+ * - DTOs are *type-holders for semantic intent*. They do NOT contain ARIA
764
+ * generation logic themselves.
765
+ * - Each DTO compiles to an `A11yNode` whose `kind` field carries the
766
+ * semantic discriminator. Strategies can then dispatch on `kind`
767
+ * (preferred) or fall back to `role` (for plain `A11yNode` authors).
768
+ * - This keeps strategies pure and independently testable, while letting
769
+ * authors write:
770
+ *
771
+ * ```ts
772
+ * new A11yContainerNode('st-root', { label, description })
773
+ * .childrenWith(
774
+ * new A11yHeadingNode('st-heading', { level: 2, label }),
775
+ * new A11yIconNode('st-icon'),
776
+ * );
777
+ * ```
778
+ *
779
+ * instead of hand-shaping `{ role: 'group', label, description, … }`.
780
+ *
781
+ * ## Migration path
782
+ *
783
+ * Phase 1 (this file): DTOs are an additive layer on top of `A11yNode`.
784
+ * Existing strategies continue to work unchanged because each DTO emits
785
+ * a fully-populated `A11yNode` with `role` set correctly.
786
+ *
787
+ * Phase 2 (follow-up): strategies grow `compileNode(node)` methods that
788
+ * dispatch on `node.kind` for cases where semantic intent is richer than
789
+ * `role` alone can express.
790
+ */
791
+ /**
792
+ * Base class for all semantic DTO nodes. Provides the `childrenWith()`
793
+ * composition helper and the abstract `toA11yNode()` contract.
794
+ */
795
+ class A11yNodeDto {
796
+ constructor() {
797
+ this.childDtos = [];
798
+ }
799
+ /**
800
+ * Declare the semantic children of this node in reading order.
801
+ *
802
+ * @param {...A11yNodeDto} children - Semantic child DTOs in reading order.
803
+ * @returns {this} `this`, for fluent chaining.
804
+ */
805
+ childrenWith(...children) {
806
+ this.childDtos = children;
807
+ return this;
808
+ }
809
+ /**
810
+ * Compile the declared child DTOs into their `A11yNode` representations.
811
+ *
812
+ * @returns {A11yNode[] | undefined} The compiled children, or `undefined` when none.
813
+ */
814
+ compileChildren() {
815
+ if (this.childDtos.length === 0)
816
+ return undefined;
817
+ return this.childDtos.map((c) => c.toA11yNode());
818
+ }
819
+ }
820
+ /**
821
+ * A heading at the given level (1–6, defaults to 2).
822
+ *
823
+ * Use this instead of a raw `{ role: 'heading', level: 2 }` literal to
824
+ * benefit from the default-level guard and the `kind` discriminator.
825
+ */
826
+ class A11yHeadingNode extends A11yNodeDto {
827
+ constructor(id, opts = {}) {
828
+ super();
829
+ this.id = id;
830
+ this.opts = opts;
831
+ this.kind = 'heading';
832
+ }
833
+ /**
834
+ * Compile this DTO into its `A11yNode` representation.
835
+ *
836
+ * @returns {A11yNode} The compiled semantic node.
837
+ */
838
+ toA11yNode() {
839
+ var _a;
840
+ return {
841
+ id: this.id,
842
+ kind: this.kind,
843
+ role: 'heading',
844
+ level: (_a = this.opts.level) !== null && _a !== void 0 ? _a : 2,
845
+ label: this.opts.label,
846
+ children: this.compileChildren(),
847
+ };
848
+ }
849
+ }
850
+ /**
851
+ * A purely decorative icon. `decorative` is always `true` so authors never
852
+ * have to remember the flag — that is the whole point of this DTO class.
853
+ *
854
+ * Produces `aria-hidden="true"` via the baseline strategy; webkit-voiceover
855
+ * additionally sets `role="none"` as a belt-and-suspenders guard.
856
+ */
857
+ class A11yIconNode extends A11yNodeDto {
858
+ constructor(id) {
859
+ super();
860
+ this.id = id;
861
+ this.kind = 'icon';
862
+ }
863
+ /**
864
+ * Compile this DTO into its `A11yNode` representation.
865
+ *
866
+ * @returns {A11yNode} The compiled semantic node.
867
+ */
868
+ toA11yNode() {
869
+ return {
870
+ id: this.id,
871
+ kind: this.kind,
872
+ role: 'img',
873
+ decorative: true,
874
+ children: this.compileChildren(),
875
+ };
876
+ }
877
+ }
878
+
879
+ /**
880
+ * Build the semantic A11y Tree for a `vega-section-title` instance.
881
+ *
882
+ * The structure uses a presentation wrapper so the container is transparent to
883
+ * assistive technology — the heading is the semantic anchor:
884
+ *
885
+ * ```
886
+ * presentation "st-root" (role=none — AT-transparent wrapper)
887
+ * ├── heading "st-heading" (titleText, level=2 by default)
888
+ * └── icon "st-icon" (decorative — only when an icon prop is set)
889
+ * ```
890
+ *
891
+ * Description text is not wired into the A11y tree. It is exposed as plain
892
+ * visible text in the component's shadow DOM, read by screen readers via normal
893
+ * linear traversal. This avoids three VoiceOver regressions introduced when the
894
+ * container carried `role="group"` with `aria-label` + `aria-describedby`:
895
+ *
896
+ * - Bug 1 (Safari): webkit folded the description into the heading `aria-label`,
897
+ * so focusing the H2 announced both title AND description together.
898
+ * - Bug 2 (Chrome, no description): `role="group"` created an extra navigation
899
+ * boundary and announced the title twice (group label + heading).
900
+ * - Bug 3 (Chrome, with description): description read twice — once via the
901
+ * hidden `aria-describedby` span on the group, once via the visible div.
902
+ *
903
+ * **No inline ARIA / no double projection**: this function must NOT set
904
+ * `aria-*` or `role` attributes directly on the component. The A11y Tree
905
+ * slimmer (`A11yTreeSlimmer`) calls `applyA11yTree()` on every render to
906
+ * project the semantic intent through the chosen strategy.
907
+ *
908
+ * @param {BuildArgs} args - Section-title fields used to author the semantic tree.
909
+ * @returns {A11yNode} The semantic A11y Tree root for the section title.
910
+ */
911
+ function buildSectionTitleA11yTree(args) {
912
+ var _a;
913
+ const children = [];
914
+ // Only add heading if titleText is provided; avoid empty heading elements
915
+ // that cause cross-browser inconsistencies (Chrome skips them, Firefox may
916
+ // announce an empty group). The A11y Tree projection (via strategy) onto
917
+ // shadow DOM handles all ARIA semantics; no host-level ARIA is used.
918
+ if (args.titleText) {
919
+ children.push(new A11yHeadingNode('st-heading', {
920
+ level: (_a = args.headingLevel) !== null && _a !== void 0 ? _a : 2,
921
+ }).toA11yNode());
922
+ }
923
+ if (args.icon) {
924
+ children.push(new A11yIconNode('st-icon').toA11yNode());
925
+ }
926
+ return {
927
+ id: 'st-root',
928
+ role: 'none',
929
+ children,
930
+ };
931
+ }
932
+
65
933
  const vegaSectionTitleCss = ":host{display:block}.section-title-text{color:rgba(var(--v-text-primary, 32, 54, 69, 1));font-family:\"Inter\", sans-serif;font-size:20px;font-weight:700;line-height:28px;letter-spacing:0px}@media screen and (min-width: 768px) and (max-width: 1023px){.section-title-text{font-family:\"Inter\", sans-serif;font-size:20px;font-weight:700;line-height:28px;letter-spacing:0px}}@media screen and (min-width: 1024px) and (max-width: 1439px){.section-title-text{font-family:\"Inter\", sans-serif;font-size:20px;font-weight:700;line-height:28px;letter-spacing:0px}}@media screen and (min-width: 1440px) and (max-width: 9999px){.section-title-text{font-family:\"Inter\", sans-serif;font-size:20px;font-weight:700;line-height:28px;letter-spacing:0px}}.section-title-description{font-family:\"Inter\", sans-serif;font-size:18px;font-weight:500;line-height:28px;letter-spacing:0px;color:rgba(var(--v-text-secondary, 107, 116, 125, 1))}@media screen and (min-width: 768px) and (max-width: 1023px){.section-title-description{font-family:\"Inter\", sans-serif;font-size:16px;font-weight:500;line-height:22px;letter-spacing:0px}}@media screen and (min-width: 1024px) and (max-width: 1439px){.section-title-description{font-family:\"Inter\", sans-serif;font-size:16px;font-weight:500;line-height:22px;letter-spacing:0px}}@media screen and (min-width: 1440px) and (max-width: 9999px){.section-title-description{font-family:\"Inter\", sans-serif;font-size:16px;font-weight:500;line-height:22px;letter-spacing:0px}}.section-title-icon-container{margin-top:4px}.right-icon-container{display:inline-block;margin-left:8px;margin-top:4px;vertical-align:middle}.section-title-small .section-title-text{font-family:\"Inter\", sans-serif;font-size:18px;font-weight:700;line-height:25px;letter-spacing:0px}@media screen and (min-width: 768px) and (max-width: 1023px){.section-title-small .section-title-text{font-family:\"Inter\", sans-serif;font-size:18px;font-weight:700;line-height:25px;letter-spacing:0px}}@media screen and (min-width: 1024px) and (max-width: 1439px){.section-title-small .section-title-text{font-family:\"Inter\", sans-serif;font-size:18px;font-weight:700;line-height:25px;letter-spacing:0px}}@media screen and (min-width: 1440px) and (max-width: 9999px){.section-title-small .section-title-text{font-family:\"Inter\", sans-serif;font-size:18px;font-weight:700;line-height:25px;letter-spacing:0px}}";
66
934
 
67
935
  var __decorate = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
@@ -80,6 +948,18 @@ const VegaSectionTitle = class {
80
948
  this.globalSlimmers = {};
81
949
  this.renderer = new VegaSectionTitleRenderer();
82
950
  this.vegaComponentUsageRuntimeMetricsSlimmer = new VegaComponentUsageRuntimeMetricsSlimmer();
951
+ /**
952
+ * Projects the component's semantic accessibility intent onto the shadow
953
+ * DOM via the A11y Tree foundation. Replaces the previous inline `role` /
954
+ * `aria-label` on the host element so ARIA is authored once, in
955
+ * `buildSectionTitleA11yTree`, and projected through the browser-engine
956
+ * strategy layer (no double projection).
957
+ */
958
+ this.a11yTreeSlimmer = new A11yTreeSlimmer((host) => buildSectionTitleA11yTree({
959
+ titleText: host.titleText,
960
+ icon: host.icon,
961
+ iconAlign: host.iconAlign,
962
+ }));
83
963
  /**
84
964
  * Specifies the text content of the title displayed
85
965
  * within the section title.
@@ -108,8 +988,7 @@ const VegaSectionTitle = class {
108
988
  this.size = 'default';
109
989
  }
110
990
  render() {
111
- const ariaLabel = [this.titleText, this.description].filter(Boolean).join(', ');
112
- return sanitizeVegaComponent(h(Host, { role: ariaLabel ? 'group' : undefined, "aria-label": ariaLabel || undefined }, this.renderer.render()), this.host);
991
+ return sanitizeVegaComponent(h(Host, null, this.renderer.render()), this.host);
113
992
  }
114
993
  get host() { return getElement(this); }
115
994
  };
@@ -122,6 +1001,9 @@ __decorate([
122
1001
  __decorate([
123
1002
  InjectVegaSlimmer()
124
1003
  ], VegaSectionTitle.prototype, "vegaComponentUsageRuntimeMetricsSlimmer", void 0);
1004
+ __decorate([
1005
+ InjectVegaSlimmer()
1006
+ ], VegaSectionTitle.prototype, "a11yTreeSlimmer", void 0);
125
1007
  VegaSectionTitle.style = vegaSectionTitleCss;
126
1008
 
127
1009
  export { VegaSectionTitle as vega_section_title };