@cssints/apg-specs 0.0.0-stage → 0.5.2

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,1126 @@
1
+ {
2
+ "pattern": "checkbox",
3
+ "source": "base-ui",
4
+ "commit": "19511bb171f3b360b006c94cf6d07e53cb446505",
5
+ "license": "MIT",
6
+ "skipped": [
7
+ { "reason": "describeConformance blocks" },
8
+ { "reason": "id generation, hydration and SSR fallback tests" },
9
+ {
10
+ "reason": "Field/Form integration, validation, error focus and description wiring"
11
+ },
12
+ {
13
+ "reason": "form value projection through portals/fieldsets and form-owner changes"
14
+ },
15
+ {
16
+ "reason": "data-* style hooks on root/indicator (data-touched, data-dirty, data-filled, data-focused, data-valid, data-invalid) unless the upstream assertion encodes ARIA state"
17
+ },
18
+ { "reason": "inputRef prop tests and imperative ref-callback edge cases" },
19
+ { "reason": "React StrictMode internals and console-warning tests" },
20
+ { "reason": "styling/class-name assertions" }
21
+ ],
22
+ "scenarios": [
23
+ {
24
+ "id": "checkbox.base-ui.aria-attributes",
25
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox/root/CheckboxRoot.test.tsx#L24",
26
+ "upstreamTest": "ARIA attributes > sets the correct aria attributes",
27
+ "apg": "aria",
28
+ "config": { "part": "checkbox", "required": false },
29
+ "steps": [
30
+ { "event": "prop", "set": {} },
31
+ {
32
+ "expect": {
33
+ "attrs": {
34
+ "checkbox": { "role": "checkbox", "aria-checked": "false" }
35
+ }
36
+ }
37
+ },
38
+ { "event": "prop", "set": { "required": true } },
39
+ { "expect": { "attrs": { "checkbox": { "aria-required": "true" } } } }
40
+ ],
41
+ "notes": "Required adds aria-required to the exposed checkbox."
42
+ },
43
+ {
44
+ "id": "checkbox.base-ui.role-can-be-overridden",
45
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox/root/CheckboxRoot.test.tsx#L35",
46
+ "upstreamTest": "extra props > can override the built-in attributes",
47
+ "apg": "extension",
48
+ "config": { "part": "checkbox", "role": "switch" },
49
+ "steps": [
50
+ { "event": "prop", "set": {} },
51
+ { "expect": { "attrs": { "checkbox": { "role": "switch" } } } }
52
+ ],
53
+ "notes": "Consumer role overrides the default checkbox role."
54
+ },
55
+ {
56
+ "id": "checkbox.base-ui.onclick-propagates-once",
57
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox/root/CheckboxRoot.test.tsx#L134",
58
+ "upstreamTest": "prop: onClick > propagates a single click event to ancestors per user click",
59
+ "apg": "extension",
60
+ "config": { "part": "checkbox" },
61
+ "steps": [
62
+ { "event": "click", "target": "checkbox" },
63
+ {
64
+ "expect": {
65
+ "attrs": { "checkbox": { "aria-checked": "true" } },
66
+ "events": { "onAncestorClick": [1] }
67
+ }
68
+ }
69
+ ],
70
+ "notes": "One user click reaches the ancestor once."
71
+ },
72
+ {
73
+ "id": "checkbox.base-ui.onclick-stop-propagation",
74
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox/root/CheckboxRoot.test.tsx#L148",
75
+ "upstreamTest": "prop: onClick > does not propagate to ancestors when stopPropagation() is called",
76
+ "apg": "extension",
77
+ "config": { "part": "checkbox", "stopPropagation": true },
78
+ "steps": [
79
+ { "event": "click", "target": "checkbox" },
80
+ {
81
+ "expect": {
82
+ "attrs": { "checkbox": { "aria-checked": "true" } },
83
+ "events": { "onAncestorClick": [0] }
84
+ }
85
+ }
86
+ ],
87
+ "notes": "State still toggles when propagation is stopped."
88
+ },
89
+ {
90
+ "id": "checkbox.base-ui.onclick-propagates-once-native-button",
91
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox/root/CheckboxRoot.test.tsx#L162",
92
+ "upstreamTest": "prop: onClick > propagates a single click event to ancestors with a native button",
93
+ "apg": "extension",
94
+ "config": { "part": "checkbox", "nativeButton": true },
95
+ "steps": [
96
+ { "event": "click", "target": "checkbox" },
97
+ {
98
+ "expect": {
99
+ "attrs": { "checkbox": { "aria-checked": "true" } },
100
+ "events": { "onAncestorClick": [1] }
101
+ }
102
+ }
103
+ ],
104
+ "notes": "Native-button rendering keeps single-click propagation."
105
+ },
106
+ {
107
+ "id": "checkbox.base-ui.onclick-stop-propagation-native-button",
108
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox/root/CheckboxRoot.test.tsx#L176",
109
+ "upstreamTest": "prop: onClick > does not propagate to ancestors when stopPropagation() is called with a native button",
110
+ "apg": "extension",
111
+ "config": {
112
+ "part": "checkbox",
113
+ "nativeButton": true,
114
+ "stopPropagation": true
115
+ },
116
+ "steps": [
117
+ { "event": "click", "target": "checkbox" },
118
+ {
119
+ "expect": {
120
+ "attrs": { "checkbox": { "aria-checked": "true" } },
121
+ "events": { "onAncestorClick": [0] }
122
+ }
123
+ }
124
+ ],
125
+ "notes": "Native-button variant honours stopPropagation."
126
+ },
127
+ {
128
+ "id": "checkbox.base-ui.click-toggles-aria-checked-and-input",
129
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox/root/CheckboxRoot.test.tsx#L213",
130
+ "upstreamTest": "interactions > should change its state when clicked",
131
+ "apg": "aria",
132
+ "config": { "part": "checkbox" },
133
+ "steps": [
134
+ { "event": "prop", "set": {} },
135
+ {
136
+ "expect": {
137
+ "attrs": {
138
+ "checkbox": { "aria-checked": "false" },
139
+ "input:hidden": { "checked": "false" }
140
+ }
141
+ }
142
+ },
143
+ { "event": "click", "target": "checkbox" },
144
+ {
145
+ "expect": {
146
+ "attrs": {
147
+ "checkbox": { "aria-checked": "true" },
148
+ "input:hidden": { "checked": "true" }
149
+ }
150
+ }
151
+ },
152
+ { "event": "click", "target": "checkbox" },
153
+ {
154
+ "expect": {
155
+ "attrs": {
156
+ "checkbox": { "aria-checked": "false" },
157
+ "input:hidden": { "checked": "false" }
158
+ }
159
+ }
160
+ }
161
+ ],
162
+ "notes": "Exposed aria-checked and hidden input checked stay in sync."
163
+ },
164
+ {
165
+ "id": "checkbox.base-ui.controlled-updates-from-outside",
166
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox/root/CheckboxRoot.test.tsx#L240",
167
+ "upstreamTest": "interactions > should update its state when changed from outside",
168
+ "apg": "states",
169
+ "config": { "part": "checkbox", "checked": false },
170
+ "steps": [
171
+ { "event": "prop", "set": { "checked": true } },
172
+ { "expect": { "attrs": { "checkbox": { "aria-checked": "true" } } } },
173
+ { "event": "prop", "set": { "checked": false } },
174
+ { "expect": { "attrs": { "checkbox": { "aria-checked": "false" } } } }
175
+ ],
176
+ "notes": "aria-checked follows the controlled checked prop."
177
+ },
178
+ {
179
+ "id": "checkbox.base-ui.oncheckedchange-called",
180
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox/root/CheckboxRoot.test.tsx#L269",
181
+ "upstreamTest": "interactions > should call onCheckedChange when clicked",
182
+ "apg": "extension",
183
+ "config": { "part": "checkbox" },
184
+ "steps": [
185
+ { "event": "click", "target": "checkbox" },
186
+ { "expect": { "events": { "onCheckedChange": [true] } } }
187
+ ],
188
+ "notes": "Callback receives the next checked value."
189
+ },
190
+ {
191
+ "id": "checkbox.base-ui.oncheckedchange-cancel",
192
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox/root/CheckboxRoot.test.tsx#L282",
193
+ "upstreamTest": "interactions > does not update its state when onCheckedChange cancels the event",
194
+ "apg": "extension",
195
+ "config": { "part": "checkbox", "cancelOnCheckedChange": true },
196
+ "steps": [
197
+ { "event": "click", "target": "checkbox" },
198
+ {
199
+ "expect": {
200
+ "attrs": {
201
+ "checkbox": { "aria-checked": "false" },
202
+ "input:hidden": { "checked": "false" }
203
+ },
204
+ "events": { "onCheckedChange": [1] }
205
+ }
206
+ }
207
+ ],
208
+ "notes": "cancel() keeps the checkbox unchecked."
209
+ },
210
+ {
211
+ "id": "checkbox.base-ui.oncheckedchange-reports-modifiers",
212
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox/root/CheckboxRoot.test.tsx#L300",
213
+ "upstreamTest": "interactions > should report keyboard modifier event properties",
214
+ "apg": "extension",
215
+ "config": { "part": "checkbox" },
216
+ "steps": [
217
+ { "event": "click", "target": "checkbox", "modifiers": ["Shift"] },
218
+ {
219
+ "expect": { "events": { "onCheckedChange": [{ "shiftKey": true }] } }
220
+ }
221
+ ],
222
+ "notes": "Event details expose modifier state."
223
+ },
224
+ {
225
+ "id": "checkbox.base-ui.hidden-input-toggle-updates-checkbox",
226
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox/root/CheckboxRoot.test.tsx#L313",
227
+ "upstreamTest": "interactions > should update its state if the underlying input is toggled",
228
+ "apg": "extension",
229
+ "config": { "part": "checkbox" },
230
+ "steps": [
231
+ { "event": "click", "target": "input:hidden" },
232
+ { "expect": { "attrs": { "checkbox": { "aria-checked": "true" } } } }
233
+ ],
234
+ "notes": "Toggling the hidden input updates the exposed checkbox."
235
+ },
236
+ {
237
+ "id": "checkbox.base-ui.ignores-canceled-hidden-input-click",
238
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox/root/CheckboxRoot.test.tsx#L325",
239
+ "upstreamTest": "interactions > ignores a hidden input click canceled before React handles it",
240
+ "apg": "extension",
241
+ "config": { "part": "checkbox" },
242
+ "steps": [
243
+ { "event": "click", "target": "input:hidden", "canceled": true },
244
+ {
245
+ "expect": {
246
+ "attrs": { "checkbox": { "aria-checked": "false" } },
247
+ "events": { "onCheckedChange": [0] }
248
+ }
249
+ }
250
+ ],
251
+ "notes": "A click whose default is prevented never activates the checkbox."
252
+ },
253
+ {
254
+ "id": "checkbox.base-ui.space-activates",
255
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox/root/CheckboxRoot.test.tsx#L340",
256
+ "upstreamTest": "interactions > can be activated with Space key",
257
+ "apg": "keyboard",
258
+ "config": { "part": "checkbox" },
259
+ "steps": [
260
+ { "event": "key", "key": "Tab" },
261
+ { "expect": { "focus": "checkbox" } },
262
+ { "event": "key", "key": " ", "target": "checkbox" },
263
+ { "expect": { "attrs": { "checkbox": { "aria-checked": "true" } } } }
264
+ ],
265
+ "notes": "Space activates the checkbox."
266
+ },
267
+ {
268
+ "id": "checkbox.base-ui.enter-does-not-activate",
269
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox/root/CheckboxRoot.test.tsx#L353",
270
+ "upstreamTest": "interactions > does not activate with Enter key",
271
+ "apg": "keyboard",
272
+ "config": { "part": "checkbox" },
273
+ "steps": [
274
+ { "event": "key", "key": "Tab" },
275
+ { "expect": { "focus": "checkbox" } },
276
+ { "event": "key", "key": "Enter", "target": "checkbox" },
277
+ { "expect": { "attrs": { "checkbox": { "aria-checked": "false" } } } }
278
+ ],
279
+ "notes": "Enter does not toggle a checkbox (APG spec for the checkbox pattern)."
280
+ },
281
+ {
282
+ "id": "checkbox.base-ui.disabled-uses-aria-disabled",
283
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox/root/CheckboxRoot.test.tsx#L368",
284
+ "upstreamTest": "prop: disabled > uses aria-disabled instead of HTML disabled",
285
+ "apg": "states",
286
+ "config": { "part": "checkbox", "disabled": true },
287
+ "steps": [
288
+ { "event": "prop", "set": {} },
289
+ {
290
+ "expect": {
291
+ "attrs": {
292
+ "checkbox": { "disabled": null, "aria-disabled": "true" }
293
+ }
294
+ }
295
+ }
296
+ ],
297
+ "notes": "Disabled checkbox exposes aria-disabled."
298
+ },
299
+ {
300
+ "id": "checkbox.base-ui.disabled-ignores-click",
301
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox/root/CheckboxRoot.test.tsx#L374",
302
+ "upstreamTest": "prop: disabled > should not change its state when clicked",
303
+ "apg": "states",
304
+ "config": { "part": "checkbox", "disabled": true },
305
+ "steps": [
306
+ { "event": "click", "target": "checkbox" },
307
+ { "expect": { "attrs": { "checkbox": { "aria-checked": "false" } } } }
308
+ ],
309
+ "notes": "Click is ignored while disabled."
310
+ },
311
+ {
312
+ "id": "checkbox.base-ui.readonly-aria",
313
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox/root/CheckboxRoot.test.tsx#L389",
314
+ "upstreamTest": "prop: readOnly > should have the aria-readonly attribute",
315
+ "apg": "states",
316
+ "config": { "part": "checkbox", "readOnly": true },
317
+ "steps": [
318
+ { "event": "prop", "set": {} },
319
+ { "expect": { "attrs": { "checkbox": { "aria-readonly": "true" } } } }
320
+ ],
321
+ "notes": "Read-only checkbox exposes aria-readonly."
322
+ },
323
+ {
324
+ "id": "checkbox.base-ui.readonly-ignores-click",
325
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox/root/CheckboxRoot.test.tsx#L399",
326
+ "upstreamTest": "prop: readOnly > should not change its state when clicked",
327
+ "apg": "states",
328
+ "config": { "part": "checkbox", "readOnly": true },
329
+ "steps": [
330
+ { "event": "click", "target": "checkbox" },
331
+ { "expect": { "attrs": { "checkbox": { "aria-checked": "false" } } } }
332
+ ],
333
+ "notes": "Read-only blocks direct clicks."
334
+ },
335
+ {
336
+ "id": "checkbox.base-ui.readonly-ignores-label-click",
337
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox/root/CheckboxRoot.test.tsx#L412",
338
+ "upstreamTest": "prop: readOnly > should not change its state when its label is clicked",
339
+ "apg": "states",
340
+ "config": { "part": "checkbox", "readOnly": true },
341
+ "steps": [
342
+ { "event": "click", "target": "label" },
343
+ { "expect": { "attrs": { "checkbox": { "aria-checked": "false" } } } }
344
+ ],
345
+ "notes": "Read-only also blocks activation through the label."
346
+ },
347
+ {
348
+ "id": "checkbox.base-ui.indeterminate-mixed",
349
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox/root/CheckboxRoot.test.tsx#L433",
350
+ "upstreamTest": "prop: indeterminate > should set the aria-checked attribute as mixed",
351
+ "apg": "states",
352
+ "config": { "part": "checkbox", "indeterminate": true },
353
+ "steps": [
354
+ { "event": "prop", "set": {} },
355
+ { "expect": { "attrs": { "checkbox": { "aria-checked": "mixed" } } } }
356
+ ],
357
+ "notes": "Indeterminate maps to aria-checked=mixed."
358
+ },
359
+ {
360
+ "id": "checkbox.base-ui.indeterminate-ignores-click",
361
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox/root/CheckboxRoot.test.tsx#L438",
362
+ "upstreamTest": "prop: indeterminate > should not change its state when clicked",
363
+ "apg": "states",
364
+ "config": { "part": "checkbox", "indeterminate": true },
365
+ "steps": [
366
+ { "event": "click", "target": "checkbox" },
367
+ { "expect": { "attrs": { "checkbox": { "aria-checked": "mixed" } } } }
368
+ ],
369
+ "notes": "A manually indeterminate checkbox stays mixed after a click."
370
+ },
371
+ {
372
+ "id": "checkbox.base-ui.indeterminate-not-overridden-by-checked",
373
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox/root/CheckboxRoot.test.tsx#L456",
374
+ "upstreamTest": "prop: indeterminate > should not be overridden by checked prop",
375
+ "apg": "states",
376
+ "config": { "part": "checkbox", "indeterminate": true, "checked": true },
377
+ "steps": [
378
+ { "event": "prop", "set": {} },
379
+ { "expect": { "attrs": { "checkbox": { "aria-checked": "mixed" } } } }
380
+ ],
381
+ "notes": "indeterminate wins over checked for aria-checked."
382
+ },
383
+ {
384
+ "id": "checkbox.base-ui.indeterminate-native-input-state",
385
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox/root/CheckboxRoot.test.tsx#L461",
386
+ "upstreamTest": "prop: indeterminate > sets the native input state when indeterminate",
387
+ "apg": "extension",
388
+ "config": { "part": "checkbox", "indeterminate": true },
389
+ "steps": [
390
+ { "event": "prop", "set": {} },
391
+ {
392
+ "expect": { "attrs": { "input:hidden": { "indeterminate": "true" } } }
393
+ }
394
+ ],
395
+ "notes": "The hidden native input's indeterminate flag is set."
396
+ },
397
+ {
398
+ "id": "checkbox.base-ui.indeterminate-grouped-parent-mixed",
399
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox/root/CheckboxRoot.test.tsx#L506",
400
+ "upstreamTest": "prop: indeterminate > sets grouped parent aria when manually indeterminate",
401
+ "apg": "states",
402
+ "config": {
403
+ "part": "checkbox",
404
+ "group": true,
405
+ "parentIndeterminate": true,
406
+ "values": []
407
+ },
408
+ "steps": [
409
+ { "event": "prop", "set": {} },
410
+ {
411
+ "expect": {
412
+ "attrs": { "checkbox:parent": { "aria-checked": "mixed" } }
413
+ }
414
+ }
415
+ ],
416
+ "notes": "A manually indeterminate parent checkbox is mixed inside a group."
417
+ },
418
+ {
419
+ "id": "checkbox.base-ui.wrapping-label-toggles",
420
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox/root/CheckboxRoot.test.tsx#L589",
421
+ "upstreamTest": "with native <label> > should toggle the checkbox when a wrapping <label> is clicked",
422
+ "apg": "extension",
423
+ "config": { "part": "checkbox" },
424
+ "steps": [
425
+ { "event": "click", "target": "label" },
426
+ { "expect": { "attrs": { "checkbox": { "aria-checked": "true" } } } }
427
+ ],
428
+ "notes": "Wrapping label toggles the checkbox."
429
+ },
430
+ {
431
+ "id": "checkbox.base-ui.click-wrapping-label-checkbox",
432
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox/root/CheckboxRoot.test.tsx#L1764",
433
+ "upstreamTest": "should change state when clicking the checkbox if it has a wrapping label",
434
+ "apg": "extension",
435
+ "config": { "part": "checkbox" },
436
+ "steps": [
437
+ { "event": "click", "target": "checkbox" },
438
+ { "expect": { "attrs": { "checkbox": { "aria-checked": "true" } } } },
439
+ { "event": "click", "target": "checkbox" },
440
+ { "expect": { "attrs": { "checkbox": { "aria-checked": "false" } } } }
441
+ ],
442
+ "notes": "Clicking the control itself also toggles when wrapped in a label."
443
+ },
444
+ {
445
+ "id": "checkbox.base-ui.linked-label-toggles",
446
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox/root/CheckboxRoot.test.tsx#L604",
447
+ "upstreamTest": "with native <label> > should toggle the checkbox when a explicitly linked <label> is clicked",
448
+ "apg": "extension",
449
+ "config": { "part": "checkbox", "labelFor": true },
450
+ "steps": [
451
+ { "event": "click", "target": "label" },
452
+ { "expect": { "attrs": { "checkbox": { "aria-checked": "true" } } } }
453
+ ],
454
+ "notes": "A label with htmlFor pointing at the checkbox toggles it."
455
+ },
456
+ {
457
+ "id": "checkbox.base-ui.native-button-id-association",
458
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox/root/CheckboxRoot.test.tsx#L622",
459
+ "upstreamTest": "with native <label> > should associate id with the native button when nativeButton=true",
460
+ "apg": "extension",
461
+ "config": { "part": "checkbox", "nativeButton": true, "labelFor": true },
462
+ "steps": [
463
+ { "event": "prop", "set": {} },
464
+ {
465
+ "expect": {
466
+ "attrs": {
467
+ "checkbox": { "id": "myCheckbox" },
468
+ "input:hidden": { "id": null }
469
+ }
470
+ }
471
+ },
472
+ { "event": "click", "target": "label" },
473
+ { "expect": { "attrs": { "checkbox": { "aria-checked": "true" } } } }
474
+ ],
475
+ "notes": "In native-button mode the id lives on the button; the label still toggles."
476
+ },
477
+ {
478
+ "id": "checkbox.base-ui.aria-labelledby-from-sibling-label",
479
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox/root/CheckboxRoot.test.tsx#L1785",
480
+ "upstreamTest": "sets aria-labelledby from a sibling label associated with the hidden input",
481
+ "apg": "aria",
482
+ "config": { "part": "checkbox", "label": "Label", "labelFor": true },
483
+ "steps": [
484
+ { "event": "prop", "set": {} },
485
+ {
486
+ "expect": { "attrs": { "checkbox": { "aria-labelledby": "label" } } }
487
+ }
488
+ ],
489
+ "notes": "A sibling <label htmlFor> supplies the accessible name."
490
+ },
491
+ {
492
+ "id": "checkbox.base-ui.aria-labelledby-updates-with-input-id",
493
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox/root/CheckboxRoot.test.tsx#L1798",
494
+ "upstreamTest": "updates fallback aria-labelledby when the hidden input id changes",
495
+ "apg": "aria",
496
+ "config": { "part": "checkbox", "labels": ["Label A", "Label B"] },
497
+ "steps": [
498
+ { "event": "prop", "set": { "id": "checkbox-input-a" } },
499
+ {
500
+ "expect": {
501
+ "attrs": { "checkbox": { "aria-labelledby": "label-a" } }
502
+ }
503
+ },
504
+ { "event": "prop", "set": { "id": "checkbox-input-b" } },
505
+ {
506
+ "expect": {
507
+ "attrs": { "checkbox": { "aria-labelledby": "label-b" } }
508
+ }
509
+ }
510
+ ],
511
+ "notes": "aria-labelledby tracks the current associated label."
512
+ },
513
+ {
514
+ "id": "checkbox.base-ui.aria-label-preferred-over-label",
515
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox/root/CheckboxRoot.test.tsx#L1833",
516
+ "upstreamTest": "prefers aria-label over an associated label",
517
+ "apg": "aria",
518
+ "config": {
519
+ "part": "checkbox",
520
+ "aria-label": "lease.pdf",
521
+ "label": "lease.pdf"
522
+ },
523
+ "steps": [
524
+ { "event": "prop", "set": {} },
525
+ { "expect": { "attrs": { "checkbox": { "aria-labelledby": null } } } }
526
+ ],
527
+ "notes": "With aria-label present the wrapping label is not referenced."
528
+ },
529
+ {
530
+ "id": "checkbox.base-ui.blank-aria-label-ignored",
531
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox/root/CheckboxRoot.test.tsx#L1856",
532
+ "upstreamTest": "ignores a blank `aria-label`",
533
+ "apg": "aria",
534
+ "config": {
535
+ "part": "checkbox",
536
+ "aria-label": " ",
537
+ "label": "Native label"
538
+ },
539
+ "steps": [
540
+ { "event": "prop", "set": {} },
541
+ { "expect": { "attrs": { "checkbox": { "aria-label": null } } } }
542
+ ],
543
+ "notes": "Whitespace-only aria-label is ignored, so the associated label names the control."
544
+ },
545
+ {
546
+ "id": "checkbox.base-ui.native-button-enter-and-space",
547
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox/root/CheckboxRoot.test.tsx#L1947",
548
+ "upstreamTest": "can render a native button",
549
+ "apg": "keyboard",
550
+ "config": { "part": "checkbox", "nativeButton": true },
551
+ "steps": [
552
+ { "event": "key", "key": "Tab" },
553
+ {
554
+ "expect": {
555
+ "focus": "checkbox",
556
+ "attrs": { "checkbox": { "aria-checked": "false" } }
557
+ }
558
+ },
559
+ { "event": "key", "key": "Enter", "target": "checkbox" },
560
+ { "expect": { "attrs": { "checkbox": { "aria-checked": "false" } } } },
561
+ { "event": "key", "key": " ", "target": "checkbox" },
562
+ { "expect": { "attrs": { "checkbox": { "aria-checked": "true" } } } },
563
+ { "event": "click", "target": "checkbox" },
564
+ { "expect": { "attrs": { "checkbox": { "aria-checked": "false" } } } }
565
+ ],
566
+ "notes": "Even as a native button the checkbox pattern keeps Enter inert and Space/click toggling."
567
+ },
568
+ {
569
+ "id": "checkbox.base-ui.group-controlled-value",
570
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox-group/CheckboxGroup.test.tsx#L30",
571
+ "upstreamTest": "prop: value > should control the value",
572
+ "apg": "states",
573
+ "config": {
574
+ "group": true,
575
+ "value": ["red"],
576
+ "values": ["red", "green", "blue"]
577
+ },
578
+ "steps": [
579
+ { "event": "prop", "set": {} },
580
+ {
581
+ "expect": {
582
+ "attrs": {
583
+ "checkbox:0": { "aria-checked": "true" },
584
+ "checkbox:1": { "aria-checked": "false" }
585
+ }
586
+ }
587
+ },
588
+ { "event": "click", "target": "checkbox:1" },
589
+ {
590
+ "expect": {
591
+ "attrs": {
592
+ "checkbox:0": { "aria-checked": "true" },
593
+ "checkbox:1": { "aria-checked": "true" }
594
+ }
595
+ }
596
+ },
597
+ { "event": "click", "target": "checkbox:0" },
598
+ {
599
+ "expect": {
600
+ "attrs": {
601
+ "checkbox:0": { "aria-checked": "false" },
602
+ "checkbox:1": { "aria-checked": "true" }
603
+ }
604
+ }
605
+ }
606
+ ],
607
+ "notes": "Controlled array determines which checkboxes are checked."
608
+ },
609
+ {
610
+ "id": "checkbox.base-ui.group-empty-string-value",
611
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox-group/CheckboxGroup.test.tsx#L71",
612
+ "upstreamTest": "prop: value > supports an empty string item value",
613
+ "apg": "extension",
614
+ "config": { "group": true, "value": [""], "values": ["", "other"] },
615
+ "steps": [
616
+ { "event": "prop", "set": {} },
617
+ {
618
+ "expect": {
619
+ "attrs": {
620
+ "checkbox:0": { "aria-checked": "true" },
621
+ "checkbox:1": { "aria-checked": "false" }
622
+ }
623
+ }
624
+ },
625
+ { "event": "click", "target": "checkbox:0" },
626
+ { "expect": { "attrs": { "checkbox:0": { "aria-checked": "false" } } } }
627
+ ],
628
+ "notes": "An empty-string value is a valid selectable item."
629
+ },
630
+ {
631
+ "id": "checkbox.base-ui.group-controlled-value-undefined-becomes-empty",
632
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox-group/CheckboxGroup.test.tsx#L95",
633
+ "upstreamTest": "prop: value > treats a controlled value that becomes undefined as an empty array",
634
+ "apg": "extension",
635
+ "config": { "group": true, "value": ["red"] },
636
+ "steps": [
637
+ { "event": "prop", "set": { "value": ["red"] } },
638
+ { "expect": { "attrs": { "checkbox:0": { "aria-checked": "true" } } } },
639
+ { "event": "prop", "set": { "value": null } },
640
+ { "expect": { "attrs": { "checkbox:0": { "aria-checked": "false" } } } }
641
+ ],
642
+ "notes": "A controlled value that becomes undefined/null is treated as empty."
643
+ },
644
+ {
645
+ "id": "checkbox.base-ui.group-onvaluechange",
646
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox-group/CheckboxGroup.test.tsx#L127",
647
+ "upstreamTest": "prop: onValueChange > should be called when the value changes",
648
+ "apg": "extension",
649
+ "config": {
650
+ "group": true,
651
+ "value": [],
652
+ "values": ["red", "green", "blue"]
653
+ },
654
+ "steps": [
655
+ { "event": "click", "target": "checkbox:0" },
656
+ { "expect": { "events": { "onValueChange": [["red"]] } } },
657
+ { "event": "click", "target": "checkbox:1" },
658
+ { "expect": { "events": { "onValueChange": [["red", "green"]] } } },
659
+ { "event": "click", "target": "checkbox:2" },
660
+ {
661
+ "expect": {
662
+ "events": { "onValueChange": [["red", "green", "blue"]] }
663
+ }
664
+ }
665
+ ],
666
+ "notes": "Callback receives the next checked-values array."
667
+ },
668
+ {
669
+ "id": "checkbox.base-ui.group-omitted-defaultvalue",
670
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox-group/CheckboxGroup.test.tsx#L169",
671
+ "upstreamTest": "prop: onValueChange > should treat an omitted defaultValue as an empty array",
672
+ "apg": "states",
673
+ "config": { "group": true },
674
+ "steps": [
675
+ { "event": "click", "target": "checkbox:0" },
676
+ { "expect": { "events": { "onValueChange": [["red"]] } } },
677
+ { "event": "click", "target": "checkbox:1" },
678
+ { "expect": { "events": { "onValueChange": [["red", "green"]] } } },
679
+ { "event": "click", "target": "checkbox:0" },
680
+ { "expect": { "events": { "onValueChange": [["green"]] } } }
681
+ ],
682
+ "notes": "Uncontrolled group starts empty and unchecking removes the item."
683
+ },
684
+ {
685
+ "id": "checkbox.base-ui.group-onvaluechange-cancel",
686
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox-group/CheckboxGroup.test.tsx#L196",
687
+ "upstreamTest": "prop: onValueChange > does not update the group when onValueChange cancels the event",
688
+ "apg": "extension",
689
+ "config": { "group": true, "cancelOnValueChange": true },
690
+ "steps": [
691
+ { "event": "click", "target": "checkbox:0" },
692
+ {
693
+ "expect": {
694
+ "attrs": { "checkbox:0": { "aria-checked": "false" } },
695
+ "events": { "onValueChange": [["red"]] }
696
+ }
697
+ }
698
+ ],
699
+ "notes": "cancel() leaves the group value unchanged."
700
+ },
701
+ {
702
+ "id": "checkbox.base-ui.group-default-label",
703
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox-group/CheckboxGroup.test.tsx#L230",
704
+ "upstreamTest": "prop: defaultValue > should set the initial value",
705
+ "apg": "states",
706
+ "config": {
707
+ "group": true,
708
+ "defaultValue": ["red"],
709
+ "values": ["red", "green", "blue"]
710
+ },
711
+ "steps": [
712
+ { "event": "prop", "set": {} },
713
+ {
714
+ "expect": {
715
+ "attrs": {
716
+ "checkbox:0": { "aria-checked": "true" },
717
+ "checkbox:1": { "aria-checked": "false" }
718
+ }
719
+ }
720
+ },
721
+ { "event": "click", "target": "checkbox:1" },
722
+ {
723
+ "expect": {
724
+ "attrs": {
725
+ "checkbox:0": { "aria-checked": "true" },
726
+ "checkbox:1": { "aria-checked": "true" }
727
+ }
728
+ }
729
+ }
730
+ ],
731
+ "notes": "defaultValue seeds an uncontrolled group."
732
+ },
733
+ {
734
+ "id": "checkbox.base-ui.group-disabled-all",
735
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox-group/CheckboxGroup.test.tsx#L305",
736
+ "upstreamTest": "prop: disabled > disables all checkboxes when true",
737
+ "apg": "states",
738
+ "config": { "group": true, "disabled": true },
739
+ "steps": [
740
+ { "event": "prop", "set": {} },
741
+ {
742
+ "expect": {
743
+ "attrs": {
744
+ "checkbox:0": { "aria-disabled": "true" },
745
+ "checkbox:1": { "aria-disabled": "true" },
746
+ "checkbox:2": { "aria-disabled": "true" }
747
+ }
748
+ }
749
+ }
750
+ ],
751
+ "notes": "Group disabled propagates aria-disabled to all items."
752
+ },
753
+ {
754
+ "id": "checkbox.base-ui.group-disabled-precedence",
755
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox-group/CheckboxGroup.test.tsx#L349",
756
+ "upstreamTest": "prop: disabled > takes precedence over individual checkboxes",
757
+ "apg": "states",
758
+ "config": { "group": true, "disabled": true, "itemDisabled": false },
759
+ "steps": [
760
+ { "event": "prop", "set": {} },
761
+ { "expect": { "attrs": { "checkbox:0": { "aria-disabled": "true" } } } }
762
+ ],
763
+ "notes": "Group disabled wins over a per-item disabled=false."
764
+ },
765
+ {
766
+ "id": "checkbox.base-ui.parent-controls-children",
767
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox-group/useCheckboxGroupParent.test.tsx#L11",
768
+ "upstreamTest": "should control child checkboxes",
769
+ "apg": "extension",
770
+ "config": { "group": true, "parent": true, "values": ["a", "b", "c"] },
771
+ "steps": [
772
+ { "event": "prop", "set": {} },
773
+ {
774
+ "expect": {
775
+ "attrs": {
776
+ "checkbox:parent": { "aria-checked": "false" },
777
+ "checkbox:0": { "aria-checked": "false" },
778
+ "checkbox:1": { "aria-checked": "false" },
779
+ "checkbox:2": { "aria-checked": "false" }
780
+ }
781
+ }
782
+ },
783
+ { "event": "click", "target": "checkbox:parent" },
784
+ {
785
+ "expect": {
786
+ "attrs": {
787
+ "checkbox:parent": { "aria-checked": "true" },
788
+ "checkbox:0": { "aria-checked": "true" },
789
+ "checkbox:1": { "aria-checked": "true" },
790
+ "checkbox:2": { "aria-checked": "true" }
791
+ }
792
+ }
793
+ },
794
+ { "event": "click", "target": "checkbox:parent" },
795
+ {
796
+ "expect": {
797
+ "attrs": {
798
+ "checkbox:parent": { "aria-checked": "false" },
799
+ "checkbox:0": { "aria-checked": "false" },
800
+ "checkbox:1": { "aria-checked": "false" },
801
+ "checkbox:2": { "aria-checked": "false" }
802
+ }
803
+ }
804
+ }
805
+ ],
806
+ "notes": "Parent checkbox checks/unchecks all children; child onChange does not fire for parent-driven changes."
807
+ },
808
+ {
809
+ "id": "checkbox.base-ui.parent-mixed-when-some-children-checked",
810
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox-group/useCheckboxGroupParent.test.tsx#L58",
811
+ "upstreamTest": "parent should be marked as mixed if some children are checked",
812
+ "apg": "states",
813
+ "config": { "group": true, "parent": true, "values": ["a", "b", "c"] },
814
+ "steps": [
815
+ { "event": "click", "target": "checkbox:0" },
816
+ {
817
+ "expect": {
818
+ "attrs": { "checkbox:parent": { "aria-checked": "mixed" } }
819
+ }
820
+ }
821
+ ],
822
+ "notes": "Partial selection makes the parent mixed."
823
+ },
824
+ {
825
+ "id": "checkbox.base-ui.parent-uncontrolled-updates",
826
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox-group/useCheckboxGroupParent.test.tsx#L87",
827
+ "upstreamTest": "updates uncontrolled parent-enabled groups from child clicks without duplicate callbacks",
828
+ "apg": "states",
829
+ "config": { "group": true, "parent": true, "values": ["a", "b", "c"] },
830
+ "steps": [
831
+ { "event": "click", "target": "checkbox:0" },
832
+ {
833
+ "expect": {
834
+ "attrs": { "checkbox:parent": { "aria-checked": "mixed" } },
835
+ "events": { "onValueChange": [["a"]] }
836
+ }
837
+ },
838
+ { "event": "click", "target": "checkbox:parent" },
839
+ {
840
+ "expect": {
841
+ "attrs": {
842
+ "checkbox:parent": { "aria-checked": "true" },
843
+ "checkbox:1": { "aria-checked": "true" },
844
+ "checkbox:2": { "aria-checked": "true" }
845
+ },
846
+ "events": { "onValueChange": [["a", "b", "c"]] }
847
+ }
848
+ },
849
+ { "event": "click", "target": "checkbox:parent" },
850
+ {
851
+ "expect": {
852
+ "attrs": {
853
+ "checkbox:parent": { "aria-checked": "false" },
854
+ "checkbox:0": { "aria-checked": "false" }
855
+ },
856
+ "events": { "onValueChange": [[]] }
857
+ }
858
+ }
859
+ ],
860
+ "notes": "Child click fires onValueChange once; parent click checks all then clears."
861
+ },
862
+ {
863
+ "id": "checkbox.base-ui.parent-initial-values",
864
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox-group/useCheckboxGroupParent.test.tsx#L131",
865
+ "upstreamTest": "should correctly initialize the values array",
866
+ "apg": "states",
867
+ "config": {
868
+ "group": true,
869
+ "parent": true,
870
+ "value": ["a"],
871
+ "values": ["a", "b", "c"]
872
+ },
873
+ "steps": [
874
+ { "event": "prop", "set": {} },
875
+ {
876
+ "expect": {
877
+ "attrs": {
878
+ "checkbox:parent": { "aria-checked": "mixed" },
879
+ "checkbox:0": { "aria-checked": "true" }
880
+ }
881
+ }
882
+ }
883
+ ],
884
+ "notes": "Initial partial value makes the parent mixed."
885
+ },
886
+ {
887
+ "id": "checkbox.base-ui.parent-aria-controls",
888
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox-group/useCheckboxGroupParent.test.tsx#L184",
889
+ "upstreamTest": "should apply space-separated aria-controls attribute with child names",
890
+ "apg": "aria",
891
+ "config": { "group": true, "parent": true, "values": ["a", "b", "c"] },
892
+ "steps": [
893
+ { "event": "prop", "set": {} },
894
+ {
895
+ "expect": {
896
+ "attrs": {
897
+ "checkbox:parent": {
898
+ "aria-controls": "checkbox-a checkbox-b checkbox-c"
899
+ }
900
+ }
901
+ }
902
+ }
903
+ ],
904
+ "notes": "Parent aria-controls lists the child control ids, space separated."
905
+ },
906
+ {
907
+ "id": "checkbox.base-ui.parent-aria-controls-drops-unmounted",
908
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox-group/useCheckboxGroupParent.test.tsx#L272",
909
+ "upstreamTest": "drops an unmounted child from aria-controls",
910
+ "apg": "aria",
911
+ "config": {
912
+ "group": true,
913
+ "parent": true,
914
+ "values": ["a", "b"],
915
+ "initialMounted": ["a", "b"]
916
+ },
917
+ "steps": [
918
+ { "event": "prop", "set": { "mounted": ["a"] } },
919
+ {
920
+ "expect": {
921
+ "attrs": { "checkbox:parent": { "aria-controls": "checkbox-a" } }
922
+ }
923
+ }
924
+ ],
925
+ "notes": "Unmounted children are removed from aria-controls."
926
+ },
927
+ {
928
+ "id": "checkbox.base-ui.parent-does-not-select-valueless-child",
929
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox-group/useCheckboxGroupParent.test.tsx#L319",
930
+ "upstreamTest": "does not select a child without an identifying value",
931
+ "apg": "extension",
932
+ "config": {
933
+ "group": true,
934
+ "parent": true,
935
+ "values": ["a"],
936
+ "includeValueless": true
937
+ },
938
+ "steps": [
939
+ { "event": "click", "target": "checkbox:parent" },
940
+ {
941
+ "expect": {
942
+ "attrs": {
943
+ "checkbox:parent": { "aria-checked": "true" },
944
+ "checkbox:valueless": { "aria-checked": "false" }
945
+ }
946
+ }
947
+ }
948
+ ],
949
+ "notes": "Parent only toggles children that carry a value."
950
+ },
951
+ {
952
+ "id": "checkbox.base-ui.parent-preserves-mixed-cycle",
953
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox-group/useCheckboxGroupParent.test.tsx#L340",
954
+ "upstreamTest": "preserves initial state if mixed when parent is clicked",
955
+ "apg": "states",
956
+ "config": { "group": true, "parent": true, "values": ["a", "b", "c"] },
957
+ "steps": [
958
+ { "event": "click", "target": "checkbox:0" },
959
+ {
960
+ "expect": {
961
+ "attrs": { "checkbox:parent": { "aria-checked": "mixed" } }
962
+ }
963
+ },
964
+ { "event": "click", "target": "checkbox:parent" },
965
+ {
966
+ "expect": {
967
+ "attrs": {
968
+ "checkbox:parent": { "aria-checked": "true" },
969
+ "checkbox:0": { "aria-checked": "true" },
970
+ "checkbox:1": { "aria-checked": "true" },
971
+ "checkbox:2": { "aria-checked": "true" }
972
+ }
973
+ }
974
+ },
975
+ { "event": "click", "target": "checkbox:parent" },
976
+ {
977
+ "expect": {
978
+ "attrs": {
979
+ "checkbox:parent": { "aria-checked": "false" },
980
+ "checkbox:0": { "aria-checked": "false" }
981
+ }
982
+ }
983
+ },
984
+ { "event": "click", "target": "checkbox:parent" },
985
+ {
986
+ "expect": {
987
+ "attrs": {
988
+ "checkbox:parent": { "aria-checked": "mixed" },
989
+ "checkbox:0": { "aria-checked": "true" },
990
+ "checkbox:1": { "aria-checked": "false" }
991
+ }
992
+ }
993
+ }
994
+ ],
995
+ "notes": "mixed -> all -> none -> the previous mixed snapshot."
996
+ },
997
+ {
998
+ "id": "checkbox.base-ui.parent-cancel-change",
999
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox-group/useCheckboxGroupParent.test.tsx#L386",
1000
+ "upstreamTest": "lets a parent checkbox cancel a parent-enabled group change",
1001
+ "apg": "extension",
1002
+ "config": {
1003
+ "group": true,
1004
+ "parent": true,
1005
+ "values": ["a", "b", "c"],
1006
+ "cancelParentChange": true
1007
+ },
1008
+ "steps": [
1009
+ { "event": "click", "target": "checkbox:parent" },
1010
+ {
1011
+ "expect": {
1012
+ "attrs": {
1013
+ "checkbox:parent": { "aria-checked": "false" },
1014
+ "checkbox:0": { "aria-checked": "false" }
1015
+ },
1016
+ "events": { "onValueChange": [0] }
1017
+ }
1018
+ }
1019
+ ],
1020
+ "notes": "Cancelling the parent leaves the group unchanged and never fires onValueChange."
1021
+ },
1022
+ {
1023
+ "id": "checkbox.base-ui.child-cancel-change",
1024
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox-group/useCheckboxGroupParent.test.tsx#L411",
1025
+ "upstreamTest": "lets a child checkbox cancel a parent-enabled group change",
1026
+ "apg": "extension",
1027
+ "config": {
1028
+ "group": true,
1029
+ "parent": true,
1030
+ "values": ["a", "b", "c"],
1031
+ "cancelChildChange": true
1032
+ },
1033
+ "steps": [
1034
+ { "event": "click", "target": "checkbox:0" },
1035
+ {
1036
+ "expect": {
1037
+ "attrs": {
1038
+ "checkbox:parent": { "aria-checked": "false" },
1039
+ "checkbox:0": { "aria-checked": "false" }
1040
+ },
1041
+ "events": { "onValueChange": [0] }
1042
+ }
1043
+ }
1044
+ ],
1045
+ "notes": "Cancelling a child leaves the parent and group untouched."
1046
+ },
1047
+ {
1048
+ "id": "checkbox.base-ui.parent-toggle-cycle-not-advanced-on-cancel",
1049
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox-group/useCheckboxGroupParent.test.tsx#L434",
1050
+ "upstreamTest": "does not advance the parent toggle cycle when the group cancels a parent change",
1051
+ "apg": "extension",
1052
+ "config": {
1053
+ "group": true,
1054
+ "parent": true,
1055
+ "value": ["a"],
1056
+ "values": ["a", "b", "c"],
1057
+ "cancelAllGroupChanges": true
1058
+ },
1059
+ "steps": [
1060
+ { "event": "click", "target": "checkbox:parent" },
1061
+ { "expect": { "events": { "onValueChange": [["a", "b", "c"]] } } },
1062
+ { "event": "click", "target": "checkbox:parent" },
1063
+ { "expect": { "events": { "onValueChange": [["a", "b", "c"]] } } }
1064
+ ],
1065
+ "notes": "Because the group cancels both attempts, the parent retries mixed->all each time instead of advancing."
1066
+ },
1067
+ {
1068
+ "id": "checkbox.base-ui.unchecked-disabled-child",
1069
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox-group/useCheckboxGroupParent.test.tsx#L488",
1070
+ "upstreamTest": "handles unchecked disabled checkboxes",
1071
+ "apg": "states",
1072
+ "config": {
1073
+ "group": true,
1074
+ "parent": true,
1075
+ "values": ["a", "b", "c"],
1076
+ "disabledChild": 0
1077
+ },
1078
+ "steps": [
1079
+ { "event": "click", "target": "checkbox:parent" },
1080
+ {
1081
+ "expect": {
1082
+ "attrs": {
1083
+ "checkbox:parent": { "aria-checked": "mixed" },
1084
+ "checkbox:0": { "aria-checked": "false" }
1085
+ }
1086
+ }
1087
+ }
1088
+ ],
1089
+ "notes": "A disabled unchecked child prevents the parent from reaching checked."
1090
+ },
1091
+ {
1092
+ "id": "checkbox.base-ui.checked-disabled-child",
1093
+ "upstream": "https://github.com/mui/base-ui/blob/19511bb171f3b360b006c94cf6d07e53cb446505/packages/react/src/checkbox-group/useCheckboxGroupParent.test.tsx#L510",
1094
+ "upstreamTest": "handles checked disabled checkboxes",
1095
+ "apg": "states",
1096
+ "config": {
1097
+ "group": true,
1098
+ "parent": true,
1099
+ "value": ["a"],
1100
+ "values": ["a", "b", "c"],
1101
+ "disabledChild": 0
1102
+ },
1103
+ "steps": [
1104
+ { "event": "click", "target": "checkbox:parent" },
1105
+ {
1106
+ "expect": {
1107
+ "attrs": {
1108
+ "checkbox:0": { "aria-checked": "true" },
1109
+ "checkbox:1": { "aria-checked": "true" }
1110
+ }
1111
+ }
1112
+ },
1113
+ { "event": "click", "target": "checkbox:parent" },
1114
+ {
1115
+ "expect": {
1116
+ "attrs": {
1117
+ "checkbox:0": { "aria-checked": "true" },
1118
+ "checkbox:1": { "aria-checked": "false" }
1119
+ }
1120
+ }
1121
+ }
1122
+ ],
1123
+ "notes": "A disabled checked child is not unchecked by the parent's clear pass."
1124
+ }
1125
+ ]
1126
+ }