@cssints/apg-specs 0.0.0-stage → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +65 -2
- package/dist/apg/accordion.bridge.d.mts +35 -0
- package/dist/apg/accordion.bridge.mjs +326 -0
- package/dist/apg/accordion.model.json +8397 -0
- package/dist/apg/alert.bridge.d.mts +22 -0
- package/dist/apg/alert.bridge.mjs +86 -0
- package/dist/apg/alert.model.json +871 -0
- package/dist/apg/alertdialog.bridge.d.mts +21 -0
- package/dist/apg/alertdialog.bridge.mjs +221 -0
- package/dist/apg/alertdialog.model.json +5232 -0
- package/dist/apg/breadcrumb.bridge.d.mts +26 -0
- package/dist/apg/breadcrumb.bridge.mjs +120 -0
- package/dist/apg/breadcrumb.model.json +574 -0
- package/dist/apg/button.bridge.d.mts +35 -0
- package/dist/apg/button.bridge.mjs +208 -0
- package/dist/apg/button.model.json +5814 -0
- package/dist/apg/carousel.bridge.d.mts +44 -0
- package/dist/apg/carousel.bridge.mjs +262 -0
- package/dist/apg/carousel.model.json +8963 -0
- package/dist/apg/checkbox-group.bridge.d.mts +25 -0
- package/dist/apg/checkbox-group.bridge.mjs +276 -0
- package/dist/apg/checkbox-group.model.json +3863 -0
- package/dist/apg/checkbox.bridge.d.mts +34 -0
- package/dist/apg/checkbox.bridge.mjs +253 -0
- package/dist/apg/checkbox.model.json +3158 -0
- package/dist/apg/combobox-autocomplete.bridge.d.mts +14 -0
- package/dist/apg/combobox-autocomplete.bridge.mjs +326 -0
- package/dist/apg/combobox-autocomplete.model.json +11586 -0
- package/dist/apg/combobox-dialog.bridge.d.mts +17 -0
- package/dist/apg/combobox-dialog.bridge.mjs +250 -0
- package/dist/apg/combobox-dialog.model.json +8981 -0
- package/dist/apg/combobox-grid.bridge.d.mts +17 -0
- package/dist/apg/combobox-grid.bridge.mjs +227 -0
- package/dist/apg/combobox-grid.model.json +8554 -0
- package/dist/apg/combobox-select-only.bridge.d.mts +24 -0
- package/dist/apg/combobox-select-only.bridge.mjs +304 -0
- package/dist/apg/combobox-select-only.model.json +7846 -0
- package/dist/apg/combobox-tree.bridge.d.mts +17 -0
- package/dist/apg/combobox-tree.bridge.mjs +211 -0
- package/dist/apg/combobox-tree.model.json +9345 -0
- package/dist/apg/dialog-modal.bridge.d.mts +35 -0
- package/dist/apg/dialog-modal.bridge.mjs +186 -0
- package/dist/apg/dialog-modal.model.json +7580 -0
- package/dist/apg/disclosure.bridge.d.mts +25 -0
- package/dist/apg/disclosure.bridge.mjs +202 -0
- package/dist/apg/disclosure.model.json +4703 -0
- package/dist/apg/feed.bridge.d.mts +31 -0
- package/dist/apg/feed.bridge.mjs +246 -0
- package/dist/apg/feed.model.json +4523 -0
- package/dist/apg/grid-selection.bridge.d.mts +13 -0
- package/dist/apg/grid-selection.bridge.mjs +160 -0
- package/dist/apg/grid-selection.model.json +6974 -0
- package/dist/apg/grid-sort.bridge.d.mts +12 -0
- package/dist/apg/grid-sort.bridge.mjs +138 -0
- package/dist/apg/grid-sort.model.json +3799 -0
- package/dist/apg/grid.bridge.d.mts +54 -0
- package/dist/apg/grid.bridge.mjs +441 -0
- package/dist/apg/grid.model.json +3802 -0
- package/dist/apg/link.bridge.d.mts +24 -0
- package/dist/apg/link.bridge.mjs +126 -0
- package/dist/apg/link.model.json +694 -0
- package/dist/apg/listbox-multi.bridge.d.mts +10 -0
- package/dist/apg/listbox-multi.bridge.mjs +261 -0
- package/dist/apg/listbox-multi.model.json +10893 -0
- package/dist/apg/listbox-rearrangeable.bridge.d.mts +20 -0
- package/dist/apg/listbox-rearrangeable.bridge.mjs +237 -0
- package/dist/apg/listbox-rearrangeable.model.json +17592 -0
- package/dist/apg/listbox-shared.d.mts +58 -0
- package/dist/apg/listbox-shared.mjs +171 -0
- package/dist/apg/listbox-single.bridge.d.mts +10 -0
- package/dist/apg/listbox-single.bridge.mjs +196 -0
- package/dist/apg/listbox-single.model.json +8024 -0
- package/dist/apg/listbox-typeahead.bridge.d.mts +10 -0
- package/dist/apg/listbox-typeahead.bridge.mjs +153 -0
- package/dist/apg/listbox-typeahead.model.json +5615 -0
- package/dist/apg/menu-button.bridge.d.mts +29 -0
- package/dist/apg/menu-button.bridge.mjs +259 -0
- package/dist/apg/menu-button.model.json +5706 -0
- package/dist/apg/menu-checkable.bridge.d.mts +25 -0
- package/dist/apg/menu-checkable.bridge.mjs +226 -0
- package/dist/apg/menu-checkable.model.json +4277 -0
- package/dist/apg/menu-menubar.bridge.d.mts +27 -0
- package/dist/apg/menu-menubar.bridge.mjs +273 -0
- package/dist/apg/menu-menubar.model.json +9540 -0
- package/dist/apg/meter.bridge.d.mts +28 -0
- package/dist/apg/meter.bridge.mjs +159 -0
- package/dist/apg/meter.model.json +1185 -0
- package/dist/apg/player.bridge.d.mts +24 -0
- package/dist/apg/player.bridge.mjs +342 -0
- package/dist/apg/player.model.json +11013 -0
- package/dist/apg/radio.bridge.d.mts +35 -0
- package/dist/apg/radio.bridge.mjs +371 -0
- package/dist/apg/radio.model.json +5011 -0
- package/dist/apg/slider-multithumb.bridge.d.mts +34 -0
- package/dist/apg/slider-multithumb.bridge.mjs +365 -0
- package/dist/apg/slider-multithumb.model.json +5774 -0
- package/dist/apg/slider.bridge.d.mts +54 -0
- package/dist/apg/slider.bridge.mjs +359 -0
- package/dist/apg/slider.model.json +4881 -0
- package/dist/apg/spinbutton.bridge.d.mts +41 -0
- package/dist/apg/spinbutton.bridge.mjs +327 -0
- package/dist/apg/spinbutton.model.json +7571 -0
- package/dist/apg/switch.bridge.d.mts +30 -0
- package/dist/apg/switch.bridge.mjs +243 -0
- package/dist/apg/switch.model.json +3159 -0
- package/dist/apg/tabs.bridge.d.mts +41 -0
- package/dist/apg/tabs.bridge.mjs +294 -0
- package/dist/apg/tabs.model.json +7659 -0
- package/dist/apg/timeline.bridge.d.mts +36 -0
- package/dist/apg/timeline.bridge.mjs +265 -0
- package/dist/apg/timeline.model.json +6189 -0
- package/dist/apg/toolbar.bridge.d.mts +25 -0
- package/dist/apg/toolbar.bridge.mjs +307 -0
- package/dist/apg/toolbar.model.json +6616 -0
- package/dist/apg/tooltip.bridge.d.mts +36 -0
- package/dist/apg/tooltip.bridge.mjs +208 -0
- package/dist/apg/tooltip.model.json +8295 -0
- package/dist/apg/treegrid.bridge.d.mts +28 -0
- package/dist/apg/treegrid.bridge.mjs +311 -0
- package/dist/apg/treegrid.model.json +17358 -0
- package/dist/apg/treeview.bridge.d.mts +26 -0
- package/dist/apg/treeview.bridge.mjs +396 -0
- package/dist/apg/treeview.model.json +13745 -0
- package/dist/apg/windowsplitter.bridge.d.mts +36 -0
- package/dist/apg/windowsplitter.bridge.mjs +242 -0
- package/dist/apg/windowsplitter.model.json +6253 -0
- package/dist/canvas/camera.model.json +6568 -0
- package/dist/canvas/canvas.bridge.d.mts +190 -0
- package/dist/canvas/canvas.bridge.mjs +729 -0
- package/dist/canvas/pointer.model.json +17095 -0
- package/dist/scenario.d.mts +233 -0
- package/dist/scenario.mjs +313 -0
- package/package.json +57 -4
- package/scenarios/apg/README.md +221 -0
- package/scenarios/apg/accordion.base-ui.json +1005 -0
- package/scenarios/apg/accordion.react-aria.json +929 -0
- package/scenarios/apg/alert.base-ui.json +81 -0
- package/scenarios/apg/alert.react-aria.json +98 -0
- package/scenarios/apg/alertdialog.base-ui.json +331 -0
- package/scenarios/apg/alertdialog.react-aria.json +225 -0
- package/scenarios/apg/breadcrumb.react-aria.json +312 -0
- package/scenarios/apg/button.ariakit.json +136 -0
- package/scenarios/apg/button.base-ui.json +747 -0
- package/scenarios/apg/button.react-aria.json +443 -0
- package/scenarios/apg/carousel.apg.json +909 -0
- package/scenarios/apg/checkbox.ariakit.json +299 -0
- package/scenarios/apg/checkbox.base-ui.json +1126 -0
- package/scenarios/apg/checkbox.react-aria.json +518 -0
- package/scenarios/apg/combobox.ariakit.json +945 -0
- package/scenarios/apg/combobox.base-ui.json +2444 -0
- package/scenarios/apg/combobox.react-aria.json +845 -0
- package/scenarios/apg/dialog-modal.ariakit.json +1102 -0
- package/scenarios/apg/dialog-modal.base-ui.json +775 -0
- package/scenarios/apg/dialog-modal.react-aria.json +638 -0
- package/scenarios/apg/disclosure.apg.json +349 -0
- package/scenarios/apg/disclosure.ariakit.json +163 -0
- package/scenarios/apg/disclosure.base-ui.json +451 -0
- package/scenarios/apg/disclosure.react-aria.json +643 -0
- package/scenarios/apg/feed.apg.json +442 -0
- package/scenarios/apg/grid.ariakit.json +197 -0
- package/scenarios/apg/grid.base-ui.json +720 -0
- package/scenarios/apg/grid.react-aria.json +969 -0
- package/scenarios/apg/landmarks.ariakit.json +93 -0
- package/scenarios/apg/landmarks.react-aria.json +330 -0
- package/scenarios/apg/link.ariakit.json +83 -0
- package/scenarios/apg/link.base-ui.json +88 -0
- package/scenarios/apg/link.react-aria.json +186 -0
- package/scenarios/apg/listbox.ariakit.json +78 -0
- package/scenarios/apg/listbox.base-ui.json +163 -0
- package/scenarios/apg/listbox.react-aria.json +1118 -0
- package/scenarios/apg/menu-button.ariakit.json +924 -0
- package/scenarios/apg/menu-button.base-ui.json +1155 -0
- package/scenarios/apg/menu-button.react-aria.json +1080 -0
- package/scenarios/apg/menubar.ariakit.json +758 -0
- package/scenarios/apg/menubar.base-ui.json +673 -0
- package/scenarios/apg/meter.base-ui.json +243 -0
- package/scenarios/apg/meter.react-aria.json +201 -0
- package/scenarios/apg/radio.ariakit.json +459 -0
- package/scenarios/apg/radio.base-ui.json +581 -0
- package/scenarios/apg/radio.react-aria.json +576 -0
- package/scenarios/apg/slider-multithumb.base-ui.json +316 -0
- package/scenarios/apg/slider-multithumb.react-aria.json +363 -0
- package/scenarios/apg/slider.base-ui.json +544 -0
- package/scenarios/apg/slider.react-aria.json +456 -0
- package/scenarios/apg/spinbutton.base-ui.json +1688 -0
- package/scenarios/apg/spinbutton.react-aria.json +426 -0
- package/scenarios/apg/switch.base-ui.json +456 -0
- package/scenarios/apg/switch.react-aria.json +303 -0
- package/scenarios/apg/table.ariakit.json +65 -0
- package/scenarios/apg/table.react-aria.json +221 -0
- package/scenarios/apg/tabs.ariakit.json +329 -0
- package/scenarios/apg/tabs.base-ui.json +875 -0
- package/scenarios/apg/tabs.react-aria.json +644 -0
- package/scenarios/apg/toolbar.ariakit.json +595 -0
- package/scenarios/apg/toolbar.base-ui.json +1189 -0
- package/scenarios/apg/toolbar.react-aria.json +383 -0
- package/scenarios/apg/tooltip.ariakit.json +441 -0
- package/scenarios/apg/tooltip.base-ui.json +411 -0
- package/scenarios/apg/tooltip.react-aria.json +454 -0
- package/scenarios/apg/treegrid.apg.json +2558 -0
- package/scenarios/apg/treegrid.react-aria.json +5094 -0
- package/scenarios/apg/treeview.apg.json +928 -0
- package/scenarios/apg/windowsplitter.apg.json +557 -0
- package/scenarios/canvas/README.md +69 -0
- package/scenarios/canvas/camera.contract.json +237 -0
- package/scenarios/canvas/camera.excalidraw.json +57 -0
- package/scenarios/canvas/marquee.excalidraw.json +122 -0
- package/scenarios/canvas/pan.excalidraw.json +46 -0
- package/scenarios/canvas/pointer.contract.json +528 -0
- package/scenarios/parts.json +291 -0
- package/shared/aria.qnt +186 -0
- package/shared/details-group.qnt +50 -0
- package/shared/focusgroup.qnt +152 -0
- package/shared/invokers.qnt +81 -0
- package/shared/popover.qnt +71 -0
- package/specs/apg/STATIC.md +103 -0
- package/specs/apg/accordion.qnt +578 -0
- package/specs/apg/alert.qnt +131 -0
- package/specs/apg/alertdialog.qnt +455 -0
- package/specs/apg/breadcrumb.qnt +88 -0
- package/specs/apg/button.qnt +445 -0
- package/specs/apg/carousel.qnt +732 -0
- package/specs/apg/checkbox-group.qnt +388 -0
- package/specs/apg/checkbox.qnt +394 -0
- package/specs/apg/combobox-autocomplete.qnt +764 -0
- package/specs/apg/combobox-dialog.qnt +627 -0
- package/specs/apg/combobox-grid.qnt +632 -0
- package/specs/apg/combobox-select-only.qnt +626 -0
- package/specs/apg/combobox-tree.qnt +633 -0
- package/specs/apg/dialog-modal.qnt +499 -0
- package/specs/apg/disclosure.qnt +309 -0
- package/specs/apg/feed.qnt +485 -0
- package/specs/apg/grid-selection.qnt +512 -0
- package/specs/apg/grid-sort.qnt +330 -0
- package/specs/apg/grid.qnt +360 -0
- package/specs/apg/link.qnt +119 -0
- package/specs/apg/listbox-multi.qnt +799 -0
- package/specs/apg/listbox-rearrangeable.qnt +801 -0
- package/specs/apg/listbox-single.qnt +511 -0
- package/specs/apg/listbox-typeahead.qnt +396 -0
- package/specs/apg/menu-button.qnt +363 -0
- package/specs/apg/menu-checkable.qnt +304 -0
- package/specs/apg/menu-menubar.qnt +531 -0
- package/specs/apg/meter.qnt +129 -0
- package/specs/apg/player.qnt +1081 -0
- package/specs/apg/radio.qnt +394 -0
- package/specs/apg/slider-multithumb.qnt +441 -0
- package/specs/apg/slider.qnt +396 -0
- package/specs/apg/spinbutton.qnt +494 -0
- package/specs/apg/switch.qnt +389 -0
- package/specs/apg/tabs.qnt +412 -0
- package/specs/apg/timeline.qnt +612 -0
- package/specs/apg/toolbar.qnt +364 -0
- package/specs/apg/tooltip.qnt +553 -0
- package/specs/apg/treegrid.qnt +983 -0
- package/specs/apg/treeview.qnt +1004 -0
- package/specs/apg/windowsplitter.qnt +487 -0
- package/specs/canvas/camera.qnt +407 -0
- package/specs/canvas/pointer.qnt +841 -0
|
@@ -0,0 +1,928 @@
|
|
|
1
|
+
{
|
|
2
|
+
"pattern": "treeview",
|
|
3
|
+
"source": "apg",
|
|
4
|
+
"commit": null,
|
|
5
|
+
"license": "W3C Software and Document License",
|
|
6
|
+
"upstream": "https://www.w3.org/WAI/ARIA/apg/patterns/treeview/",
|
|
7
|
+
"retrieved": "2026-10-03",
|
|
8
|
+
"fixture": {
|
|
9
|
+
"orientation": "vertical",
|
|
10
|
+
"tree": [
|
|
11
|
+
{
|
|
12
|
+
"name": "Projects",
|
|
13
|
+
"children": [
|
|
14
|
+
{
|
|
15
|
+
"name": "Reports",
|
|
16
|
+
"children": [{ "name": "Roadmap" }, { "name": "Summary" }]
|
|
17
|
+
},
|
|
18
|
+
{ "name": "Notes" }
|
|
19
|
+
]
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"name": "Photos",
|
|
23
|
+
"children": [{ "name": "Trip" }]
|
|
24
|
+
}
|
|
25
|
+
],
|
|
26
|
+
"treeNote": "Child order is document order. A treeitem target carries its slash path: root item i is `treeitem:i`, and `treeitem:0/1` is child 1 of root item 0. Paths map to the fixed pre-order node ids of specs/apg/treeview.qnt (Projects=1, Reports=2, Roadmap=3, Summary=4, Notes=5, Photos=6, Trip=7)."
|
|
27
|
+
},
|
|
28
|
+
"scenarios": [
|
|
29
|
+
{
|
|
30
|
+
"id": "treeview.apg.focus-first-node",
|
|
31
|
+
"upstream": "https://www.w3.org/WAI/ARIA/apg/patterns/treeview/#keyboardinteraction",
|
|
32
|
+
"upstreamTest": "When a single-select tree receives focus and none of the nodes are selected, focus is set on the first node",
|
|
33
|
+
"apg": "keyboard",
|
|
34
|
+
"config": {
|
|
35
|
+
"focused": false,
|
|
36
|
+
"multiSelectable": false,
|
|
37
|
+
"expanded": [],
|
|
38
|
+
"selected": [],
|
|
39
|
+
"focus": "treeitem:0"
|
|
40
|
+
},
|
|
41
|
+
"steps": [
|
|
42
|
+
{ "event": "focus", "target": "tree" },
|
|
43
|
+
{ "expect": { "focus": "treeitem:0" } }
|
|
44
|
+
]
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"id": "treeview.apg.focus-selected-node",
|
|
48
|
+
"upstream": "https://www.w3.org/WAI/ARIA/apg/patterns/treeview/#keyboardinteraction",
|
|
49
|
+
"upstreamTest": "When a single-select tree receives focus and a node is selected, focus is set on the selected node",
|
|
50
|
+
"apg": "keyboard",
|
|
51
|
+
"config": {
|
|
52
|
+
"focused": false,
|
|
53
|
+
"multiSelectable": false,
|
|
54
|
+
"expanded": ["0"],
|
|
55
|
+
"selected": ["treeitem:0/1"],
|
|
56
|
+
"focus": "treeitem:0"
|
|
57
|
+
},
|
|
58
|
+
"steps": [
|
|
59
|
+
{ "event": "focus", "target": "tree" },
|
|
60
|
+
{ "expect": { "focus": "treeitem:0/1" } }
|
|
61
|
+
],
|
|
62
|
+
"notes": "APG focus-on-entry rule. The current treeview spec deliberately omits it (focusTree keeps the roving node), so this scenario is a known divergence for the spec to grow into."
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"id": "treeview.apg.focus-first-selected-node-multi-select",
|
|
66
|
+
"upstream": "https://www.w3.org/WAI/ARIA/apg/patterns/treeview/#keyboardinteraction",
|
|
67
|
+
"upstreamTest": "When a multi-select tree receives focus and one or more nodes are selected, focus is set on the first selected node",
|
|
68
|
+
"apg": "keyboard",
|
|
69
|
+
"config": {
|
|
70
|
+
"focused": false,
|
|
71
|
+
"multiSelectable": true,
|
|
72
|
+
"expanded": ["0", "0/0"],
|
|
73
|
+
"selected": ["treeitem:1", "treeitem:0/0/1"],
|
|
74
|
+
"focus": "treeitem:0/0/0"
|
|
75
|
+
},
|
|
76
|
+
"steps": [
|
|
77
|
+
{ "event": "focus", "target": "tree" },
|
|
78
|
+
{ "expect": { "focus": "treeitem:1" } }
|
|
79
|
+
],
|
|
80
|
+
"notes": "First selected node in document order is Photos. Same focus-on-entry divergence as above."
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"id": "treeview.apg.right-opens-closed-node",
|
|
84
|
+
"upstream": "https://www.w3.org/WAI/ARIA/apg/patterns/treeview/#keyboardinteraction",
|
|
85
|
+
"upstreamTest": "Right arrow: when focus is on a closed node, opens the node; focus does not move",
|
|
86
|
+
"apg": "keyboard",
|
|
87
|
+
"config": {
|
|
88
|
+
"focused": true,
|
|
89
|
+
"multiSelectable": false,
|
|
90
|
+
"expanded": [],
|
|
91
|
+
"selected": [],
|
|
92
|
+
"focus": "treeitem:0"
|
|
93
|
+
},
|
|
94
|
+
"steps": [
|
|
95
|
+
{ "event": "key", "key": "ArrowRight", "target": "treeitem:0" },
|
|
96
|
+
{
|
|
97
|
+
"expect": {
|
|
98
|
+
"focus": "treeitem:0",
|
|
99
|
+
"attrs": { "treeitem:0": { "aria-expanded": "true" } },
|
|
100
|
+
"visible": [
|
|
101
|
+
"treeitem:0",
|
|
102
|
+
"treeitem:0/0",
|
|
103
|
+
"treeitem:0/1",
|
|
104
|
+
"treeitem:1"
|
|
105
|
+
],
|
|
106
|
+
"events": { "onExpandedChange": ["treeitem:0"] }
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
]
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"id": "treeview.apg.right-moves-to-first-child",
|
|
113
|
+
"upstream": "https://www.w3.org/WAI/ARIA/apg/patterns/treeview/#keyboardinteraction",
|
|
114
|
+
"upstreamTest": "Right arrow: when focus is on an open node, moves focus to the first child node",
|
|
115
|
+
"apg": "keyboard",
|
|
116
|
+
"config": {
|
|
117
|
+
"focused": true,
|
|
118
|
+
"multiSelectable": false,
|
|
119
|
+
"expanded": ["0"],
|
|
120
|
+
"selected": [],
|
|
121
|
+
"focus": "treeitem:0"
|
|
122
|
+
},
|
|
123
|
+
"steps": [
|
|
124
|
+
{ "event": "key", "key": "ArrowRight", "target": "treeitem:0" },
|
|
125
|
+
{ "expect": { "focus": "treeitem:0/0" } }
|
|
126
|
+
]
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
"id": "treeview.apg.right-on-end-node-does-nothing",
|
|
130
|
+
"upstream": "https://www.w3.org/WAI/ARIA/apg/patterns/treeview/#keyboardinteraction",
|
|
131
|
+
"upstreamTest": "Right arrow: when focus is on an end node, does nothing",
|
|
132
|
+
"apg": "keyboard",
|
|
133
|
+
"config": {
|
|
134
|
+
"focused": true,
|
|
135
|
+
"multiSelectable": false,
|
|
136
|
+
"expanded": ["0", "0/0"],
|
|
137
|
+
"selected": [],
|
|
138
|
+
"focus": "treeitem:0/0/0"
|
|
139
|
+
},
|
|
140
|
+
"steps": [
|
|
141
|
+
{ "event": "key", "key": "ArrowRight", "target": "treeitem:0/0/0" },
|
|
142
|
+
{
|
|
143
|
+
"expect": {
|
|
144
|
+
"focus": "treeitem:0/0/0",
|
|
145
|
+
"attrs": { "treeitem:0/0/0": { "aria-expanded": null } }
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
]
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
"id": "treeview.apg.left-closes-open-node",
|
|
152
|
+
"upstream": "https://www.w3.org/WAI/ARIA/apg/patterns/treeview/#keyboardinteraction",
|
|
153
|
+
"upstreamTest": "Left arrow: when focus is on an open node, closes the node",
|
|
154
|
+
"apg": "keyboard",
|
|
155
|
+
"config": {
|
|
156
|
+
"focused": true,
|
|
157
|
+
"multiSelectable": false,
|
|
158
|
+
"expanded": ["0"],
|
|
159
|
+
"selected": [],
|
|
160
|
+
"focus": "treeitem:0"
|
|
161
|
+
},
|
|
162
|
+
"steps": [
|
|
163
|
+
{ "event": "key", "key": "ArrowLeft", "target": "treeitem:0" },
|
|
164
|
+
{
|
|
165
|
+
"expect": {
|
|
166
|
+
"focus": "treeitem:0",
|
|
167
|
+
"attrs": { "treeitem:0": { "aria-expanded": "false" } },
|
|
168
|
+
"visible": ["treeitem:0", "treeitem:1"],
|
|
169
|
+
"events": { "onExpandedChange": ["treeitem:0"] }
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
]
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
"id": "treeview.apg.left-moves-to-parent",
|
|
176
|
+
"upstream": "https://www.w3.org/WAI/ARIA/apg/patterns/treeview/#keyboardinteraction",
|
|
177
|
+
"upstreamTest": "Left arrow: when focus is on a child node that is also either an end node or a closed node, moves focus to its parent node",
|
|
178
|
+
"apg": "keyboard",
|
|
179
|
+
"config": {
|
|
180
|
+
"focused": true,
|
|
181
|
+
"multiSelectable": false,
|
|
182
|
+
"expanded": ["0"],
|
|
183
|
+
"selected": [],
|
|
184
|
+
"focus": "treeitem:0/1"
|
|
185
|
+
},
|
|
186
|
+
"steps": [
|
|
187
|
+
{ "event": "key", "key": "ArrowLeft", "target": "treeitem:0/1" },
|
|
188
|
+
{ "expect": { "focus": "treeitem:0" } }
|
|
189
|
+
]
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
"id": "treeview.apg.left-on-root-does-nothing",
|
|
193
|
+
"upstream": "https://www.w3.org/WAI/ARIA/apg/patterns/treeview/#keyboardinteraction",
|
|
194
|
+
"upstreamTest": "Left arrow: when focus is on a root node that is also either an end node or a closed node, does nothing",
|
|
195
|
+
"apg": "keyboard",
|
|
196
|
+
"config": {
|
|
197
|
+
"focused": true,
|
|
198
|
+
"multiSelectable": false,
|
|
199
|
+
"expanded": [],
|
|
200
|
+
"selected": [],
|
|
201
|
+
"focus": "treeitem:1"
|
|
202
|
+
},
|
|
203
|
+
"steps": [
|
|
204
|
+
{ "event": "key", "key": "ArrowLeft", "target": "treeitem:1" },
|
|
205
|
+
{ "expect": { "focus": "treeitem:1" } }
|
|
206
|
+
]
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
"id": "treeview.apg.down-skips-collapsed-subtrees",
|
|
210
|
+
"upstream": "https://www.w3.org/WAI/ARIA/apg/patterns/treeview/#keyboardinteraction",
|
|
211
|
+
"upstreamTest": "Down arrow: moves focus to the next node that is focusable without opening or closing a node",
|
|
212
|
+
"apg": "keyboard",
|
|
213
|
+
"config": {
|
|
214
|
+
"focused": true,
|
|
215
|
+
"multiSelectable": false,
|
|
216
|
+
"expanded": [],
|
|
217
|
+
"selected": [],
|
|
218
|
+
"focus": "treeitem:0"
|
|
219
|
+
},
|
|
220
|
+
"steps": [
|
|
221
|
+
{ "event": "key", "key": "ArrowDown", "target": "treeitem:0" },
|
|
222
|
+
{
|
|
223
|
+
"expect": {
|
|
224
|
+
"focus": "treeitem:1",
|
|
225
|
+
"visible": ["treeitem:0", "treeitem:1"]
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
],
|
|
229
|
+
"notes": "Children of the collapsed Projects node are skipped; the next focusable node is the root Photos."
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
"id": "treeview.apg.down-moves-into-expanded-children",
|
|
233
|
+
"upstream": "https://www.w3.org/WAI/ARIA/apg/patterns/treeview/#keyboardinteraction",
|
|
234
|
+
"upstreamTest": "Down arrow: moves focus to the next node that is focusable without opening or closing a node",
|
|
235
|
+
"apg": "keyboard",
|
|
236
|
+
"config": {
|
|
237
|
+
"focused": true,
|
|
238
|
+
"multiSelectable": false,
|
|
239
|
+
"expanded": ["0"],
|
|
240
|
+
"selected": [],
|
|
241
|
+
"focus": "treeitem:0"
|
|
242
|
+
},
|
|
243
|
+
"steps": [
|
|
244
|
+
{ "event": "key", "key": "ArrowDown", "target": "treeitem:0" },
|
|
245
|
+
{ "expect": { "focus": "treeitem:0/0" } }
|
|
246
|
+
]
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
"id": "treeview.apg.up-moves-to-previous-visible",
|
|
250
|
+
"upstream": "https://www.w3.org/WAI/ARIA/apg/patterns/treeview/#keyboardinteraction",
|
|
251
|
+
"upstreamTest": "Up arrow: moves focus to the previous node that is focusable without opening or closing a node",
|
|
252
|
+
"apg": "keyboard",
|
|
253
|
+
"config": {
|
|
254
|
+
"focused": true,
|
|
255
|
+
"multiSelectable": false,
|
|
256
|
+
"expanded": ["0"],
|
|
257
|
+
"selected": [],
|
|
258
|
+
"focus": "treeitem:0/1"
|
|
259
|
+
},
|
|
260
|
+
"steps": [
|
|
261
|
+
{ "event": "key", "key": "ArrowUp", "target": "treeitem:0/1" },
|
|
262
|
+
{ "expect": { "focus": "treeitem:0/0" } }
|
|
263
|
+
]
|
|
264
|
+
},
|
|
265
|
+
{
|
|
266
|
+
"id": "treeview.apg.home-moves-to-first-node",
|
|
267
|
+
"upstream": "https://www.w3.org/WAI/ARIA/apg/patterns/treeview/#keyboardinteraction",
|
|
268
|
+
"upstreamTest": "Home: moves focus to the first node in the tree without opening or closing a node",
|
|
269
|
+
"apg": "keyboard",
|
|
270
|
+
"config": {
|
|
271
|
+
"focused": true,
|
|
272
|
+
"multiSelectable": false,
|
|
273
|
+
"expanded": ["0", "1"],
|
|
274
|
+
"selected": [],
|
|
275
|
+
"focus": "treeitem:1/0"
|
|
276
|
+
},
|
|
277
|
+
"steps": [
|
|
278
|
+
{ "event": "key", "key": "Home", "target": "treeitem:1/0" },
|
|
279
|
+
{ "expect": { "focus": "treeitem:0" } }
|
|
280
|
+
]
|
|
281
|
+
},
|
|
282
|
+
{
|
|
283
|
+
"id": "treeview.apg.end-moves-to-last-visible",
|
|
284
|
+
"upstream": "https://www.w3.org/WAI/ARIA/apg/patterns/treeview/#keyboardinteraction",
|
|
285
|
+
"upstreamTest": "End: moves focus to the last node in the tree that is focusable without opening a node",
|
|
286
|
+
"apg": "keyboard",
|
|
287
|
+
"config": {
|
|
288
|
+
"focused": true,
|
|
289
|
+
"multiSelectable": false,
|
|
290
|
+
"expanded": ["0", "1"],
|
|
291
|
+
"selected": [],
|
|
292
|
+
"focus": "treeitem:0"
|
|
293
|
+
},
|
|
294
|
+
"steps": [
|
|
295
|
+
{ "event": "key", "key": "End", "target": "treeitem:0" },
|
|
296
|
+
{ "expect": { "focus": "treeitem:1/0" } }
|
|
297
|
+
]
|
|
298
|
+
},
|
|
299
|
+
{
|
|
300
|
+
"id": "treeview.apg.enter-opens-and-closes-parent",
|
|
301
|
+
"upstream": "https://www.w3.org/WAI/ARIA/apg/patterns/treeview/#keyboardinteraction",
|
|
302
|
+
"upstreamTest": "Enter: activates a node, i.e., performs its default action; for parent nodes one possible default action is to open or close the node",
|
|
303
|
+
"apg": "keyboard",
|
|
304
|
+
"config": {
|
|
305
|
+
"focused": true,
|
|
306
|
+
"multiSelectable": false,
|
|
307
|
+
"expanded": [],
|
|
308
|
+
"selected": [],
|
|
309
|
+
"focus": "treeitem:0"
|
|
310
|
+
},
|
|
311
|
+
"steps": [
|
|
312
|
+
{ "event": "key", "key": "Enter", "target": "treeitem:0" },
|
|
313
|
+
{
|
|
314
|
+
"expect": {
|
|
315
|
+
"focus": "treeitem:0",
|
|
316
|
+
"attrs": {
|
|
317
|
+
"treeitem:0": { "aria-expanded": "true", "aria-selected": "true" }
|
|
318
|
+
},
|
|
319
|
+
"events": {
|
|
320
|
+
"onActivate": ["treeitem:0"],
|
|
321
|
+
"onExpandedChange": ["treeitem:0"],
|
|
322
|
+
"onSelectionChange": ["treeitem:0"]
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
},
|
|
326
|
+
{ "event": "key", "key": "Enter", "target": "treeitem:0" },
|
|
327
|
+
{
|
|
328
|
+
"expect": {
|
|
329
|
+
"focus": "treeitem:0",
|
|
330
|
+
"attrs": { "treeitem:0": { "aria-expanded": "false" } },
|
|
331
|
+
"events": {
|
|
332
|
+
"onActivate": ["treeitem:0"],
|
|
333
|
+
"onExpandedChange": ["treeitem:0"]
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
],
|
|
338
|
+
"notes": "Non-selection-follows-focus single-select: the default action selects the focused node as well as toggling a parent. The spec's pressEnter implements both."
|
|
339
|
+
},
|
|
340
|
+
{
|
|
341
|
+
"id": "treeview.apg.enter-selects-end-node-single-select",
|
|
342
|
+
"upstream": "https://www.w3.org/WAI/ARIA/apg/patterns/treeview/#keyboardinteraction",
|
|
343
|
+
"upstreamTest": "Enter: in single-select trees where selection does not follow focus, the default action is typically to select the focused node",
|
|
344
|
+
"apg": "keyboard",
|
|
345
|
+
"config": {
|
|
346
|
+
"focused": true,
|
|
347
|
+
"multiSelectable": false,
|
|
348
|
+
"expanded": ["0", "0/0"],
|
|
349
|
+
"selected": [],
|
|
350
|
+
"focus": "treeitem:0/0/0"
|
|
351
|
+
},
|
|
352
|
+
"steps": [
|
|
353
|
+
{ "event": "key", "key": "Enter", "target": "treeitem:0/0/0" },
|
|
354
|
+
{
|
|
355
|
+
"expect": {
|
|
356
|
+
"focus": "treeitem:0/0/0",
|
|
357
|
+
"attrs": { "treeitem:0/0/0": { "aria-selected": "true" } },
|
|
358
|
+
"events": {
|
|
359
|
+
"onActivate": ["treeitem:0/0/0"],
|
|
360
|
+
"onSelectionChange": ["treeitem:0/0/0"]
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
]
|
|
365
|
+
},
|
|
366
|
+
{
|
|
367
|
+
"id": "treeview.apg.typeahead-single-character",
|
|
368
|
+
"upstream": "https://www.w3.org/WAI/ARIA/apg/patterns/treeview/#keyboardinteraction",
|
|
369
|
+
"upstreamTest": "Type a character: focus moves to the next node with a name that starts with the typed character",
|
|
370
|
+
"apg": "keyboard",
|
|
371
|
+
"config": {
|
|
372
|
+
"focused": true,
|
|
373
|
+
"multiSelectable": false,
|
|
374
|
+
"expanded": ["0"],
|
|
375
|
+
"selected": [],
|
|
376
|
+
"focus": "treeitem:0"
|
|
377
|
+
},
|
|
378
|
+
"steps": [
|
|
379
|
+
{ "event": "type", "text": "r", "target": "treeitem:0" },
|
|
380
|
+
{ "expect": { "focus": "treeitem:0/0" } }
|
|
381
|
+
],
|
|
382
|
+
"notes": "Search starts at the node after the focused one and wraps; only visible nodes match."
|
|
383
|
+
},
|
|
384
|
+
{
|
|
385
|
+
"id": "treeview.apg.typeahead-multiple-characters",
|
|
386
|
+
"upstream": "https://www.w3.org/WAI/ARIA/apg/patterns/treeview/#keyboardinteraction",
|
|
387
|
+
"upstreamTest": "Type multiple characters in rapid succession: focus moves to the next node with a name that starts with the string of characters typed",
|
|
388
|
+
"apg": "keyboard",
|
|
389
|
+
"config": {
|
|
390
|
+
"focused": true,
|
|
391
|
+
"multiSelectable": false,
|
|
392
|
+
"expanded": ["0", "0/0"],
|
|
393
|
+
"selected": [],
|
|
394
|
+
"focus": "treeitem:0"
|
|
395
|
+
},
|
|
396
|
+
"steps": [
|
|
397
|
+
{ "event": "type", "text": "r", "target": "treeitem:0" },
|
|
398
|
+
{ "expect": { "focus": "treeitem:0/0" } },
|
|
399
|
+
{ "event": "type", "text": "o", "target": "treeitem:0/0" },
|
|
400
|
+
{ "expect": { "focus": "treeitem:0/0/0" } }
|
|
401
|
+
],
|
|
402
|
+
"notes": "The second character refines the buffer from the already-focused node, so `r` -> Reports then `ro` -> Roadmap."
|
|
403
|
+
},
|
|
404
|
+
{
|
|
405
|
+
"id": "treeview.apg.typeahead-reset-after-timeout",
|
|
406
|
+
"upstream": "https://www.w3.org/WAI/ARIA/apg/patterns/treeview/#keyboardinteraction",
|
|
407
|
+
"upstreamTest": "Type-ahead searches with the string of characters typed in rapid succession; a pause starts a new search string",
|
|
408
|
+
"apg": "keyboard",
|
|
409
|
+
"config": {
|
|
410
|
+
"focused": true,
|
|
411
|
+
"multiSelectable": false,
|
|
412
|
+
"expanded": ["0", "0/0"],
|
|
413
|
+
"selected": [],
|
|
414
|
+
"focus": "treeitem:0"
|
|
415
|
+
},
|
|
416
|
+
"steps": [
|
|
417
|
+
{ "event": "type", "text": "s", "target": "treeitem:0" },
|
|
418
|
+
{ "expect": { "focus": "treeitem:0/0/1" } },
|
|
419
|
+
{ "event": "typeaheadReset" },
|
|
420
|
+
{ "event": "type", "text": "r", "target": "treeitem:0/0/1" },
|
|
421
|
+
{ "expect": { "focus": "treeitem:0/0" } }
|
|
422
|
+
],
|
|
423
|
+
"notes": "`typeaheadReset` models the type-ahead timeout, an event outside the README's base event vocabulary. After it, `r` is a fresh one-character search from the node after focus; without the reset `sr` would match nothing."
|
|
424
|
+
},
|
|
425
|
+
{
|
|
426
|
+
"id": "treeview.apg.star-expands-siblings",
|
|
427
|
+
"upstream": "https://www.w3.org/WAI/ARIA/apg/patterns/treeview/#keyboardinteraction",
|
|
428
|
+
"upstreamTest": "* (Optional): expands all siblings that are at the same level as the current node",
|
|
429
|
+
"apg": "keyboard",
|
|
430
|
+
"config": {
|
|
431
|
+
"focused": true,
|
|
432
|
+
"multiSelectable": false,
|
|
433
|
+
"expanded": [],
|
|
434
|
+
"selected": [],
|
|
435
|
+
"focus": "treeitem:0"
|
|
436
|
+
},
|
|
437
|
+
"steps": [
|
|
438
|
+
{ "event": "key", "key": "*", "target": "treeitem:0" },
|
|
439
|
+
{
|
|
440
|
+
"expect": {
|
|
441
|
+
"focus": "treeitem:0",
|
|
442
|
+
"attrs": {
|
|
443
|
+
"treeitem:0": { "aria-expanded": "true" },
|
|
444
|
+
"treeitem:1": { "aria-expanded": "true" }
|
|
445
|
+
},
|
|
446
|
+
"visible": [
|
|
447
|
+
"treeitem:0",
|
|
448
|
+
"treeitem:0/0",
|
|
449
|
+
"treeitem:0/1",
|
|
450
|
+
"treeitem:1",
|
|
451
|
+
"treeitem:1/0"
|
|
452
|
+
],
|
|
453
|
+
"events": { "onExpandedChange": ["treeitem:0", "treeitem:1"] }
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
]
|
|
457
|
+
},
|
|
458
|
+
{
|
|
459
|
+
"id": "treeview.apg.blur-clears-typeahead",
|
|
460
|
+
"upstream": "https://www.w3.org/WAI/ARIA/apg/patterns/treeview/#keyboardinteraction",
|
|
461
|
+
"upstreamTest": "Type-ahead buffer restarts after the tree loses focus",
|
|
462
|
+
"apg": "keyboard",
|
|
463
|
+
"config": {
|
|
464
|
+
"focused": true,
|
|
465
|
+
"multiSelectable": false,
|
|
466
|
+
"expanded": ["0", "0/0"],
|
|
467
|
+
"selected": [],
|
|
468
|
+
"focus": "treeitem:0"
|
|
469
|
+
},
|
|
470
|
+
"steps": [
|
|
471
|
+
{ "event": "type", "text": "s", "target": "treeitem:0" },
|
|
472
|
+
{ "expect": { "focus": "treeitem:0/0/1" } },
|
|
473
|
+
{ "event": "blur", "target": "tree" },
|
|
474
|
+
{ "event": "focus", "target": "tree" },
|
|
475
|
+
{ "event": "type", "text": "r", "target": "treeitem:0/0/1" },
|
|
476
|
+
{ "expect": { "focus": "treeitem:0/0" } }
|
|
477
|
+
],
|
|
478
|
+
"notes": "If the buffer survived blur, `sr` would match nothing and focus would stay on Summary."
|
|
479
|
+
},
|
|
480
|
+
{
|
|
481
|
+
"id": "treeview.apg.multi-space-toggles-focused-node",
|
|
482
|
+
"upstream": "https://www.w3.org/WAI/ARIA/apg/patterns/treeview/#keyboardinteraction",
|
|
483
|
+
"upstreamTest": "Multi-select recommended model: Space toggles the selection state of the focused node",
|
|
484
|
+
"apg": "keyboard",
|
|
485
|
+
"config": {
|
|
486
|
+
"focused": true,
|
|
487
|
+
"multiSelectable": true,
|
|
488
|
+
"expanded": ["0"],
|
|
489
|
+
"selected": [],
|
|
490
|
+
"focus": "treeitem:0/1"
|
|
491
|
+
},
|
|
492
|
+
"steps": [
|
|
493
|
+
{ "event": "key", "key": " ", "target": "treeitem:0/1" },
|
|
494
|
+
{
|
|
495
|
+
"expect": {
|
|
496
|
+
"focus": "treeitem:0/1",
|
|
497
|
+
"attrs": { "treeitem:0/1": { "aria-selected": "true" } },
|
|
498
|
+
"events": { "onSelectionChange": ["treeitem:0/1"] }
|
|
499
|
+
}
|
|
500
|
+
},
|
|
501
|
+
{ "event": "key", "key": " ", "target": "treeitem:0/1" },
|
|
502
|
+
{
|
|
503
|
+
"expect": {
|
|
504
|
+
"focus": "treeitem:0/1",
|
|
505
|
+
"attrs": { "treeitem:0/1": { "aria-selected": "false" } },
|
|
506
|
+
"events": { "onSelectionChange": [] }
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
]
|
|
510
|
+
},
|
|
511
|
+
{
|
|
512
|
+
"id": "treeview.apg.multi-shift-down-moves-and-toggles",
|
|
513
|
+
"upstream": "https://www.w3.org/WAI/ARIA/apg/patterns/treeview/#keyboardinteraction",
|
|
514
|
+
"upstreamTest": "Multi-select recommended model: Shift + Down Arrow moves focus to and toggles the selection state of the next node",
|
|
515
|
+
"apg": "keyboard",
|
|
516
|
+
"config": {
|
|
517
|
+
"focused": true,
|
|
518
|
+
"multiSelectable": true,
|
|
519
|
+
"expanded": ["0"],
|
|
520
|
+
"selected": [],
|
|
521
|
+
"focus": "treeitem:0"
|
|
522
|
+
},
|
|
523
|
+
"steps": [
|
|
524
|
+
{
|
|
525
|
+
"event": "key",
|
|
526
|
+
"key": "ArrowDown",
|
|
527
|
+
"target": "treeitem:0",
|
|
528
|
+
"modifiers": ["Shift"]
|
|
529
|
+
},
|
|
530
|
+
{
|
|
531
|
+
"expect": {
|
|
532
|
+
"focus": "treeitem:0/0",
|
|
533
|
+
"attrs": { "treeitem:0/0": { "aria-selected": "true" } },
|
|
534
|
+
"events": { "onSelectionChange": ["treeitem:0/0"] }
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
]
|
|
538
|
+
},
|
|
539
|
+
{
|
|
540
|
+
"id": "treeview.apg.multi-shift-up-moves-and-toggles",
|
|
541
|
+
"upstream": "https://www.w3.org/WAI/ARIA/apg/patterns/treeview/#keyboardinteraction",
|
|
542
|
+
"upstreamTest": "Multi-select recommended model: Shift + Up Arrow moves focus to and toggles the selection state of the previous node",
|
|
543
|
+
"apg": "keyboard",
|
|
544
|
+
"config": {
|
|
545
|
+
"focused": true,
|
|
546
|
+
"multiSelectable": true,
|
|
547
|
+
"expanded": ["0"],
|
|
548
|
+
"selected": [],
|
|
549
|
+
"focus": "treeitem:0/1"
|
|
550
|
+
},
|
|
551
|
+
"steps": [
|
|
552
|
+
{
|
|
553
|
+
"event": "key",
|
|
554
|
+
"key": "ArrowUp",
|
|
555
|
+
"target": "treeitem:0/1",
|
|
556
|
+
"modifiers": ["Shift"]
|
|
557
|
+
},
|
|
558
|
+
{
|
|
559
|
+
"expect": {
|
|
560
|
+
"focus": "treeitem:0/0",
|
|
561
|
+
"attrs": { "treeitem:0/0": { "aria-selected": "true" } },
|
|
562
|
+
"events": { "onSelectionChange": ["treeitem:0/0"] }
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
]
|
|
566
|
+
},
|
|
567
|
+
{
|
|
568
|
+
"id": "treeview.apg.multi-ctrl-a-selects-all-then-clears",
|
|
569
|
+
"upstream": "https://www.w3.org/WAI/ARIA/apg/patterns/treeview/#keyboardinteraction",
|
|
570
|
+
"upstreamTest": "Multi-select recommended model: Control + A selects all nodes in the tree; optionally, if all nodes are selected, it can also unselect all nodes",
|
|
571
|
+
"apg": "keyboard",
|
|
572
|
+
"config": {
|
|
573
|
+
"focused": true,
|
|
574
|
+
"multiSelectable": true,
|
|
575
|
+
"expanded": ["0"],
|
|
576
|
+
"selected": [],
|
|
577
|
+
"focus": "treeitem:0"
|
|
578
|
+
},
|
|
579
|
+
"steps": [
|
|
580
|
+
{
|
|
581
|
+
"event": "key",
|
|
582
|
+
"key": "a",
|
|
583
|
+
"target": "treeitem:0",
|
|
584
|
+
"modifiers": ["Control"]
|
|
585
|
+
},
|
|
586
|
+
{
|
|
587
|
+
"expect": {
|
|
588
|
+
"focus": "treeitem:0",
|
|
589
|
+
"attrs": {
|
|
590
|
+
"treeitem:0": { "aria-selected": "true" },
|
|
591
|
+
"treeitem:0/0": { "aria-selected": "true" },
|
|
592
|
+
"treeitem:0/0/0": { "aria-selected": "true" },
|
|
593
|
+
"treeitem:0/0/1": { "aria-selected": "true" },
|
|
594
|
+
"treeitem:0/1": { "aria-selected": "true" },
|
|
595
|
+
"treeitem:1": { "aria-selected": "true" },
|
|
596
|
+
"treeitem:1/0": { "aria-selected": "true" }
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
},
|
|
600
|
+
{
|
|
601
|
+
"event": "key",
|
|
602
|
+
"key": "a",
|
|
603
|
+
"target": "treeitem:0",
|
|
604
|
+
"modifiers": ["Control"]
|
|
605
|
+
},
|
|
606
|
+
{
|
|
607
|
+
"expect": {
|
|
608
|
+
"attrs": {
|
|
609
|
+
"treeitem:0": { "aria-selected": "false" },
|
|
610
|
+
"treeitem:0/0/0": { "aria-selected": "false" },
|
|
611
|
+
"treeitem:1/0": { "aria-selected": "false" }
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
],
|
|
616
|
+
"notes": "The spec selects every node including those inside collapsed subtrees (nodes Roadmap, Summary, Trip here)."
|
|
617
|
+
},
|
|
618
|
+
{
|
|
619
|
+
"id": "treeview.apg.click-selects-and-focuses-node",
|
|
620
|
+
"upstream": "https://www.w3.org/WAI/ARIA/apg/patterns/treeview/examples/treeview-1b/",
|
|
621
|
+
"upstreamTest": "File Directory Treeview: clicking a treeitem moves focus to it and makes it the selected node",
|
|
622
|
+
"apg": "keyboard",
|
|
623
|
+
"config": {
|
|
624
|
+
"focused": false,
|
|
625
|
+
"multiSelectable": false,
|
|
626
|
+
"expanded": ["0"],
|
|
627
|
+
"selected": [],
|
|
628
|
+
"focus": "treeitem:0"
|
|
629
|
+
},
|
|
630
|
+
"steps": [
|
|
631
|
+
{ "event": "click", "target": "treeitem:0/1" },
|
|
632
|
+
{
|
|
633
|
+
"expect": {
|
|
634
|
+
"focus": "treeitem:0/1",
|
|
635
|
+
"attrs": { "treeitem:0/1": { "aria-selected": "true" } },
|
|
636
|
+
"events": { "onSelectionChange": ["treeitem:0/1"] }
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
]
|
|
640
|
+
},
|
|
641
|
+
{
|
|
642
|
+
"id": "treeview.apg.aria-expanded-only-on-parents",
|
|
643
|
+
"upstream": "https://www.w3.org/WAI/ARIA/apg/patterns/treeview/#wai-ariaroles,states,andproperties",
|
|
644
|
+
"upstreamTest": "Each treeitem that serves as a parent node has aria-expanded; end nodes do not have the attribute",
|
|
645
|
+
"apg": "aria",
|
|
646
|
+
"config": {
|
|
647
|
+
"focused": true,
|
|
648
|
+
"multiSelectable": false,
|
|
649
|
+
"expanded": ["0"],
|
|
650
|
+
"selected": [],
|
|
651
|
+
"focus": "treeitem:0"
|
|
652
|
+
},
|
|
653
|
+
"steps": [
|
|
654
|
+
{
|
|
655
|
+
"expect": {
|
|
656
|
+
"attrs": {
|
|
657
|
+
"treeitem:0": { "aria-expanded": "true" },
|
|
658
|
+
"treeitem:0/0": { "aria-expanded": "false" },
|
|
659
|
+
"treeitem:0/1": { "aria-expanded": null },
|
|
660
|
+
"treeitem:0/0/0": { "aria-expanded": null },
|
|
661
|
+
"treeitem:1": { "aria-expanded": "false" },
|
|
662
|
+
"treeitem:1/0": { "aria-expanded": null }
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
]
|
|
667
|
+
},
|
|
668
|
+
{
|
|
669
|
+
"id": "treeview.apg.aria-level-setsize-posinset",
|
|
670
|
+
"upstream": "https://www.w3.org/WAI/ARIA/apg/patterns/treeview/examples/treeview-1b/",
|
|
671
|
+
"upstreamTest": "File Directory Treeview (declared properties): every treeitem declares aria-level, aria-setsize and aria-posinset",
|
|
672
|
+
"apg": "aria",
|
|
673
|
+
"config": {
|
|
674
|
+
"focused": true,
|
|
675
|
+
"multiSelectable": false,
|
|
676
|
+
"expanded": ["0", "0/0"],
|
|
677
|
+
"selected": [],
|
|
678
|
+
"focus": "treeitem:0"
|
|
679
|
+
},
|
|
680
|
+
"steps": [
|
|
681
|
+
{
|
|
682
|
+
"expect": {
|
|
683
|
+
"attrs": {
|
|
684
|
+
"treeitem:0": {
|
|
685
|
+
"aria-level": "1",
|
|
686
|
+
"aria-setsize": "2",
|
|
687
|
+
"aria-posinset": "1"
|
|
688
|
+
},
|
|
689
|
+
"treeitem:0/0": {
|
|
690
|
+
"aria-level": "2",
|
|
691
|
+
"aria-setsize": "2",
|
|
692
|
+
"aria-posinset": "1"
|
|
693
|
+
},
|
|
694
|
+
"treeitem:0/0/0": {
|
|
695
|
+
"aria-level": "3",
|
|
696
|
+
"aria-setsize": "2",
|
|
697
|
+
"aria-posinset": "1"
|
|
698
|
+
},
|
|
699
|
+
"treeitem:0/0/1": {
|
|
700
|
+
"aria-level": "3",
|
|
701
|
+
"aria-setsize": "2",
|
|
702
|
+
"aria-posinset": "2"
|
|
703
|
+
},
|
|
704
|
+
"treeitem:0/1": {
|
|
705
|
+
"aria-level": "2",
|
|
706
|
+
"aria-setsize": "2",
|
|
707
|
+
"aria-posinset": "2"
|
|
708
|
+
},
|
|
709
|
+
"treeitem:1": {
|
|
710
|
+
"aria-level": "1",
|
|
711
|
+
"aria-setsize": "2",
|
|
712
|
+
"aria-posinset": "2"
|
|
713
|
+
},
|
|
714
|
+
"treeitem:1/0": {
|
|
715
|
+
"aria-level": "2",
|
|
716
|
+
"aria-setsize": "1",
|
|
717
|
+
"aria-posinset": "1"
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
]
|
|
723
|
+
},
|
|
724
|
+
{
|
|
725
|
+
"id": "treeview.apg.aria-selected-on-selectable-nodes",
|
|
726
|
+
"upstream": "https://www.w3.org/WAI/ARIA/apg/patterns/treeview/#wai-ariaroles,states,andproperties",
|
|
727
|
+
"upstreamTest": "If any nodes are selected each selected node has aria-selected true; all selectable but unselected nodes have aria-selected false",
|
|
728
|
+
"apg": "aria",
|
|
729
|
+
"config": {
|
|
730
|
+
"focused": true,
|
|
731
|
+
"multiSelectable": false,
|
|
732
|
+
"expanded": ["0"],
|
|
733
|
+
"selected": ["treeitem:0/0"],
|
|
734
|
+
"focus": "treeitem:0"
|
|
735
|
+
},
|
|
736
|
+
"steps": [
|
|
737
|
+
{
|
|
738
|
+
"expect": {
|
|
739
|
+
"attrs": {
|
|
740
|
+
"treeitem:0": { "aria-selected": "false" },
|
|
741
|
+
"treeitem:0/0": { "aria-selected": "true" },
|
|
742
|
+
"treeitem:0/1": { "aria-selected": "false" },
|
|
743
|
+
"treeitem:1": { "aria-selected": "false" }
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
]
|
|
748
|
+
},
|
|
749
|
+
{
|
|
750
|
+
"id": "treeview.apg.aria-multiselectable-false-by-default",
|
|
751
|
+
"upstream": "https://www.w3.org/WAI/ARIA/apg/patterns/treeview/#wai-ariaroles,states,andproperties",
|
|
752
|
+
"upstreamTest": "If the tree does not support selection of more than one node, aria-multiselectable is false or the default value of false is implied",
|
|
753
|
+
"apg": "aria",
|
|
754
|
+
"config": {
|
|
755
|
+
"focused": true,
|
|
756
|
+
"multiSelectable": false,
|
|
757
|
+
"expanded": [],
|
|
758
|
+
"selected": [],
|
|
759
|
+
"focus": "treeitem:0"
|
|
760
|
+
},
|
|
761
|
+
"steps": [
|
|
762
|
+
{
|
|
763
|
+
"expect": { "attrs": { "tree": { "aria-multiselectable": "false" } } }
|
|
764
|
+
}
|
|
765
|
+
],
|
|
766
|
+
"notes": "APG also permits omitting the attribute (implied false); the spec derives an explicit \"false\"."
|
|
767
|
+
},
|
|
768
|
+
{
|
|
769
|
+
"id": "treeview.apg.aria-multiselectable-true",
|
|
770
|
+
"upstream": "https://www.w3.org/WAI/ARIA/apg/patterns/treeview/#wai-ariaroles,states,andproperties",
|
|
771
|
+
"upstreamTest": "If the tree supports selection of more than one node, the element with role tree has aria-multiselectable set to true",
|
|
772
|
+
"apg": "aria",
|
|
773
|
+
"config": {
|
|
774
|
+
"focused": true,
|
|
775
|
+
"multiSelectable": true,
|
|
776
|
+
"expanded": [],
|
|
777
|
+
"selected": [],
|
|
778
|
+
"focus": "treeitem:0"
|
|
779
|
+
},
|
|
780
|
+
"steps": [
|
|
781
|
+
{
|
|
782
|
+
"expect": { "attrs": { "tree": { "aria-multiselectable": "true" } } }
|
|
783
|
+
}
|
|
784
|
+
]
|
|
785
|
+
},
|
|
786
|
+
{
|
|
787
|
+
"id": "treeview.apg.roving-tabindex-exactly-one-tabbable",
|
|
788
|
+
"upstream": "https://www.w3.org/WAI/ARIA/apg/patterns/treeview/#keyboardinteraction",
|
|
789
|
+
"upstreamTest": "A tree keeps a roving tabindex: exactly one treeitem is tabbable at a time",
|
|
790
|
+
"apg": "focus",
|
|
791
|
+
"config": {
|
|
792
|
+
"focused": true,
|
|
793
|
+
"multiSelectable": false,
|
|
794
|
+
"expanded": ["0"],
|
|
795
|
+
"selected": [],
|
|
796
|
+
"focus": "treeitem:0/1"
|
|
797
|
+
},
|
|
798
|
+
"steps": [
|
|
799
|
+
{
|
|
800
|
+
"expect": {
|
|
801
|
+
"attrs": {
|
|
802
|
+
"treeitem:0": { "tabindex": "-1" },
|
|
803
|
+
"treeitem:0/0": { "tabindex": "-1" },
|
|
804
|
+
"treeitem:0/1": { "tabindex": "0" },
|
|
805
|
+
"treeitem:1": { "tabindex": "-1" }
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
]
|
|
810
|
+
},
|
|
811
|
+
{
|
|
812
|
+
"id": "treeview.apg.tree-has-accessible-label",
|
|
813
|
+
"upstream": "https://www.w3.org/WAI/ARIA/apg/patterns/treeview/#wai-ariaroles,states,andproperties",
|
|
814
|
+
"upstreamTest": "The element with role tree has either a visible label referenced by aria-labelledby or a value specified for aria-label",
|
|
815
|
+
"apg": "aria",
|
|
816
|
+
"config": {
|
|
817
|
+
"focused": true,
|
|
818
|
+
"multiSelectable": false,
|
|
819
|
+
"expanded": [],
|
|
820
|
+
"selected": [],
|
|
821
|
+
"focus": "treeitem:0",
|
|
822
|
+
"label": "File directory"
|
|
823
|
+
},
|
|
824
|
+
"steps": [
|
|
825
|
+
{
|
|
826
|
+
"expect": { "attrs": { "tree": { "aria-label": "File directory" } } }
|
|
827
|
+
}
|
|
828
|
+
]
|
|
829
|
+
},
|
|
830
|
+
{
|
|
831
|
+
"id": "treeview.apg.tree-orientation-default-vertical",
|
|
832
|
+
"upstream": "https://www.w3.org/WAI/ARIA/apg/patterns/treeview/#wai-ariaroles,states,andproperties",
|
|
833
|
+
"upstreamTest": "If the tree element is horizontally oriented it has aria-orientation set to horizontal; the default for a tree is vertical",
|
|
834
|
+
"apg": "aria",
|
|
835
|
+
"config": {
|
|
836
|
+
"focused": true,
|
|
837
|
+
"multiSelectable": false,
|
|
838
|
+
"expanded": [],
|
|
839
|
+
"selected": [],
|
|
840
|
+
"focus": "treeitem:0",
|
|
841
|
+
"orientation": "vertical"
|
|
842
|
+
},
|
|
843
|
+
"steps": [
|
|
844
|
+
{ "expect": { "attrs": { "tree": { "aria-orientation": null } } } }
|
|
845
|
+
]
|
|
846
|
+
},
|
|
847
|
+
{
|
|
848
|
+
"id": "treeview.apg.single-select-keeps-at-most-one-selected",
|
|
849
|
+
"upstream": "https://www.w3.org/WAI/ARIA/apg/patterns/treeview/examples/treeview-1b/",
|
|
850
|
+
"upstreamTest": "File Directory Treeview (single-select): no more than one node is selected at a time",
|
|
851
|
+
"apg": "keyboard",
|
|
852
|
+
"config": {
|
|
853
|
+
"focused": true,
|
|
854
|
+
"multiSelectable": false,
|
|
855
|
+
"expanded": ["0", "0/0"],
|
|
856
|
+
"selected": ["treeitem:0/0"],
|
|
857
|
+
"focus": "treeitem:0/0"
|
|
858
|
+
},
|
|
859
|
+
"steps": [
|
|
860
|
+
{ "event": "click", "target": "treeitem:0/0/1" },
|
|
861
|
+
{
|
|
862
|
+
"expect": {
|
|
863
|
+
"focus": "treeitem:0/0/1",
|
|
864
|
+
"attrs": {
|
|
865
|
+
"treeitem:0/0": { "aria-selected": "false" },
|
|
866
|
+
"treeitem:0/0/1": { "aria-selected": "true" }
|
|
867
|
+
},
|
|
868
|
+
"events": { "onSelectionChange": ["treeitem:0/0/1"] }
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
]
|
|
872
|
+
}
|
|
873
|
+
],
|
|
874
|
+
"skipped": [
|
|
875
|
+
{
|
|
876
|
+
"id": "treeview.apg.selection-follows-focus",
|
|
877
|
+
"reason": "APG optional single-select model; the treeview spec keeps selection independent of focus."
|
|
878
|
+
},
|
|
879
|
+
{
|
|
880
|
+
"id": "treeview.apg.shift-space-range-selection",
|
|
881
|
+
"reason": "Optional contiguous range selection; needs a selection anchor the spec does not model."
|
|
882
|
+
},
|
|
883
|
+
{
|
|
884
|
+
"id": "treeview.apg.ctrl-shift-home-end-range-selection",
|
|
885
|
+
"reason": "Optional range selection to the first/last node; anchor-based, out of scope."
|
|
886
|
+
},
|
|
887
|
+
{
|
|
888
|
+
"id": "treeview.apg.alternative-selection-model",
|
|
889
|
+
"reason": "APG alternative modifier-key navigation model (Control+Arrow, Control+Space); the recommended model is ported instead."
|
|
890
|
+
},
|
|
891
|
+
{
|
|
892
|
+
"id": "treeview.apg.aria-activedescendant",
|
|
893
|
+
"reason": "Focus-management alternative to moving DOM focus among treeitems; reported focus is modelled as DOM focus."
|
|
894
|
+
},
|
|
895
|
+
{
|
|
896
|
+
"id": "treeview.apg.aria-checked-selection-variant",
|
|
897
|
+
"reason": "APG permits aria-checked instead of aria-selected; the treeview spec fixes aria-selected."
|
|
898
|
+
},
|
|
899
|
+
{
|
|
900
|
+
"id": "treeview.apg.navigation-treeview-links",
|
|
901
|
+
"reason": "Navigation Treeview example adds aria-current and link semantics, outside the treeview pattern's state machine."
|
|
902
|
+
},
|
|
903
|
+
{
|
|
904
|
+
"id": "treeview.apg.dynamic-lazy-loading",
|
|
905
|
+
"reason": "Virtualization, dynamic loading and scrolling are rendering concerns with no key/state behaviour to replay."
|
|
906
|
+
},
|
|
907
|
+
{
|
|
908
|
+
"id": "treeview.apg.aria-owns-group-wrappers",
|
|
909
|
+
"reason": "ARIA group wrappers and aria-owns re-ordering are DOM-structure details, not keyboard/state behaviour."
|
|
910
|
+
},
|
|
911
|
+
{
|
|
912
|
+
"id": "treeview.apg.horizontal-orientation",
|
|
913
|
+
"reason": "Horizontally oriented tree (arrow keys swap); the spec is vertical-only."
|
|
914
|
+
},
|
|
915
|
+
{
|
|
916
|
+
"id": "treeview.apg.drag-and-drop",
|
|
917
|
+
"reason": "Drag and drop is not part of the APG treeview pattern."
|
|
918
|
+
},
|
|
919
|
+
{
|
|
920
|
+
"id": "treeview.apg.styling-and-snapshots",
|
|
921
|
+
"reason": "Styling, snapshots and visual states are out of scope per the scenarios README."
|
|
922
|
+
},
|
|
923
|
+
{
|
|
924
|
+
"id": "treeview.apg.react-api-only",
|
|
925
|
+
"reason": "React-only props, render props, refs and component composition are not library-neutral behaviour."
|
|
926
|
+
}
|
|
927
|
+
]
|
|
928
|
+
}
|