@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.
Files changed (260) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +65 -2
  3. package/dist/apg/accordion.bridge.d.mts +35 -0
  4. package/dist/apg/accordion.bridge.mjs +326 -0
  5. package/dist/apg/accordion.model.json +8397 -0
  6. package/dist/apg/alert.bridge.d.mts +22 -0
  7. package/dist/apg/alert.bridge.mjs +86 -0
  8. package/dist/apg/alert.model.json +871 -0
  9. package/dist/apg/alertdialog.bridge.d.mts +21 -0
  10. package/dist/apg/alertdialog.bridge.mjs +221 -0
  11. package/dist/apg/alertdialog.model.json +5232 -0
  12. package/dist/apg/breadcrumb.bridge.d.mts +26 -0
  13. package/dist/apg/breadcrumb.bridge.mjs +120 -0
  14. package/dist/apg/breadcrumb.model.json +574 -0
  15. package/dist/apg/button.bridge.d.mts +35 -0
  16. package/dist/apg/button.bridge.mjs +208 -0
  17. package/dist/apg/button.model.json +5814 -0
  18. package/dist/apg/carousel.bridge.d.mts +44 -0
  19. package/dist/apg/carousel.bridge.mjs +262 -0
  20. package/dist/apg/carousel.model.json +8963 -0
  21. package/dist/apg/checkbox-group.bridge.d.mts +25 -0
  22. package/dist/apg/checkbox-group.bridge.mjs +276 -0
  23. package/dist/apg/checkbox-group.model.json +3863 -0
  24. package/dist/apg/checkbox.bridge.d.mts +34 -0
  25. package/dist/apg/checkbox.bridge.mjs +253 -0
  26. package/dist/apg/checkbox.model.json +3158 -0
  27. package/dist/apg/combobox-autocomplete.bridge.d.mts +14 -0
  28. package/dist/apg/combobox-autocomplete.bridge.mjs +326 -0
  29. package/dist/apg/combobox-autocomplete.model.json +11586 -0
  30. package/dist/apg/combobox-dialog.bridge.d.mts +17 -0
  31. package/dist/apg/combobox-dialog.bridge.mjs +250 -0
  32. package/dist/apg/combobox-dialog.model.json +8981 -0
  33. package/dist/apg/combobox-grid.bridge.d.mts +17 -0
  34. package/dist/apg/combobox-grid.bridge.mjs +227 -0
  35. package/dist/apg/combobox-grid.model.json +8554 -0
  36. package/dist/apg/combobox-select-only.bridge.d.mts +24 -0
  37. package/dist/apg/combobox-select-only.bridge.mjs +304 -0
  38. package/dist/apg/combobox-select-only.model.json +7846 -0
  39. package/dist/apg/combobox-tree.bridge.d.mts +17 -0
  40. package/dist/apg/combobox-tree.bridge.mjs +211 -0
  41. package/dist/apg/combobox-tree.model.json +9345 -0
  42. package/dist/apg/dialog-modal.bridge.d.mts +35 -0
  43. package/dist/apg/dialog-modal.bridge.mjs +186 -0
  44. package/dist/apg/dialog-modal.model.json +7580 -0
  45. package/dist/apg/disclosure.bridge.d.mts +25 -0
  46. package/dist/apg/disclosure.bridge.mjs +202 -0
  47. package/dist/apg/disclosure.model.json +4703 -0
  48. package/dist/apg/feed.bridge.d.mts +31 -0
  49. package/dist/apg/feed.bridge.mjs +246 -0
  50. package/dist/apg/feed.model.json +4523 -0
  51. package/dist/apg/grid-selection.bridge.d.mts +13 -0
  52. package/dist/apg/grid-selection.bridge.mjs +160 -0
  53. package/dist/apg/grid-selection.model.json +6974 -0
  54. package/dist/apg/grid-sort.bridge.d.mts +12 -0
  55. package/dist/apg/grid-sort.bridge.mjs +138 -0
  56. package/dist/apg/grid-sort.model.json +3799 -0
  57. package/dist/apg/grid.bridge.d.mts +54 -0
  58. package/dist/apg/grid.bridge.mjs +441 -0
  59. package/dist/apg/grid.model.json +3802 -0
  60. package/dist/apg/link.bridge.d.mts +24 -0
  61. package/dist/apg/link.bridge.mjs +126 -0
  62. package/dist/apg/link.model.json +694 -0
  63. package/dist/apg/listbox-multi.bridge.d.mts +10 -0
  64. package/dist/apg/listbox-multi.bridge.mjs +261 -0
  65. package/dist/apg/listbox-multi.model.json +10893 -0
  66. package/dist/apg/listbox-rearrangeable.bridge.d.mts +20 -0
  67. package/dist/apg/listbox-rearrangeable.bridge.mjs +237 -0
  68. package/dist/apg/listbox-rearrangeable.model.json +17592 -0
  69. package/dist/apg/listbox-shared.d.mts +58 -0
  70. package/dist/apg/listbox-shared.mjs +171 -0
  71. package/dist/apg/listbox-single.bridge.d.mts +10 -0
  72. package/dist/apg/listbox-single.bridge.mjs +196 -0
  73. package/dist/apg/listbox-single.model.json +8024 -0
  74. package/dist/apg/listbox-typeahead.bridge.d.mts +10 -0
  75. package/dist/apg/listbox-typeahead.bridge.mjs +153 -0
  76. package/dist/apg/listbox-typeahead.model.json +5615 -0
  77. package/dist/apg/menu-button.bridge.d.mts +29 -0
  78. package/dist/apg/menu-button.bridge.mjs +259 -0
  79. package/dist/apg/menu-button.model.json +5706 -0
  80. package/dist/apg/menu-checkable.bridge.d.mts +25 -0
  81. package/dist/apg/menu-checkable.bridge.mjs +226 -0
  82. package/dist/apg/menu-checkable.model.json +4277 -0
  83. package/dist/apg/menu-menubar.bridge.d.mts +27 -0
  84. package/dist/apg/menu-menubar.bridge.mjs +273 -0
  85. package/dist/apg/menu-menubar.model.json +9540 -0
  86. package/dist/apg/meter.bridge.d.mts +28 -0
  87. package/dist/apg/meter.bridge.mjs +159 -0
  88. package/dist/apg/meter.model.json +1185 -0
  89. package/dist/apg/player.bridge.d.mts +24 -0
  90. package/dist/apg/player.bridge.mjs +342 -0
  91. package/dist/apg/player.model.json +11013 -0
  92. package/dist/apg/radio.bridge.d.mts +35 -0
  93. package/dist/apg/radio.bridge.mjs +371 -0
  94. package/dist/apg/radio.model.json +5011 -0
  95. package/dist/apg/slider-multithumb.bridge.d.mts +34 -0
  96. package/dist/apg/slider-multithumb.bridge.mjs +365 -0
  97. package/dist/apg/slider-multithumb.model.json +5774 -0
  98. package/dist/apg/slider.bridge.d.mts +54 -0
  99. package/dist/apg/slider.bridge.mjs +359 -0
  100. package/dist/apg/slider.model.json +4881 -0
  101. package/dist/apg/spinbutton.bridge.d.mts +41 -0
  102. package/dist/apg/spinbutton.bridge.mjs +327 -0
  103. package/dist/apg/spinbutton.model.json +7571 -0
  104. package/dist/apg/switch.bridge.d.mts +30 -0
  105. package/dist/apg/switch.bridge.mjs +243 -0
  106. package/dist/apg/switch.model.json +3159 -0
  107. package/dist/apg/tabs.bridge.d.mts +41 -0
  108. package/dist/apg/tabs.bridge.mjs +294 -0
  109. package/dist/apg/tabs.model.json +7659 -0
  110. package/dist/apg/timeline.bridge.d.mts +36 -0
  111. package/dist/apg/timeline.bridge.mjs +265 -0
  112. package/dist/apg/timeline.model.json +6189 -0
  113. package/dist/apg/toolbar.bridge.d.mts +25 -0
  114. package/dist/apg/toolbar.bridge.mjs +307 -0
  115. package/dist/apg/toolbar.model.json +6616 -0
  116. package/dist/apg/tooltip.bridge.d.mts +36 -0
  117. package/dist/apg/tooltip.bridge.mjs +208 -0
  118. package/dist/apg/tooltip.model.json +8295 -0
  119. package/dist/apg/treegrid.bridge.d.mts +28 -0
  120. package/dist/apg/treegrid.bridge.mjs +311 -0
  121. package/dist/apg/treegrid.model.json +17358 -0
  122. package/dist/apg/treeview.bridge.d.mts +26 -0
  123. package/dist/apg/treeview.bridge.mjs +396 -0
  124. package/dist/apg/treeview.model.json +13745 -0
  125. package/dist/apg/windowsplitter.bridge.d.mts +36 -0
  126. package/dist/apg/windowsplitter.bridge.mjs +242 -0
  127. package/dist/apg/windowsplitter.model.json +6253 -0
  128. package/dist/canvas/camera.model.json +6568 -0
  129. package/dist/canvas/canvas.bridge.d.mts +190 -0
  130. package/dist/canvas/canvas.bridge.mjs +729 -0
  131. package/dist/canvas/pointer.model.json +17095 -0
  132. package/dist/scenario.d.mts +233 -0
  133. package/dist/scenario.mjs +313 -0
  134. package/package.json +57 -4
  135. package/scenarios/apg/README.md +221 -0
  136. package/scenarios/apg/accordion.base-ui.json +1005 -0
  137. package/scenarios/apg/accordion.react-aria.json +929 -0
  138. package/scenarios/apg/alert.base-ui.json +81 -0
  139. package/scenarios/apg/alert.react-aria.json +98 -0
  140. package/scenarios/apg/alertdialog.base-ui.json +331 -0
  141. package/scenarios/apg/alertdialog.react-aria.json +225 -0
  142. package/scenarios/apg/breadcrumb.react-aria.json +312 -0
  143. package/scenarios/apg/button.ariakit.json +136 -0
  144. package/scenarios/apg/button.base-ui.json +747 -0
  145. package/scenarios/apg/button.react-aria.json +443 -0
  146. package/scenarios/apg/carousel.apg.json +909 -0
  147. package/scenarios/apg/checkbox.ariakit.json +299 -0
  148. package/scenarios/apg/checkbox.base-ui.json +1126 -0
  149. package/scenarios/apg/checkbox.react-aria.json +518 -0
  150. package/scenarios/apg/combobox.ariakit.json +945 -0
  151. package/scenarios/apg/combobox.base-ui.json +2444 -0
  152. package/scenarios/apg/combobox.react-aria.json +845 -0
  153. package/scenarios/apg/dialog-modal.ariakit.json +1102 -0
  154. package/scenarios/apg/dialog-modal.base-ui.json +775 -0
  155. package/scenarios/apg/dialog-modal.react-aria.json +638 -0
  156. package/scenarios/apg/disclosure.apg.json +349 -0
  157. package/scenarios/apg/disclosure.ariakit.json +163 -0
  158. package/scenarios/apg/disclosure.base-ui.json +451 -0
  159. package/scenarios/apg/disclosure.react-aria.json +643 -0
  160. package/scenarios/apg/feed.apg.json +442 -0
  161. package/scenarios/apg/grid.ariakit.json +197 -0
  162. package/scenarios/apg/grid.base-ui.json +720 -0
  163. package/scenarios/apg/grid.react-aria.json +969 -0
  164. package/scenarios/apg/landmarks.ariakit.json +93 -0
  165. package/scenarios/apg/landmarks.react-aria.json +330 -0
  166. package/scenarios/apg/link.ariakit.json +83 -0
  167. package/scenarios/apg/link.base-ui.json +88 -0
  168. package/scenarios/apg/link.react-aria.json +186 -0
  169. package/scenarios/apg/listbox.ariakit.json +78 -0
  170. package/scenarios/apg/listbox.base-ui.json +163 -0
  171. package/scenarios/apg/listbox.react-aria.json +1118 -0
  172. package/scenarios/apg/menu-button.ariakit.json +924 -0
  173. package/scenarios/apg/menu-button.base-ui.json +1155 -0
  174. package/scenarios/apg/menu-button.react-aria.json +1080 -0
  175. package/scenarios/apg/menubar.ariakit.json +758 -0
  176. package/scenarios/apg/menubar.base-ui.json +673 -0
  177. package/scenarios/apg/meter.base-ui.json +243 -0
  178. package/scenarios/apg/meter.react-aria.json +201 -0
  179. package/scenarios/apg/radio.ariakit.json +459 -0
  180. package/scenarios/apg/radio.base-ui.json +581 -0
  181. package/scenarios/apg/radio.react-aria.json +576 -0
  182. package/scenarios/apg/slider-multithumb.base-ui.json +316 -0
  183. package/scenarios/apg/slider-multithumb.react-aria.json +363 -0
  184. package/scenarios/apg/slider.base-ui.json +544 -0
  185. package/scenarios/apg/slider.react-aria.json +456 -0
  186. package/scenarios/apg/spinbutton.base-ui.json +1688 -0
  187. package/scenarios/apg/spinbutton.react-aria.json +426 -0
  188. package/scenarios/apg/switch.base-ui.json +456 -0
  189. package/scenarios/apg/switch.react-aria.json +303 -0
  190. package/scenarios/apg/table.ariakit.json +65 -0
  191. package/scenarios/apg/table.react-aria.json +221 -0
  192. package/scenarios/apg/tabs.ariakit.json +329 -0
  193. package/scenarios/apg/tabs.base-ui.json +875 -0
  194. package/scenarios/apg/tabs.react-aria.json +644 -0
  195. package/scenarios/apg/toolbar.ariakit.json +595 -0
  196. package/scenarios/apg/toolbar.base-ui.json +1189 -0
  197. package/scenarios/apg/toolbar.react-aria.json +383 -0
  198. package/scenarios/apg/tooltip.ariakit.json +441 -0
  199. package/scenarios/apg/tooltip.base-ui.json +411 -0
  200. package/scenarios/apg/tooltip.react-aria.json +454 -0
  201. package/scenarios/apg/treegrid.apg.json +2558 -0
  202. package/scenarios/apg/treegrid.react-aria.json +5094 -0
  203. package/scenarios/apg/treeview.apg.json +928 -0
  204. package/scenarios/apg/windowsplitter.apg.json +557 -0
  205. package/scenarios/canvas/README.md +69 -0
  206. package/scenarios/canvas/camera.contract.json +237 -0
  207. package/scenarios/canvas/camera.excalidraw.json +57 -0
  208. package/scenarios/canvas/marquee.excalidraw.json +122 -0
  209. package/scenarios/canvas/pan.excalidraw.json +46 -0
  210. package/scenarios/canvas/pointer.contract.json +528 -0
  211. package/scenarios/parts.json +291 -0
  212. package/shared/aria.qnt +186 -0
  213. package/shared/details-group.qnt +50 -0
  214. package/shared/focusgroup.qnt +152 -0
  215. package/shared/invokers.qnt +81 -0
  216. package/shared/popover.qnt +71 -0
  217. package/specs/apg/STATIC.md +103 -0
  218. package/specs/apg/accordion.qnt +578 -0
  219. package/specs/apg/alert.qnt +131 -0
  220. package/specs/apg/alertdialog.qnt +455 -0
  221. package/specs/apg/breadcrumb.qnt +88 -0
  222. package/specs/apg/button.qnt +445 -0
  223. package/specs/apg/carousel.qnt +732 -0
  224. package/specs/apg/checkbox-group.qnt +388 -0
  225. package/specs/apg/checkbox.qnt +394 -0
  226. package/specs/apg/combobox-autocomplete.qnt +764 -0
  227. package/specs/apg/combobox-dialog.qnt +627 -0
  228. package/specs/apg/combobox-grid.qnt +632 -0
  229. package/specs/apg/combobox-select-only.qnt +626 -0
  230. package/specs/apg/combobox-tree.qnt +633 -0
  231. package/specs/apg/dialog-modal.qnt +499 -0
  232. package/specs/apg/disclosure.qnt +309 -0
  233. package/specs/apg/feed.qnt +485 -0
  234. package/specs/apg/grid-selection.qnt +512 -0
  235. package/specs/apg/grid-sort.qnt +330 -0
  236. package/specs/apg/grid.qnt +360 -0
  237. package/specs/apg/link.qnt +119 -0
  238. package/specs/apg/listbox-multi.qnt +799 -0
  239. package/specs/apg/listbox-rearrangeable.qnt +801 -0
  240. package/specs/apg/listbox-single.qnt +511 -0
  241. package/specs/apg/listbox-typeahead.qnt +396 -0
  242. package/specs/apg/menu-button.qnt +363 -0
  243. package/specs/apg/menu-checkable.qnt +304 -0
  244. package/specs/apg/menu-menubar.qnt +531 -0
  245. package/specs/apg/meter.qnt +129 -0
  246. package/specs/apg/player.qnt +1081 -0
  247. package/specs/apg/radio.qnt +394 -0
  248. package/specs/apg/slider-multithumb.qnt +441 -0
  249. package/specs/apg/slider.qnt +396 -0
  250. package/specs/apg/spinbutton.qnt +494 -0
  251. package/specs/apg/switch.qnt +389 -0
  252. package/specs/apg/tabs.qnt +412 -0
  253. package/specs/apg/timeline.qnt +612 -0
  254. package/specs/apg/toolbar.qnt +364 -0
  255. package/specs/apg/tooltip.qnt +553 -0
  256. package/specs/apg/treegrid.qnt +983 -0
  257. package/specs/apg/treeview.qnt +1004 -0
  258. package/specs/apg/windowsplitter.qnt +487 -0
  259. package/specs/canvas/camera.qnt +407 -0
  260. package/specs/canvas/pointer.qnt +841 -0
@@ -0,0 +1,1189 @@
1
+ {
2
+ "pattern": "toolbar",
3
+ "source": "base-ui",
4
+ "commit": "19511bb171f3b360b006c94cf6d07e53cb446505",
5
+ "license": "MIT",
6
+ "skipped": [
7
+ {
8
+ "reason": "ToolbarRoot context 'allows optional consumers both outside and inside a toolbar' - React context API"
9
+ },
10
+ {
11
+ "reason": "CompositeRoot grid scenarios (uniform 1x1, onLoop across cells, dense packing, spanning items, RTL grid, 'prevents default for grid navigation') - 2D grid model, not the toolbar roving model"
12
+ },
13
+ {
14
+ "reason": "CompositeRoot 'uses an active item explicit index as the initial highlighted index' - store internals"
15
+ },
16
+ {
17
+ "reason": "CompositeRoot 'keeps native input behavior when the native target differs from the synthetic target' - synthetic composedPath internals"
18
+ },
19
+ {
20
+ "reason": "CompositeRoot nested registration-order scenarios ('keeps the outer registration when only the inner item updates') - store lifecycle"
21
+ },
22
+ {
23
+ "reason": "ToggleGroup warning/styling tests ('should warn if Toggle value is not set', 'sets data-multiple only when true', pressed-state CSS attrs) - implementation/styling"
24
+ },
25
+ {
26
+ "reason": "ToolbarButton / Toolbar.Input describeConformance and render-prop conformance - React API only"
27
+ },
28
+ {
29
+ "reason": "Toolbar.Button with Switch/Menu/Select/Dialog/AlertDialog/Popover trigger rendering - composition render tests, not keyboard model (the arrow consumptions that matter are captured separately)"
30
+ },
31
+ {
32
+ "reason": "ToolbarInput NumberField 'renders NumberField.Input' - render assertion"
33
+ }
34
+ ],
35
+ "scenarios": [
36
+ {
37
+ "id": "toolbar.base-ui.role-toolbar",
38
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/toolbar/root/ToolbarRoot.test.tsx#L19",
39
+ "upstreamTest": "<Toolbar.Root /> > ARIA attributes > has role=\"toolbar\"",
40
+ "apg": "aria",
41
+ "config": { "items": 0 },
42
+ "steps": [{ "expect": { "attrs": { "toolbar": { "role": "toolbar" } } } }]
43
+ },
44
+ {
45
+ "id": "toolbar.base-ui.arrow-ltr-horizontal-loop",
46
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/toolbar/root/ToolbarRoot.test.tsx#L57",
47
+ "upstreamTest": "<Toolbar.Root /> > keyboard navigation > ltr > orientation: horizontal",
48
+ "apg": "keyboard",
49
+ "config": {
50
+ "direction": "ltr",
51
+ "orientation": "horizontal",
52
+ "loopFocus": true,
53
+ "items": ["button", "link", "group:button:button", "textbox"]
54
+ },
55
+ "steps": [
56
+ { "event": "key", "key": "Tab", "target": "toolbar" },
57
+ { "expect": { "focus": "item:0" } },
58
+ { "event": "key", "key": "ArrowRight", "target": "item:0" },
59
+ { "expect": { "focus": "item:1" } },
60
+ { "event": "key", "key": "ArrowRight", "target": "item:1" },
61
+ { "expect": { "focus": "item:2" } },
62
+ { "event": "key", "key": "ArrowRight", "target": "item:2" },
63
+ { "expect": { "focus": "item:3" } },
64
+ { "event": "key", "key": "ArrowRight", "target": "item:3" },
65
+ { "expect": { "focus": "item:4" } },
66
+ { "event": "key", "key": "ArrowRight", "target": "item:4" },
67
+ { "expect": { "focus": "item:0" } },
68
+ { "event": "key", "key": "ArrowLeft", "target": "item:0" },
69
+ { "expect": { "focus": "item:4" } },
70
+ { "event": "key", "key": "ArrowLeft", "target": "item:4" },
71
+ { "expect": { "focus": "item:3" } }
72
+ ],
73
+ "notes": "Loop wraps both directions; navigation crosses into nested Toolbar.Group items (flat index order)."
74
+ },
75
+ {
76
+ "id": "toolbar.base-ui.arrow-ltr-vertical-loop",
77
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/toolbar/root/ToolbarRoot.test.tsx#L57",
78
+ "upstreamTest": "<Toolbar.Root /> > keyboard navigation > ltr > orientation: vertical",
79
+ "apg": "keyboard",
80
+ "config": {
81
+ "direction": "ltr",
82
+ "orientation": "vertical",
83
+ "loopFocus": true,
84
+ "items": ["button", "link", "group:button:button", "textbox"]
85
+ },
86
+ "steps": [
87
+ { "event": "key", "key": "Tab", "target": "toolbar" },
88
+ { "event": "key", "key": "ArrowDown", "target": "item:0" },
89
+ { "expect": { "focus": "item:1" } },
90
+ { "event": "key", "key": "ArrowDown", "target": "item:1" },
91
+ { "expect": { "focus": "item:2" } },
92
+ { "event": "key", "key": "ArrowDown", "target": "item:2" },
93
+ { "expect": { "focus": "item:3" } },
94
+ { "event": "key", "key": "ArrowDown", "target": "item:3" },
95
+ { "expect": { "focus": "item:4" } },
96
+ { "event": "key", "key": "ArrowDown", "target": "item:4" },
97
+ { "expect": { "focus": "item:0" } },
98
+ { "event": "key", "key": "ArrowUp", "target": "item:0" },
99
+ { "expect": { "focus": "item:4" } }
100
+ ]
101
+ },
102
+ {
103
+ "id": "toolbar.base-ui.arrow-rtl-horizontal-loop",
104
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/toolbar/root/ToolbarRoot.test.tsx#L51",
105
+ "upstreamTest": "<Toolbar.Root /> > keyboard navigation > rtl > orientation: horizontal",
106
+ "apg": "keyboard",
107
+ "config": {
108
+ "direction": "rtl",
109
+ "orientation": "horizontal",
110
+ "loopFocus": true,
111
+ "items": ["button", "link", "group:button:button", "textbox"]
112
+ },
113
+ "steps": [
114
+ { "event": "key", "key": "Tab", "target": "toolbar" },
115
+ { "event": "key", "key": "ArrowLeft", "target": "item:0" },
116
+ { "expect": { "focus": "item:1" } },
117
+ { "event": "key", "key": "ArrowLeft", "target": "item:1" },
118
+ { "expect": { "focus": "item:2" } }
119
+ ],
120
+ "notes": "RTL flips next/prev to ArrowLeft/ArrowRight."
121
+ },
122
+ {
123
+ "id": "toolbar.base-ui.arrow-rtl-vertical-loop",
124
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/toolbar/root/ToolbarRoot.test.tsx#L51",
125
+ "upstreamTest": "<Toolbar.Root /> > keyboard navigation > rtl > orientation: vertical",
126
+ "apg": "keyboard",
127
+ "config": {
128
+ "direction": "rtl",
129
+ "orientation": "vertical",
130
+ "loopFocus": true,
131
+ "items": ["button", "link", "group:button:button", "textbox"]
132
+ },
133
+ "steps": [
134
+ { "event": "key", "key": "Tab", "target": "toolbar" },
135
+ { "event": "key", "key": "ArrowDown", "target": "item:0" },
136
+ { "expect": { "focus": "item:1" } },
137
+ { "event": "key", "key": "ArrowUp", "target": "item:1" },
138
+ { "expect": { "focus": "item:0" } }
139
+ ],
140
+ "notes": "RTL leaves the vertical axis unchanged."
141
+ },
142
+ {
143
+ "id": "toolbar.base-ui.loop-focus-false-no-wrap",
144
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/toolbar/root/ToolbarRoot.test.tsx#L103",
145
+ "upstreamTest": "<Toolbar.Root /> > keyboard navigation > does not wrap focus when loopFocus is false",
146
+ "apg": "keyboard",
147
+ "config": { "orientation": "horizontal", "loopFocus": false, "items": 2 },
148
+ "steps": [
149
+ { "event": "key", "key": "Tab", "target": "toolbar" },
150
+ { "expect": { "focus": "item:0" } },
151
+ { "event": "key", "key": "ArrowLeft", "target": "item:0" },
152
+ { "expect": { "focus": "item:0" } },
153
+ { "event": "key", "key": "ArrowRight", "target": "item:0" },
154
+ { "expect": { "focus": "item:1" } },
155
+ { "event": "key", "key": "ArrowRight", "target": "item:1" },
156
+ { "expect": { "focus": "item:1" } }
157
+ ]
158
+ },
159
+ {
160
+ "id": "toolbar.base-ui.disabled-root-except-links",
161
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/toolbar/root/ToolbarRoot.test.tsx#L128",
162
+ "upstreamTest": "<Toolbar.Root /> > prop: disabled > disables all toolbar items except links",
163
+ "apg": "aria",
164
+ "config": {
165
+ "disabled": true,
166
+ "items": ["button", "link", "textbox", "group:button:link:textbox"]
167
+ },
168
+ "steps": [
169
+ {
170
+ "expect": {
171
+ "attrs": {
172
+ "item:0": { "aria-disabled": "true", "data-disabled": "" },
173
+ "item:1": { "aria-disabled": null, "data-disabled": null },
174
+ "item:2": { "aria-disabled": "true", "data-disabled": "" },
175
+ "item:3": { "aria-disabled": "true", "data-disabled": "" },
176
+ "item:4": { "aria-disabled": null, "data-disabled": null },
177
+ "item:5": { "aria-disabled": "true", "data-disabled": "" }
178
+ }
179
+ }
180
+ }
181
+ ],
182
+ "notes": "Links opt out of toolbar disabling."
183
+ },
184
+ {
185
+ "id": "toolbar.base-ui.focusable-when-disabled-default",
186
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/toolbar/root/ToolbarRoot.test.tsx#L165",
187
+ "upstreamTest": "<Toolbar.Root /> > prop: focusableWhenDisabled > toolbar items can be focused when disabled by default",
188
+ "apg": "keyboard",
189
+ "config": {
190
+ "orientation": "horizontal",
191
+ "items": [
192
+ "button:disabled",
193
+ "group:button:disabled,button:disabled",
194
+ "textbox:disabled"
195
+ ]
196
+ },
197
+ "steps": [
198
+ {
199
+ "expect": {
200
+ "attrs": {
201
+ "item:0": {
202
+ "disabled": null,
203
+ "data-disabled": "",
204
+ "aria-disabled": "true"
205
+ },
206
+ "item:1": { "disabled": null },
207
+ "item:2": { "disabled": null },
208
+ "item:3": { "disabled": null }
209
+ }
210
+ }
211
+ },
212
+ { "event": "key", "key": "Tab", "target": "toolbar" },
213
+ { "expect": { "focus": "item:0" } },
214
+ { "event": "key", "key": "ArrowRight", "target": "item:0" },
215
+ {
216
+ "expect": {
217
+ "focus": "item:1",
218
+ "attrs": {
219
+ "item:1": { "data-disabled": "", "aria-disabled": "true" }
220
+ }
221
+ }
222
+ },
223
+ { "event": "key", "key": "ArrowRight", "target": "item:1" },
224
+ { "expect": { "focus": "item:2" } },
225
+ { "event": "key", "key": "ArrowRight", "target": "item:2" },
226
+ { "expect": { "focus": "item:3" } },
227
+ { "event": "key", "key": "ArrowRight", "target": "item:3" },
228
+ {
229
+ "expect": {
230
+ "focus": "item:0",
231
+ "attrs": { "item:0": { "tabindex": "0" } }
232
+ }
233
+ },
234
+ { "event": "key", "key": "ArrowLeft", "target": "item:0" },
235
+ { "expect": { "focus": "item:3" } }
236
+ ],
237
+ "notes": "Disabled items stay in the roving order because they are focusable (aria-disabled, no disabled attribute)."
238
+ },
239
+ {
240
+ "id": "toolbar.base-ui.focusable-when-disabled-individual-false",
241
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/toolbar/root/ToolbarRoot.test.tsx#L208",
242
+ "upstreamTest": "<Toolbar.Root /> > prop: focusableWhenDisabled > toolbar items can individually disable focusableWhenDisabled",
243
+ "apg": "keyboard",
244
+ "config": {
245
+ "orientation": "horizontal",
246
+ "items": [
247
+ "button:disabled",
248
+ "group:button:disabled,button:disabled-focusable=false",
249
+ "textbox:disabled"
250
+ ]
251
+ },
252
+ "steps": [
253
+ { "expect": { "attrs": { "item:2": { "disabled": "" } } } },
254
+ { "event": "key", "key": "Tab", "target": "toolbar" },
255
+ { "expect": { "focus": "item:0" } },
256
+ { "event": "key", "key": "ArrowRight", "target": "item:0" },
257
+ { "expect": { "focus": "item:1" } },
258
+ { "event": "key", "key": "ArrowRight", "target": "item:1" },
259
+ { "expect": { "focus": "item:3" } },
260
+ { "event": "key", "key": "ArrowRight", "target": "item:3" },
261
+ { "expect": { "focus": "item:0" } },
262
+ { "event": "key", "key": "ArrowLeft", "target": "item:0" },
263
+ { "expect": { "focus": "item:3" } },
264
+ { "event": "key", "key": "ArrowLeft", "target": "item:3" },
265
+ { "expect": { "focus": "item:1" } }
266
+ ]
267
+ },
268
+ {
269
+ "id": "toolbar.base-ui.initial-tab-stop-skips-nonfocusable-disabled",
270
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/toolbar/root/ToolbarRoot.test.tsx#L252",
271
+ "upstreamTest": "<Toolbar.Root /> > prop: focusableWhenDisabled > moves the initial tab stop off a disabled, non-focusable first item",
272
+ "apg": "keyboard",
273
+ "config": {
274
+ "orientation": "horizontal",
275
+ "items": ["button:disabled-focusable=false", "button", "button"]
276
+ },
277
+ "steps": [
278
+ {
279
+ "expect": {
280
+ "attrs": {
281
+ "item:0": { "disabled": "", "tabindex": null },
282
+ "item:1": { "tabindex": "0" }
283
+ }
284
+ }
285
+ },
286
+ { "event": "key", "key": "Tab", "target": "toolbar" },
287
+ { "expect": { "focus": "item:1" } },
288
+ { "event": "key", "key": "ArrowRight", "target": "item:1" },
289
+ { "expect": { "focus": "item:2" } },
290
+ { "event": "key", "key": "ArrowRight", "target": "item:2" },
291
+ { "expect": { "focus": "item:1" } }
292
+ ],
293
+ "notes": "A natively disabled item cannot hold the roving tab stop; looping back skips it."
294
+ },
295
+ {
296
+ "id": "toolbar.base-ui.enabled-item-nonfocusable-disabled-navigable",
297
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/toolbar/root/ToolbarRoot.test.tsx#L278",
298
+ "upstreamTest": "<Toolbar.Root /> > prop: focusableWhenDisabled > keeps an enabled item with focusableWhenDisabled={false} navigable",
299
+ "apg": "keyboard",
300
+ "config": {
301
+ "orientation": "horizontal",
302
+ "items": ["button", "button", "button"]
303
+ },
304
+ "steps": [
305
+ { "event": "key", "key": "Tab", "target": "toolbar" },
306
+ { "expect": { "focus": "item:0" } },
307
+ { "event": "key", "key": "ArrowRight", "target": "item:0" },
308
+ {
309
+ "expect": {
310
+ "focus": "item:1",
311
+ "attrs": { "item:1": { "disabled": null } }
312
+ }
313
+ },
314
+ { "event": "key", "key": "ArrowRight", "target": "item:1" },
315
+ { "expect": { "focus": "item:2" } }
316
+ ]
317
+ },
318
+ {
319
+ "id": "toolbar.base-ui.skips-disabled-input-nonfocusable",
320
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/toolbar/root/ToolbarRoot.test.tsx#L300",
321
+ "upstreamTest": "<Toolbar.Root /> > prop: focusableWhenDisabled > skips a disabled Toolbar.Input with focusableWhenDisabled={false}",
322
+ "apg": "keyboard",
323
+ "config": {
324
+ "orientation": "horizontal",
325
+ "items": ["button", "textbox:disabled-focusable=false", "button"]
326
+ },
327
+ "steps": [
328
+ { "event": "key", "key": "Tab", "target": "toolbar" },
329
+ { "expect": { "focus": "item:0" } },
330
+ { "event": "key", "key": "ArrowRight", "target": "item:0" },
331
+ { "expect": { "focus": "item:2" } }
332
+ ],
333
+ "notes": "Nested disabled input is skipped by roving focus."
334
+ },
335
+ {
336
+ "id": "toolbar.base-ui.toggle-group-arrow-horizontal",
337
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/toggle-group/ToggleGroup.test.tsx#L380",
338
+ "upstreamTest": "<ToggleGroup /> > keyboard interactions > ltr > orientation: horizontal",
339
+ "apg": "keyboard",
340
+ "config": { "direction": "ltr", "orientation": "horizontal", "items": 3 },
341
+ "steps": [
342
+ { "event": "key", "key": "Tab", "target": "toolbar" },
343
+ {
344
+ "expect": {
345
+ "focus": "item:0",
346
+ "attrs": { "item:0": { "tabindex": "0" } }
347
+ }
348
+ },
349
+ { "event": "key", "key": "ArrowRight", "target": "item:0" },
350
+ {
351
+ "expect": {
352
+ "focus": "item:1",
353
+ "attrs": { "item:1": { "tabindex": "0" } }
354
+ }
355
+ },
356
+ { "event": "key", "key": "ArrowRight", "target": "item:1" },
357
+ {
358
+ "expect": {
359
+ "focus": "item:2",
360
+ "attrs": { "item:2": { "tabindex": "0" } }
361
+ }
362
+ },
363
+ { "event": "key", "key": "ArrowRight", "target": "item:2" },
364
+ {
365
+ "expect": {
366
+ "focus": "item:0",
367
+ "attrs": { "item:0": { "tabindex": "0" } }
368
+ }
369
+ },
370
+ { "event": "key", "key": "ArrowLeft", "target": "item:0" },
371
+ { "expect": { "focus": "item:2" } },
372
+ { "event": "key", "key": "ArrowLeft", "target": "item:2" },
373
+ { "expect": { "focus": "item:1" } },
374
+ { "event": "key", "key": "ArrowDown", "target": "item:1" },
375
+ {
376
+ "expect": {
377
+ "focus": "item:1",
378
+ "attrs": { "item:1": { "tabindex": "0" } }
379
+ }
380
+ },
381
+ { "event": "key", "key": "ArrowUp", "target": "item:1" },
382
+ { "expect": { "focus": "item:1" } }
383
+ ],
384
+ "notes": "Toggles use the same roving-tabindex model as toolbar; the orthogonal axis is ignored. Extension: APG toolbar does not define toggle groups."
385
+ },
386
+ {
387
+ "id": "toolbar.base-ui.toggle-group-arrow-vertical",
388
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/toggle-group/ToggleGroup.test.tsx#L373",
389
+ "upstreamTest": "<ToggleGroup /> > keyboard interactions > ltr > orientation: vertical",
390
+ "apg": "keyboard",
391
+ "config": { "direction": "ltr", "orientation": "vertical", "items": 3 },
392
+ "steps": [
393
+ { "event": "key", "key": "Tab", "target": "toolbar" },
394
+ { "expect": { "focus": "item:0" } },
395
+ { "event": "key", "key": "ArrowDown", "target": "item:0" },
396
+ { "expect": { "focus": "item:1" } },
397
+ { "event": "key", "key": "ArrowDown", "target": "item:1" },
398
+ { "expect": { "focus": "item:2" } },
399
+ { "event": "key", "key": "ArrowDown", "target": "item:2" },
400
+ { "expect": { "focus": "item:0" } },
401
+ { "event": "key", "key": "ArrowUp", "target": "item:0" },
402
+ { "expect": { "focus": "item:2" } },
403
+ { "event": "key", "key": "ArrowRight", "target": "item:2" },
404
+ { "expect": { "focus": "item:2" } },
405
+ { "event": "key", "key": "ArrowLeft", "target": "item:2" },
406
+ { "expect": { "focus": "item:2" } }
407
+ ]
408
+ },
409
+ {
410
+ "id": "toolbar.base-ui.toggle-group-home-end",
411
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/toggle-group/ToggleGroup.test.tsx#L438",
412
+ "upstreamTest": "<ToggleGroup /> > keyboard interactions > Home/End key moves focus",
413
+ "apg": "keyboard",
414
+ "config": { "orientation": "horizontal", "items": 3 },
415
+ "steps": [
416
+ { "event": "key", "key": "Tab", "target": "toolbar" },
417
+ { "expect": { "focus": "item:0" } },
418
+ { "event": "key", "key": "ArrowRight", "target": "item:0" },
419
+ { "event": "key", "key": "ArrowRight", "target": "item:1" },
420
+ { "expect": { "focus": "item:2" } },
421
+ { "event": "key", "key": "Home", "target": "item:2" },
422
+ {
423
+ "expect": {
424
+ "focus": "item:0",
425
+ "attrs": { "item:0": { "tabindex": "0" } }
426
+ }
427
+ },
428
+ { "event": "key", "key": "ArrowRight", "target": "item:0" },
429
+ { "expect": { "focus": "item:1" } },
430
+ { "event": "key", "key": "End", "target": "item:1" },
431
+ {
432
+ "expect": {
433
+ "focus": "item:2",
434
+ "attrs": { "item:2": { "tabindex": "0" } }
435
+ }
436
+ }
437
+ ]
438
+ },
439
+ {
440
+ "id": "toolbar.base-ui.toggle-group-enter-space-toggles",
441
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/toggle-group/ToggleGroup.test.tsx#L493",
442
+ "upstreamTest": "<ToggleGroup /> > keyboard interactions > key: Enter/Space toggles the pressed state",
443
+ "apg": "extension",
444
+ "config": { "orientation": "horizontal", "items": 2 },
445
+ "steps": [
446
+ { "event": "focus", "target": "item:0" },
447
+ { "expect": { "attrs": { "item:0": { "aria-pressed": "false" } } } },
448
+ { "event": "key", "key": "Enter", "target": "item:0" },
449
+ { "expect": { "attrs": { "item:0": { "aria-pressed": "true" } } } },
450
+ { "event": "key", "key": "Enter", "target": "item:0" },
451
+ { "expect": { "attrs": { "item:0": { "aria-pressed": "false" } } } },
452
+ { "event": "key", "key": "Space", "target": "item:0" },
453
+ { "expect": { "attrs": { "item:0": { "aria-pressed": "true" } } } }
454
+ ]
455
+ },
456
+ {
457
+ "id": "toolbar.base-ui.toggle-group-multiple-transition-keeps-focus",
458
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/toggle-group/ToggleGroup.test.tsx#L314",
459
+ "upstreamTest": "<ToggleGroup /> > prop: multiple transitions > preserves selection and roving focus",
460
+ "apg": "extension",
461
+ "config": {
462
+ "orientation": "horizontal",
463
+ "items": ["One", "Two"],
464
+ "defaultValue": ["One"],
465
+ "nestedInToolbarGroup": true
466
+ },
467
+ "steps": [
468
+ { "event": "key", "key": "Tab", "target": "toolbar" },
469
+ {
470
+ "expect": {
471
+ "attrs": {
472
+ "item:0": { "aria-pressed": "true" },
473
+ "item:1": { "aria-pressed": "false", "tabindex": "0" }
474
+ }
475
+ }
476
+ },
477
+ { "event": "key", "key": "ArrowRight", "target": "item:0" },
478
+ { "expect": { "focus": "item:1" } },
479
+ { "event": "click", "target": "item:1" },
480
+ {
481
+ "expect": {
482
+ "attrs": {
483
+ "item:0": { "aria-pressed": "false" },
484
+ "item:1": { "aria-pressed": "true" }
485
+ }
486
+ }
487
+ },
488
+ { "event": "prop", "target": "toolbar", "set": { "multiple": true } },
489
+ { "event": "click", "target": "item:0" },
490
+ {
491
+ "expect": {
492
+ "attrs": {
493
+ "item:0": { "aria-pressed": "true" },
494
+ "item:1": { "aria-pressed": "true" }
495
+ }
496
+ }
497
+ },
498
+ { "event": "click", "target": "item:1" },
499
+ {
500
+ "expect": {
501
+ "attrs": {
502
+ "item:0": { "aria-pressed": "true" },
503
+ "item:1": { "aria-pressed": "false" }
504
+ }
505
+ }
506
+ },
507
+ { "event": "prop", "target": "toolbar", "set": { "multiple": false } },
508
+ { "event": "click", "target": "item:1" },
509
+ {
510
+ "expect": {
511
+ "attrs": {
512
+ "item:0": { "aria-pressed": "false" },
513
+ "item:1": { "aria-pressed": "true" }
514
+ }
515
+ }
516
+ },
517
+ { "event": "key", "key": "ArrowLeft", "target": "item:1" },
518
+ { "expect": { "focus": "item:0" } }
519
+ ],
520
+ "notes": "Selection mode changes preserve both selection and the roving tab stop."
521
+ },
522
+ {
523
+ "id": "toolbar.base-ui.toggle-group-role-orientation",
524
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/toggle-group/ToggleGroup.test.tsx#L201",
525
+ "upstreamTest": "<ToggleGroup /> > prop: orientation",
526
+ "apg": "aria",
527
+ "config": { "orientation": "vertical", "items": 2 },
528
+ "steps": [
529
+ {
530
+ "expect": {
531
+ "attrs": {
532
+ "toolbar": {
533
+ "role": "group",
534
+ "data-orientation": "vertical",
535
+ "aria-orientation": null
536
+ }
537
+ }
538
+ }
539
+ }
540
+ ],
541
+ "notes": "role=group keeps data-orientation but must not emit aria-orientation."
542
+ },
543
+ {
544
+ "id": "toolbar.base-ui.toggle-group-disabled-aria",
545
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/toggle-group/ToggleGroup.test.tsx#L167",
546
+ "upstreamTest": "<ToggleGroup /> > prop: disabled > can disable the whole group / individual items",
547
+ "apg": "aria",
548
+ "config": { "disabled": true, "items": 2 },
549
+ "steps": [
550
+ {
551
+ "expect": {
552
+ "attrs": {
553
+ "item:0": { "aria-disabled": "true", "data-disabled": "" },
554
+ "item:1": { "aria-disabled": "true", "data-disabled": "" }
555
+ }
556
+ }
557
+ },
558
+ {
559
+ "event": "prop",
560
+ "target": "toolbar",
561
+ "set": { "disabled": false, "item1Disabled": true }
562
+ },
563
+ {
564
+ "expect": {
565
+ "attrs": {
566
+ "item:0": { "aria-disabled": "false", "data-disabled": null },
567
+ "item:1": { "aria-disabled": "true", "data-disabled": "" }
568
+ }
569
+ }
570
+ }
571
+ ]
572
+ },
573
+ {
574
+ "id": "toolbar.base-ui.composite-roving-controlled-and-uncontrolled",
575
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/internals/composite/root/CompositeRoot.test.tsx#L60",
576
+ "upstreamTest": "Composite > list > controlled mode / uncontrolled mode",
577
+ "apg": "keyboard",
578
+ "config": { "orientation": "vertical", "items": 3 },
579
+ "steps": [
580
+ { "event": "focus", "target": "item:0" },
581
+ { "expect": { "attrs": { "item:0": { "tabindex": "0" } } } },
582
+ { "event": "key", "key": "ArrowDown", "target": "item:0" },
583
+ {
584
+ "expect": {
585
+ "focus": "item:1",
586
+ "attrs": { "item:1": { "tabindex": "0" } }
587
+ }
588
+ },
589
+ { "event": "key", "key": "ArrowDown", "target": "item:1" },
590
+ {
591
+ "expect": {
592
+ "focus": "item:2",
593
+ "attrs": { "item:2": { "tabindex": "0" } }
594
+ }
595
+ },
596
+ { "event": "key", "key": "ArrowUp", "target": "item:2" },
597
+ { "expect": { "focus": "item:1" } },
598
+ { "event": "key", "key": "ArrowUp", "target": "item:1" },
599
+ { "expect": { "focus": "item:0" } }
600
+ ],
601
+ "notes": "Shared by controlled and uncontrolled Composite: one roving tabindex moves with focus."
602
+ },
603
+ {
604
+ "id": "toolbar.base-ui.composite-home-end",
605
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/internals/composite/root/CompositeRoot.test.tsx#L302",
606
+ "upstreamTest": "Composite > list > Home and End keys",
607
+ "apg": "keyboard",
608
+ "config": {
609
+ "orientation": "vertical",
610
+ "enableHomeAndEndKeys": true,
611
+ "items": 3
612
+ },
613
+ "steps": [
614
+ { "event": "focus", "target": "item:2" },
615
+ { "event": "key", "key": "Home", "target": "item:2" },
616
+ {
617
+ "expect": {
618
+ "focus": "item:0",
619
+ "attrs": { "item:0": { "tabindex": "0" } }
620
+ }
621
+ },
622
+ { "event": "key", "key": "End", "target": "item:0" },
623
+ {
624
+ "expect": {
625
+ "focus": "item:2",
626
+ "attrs": { "item:2": { "tabindex": "0" } }
627
+ }
628
+ }
629
+ ],
630
+ "notes": "Home/End only active when enableHomeAndEndKeys is set."
631
+ },
632
+ {
633
+ "id": "toolbar.base-ui.composite-loop-focus-false",
634
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/internals/composite/root/CompositeRoot.test.tsx#L382",
635
+ "upstreamTest": "Composite > list > does not loop or call onLoop when loopFocus is disabled",
636
+ "apg": "keyboard",
637
+ "config": { "orientation": "vertical", "loopFocus": false, "items": 3 },
638
+ "steps": [
639
+ { "event": "focus", "target": "item:2" },
640
+ { "event": "key", "key": "ArrowDown", "target": "item:2" },
641
+ {
642
+ "expect": {
643
+ "focus": "item:2",
644
+ "attrs": { "item:2": { "tabindex": "0" } }
645
+ }
646
+ }
647
+ ]
648
+ },
649
+ {
650
+ "id": "toolbar.base-ui.composite-disabled-indices-initial-stop",
651
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/internals/composite/root/CompositeRoot.test.tsx#L939",
652
+ "upstreamTest": "Composite > prop: disabledIndices > moves the initial tab stop to the first enabled item",
653
+ "apg": "keyboard",
654
+ "config": {
655
+ "orientation": "vertical",
656
+ "disabledIndices": [0],
657
+ "items": 3
658
+ },
659
+ "steps": [
660
+ {
661
+ "expect": {
662
+ "attrs": {
663
+ "item:0": { "tabindex": "-1" },
664
+ "item:1": { "tabindex": "0" },
665
+ "item:2": { "tabindex": "-1" }
666
+ }
667
+ }
668
+ }
669
+ ]
670
+ },
671
+ {
672
+ "id": "toolbar.base-ui.composite-disabled-indices-all-disabled",
673
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/internals/composite/root/CompositeRoot.test.tsx#L953",
674
+ "upstreamTest": "Composite > prop: disabledIndices > keeps the initial tab stop when all items are disabled",
675
+ "apg": "keyboard",
676
+ "config": {
677
+ "orientation": "vertical",
678
+ "disabledIndices": [0, 1],
679
+ "items": 2
680
+ },
681
+ "steps": [
682
+ {
683
+ "expect": {
684
+ "attrs": {
685
+ "item:0": { "tabindex": "0" },
686
+ "item:1": { "tabindex": "-1" }
687
+ }
688
+ }
689
+ }
690
+ ],
691
+ "notes": "When nothing is focusable the first item still owns the tab stop so the composite stays reachable."
692
+ },
693
+ {
694
+ "id": "toolbar.base-ui.composite-navigation-skips-disabled-index",
695
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/internals/composite/root/CompositeRoot.test.tsx#L965",
696
+ "upstreamTest": "Composite > prop: disabledIndices > disables navigating item when their index is included",
697
+ "apg": "keyboard",
698
+ "config": {
699
+ "orientation": "vertical",
700
+ "disabledIndices": [1],
701
+ "items": 3
702
+ },
703
+ "steps": [
704
+ { "event": "focus", "target": "item:0" },
705
+ { "event": "key", "key": "ArrowDown", "target": "item:0" },
706
+ {
707
+ "expect": {
708
+ "focus": "item:2",
709
+ "attrs": { "item:2": { "tabindex": "0" } }
710
+ }
711
+ },
712
+ { "event": "key", "key": "ArrowUp", "target": "item:2" },
713
+ { "expect": { "focus": "item:0" } }
714
+ ]
715
+ },
716
+ {
717
+ "id": "toolbar.base-ui.composite-removal-keeps-tab-stop",
718
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/internals/composite/root/CompositeRoot.test.tsx#L1066",
719
+ "upstreamTest": "Composite > item removal > keeps the tab stop on the highlighted item when an earlier item is removed",
720
+ "apg": "keyboard",
721
+ "config": { "orientation": "vertical", "items": ["1", "2", "3", "4"] },
722
+ "steps": [
723
+ { "event": "focus", "target": "item:0" },
724
+ { "event": "key", "key": "ArrowDown", "target": "item:0" },
725
+ { "event": "key", "key": "ArrowDown", "target": "item:1" },
726
+ { "expect": { "attrs": { "item:2": { "tabindex": "0" } } } },
727
+ {
728
+ "event": "prop",
729
+ "target": "toolbar",
730
+ "set": { "removeItem": "item:0" }
731
+ },
732
+ {
733
+ "expect": {
734
+ "attrs": {
735
+ "item:0": { "tabindex": "-1" },
736
+ "item:1": { "tabindex": "0" },
737
+ "item:2": { "tabindex": "-1" }
738
+ }
739
+ }
740
+ },
741
+ { "event": "key", "key": "ArrowDown", "target": "item:1" },
742
+ { "expect": { "focus": "item:2" } }
743
+ ],
744
+ "notes": "After removing the first item the tab stop follows the same highlighted element; indices shift by one."
745
+ },
746
+ {
747
+ "id": "toolbar.base-ui.composite-removal-tab-stop-back-in-range",
748
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/internals/composite/root/CompositeRoot.test.tsx#L1105",
749
+ "upstreamTest": "Composite > item removal > moves the tab stop back into range when the highlighted item is removed",
750
+ "apg": "keyboard",
751
+ "config": { "orientation": "vertical", "items": ["1", "2", "3"] },
752
+ "steps": [
753
+ { "event": "focus", "target": "item:0" },
754
+ { "event": "key", "key": "ArrowDown", "target": "item:0" },
755
+ { "event": "key", "key": "ArrowDown", "target": "item:1" },
756
+ { "expect": { "attrs": { "item:2": { "tabindex": "0" } } } },
757
+ {
758
+ "event": "prop",
759
+ "target": "toolbar",
760
+ "set": { "removeItem": "item:2" }
761
+ },
762
+ {
763
+ "expect": {
764
+ "attrs": {
765
+ "item:0": { "tabindex": "0" },
766
+ "item:1": { "tabindex": "-1" }
767
+ }
768
+ }
769
+ }
770
+ ]
771
+ },
772
+ {
773
+ "id": "toolbar.base-ui.composite-removal-tab-stop-to-active-item",
774
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/internals/composite/root/CompositeRoot.test.tsx#L1135",
775
+ "upstreamTest": "Composite > item removal > moves the tab stop to the active item when the highlighted item is removed",
776
+ "apg": "keyboard",
777
+ "config": {
778
+ "orientation": "vertical",
779
+ "items": ["1", "2", "3-active", "4"]
780
+ },
781
+ "steps": [
782
+ { "expect": { "attrs": { "item:2": { "tabindex": "0" } } } },
783
+ { "event": "focus", "target": "item:2" },
784
+ { "event": "key", "key": "ArrowDown", "target": "item:2" },
785
+ { "expect": { "attrs": { "item:3": { "tabindex": "0" } } } },
786
+ {
787
+ "event": "prop",
788
+ "target": "toolbar",
789
+ "set": { "removeItem": "item:3" }
790
+ },
791
+ {
792
+ "expect": {
793
+ "attrs": {
794
+ "item:0": { "tabindex": "-1" },
795
+ "item:2": { "tabindex": "0" }
796
+ }
797
+ }
798
+ }
799
+ ],
800
+ "notes": "Removing the highlighted item falls back to the active item."
801
+ },
802
+ {
803
+ "id": "toolbar.base-ui.composite-modifier-keys-default-prevent",
804
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/internals/composite/root/CompositeRoot.test.tsx#L1219",
805
+ "upstreamTest": "Composite > prop: modifierKeys > prevents arrow key navigation when any modifier key is pressed by default",
806
+ "apg": "extension",
807
+ "config": { "orientation": "vertical", "items": 2 },
808
+ "steps": [
809
+ { "event": "focus", "target": "item:0" },
810
+ {
811
+ "event": "key",
812
+ "key": "ArrowDown",
813
+ "target": "item:0",
814
+ "modifiers": ["Shift"]
815
+ },
816
+ { "expect": { "focus": "item:0" } },
817
+ {
818
+ "event": "key",
819
+ "key": "ArrowDown",
820
+ "target": "item:0",
821
+ "modifiers": ["Control"]
822
+ },
823
+ { "expect": { "focus": "item:0" } },
824
+ {
825
+ "event": "key",
826
+ "key": "ArrowDown",
827
+ "target": "item:0",
828
+ "modifiers": ["Alt"]
829
+ },
830
+ { "expect": { "focus": "item:0" } },
831
+ {
832
+ "event": "key",
833
+ "key": "ArrowDown",
834
+ "target": "item:0",
835
+ "modifiers": ["Meta"]
836
+ },
837
+ { "expect": { "focus": "item:0" } }
838
+ ]
839
+ },
840
+ {
841
+ "id": "toolbar.base-ui.composite-modifier-keys-allowed",
842
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/internals/composite/root/CompositeRoot.test.tsx#L1250",
843
+ "upstreamTest": "Composite > prop: modifierKeys > specifies allowed modifier keys that do not prevent arrow key navigation",
844
+ "apg": "extension",
845
+ "config": {
846
+ "orientation": "vertical",
847
+ "modifierKeys": ["Alt", "Meta"],
848
+ "items": 3
849
+ },
850
+ "steps": [
851
+ { "event": "focus", "target": "item:0" },
852
+ {
853
+ "event": "key",
854
+ "key": "ArrowDown",
855
+ "target": "item:0",
856
+ "modifiers": ["Shift"]
857
+ },
858
+ { "expect": { "focus": "item:0" } },
859
+ {
860
+ "event": "key",
861
+ "key": "ArrowDown",
862
+ "target": "item:0",
863
+ "modifiers": ["Control"]
864
+ },
865
+ { "expect": { "focus": "item:0" } },
866
+ {
867
+ "event": "key",
868
+ "key": "ArrowDown",
869
+ "target": "item:0",
870
+ "modifiers": ["Alt"]
871
+ },
872
+ { "expect": { "focus": "item:1" } },
873
+ {
874
+ "event": "key",
875
+ "key": "ArrowDown",
876
+ "target": "item:1",
877
+ "modifiers": ["Meta"]
878
+ },
879
+ { "expect": { "focus": "item:2" } }
880
+ ]
881
+ },
882
+ {
883
+ "id": "toolbar.base-ui.composite-rtl-horizontal",
884
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/internals/composite/root/CompositeRoot.test.tsx#L409",
885
+ "upstreamTest": "Composite > list > rtl > horizontal orientation",
886
+ "apg": "keyboard",
887
+ "config": { "direction": "rtl", "orientation": "horizontal", "items": 3 },
888
+ "steps": [
889
+ { "event": "focus", "target": "item:0" },
890
+ { "event": "key", "key": "ArrowDown", "target": "item:0" },
891
+ { "expect": { "focus": "item:0" } },
892
+ { "event": "key", "key": "ArrowLeft", "target": "item:0" },
893
+ { "expect": { "focus": "item:1" } },
894
+ { "event": "key", "key": "ArrowLeft", "target": "item:1" },
895
+ { "expect": { "focus": "item:2" } },
896
+ { "event": "key", "key": "ArrowRight", "target": "item:2" },
897
+ { "expect": { "focus": "item:1" } },
898
+ { "event": "key", "key": "ArrowRight", "target": "item:1" },
899
+ { "expect": { "focus": "item:0" } },
900
+ { "event": "key", "key": "ArrowRight", "target": "item:0" },
901
+ { "expect": { "focus": "item:2" } }
902
+ ],
903
+ "notes": "RTL flips horizontal direction and wraps backward."
904
+ },
905
+ {
906
+ "id": "toolbar.base-ui.composite-nested-shared-dom-node",
907
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/internals/composite/root/CompositeRoot.test.tsx#L1380",
908
+ "upstreamTest": "nested Composite items > keeps outer metadata and focus navigation when items share a DOM node",
909
+ "apg": "extension",
910
+ "config": {
911
+ "orientation": "horizontal",
912
+ "items": ["first", "second", "third"]
913
+ },
914
+ "steps": [
915
+ { "event": "key", "key": "Tab", "target": "toolbar" },
916
+ { "expect": { "focus": "item:0" } },
917
+ { "event": "key", "key": "ArrowRight", "target": "item:0" },
918
+ { "expect": { "focus": "item:1" } },
919
+ { "event": "key", "key": "ArrowRight", "target": "item:1" },
920
+ { "expect": { "focus": "item:2" } }
921
+ ],
922
+ "notes": "Two registrations on the same DOM node must not break roving focus. Nested-composition extension."
923
+ },
924
+ {
925
+ "id": "toolbar.base-ui.composite-no-aria-orientation",
926
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/internals/composite/root/CompositeRoot.test.tsx#L49",
927
+ "upstreamTest": "Composite > list > does not add aria-orientation when orientation is set",
928
+ "apg": "aria",
929
+ "config": { "orientation": "horizontal", "items": 2 },
930
+ "steps": [
931
+ { "expect": { "attrs": { "toolbar": { "aria-orientation": null } } } }
932
+ ],
933
+ "notes": "The abstract composite role does not carry aria-orientation; toolbar adds it."
934
+ },
935
+ {
936
+ "id": "toolbar.base-ui.button-renders-button",
937
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/toolbar/button/ToolbarButton.test.tsx#L49",
938
+ "upstreamTest": "<Toolbar.Button /> > ARIA attributes > renders a button",
939
+ "apg": "aria",
940
+ "config": { "items": 1 },
941
+ "steps": [{ "expect": { "attrs": { "item:0": { "role": "button" } } } }]
942
+ },
943
+ {
944
+ "id": "toolbar.base-ui.button-disabled-blocks-activation",
945
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/toolbar/button/ToolbarButton.test.tsx#L129",
946
+ "upstreamTest": "<Toolbar.Button /> > prop: disabled > disables the button",
947
+ "apg": "keyboard",
948
+ "config": { "orientation": "horizontal", "items": ["button:disabled"] },
949
+ "steps": [
950
+ {
951
+ "expect": {
952
+ "attrs": {
953
+ "item:0": {
954
+ "disabled": null,
955
+ "data-disabled": "",
956
+ "aria-disabled": "true"
957
+ }
958
+ }
959
+ }
960
+ },
961
+ { "event": "click", "target": "item:0" },
962
+ { "event": "key", "key": "Space", "target": "item:0" },
963
+ { "event": "key", "key": "Enter", "target": "item:0" },
964
+ { "expect": { "events": { "onClick": [] } } }
965
+ ],
966
+ "notes": "Disabled but focusable keeps aria-disabled and blocks activation."
967
+ },
968
+ {
969
+ "id": "toolbar.base-ui.button-nonfocusable-disabled-uses-disabled-attr",
970
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/toolbar/button/ToolbarButton.test.tsx#L162",
971
+ "upstreamTest": "<Toolbar.Button /> > prop: disabled > uses the disabled attribute when focusableWhenDisabled is false",
972
+ "apg": "aria",
973
+ "config": {
974
+ "orientation": "horizontal",
975
+ "items": ["button:disabled-focusable=false"]
976
+ },
977
+ "steps": [
978
+ {
979
+ "expect": {
980
+ "attrs": {
981
+ "item:0": {
982
+ "disabled": "",
983
+ "data-disabled": "",
984
+ "aria-disabled": null
985
+ }
986
+ }
987
+ }
988
+ }
989
+ ]
990
+ },
991
+ {
992
+ "id": "toolbar.base-ui.menu-trigger-consumes-arrows",
993
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/toolbar/button/ToolbarButton.test.tsx#L348",
994
+ "upstreamTest": "<Toolbar.Button /> > rendering other Base UI components > Menu > handles interactions",
995
+ "apg": "extension",
996
+ "config": {
997
+ "orientation": "horizontal",
998
+ "items": ["button:menutrigger"]
999
+ },
1000
+ "steps": [
1001
+ { "event": "key", "key": "Tab", "target": "toolbar" },
1002
+ { "expect": { "focus": "item:0" } },
1003
+ { "event": "key", "key": "Enter", "target": "item:0" },
1004
+ { "expect": { "visible": ["popup"], "focus": "menuitem:0" } },
1005
+ { "event": "key", "key": "ArrowDown", "target": "menuitem:0" },
1006
+ { "expect": { "focus": "menuitem:1" } },
1007
+ { "event": "key", "key": "ArrowDown", "target": "menuitem:1" },
1008
+ { "expect": { "focus": "menuitem:2" } },
1009
+ { "event": "key", "key": "ArrowUp", "target": "menuitem:2" },
1010
+ { "expect": { "focus": "menuitem:1" } },
1011
+ { "event": "key", "key": "Escape", "target": "menuitem:1" },
1012
+ { "expect": { "visible": [], "focus": "item:0" } }
1013
+ ],
1014
+ "notes": "While the menu is open arrows move the menu, not the toolbar; Escape restores focus to the trigger."
1015
+ },
1016
+ {
1017
+ "id": "toolbar.base-ui.dialog-prevents-composite-keydown-escape",
1018
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/toolbar/button/ToolbarButton.test.tsx#L681",
1019
+ "upstreamTest": "<Toolbar.Button /> > rendering other Base UI components > Dialog > prevents composite keydowns from escaping",
1020
+ "apg": "extension",
1021
+ "config": {
1022
+ "orientation": "horizontal",
1023
+ "items": ["button:modaltrigger", "button"]
1024
+ },
1025
+ "steps": [
1026
+ { "event": "click", "target": "item:0" },
1027
+ {
1028
+ "expect": { "focus": "dialog", "events": { "onOpenChange": [true] } }
1029
+ },
1030
+ { "event": "key", "key": "ArrowRight", "target": "dialog" },
1031
+ {
1032
+ "expect": { "focus": "dialog", "events": { "onOpenChange": [true] } }
1033
+ }
1034
+ ],
1035
+ "notes": "A focused modal child must swallow arrows so the composite underneath does not navigate."
1036
+ },
1037
+ {
1038
+ "id": "toolbar.base-ui.input-caret-boundaries",
1039
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/toolbar/input/ToolbarInput.test.tsx#L102",
1040
+ "upstreamTest": "<Toolbar.Input /> > keyboard navigation > respects caret and selection boundaries",
1041
+ "apg": "extension",
1042
+ "config": {
1043
+ "direction": "ltr",
1044
+ "orientation": "horizontal",
1045
+ "items": ["button", "textbox", "button"]
1046
+ },
1047
+ "steps": [
1048
+ { "event": "key", "key": "Tab", "target": "toolbar" },
1049
+ { "event": "key", "key": "ArrowRight", "target": "item:0" },
1050
+ { "expect": { "focus": "item:1" } },
1051
+ { "event": "prop", "target": "item:1", "set": { "selection": [1, 3] } },
1052
+ { "event": "key", "key": "ArrowRight", "target": "item:1" },
1053
+ { "expect": { "focus": "item:1" } },
1054
+ { "event": "prop", "target": "item:1", "set": { "selection": [4, 4] } },
1055
+ { "event": "key", "key": "ArrowRight", "target": "item:1" },
1056
+ { "expect": { "focus": "item:2" } },
1057
+ { "event": "key", "key": "ArrowLeft", "target": "item:2" },
1058
+ { "expect": { "focus": "item:1" } },
1059
+ { "event": "prop", "target": "item:1", "set": { "selection": [0, 0] } },
1060
+ { "event": "key", "key": "ArrowLeft", "target": "item:1" },
1061
+ { "expect": { "focus": "item:0" } }
1062
+ ],
1063
+ "notes": "A textbox consumes arrows until the caret reaches its boundary. Nested control, not APG."
1064
+ },
1065
+ {
1066
+ "id": "toolbar.base-ui.input-orientation-axis",
1067
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/toolbar/input/ToolbarInput.test.tsx#L158",
1068
+ "upstreamTest": "<Toolbar.Input /> > keyboard navigation > orientation",
1069
+ "apg": "extension",
1070
+ "config": {
1071
+ "orientation": "horizontal",
1072
+ "items": ["button", "textbox", "button"]
1073
+ },
1074
+ "steps": [
1075
+ { "event": "key", "key": "Tab", "target": "toolbar" },
1076
+ { "expect": { "focus": "item:0" } },
1077
+ { "event": "key", "key": "ArrowRight", "target": "item:0" },
1078
+ { "expect": { "focus": "item:1" } },
1079
+ { "event": "prop", "target": "item:1", "set": { "selection": [4, 4] } },
1080
+ { "event": "key", "key": "ArrowRight", "target": "item:1" },
1081
+ { "expect": { "focus": "item:2" } },
1082
+ { "event": "key", "key": "ArrowLeft", "target": "item:2" },
1083
+ { "expect": { "focus": "item:1" } },
1084
+ { "event": "prop", "target": "item:1", "set": { "selection": [0, 0] } },
1085
+ { "event": "key", "key": "ArrowLeft", "target": "item:1" },
1086
+ { "expect": { "focus": "item:0" } }
1087
+ ]
1088
+ },
1089
+ {
1090
+ "id": "toolbar.base-ui.input-disabled-does-not-trap-focus",
1091
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/toolbar/input/ToolbarInput.test.tsx#L196",
1092
+ "upstreamTest": "<Toolbar.Input /> > disabled > does not trap keyboard focus when disabled",
1093
+ "apg": "keyboard",
1094
+ "config": {
1095
+ "orientation": "horizontal",
1096
+ "items": ["button", "textbox:disabled"],
1097
+ "externalAfter": true
1098
+ },
1099
+ "steps": [
1100
+ { "event": "key", "key": "Tab", "target": "toolbar" },
1101
+ { "expect": { "focus": "item:0" } },
1102
+ { "event": "key", "key": "ArrowRight", "target": "item:0" },
1103
+ { "expect": { "focus": "item:1" } },
1104
+ { "event": "key", "key": "Tab", "target": "item:1" },
1105
+ { "expect": { "focus": null } },
1106
+ { "event": "key", "key": "Tab", "modifiers": ["Shift"] },
1107
+ { "expect": { "focus": "item:1" } }
1108
+ ]
1109
+ },
1110
+ {
1111
+ "id": "toolbar.base-ui.input-disabled-does-not-block-roving",
1112
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/toolbar/input/ToolbarInput.test.tsx#L227",
1113
+ "upstreamTest": "<Toolbar.Input /> > disabled > does not block vertical roving focus when disabled",
1114
+ "apg": "keyboard",
1115
+ "config": {
1116
+ "orientation": "vertical",
1117
+ "items": ["button", "textbox:disabled", "button"]
1118
+ },
1119
+ "steps": [
1120
+ { "event": "key", "key": "Tab", "target": "toolbar" },
1121
+ { "expect": { "focus": "item:0" } },
1122
+ { "event": "key", "key": "ArrowDown", "target": "item:0" },
1123
+ { "expect": { "focus": "item:1" } },
1124
+ { "event": "key", "key": "ArrowDown", "target": "item:1" },
1125
+ { "expect": { "focus": "item:2" } },
1126
+ { "event": "key", "key": "ArrowUp", "target": "item:2" },
1127
+ { "expect": { "focus": "item:1" } },
1128
+ { "event": "key", "key": "ArrowUp", "target": "item:1" },
1129
+ { "expect": { "focus": "item:0" } }
1130
+ ]
1131
+ },
1132
+ {
1133
+ "id": "toolbar.base-ui.group-renders-group",
1134
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/toolbar/group/ToolbarGroup.test.tsx#L38",
1135
+ "upstreamTest": "<Toolbar.Group /> > ARIA attributes > renders a group",
1136
+ "apg": "aria",
1137
+ "config": { "items": ["group:button"] },
1138
+ "steps": [{ "expect": { "attrs": { "item:0": { "role": "group" } } } }]
1139
+ },
1140
+ {
1141
+ "id": "toolbar.base-ui.group-disabled-except-links",
1142
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/toolbar/group/ToolbarGroup.test.tsx#L50",
1143
+ "upstreamTest": "<Toolbar.Group /> > prop: disabled > disables all toolbar items except links in the group",
1144
+ "apg": "aria",
1145
+ "config": {
1146
+ "items": ["group:button:link:textbox"],
1147
+ "groupDisabled": true
1148
+ },
1149
+ "steps": [
1150
+ {
1151
+ "expect": {
1152
+ "attrs": {
1153
+ "item:0": { "aria-disabled": "true", "data-disabled": "" },
1154
+ "item:1": { "aria-disabled": null, "data-disabled": null },
1155
+ "item:2": { "aria-disabled": "true", "data-disabled": "" }
1156
+ }
1157
+ }
1158
+ }
1159
+ ]
1160
+ },
1161
+ {
1162
+ "id": "toolbar.base-ui.numberfield-consumes-arrows",
1163
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/toolbar/input/ToolbarInput.test.tsx#L273",
1164
+ "upstreamTest": "<Toolbar.Input /> > rendering NumberField > handles interactions",
1165
+ "apg": "extension",
1166
+ "config": {
1167
+ "orientation": "horizontal",
1168
+ "items": ["numberfield"],
1169
+ "defaultValue": 5,
1170
+ "min": 1,
1171
+ "max": 10
1172
+ },
1173
+ "steps": [
1174
+ { "event": "key", "key": "Tab", "target": "toolbar" },
1175
+ {
1176
+ "expect": {
1177
+ "focus": "item:0",
1178
+ "attrs": { "item:0": { "tabindex": "0" } }
1179
+ }
1180
+ },
1181
+ { "event": "key", "key": "ArrowUp", "target": "item:0" },
1182
+ { "expect": { "value": 6, "events": { "onValueChange": [6] } } },
1183
+ { "event": "key", "key": "ArrowDown", "target": "item:0" },
1184
+ { "expect": { "value": 5, "events": { "onValueChange": [6, 5] } } }
1185
+ ],
1186
+ "notes": "A nested number field consumes Up/Down for its own value instead of moving roving focus."
1187
+ }
1188
+ ]
1189
+ }