@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.
- package/dist/cjs/{app-globals-76815382.js → app-globals-38afea36.js} +7 -7
- package/dist/cjs/{code-block-493c7ce7.js → code-block-4126dc3b.js} +1501 -55
- package/dist/cjs/{component-value-history-controller-slimmer.abstract-ab21fcbf.js → component-value-history-controller-slimmer.abstract-38ba956e.js} +2 -2
- package/dist/cjs/{content-state-fc34a814.js → content-state-50e8a03c.js} +142 -580
- package/dist/cjs/{element-appender-slimmer-1d6323c2.js → element-appender-slimmer-7773fdab.js} +115 -0
- package/dist/cjs/{image-annotation-action-7c4cd316.js → image-annotation-action-89363de8.js} +2 -2
- package/dist/cjs/{image-extension-30a7c10f.js → image-extension-c881c454.js} +2 -2
- package/dist/cjs/index.cjs.js +10 -10
- package/dist/cjs/{link-extension-92a63cb7.js → link-extension-b7f99a52.js} +2 -2
- package/dist/cjs/loader.cjs.js +7 -7
- package/dist/cjs/{public-rules-9e1ea1d9.js → public-rules-72894208.js} +3 -3
- package/dist/cjs/{range-30219330.js → range-95d41dea.js} +1 -1
- package/dist/cjs/{rich-text-editor-required-rule-23bf7485.js → rich-text-editor-required-rule-4d6d2493.js} +1 -1
- package/dist/cjs/{split-cell-operation-43752212.js → split-cell-operation-70be116d.js} +2 -2
- package/dist/cjs/{token-extension-d123d9d0.js → token-extension-eb828948.js} +35 -11
- package/dist/cjs/vega-code-block.cjs.entry.js +3 -3
- package/dist/cjs/vega-date-picker_2.cjs.entry.js +1 -1
- package/dist/cjs/vega-dropdown_5.cjs.entry.js +27 -4
- package/dist/cjs/vega-env-manager-23b8b23c.js +2 -2
- package/dist/cjs/vega-popover_2.cjs.entry.js +1 -1
- package/dist/cjs/vega-rich-text-content.cjs.entry.js +58 -9
- package/dist/cjs/vega-rich-text-editor_4.cjs.entry.js +608 -90
- package/dist/cjs/vega-rich-text-table-properties_3.cjs.entry.js +3 -3
- package/dist/cjs/vega-section-title.cjs.entry.js +896 -14
- package/dist/cjs/vega-time-picker_2.cjs.entry.js +1 -1
- package/dist/cjs/vega-tooltip_2.cjs.entry.js +1 -1
- package/dist/cjs/vega.cjs.js +7 -7
- package/dist/collection/components/vega-combo-box/vega-combo-box.js +2 -2
- package/dist/collection/components/vega-dropdown/vega-dropdown.js +30 -7
- package/dist/collection/components/vega-input-select/vega-input-select.js +2 -2
- package/dist/collection/components/vega-rich-text-content/vega-rich-text-content.css +4 -0
- package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/block-delete-node-content-strategy.js +29 -0
- 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
- package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/block-transform-to-list-strategy.js +8 -3
- package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-annotation-strategy.abstract.js +60 -0
- package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-item-replace-nest-list-strategy.js +36 -4
- package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-items-strategy.abstract.js +27 -0
- package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-nest-items-strategy.js +74 -0
- package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-remove-list-item-strategy.js +81 -1
- package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-transform-selection.js +30 -0
- package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-transform-to-list-strategy.js +160 -9
- package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-transform-to-paragraph-strategy.js +376 -10
- package/dist/collection/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-unnest-items-strategy.js +104 -0
- package/dist/collection/components/vega-rich-text-editor/dto/actions/modify-content-action.abstract.js +2 -0
- package/dist/collection/components/vega-rich-text-editor/dto/actions/nest-list-items-action.js +12 -0
- package/dist/collection/components/vega-rich-text-editor/dto/actions/unnest-list-items-action.js +12 -0
- package/dist/collection/components/vega-rich-text-editor/dto/annotations/list-annotation.js +12 -0
- package/dist/collection/components/vega-rich-text-editor/dto/blocks/list-block.js +10 -1
- package/dist/collection/components/vega-rich-text-editor/dto/blocks/list-item-block.js +11 -3
- package/dist/collection/components/vega-rich-text-editor/dto/content-state.js +7 -1
- package/dist/collection/components/vega-rich-text-editor/dto/filter-styles-strategies/list-block/list-block-filter-styles-strategy.js +8 -4
- package/dist/collection/components/vega-rich-text-editor/dto/renderers/blocks/list-block-renderer.js +34 -1
- package/dist/collection/components/vega-rich-text-editor/dto/renderers/blocks/list-item-block-renderer.js +20 -3
- package/dist/collection/components/vega-rich-text-editor/extensions/table/annotation-handler/table-annotation-handler-base.js +25 -1
- 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
- package/dist/collection/components/vega-rich-text-editor/slimmers/controllers/helper/input-event-handler/abstract-delete-content-handler.js +29 -0
- package/dist/collection/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/bullets-numbers-toolbar-button-slimmer.js +30 -1
- package/dist/collection/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/helper/abstract-list-keyboard-handler.js +204 -0
- package/dist/collection/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/helper/list-shift-tab-outdent-handler.js +42 -0
- package/dist/collection/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/helper/list-tab-indent-handler.js +34 -0
- package/dist/collection/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/list-keyboard-slimmer.js +180 -0
- package/dist/collection/components/vega-section-title/slimmers/a11y-tree/build-section-title-a11y-tree.js +54 -0
- package/dist/collection/components/vega-section-title/slimmers/renderers/vega-section-title-renderer.js +4 -4
- package/dist/collection/components/vega-section-title/vega-section-title.js +18 -2
- package/dist/collection/helpers/a11y-tree/a11y-node-dto.js +210 -0
- package/dist/collection/helpers/a11y-tree/a11y-tree-applier.js +189 -0
- package/dist/collection/helpers/a11y-tree/a11y-tree.types.js +48 -0
- package/dist/collection/helpers/a11y-tree/strategies/baseline-strategy.js +78 -0
- package/dist/collection/helpers/a11y-tree/strategies/firefox-nvda-strategy.js +56 -0
- package/dist/collection/helpers/a11y-tree/strategies/webkit-voiceover-strategy.js +140 -0
- package/dist/collection/helpers/a11y-tree/strategy-resolver.js +172 -0
- package/dist/collection/helpers/slimmers/a11y-tree-slimmer.js +54 -0
- package/dist/collection/helpers/slimmers/element-appender/element-appender-slimmer.js +29 -0
- package/dist/collection/helpers/slimmers/element-appender/visibility-modifiers/clip-on-scroll-modifier.js +70 -0
- package/dist/collection/helpers/slimmers/element-appender/visibility-modifiers/visibility-modifier.interface.js +1 -0
- package/dist/collection/helpers/ui/element-appender.js +16 -0
- package/dist/esm/{app-globals-eafcc7a1.js → app-globals-d7b651c1.js} +7 -7
- package/dist/esm/{code-block-e12588fe.js → code-block-0a88b481.js} +1495 -51
- package/dist/esm/{component-value-history-controller-slimmer.abstract-4e8eb313.js → component-value-history-controller-slimmer.abstract-6846edfa.js} +2 -2
- package/dist/esm/{content-state-8032467a.js → content-state-79ca99e5.js} +105 -541
- package/dist/esm/{element-appender-slimmer-7fcb944b.js → element-appender-slimmer-73ad10ae.js} +115 -0
- package/dist/esm/{image-annotation-action-08a20d5e.js → image-annotation-action-bb299ef1.js} +2 -2
- package/dist/esm/{image-extension-b6c7e4a7.js → image-extension-48a96f98.js} +2 -2
- package/dist/esm/index.js +8 -8
- package/dist/esm/{link-extension-97fcb8fb.js → link-extension-09534514.js} +2 -2
- package/dist/esm/loader.js +7 -7
- package/dist/esm/{public-rules-c06f0d2a.js → public-rules-5eb03ef0.js} +3 -3
- package/dist/esm/{range-e999837f.js → range-d4deb7df.js} +1 -1
- package/dist/esm/{rich-text-editor-required-rule-71f8ee98.js → rich-text-editor-required-rule-5bbbce23.js} +1 -1
- package/dist/esm/{split-cell-operation-359f8082.js → split-cell-operation-7f3058ad.js} +2 -2
- package/dist/esm/{token-extension-f5bf9c21.js → token-extension-40c32bcc.js} +30 -6
- package/dist/esm/vega-code-block.entry.js +3 -3
- package/dist/esm/vega-date-picker_2.entry.js +1 -1
- package/dist/esm/vega-dropdown_5.entry.js +27 -4
- package/dist/esm/vega-env-manager-8f8dc473.js +2 -2
- package/dist/esm/vega-popover_2.entry.js +1 -1
- package/dist/esm/vega-rich-text-content.entry.js +58 -9
- package/dist/esm/vega-rich-text-editor_4.entry.js +604 -86
- package/dist/esm/vega-rich-text-table-properties_3.entry.js +3 -3
- package/dist/esm/vega-section-title.entry.js +897 -15
- package/dist/esm/vega-time-picker_2.entry.js +1 -1
- package/dist/esm/vega-tooltip_2.entry.js +1 -1
- package/dist/esm/vega.js +7 -7
- package/dist/sri/vega-sri-manifest.json +94 -94
- package/dist/types/components/vega-combo-box/vega-combo-box.d.ts +6 -6
- package/dist/types/components/vega-dropdown/types.d.ts +2 -2
- package/dist/types/components/vega-dropdown/vega-dropdown.d.ts +32 -9
- package/dist/types/components/vega-input-select/vega-input-select.d.ts +6 -6
- package/dist/types/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-annotation-strategy.abstract.d.ts +36 -0
- 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
- package/dist/types/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-items-strategy.abstract.d.ts +22 -0
- package/dist/types/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-nest-items-strategy.d.ts +21 -0
- package/dist/types/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-remove-list-item-strategy.d.ts +14 -0
- package/dist/types/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-transform-selection.d.ts +15 -0
- package/dist/types/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-transform-to-list-strategy.d.ts +30 -3
- package/dist/types/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-transform-to-paragraph-strategy.d.ts +99 -3
- package/dist/types/components/vega-rich-text-editor/dto/action-handle-strategies/modify-content-strategies/list-unnest-items-strategy.d.ts +22 -0
- package/dist/types/components/vega-rich-text-editor/dto/actions/modify-content-action.abstract.d.ts +2 -0
- package/dist/types/components/vega-rich-text-editor/dto/actions/nest-list-items-action.d.ts +11 -0
- package/dist/types/components/vega-rich-text-editor/dto/actions/unnest-list-items-action.d.ts +11 -0
- package/dist/types/components/vega-rich-text-editor/dto/annotations/list-annotation.d.ts +8 -0
- package/dist/types/components/vega-rich-text-editor/dto/blocks/list-block.d.ts +6 -1
- package/dist/types/components/vega-rich-text-editor/dto/blocks/list-item-block.d.ts +5 -1
- package/dist/types/components/vega-rich-text-editor/dto/content-state.d.ts +2 -2
- package/dist/types/components/vega-rich-text-editor/dto/renderers/blocks/list-block-renderer.d.ts +2 -0
- package/dist/types/components/vega-rich-text-editor/dto/renderers/blocks/list-item-block-renderer.d.ts +8 -0
- package/dist/types/components/vega-rich-text-editor/extensions/table/annotation-handler/table-annotation-handler-base.d.ts +18 -0
- package/dist/types/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/bullets-numbers-toolbar-button-slimmer.d.ts +8 -0
- package/dist/types/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/helper/abstract-list-keyboard-handler.d.ts +99 -0
- package/dist/types/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/helper/list-shift-tab-outdent-handler.d.ts +15 -0
- package/dist/types/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/helper/list-tab-indent-handler.d.ts +15 -0
- package/dist/types/components/vega-rich-text-editor/slimmers/renderers/tools/bullets-numbers/list-keyboard-slimmer.d.ts +73 -0
- package/dist/types/components/vega-section-title/slimmers/a11y-tree/build-section-title-a11y-tree.d.ts +41 -0
- package/dist/types/components/vega-section-title/vega-section-title.d.ts +9 -0
- package/dist/types/components.d.ts +10 -10
- package/dist/types/helpers/a11y-tree/a11y-node-dto.d.ts +173 -0
- package/dist/types/helpers/a11y-tree/a11y-tree-applier.d.ts +28 -0
- package/dist/types/helpers/a11y-tree/a11y-tree.types.d.ts +137 -0
- package/dist/types/helpers/a11y-tree/strategies/baseline-strategy.d.ts +18 -0
- package/dist/types/helpers/a11y-tree/strategies/firefox-nvda-strategy.d.ts +16 -0
- package/dist/types/helpers/a11y-tree/strategies/webkit-voiceover-strategy.d.ts +23 -0
- package/dist/types/helpers/a11y-tree/strategy-resolver.d.ts +59 -0
- package/dist/types/helpers/slimmers/a11y-tree-slimmer.d.ts +49 -0
- package/dist/types/helpers/slimmers/element-appender/element-appender-slimmer.d.ts +9 -0
- package/dist/types/helpers/slimmers/element-appender/visibility-modifiers/clip-on-scroll-modifier.d.ts +37 -0
- package/dist/types/helpers/slimmers/element-appender/visibility-modifiers/visibility-modifier.interface.d.ts +56 -0
- package/dist/types/helpers/ui/element-appender.d.ts +7 -0
- package/dist/vega/index.esm.js +1 -1
- package/dist/vega/{p-9c39f90b.entry.js → p-1dfbc542.entry.js} +1 -1
- package/dist/vega/{p-e235020b.entry.js → p-22cc174e.entry.js} +1 -1
- package/dist/vega/{p-b187b82d.entry.js → p-2df5d59b.entry.js} +1 -1
- package/dist/vega/{p-f7e459cd.js → p-312d8205.js} +1 -1
- package/dist/vega/{p-a7209700.js → p-3345d903.js} +1 -1
- package/dist/vega/{p-02355de8.js → p-3c23ec90.js} +1 -1
- package/dist/vega/p-55e0014a.js +3 -0
- package/dist/vega/p-5f377954.js +1 -1
- package/dist/vega/p-65fee02f.entry.js +1 -0
- package/dist/vega/p-6a51d720.js +1 -0
- package/dist/vega/{p-fe24b459.js → p-6c7b6d45.js} +1 -1
- package/dist/vega/{p-579cdeae.js → p-84b7a775.js} +1 -1
- package/dist/vega/{p-df828d90.entry.js → p-96da7d30.entry.js} +1 -1
- package/dist/vega/{p-88be9ec5.js → p-9d3f69cb.js} +1 -1
- package/dist/vega/{p-8a001caa.js → p-9f11b579.js} +1 -1
- package/dist/vega/{p-ba2b9663.entry.js → p-acaff62d.entry.js} +1 -1
- package/dist/vega/p-b63319e9.entry.js +1 -0
- package/dist/vega/{p-c079c935.entry.js → p-b660f38c.entry.js} +1 -1
- package/dist/vega/p-b8ffa42f.entry.js +1 -0
- package/dist/vega/{p-4fe40b76.js → p-c4564904.js} +1 -1
- package/dist/vega/p-d9158512.js +1 -0
- package/dist/vega/p-e62d41ee.js +1 -0
- package/dist/vega/{p-9f7154d2.js → p-ec5dee32.js} +1 -1
- package/dist/vega/{p-05d04c07.entry.js → p-f29d9707.entry.js} +1 -1
- package/dist/vega/vega.esm.js +1 -1
- package/package.json +3 -2
- package/dist/vega/p-0be4df0a.js +0 -1
- package/dist/vega/p-38c9d782.js +0 -1
- package/dist/vega/p-513bc0d9.js +0 -1
- package/dist/vega/p-8d4b85e7.entry.js +0 -1
- package/dist/vega/p-c5d3b008.entry.js +0 -1
- package/dist/vega/p-d25ca0c3.entry.js +0 -1
- 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
|
|
1688
|
-
* @VegaWarning -
|
|
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
|
|
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
|
|
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
|
|
8313
|
-
* @VegaWarning -
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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;
|