@exponential-at/ui 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (251) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +54 -0
  3. package/README.md +360 -2
  4. package/catalog/a11y.json +668 -0
  5. package/catalog/basic-map.json +104 -0
  6. package/catalog/code.json +58 -0
  7. package/catalog/core.catalog.json +4752 -0
  8. package/catalog/core.schema.json +22667 -0
  9. package/catalog/host.json +64 -0
  10. package/catalog/layout.json +20 -0
  11. package/catalog/limits.json +9 -0
  12. package/catalog/locale.json +48 -0
  13. package/catalog/macros.json +3417 -0
  14. package/catalog/recipes.json +61 -0
  15. package/catalog/strings.json +72 -0
  16. package/catalog/style.json +128 -0
  17. package/catalog/theme.schema.json +42543 -0
  18. package/catalog/tokens.json +47 -0
  19. package/conformance/README.md +217 -0
  20. package/conformance/baseline.ts +101 -0
  21. package/conformance/browser-page.ts +146 -0
  22. package/conformance/browser-suites.ts +683 -0
  23. package/conformance/compare.ts +201 -0
  24. package/conformance/dom.ts +96 -0
  25. package/conformance/dump.ts +163 -0
  26. package/conformance/fonts.json +154 -0
  27. package/conformance/manifest.json +224 -0
  28. package/conformance/parity-compare.ts +191 -0
  29. package/conformance/parity-report.schema.json +73 -0
  30. package/conformance/parity.ts +412 -0
  31. package/conformance/pixel.ts +177 -0
  32. package/conformance/primitives-page.ts +49 -0
  33. package/conformance/report.schema.json +66 -0
  34. package/conformance/run.ts +118 -0
  35. package/dist/chunks/index-98npjvsd.js +3940 -0
  36. package/dist/chunks/index-98npjvsd.js.map +27 -0
  37. package/dist/chunks/index-gwkt14w3.js +7314 -0
  38. package/dist/chunks/index-gwkt14w3.js.map +10 -0
  39. package/dist/chunks/index-njt7yzzm.js +134 -0
  40. package/dist/chunks/index-njt7yzzm.js.map +9 -0
  41. package/dist/chunks/index-we7va6v6.js +7984 -0
  42. package/dist/chunks/index-we7va6v6.js.map +15 -0
  43. package/dist/chunks/index-xrm6f7wc.js +2563 -0
  44. package/dist/chunks/index-xrm6f7wc.js.map +10 -0
  45. package/dist/conformance.js +182749 -0
  46. package/dist/conformance.js.map +10 -0
  47. package/dist/entries/prompt.js +251 -0
  48. package/dist/entries/prompt.js.map +11 -0
  49. package/dist/entries/schema.js +1725 -0
  50. package/dist/entries/schema.js.map +11 -0
  51. package/dist/host/index.js +122 -0
  52. package/dist/host/index.js.map +9 -0
  53. package/dist/index.js +3213 -0
  54. package/dist/index.js.map +27 -0
  55. package/dist/types/src/a11y.d.ts +21 -0
  56. package/dist/types/src/animation.d.ts +76 -0
  57. package/dist/types/src/basic-map.d.ts +38 -0
  58. package/dist/types/src/builder.d.ts +50 -0
  59. package/dist/types/src/catalog.d.ts +54 -0
  60. package/dist/types/src/catalog.described.d.ts +33 -0
  61. package/dist/types/src/catalog.generated.d.ts +829 -0
  62. package/dist/types/src/chart.d.ts +46 -0
  63. package/dist/types/src/code.d.ts +44 -0
  64. package/dist/types/src/color.d.ts +20 -0
  65. package/dist/types/src/conformance.d.ts +39 -0
  66. package/dist/types/src/connector/app.d.ts +14 -0
  67. package/dist/types/src/connector/connector.d.ts +77 -0
  68. package/dist/types/src/connector/index.d.ts +4 -0
  69. package/dist/types/src/css.d.ts +29 -0
  70. package/dist/types/src/define.d.ts +66 -0
  71. package/dist/types/src/direction.d.ts +16 -0
  72. package/dist/types/src/dynamic.d.ts +159 -0
  73. package/dist/types/src/entries/prompt.d.ts +11 -0
  74. package/dist/types/src/entries/schema.d.ts +8 -0
  75. package/dist/types/src/expr.d.ts +71 -0
  76. package/dist/types/src/extension.d.ts +4 -0
  77. package/dist/types/src/format.d.ts +112 -0
  78. package/dist/types/src/geometry.d.ts +40 -0
  79. package/dist/types/src/host/contract.d.ts +188 -0
  80. package/dist/types/src/host/decoders.d.ts +61 -0
  81. package/dist/types/src/host/index.d.ts +11 -0
  82. package/dist/types/src/host/package.d.ts +58 -0
  83. package/dist/types/src/host/policy.d.ts +105 -0
  84. package/dist/types/src/host/router.d.ts +34 -0
  85. package/dist/types/src/host/runtime.d.ts +205 -0
  86. package/dist/types/src/host/sources.d.ts +15 -0
  87. package/dist/types/src/host/transports.d.ts +109 -0
  88. package/dist/types/src/index.d.ts +63 -0
  89. package/dist/types/src/layout.d.ts +20 -0
  90. package/dist/types/src/limits.d.ts +21 -0
  91. package/dist/types/src/list.d.ts +133 -0
  92. package/dist/types/src/locale.d.ts +22 -0
  93. package/dist/types/src/macros.d.ts +29 -0
  94. package/dist/types/src/overlay.d.ts +27 -0
  95. package/dist/types/src/prompt.d.ts +44 -0
  96. package/dist/types/src/recipes.d.ts +17 -0
  97. package/dist/types/src/reducer.d.ts +41 -0
  98. package/dist/types/src/resizable.d.ts +38 -0
  99. package/dist/types/src/schema.d.ts +7 -0
  100. package/dist/types/src/strings.d.ts +13 -0
  101. package/dist/types/src/style.d.ts +201 -0
  102. package/dist/types/src/test-preload.d.ts +1 -0
  103. package/dist/types/src/text-shimmer.d.ts +24 -0
  104. package/dist/types/src/theme-types.d.ts +162 -0
  105. package/dist/types/src/theme.d.ts +73 -0
  106. package/dist/types/src/themes.d.ts +22 -0
  107. package/dist/types/src/tree-guides.d.ts +17 -0
  108. package/dist/types/src/types.d.ts +314 -0
  109. package/dist/types/src/validate.d.ts +31 -0
  110. package/dist/types/src/web/base-css.d.ts +1 -0
  111. package/dist/types/src/web/box-css.d.ts +55 -0
  112. package/dist/types/src/web/coerce.d.ts +32 -0
  113. package/dist/types/src/web/data.d.ts +105 -0
  114. package/dist/types/src/web/dates.d.ts +12 -0
  115. package/dist/types/src/web/form.d.ts +44 -0
  116. package/dist/types/src/web/host-types.d.ts +119 -0
  117. package/dist/types/src/web/index.d.ts +28 -0
  118. package/dist/types/src/web/inputs.d.ts +55 -0
  119. package/dist/types/src/web/list.d.ts +13 -0
  120. package/dist/types/src/web/listbox.d.ts +14 -0
  121. package/dist/types/src/web/markdown.d.ts +96 -0
  122. package/dist/types/src/web/media.d.ts +62 -0
  123. package/dist/types/src/web/parts.d.ts +4 -0
  124. package/dist/types/src/web/primitives/alert-dialog.d.ts +10 -0
  125. package/dist/types/src/web/primitives/alert.d.ts +9 -0
  126. package/dist/types/src/web/primitives/avatar-color.d.ts +2 -0
  127. package/dist/types/src/web/primitives/avatar.d.ts +13 -0
  128. package/dist/types/src/web/primitives/badge.d.ts +10 -0
  129. package/dist/types/src/web/primitives/breadcrumb.d.ts +10 -0
  130. package/dist/types/src/web/primitives/button.d.ts +6 -0
  131. package/dist/types/src/web/primitives/calendar.d.ts +43 -0
  132. package/dist/types/src/web/primitives/card.d.ts +9 -0
  133. package/dist/types/src/web/primitives/checkbox.d.ts +5 -0
  134. package/dist/types/src/web/primitives/choice-tiles.d.ts +32 -0
  135. package/dist/types/src/web/primitives/cn.d.ts +3 -0
  136. package/dist/types/src/web/primitives/code-block.d.ts +24 -0
  137. package/dist/types/src/web/primitives/command.d.ts +134 -0
  138. package/dist/types/src/web/primitives/context-ring.d.ts +24 -0
  139. package/dist/types/src/web/primitives/dialog-arms.d.ts +6 -0
  140. package/dist/types/src/web/primitives/dialog.d.ts +24 -0
  141. package/dist/types/src/web/primitives/disclosure-header.d.ts +5 -0
  142. package/dist/types/src/web/primitives/dock.d.ts +42 -0
  143. package/dist/types/src/web/primitives/dropdown-menu.d.ts +14 -0
  144. package/dist/types/src/web/primitives/empty-state.d.ts +15 -0
  145. package/dist/types/src/web/primitives/glass-card.d.ts +4 -0
  146. package/dist/types/src/web/primitives/hover-card.d.ts +7 -0
  147. package/dist/types/src/web/primitives/icon-disc.d.ts +12 -0
  148. package/dist/types/src/web/primitives/index.d.ts +48 -0
  149. package/dist/types/src/web/primitives/input.d.ts +5 -0
  150. package/dist/types/src/web/primitives/kbd.d.ts +4 -0
  151. package/dist/types/src/web/primitives/label.d.ts +3 -0
  152. package/dist/types/src/web/primitives/menu-surface.d.ts +17 -0
  153. package/dist/types/src/web/primitives/meter.d.ts +21 -0
  154. package/dist/types/src/web/primitives/popover.d.ts +3 -0
  155. package/dist/types/src/web/primitives/progress-ring.d.ts +5 -0
  156. package/dist/types/src/web/primitives/progress.d.ts +8 -0
  157. package/dist/types/src/web/primitives/scroll-area.d.ts +49 -0
  158. package/dist/types/src/web/primitives/segmented-control.d.ts +5 -0
  159. package/dist/types/src/web/primitives/select.d.ts +47 -0
  160. package/dist/types/src/web/primitives/separator.d.ts +3 -0
  161. package/dist/types/src/web/primitives/sheet-chrome.d.ts +4 -0
  162. package/dist/types/src/web/primitives/sheet.d.ts +20 -0
  163. package/dist/types/src/web/primitives/skeleton.d.ts +3 -0
  164. package/dist/types/src/web/primitives/spinner.d.ts +3 -0
  165. package/dist/types/src/web/primitives/switch.d.ts +4 -0
  166. package/dist/types/src/web/primitives/table.d.ts +11 -0
  167. package/dist/types/src/web/primitives/tabs.d.ts +13 -0
  168. package/dist/types/src/web/primitives/textarea.d.ts +3 -0
  169. package/dist/types/src/web/primitives/toast.d.ts +163 -0
  170. package/dist/types/src/web/primitives/tooltip.d.ts +3 -0
  171. package/dist/types/src/web/primitives/truncate.d.ts +7 -0
  172. package/dist/types/src/web/primitives/typeahead-portal.d.ts +12 -0
  173. package/dist/types/src/web/share.d.ts +6 -0
  174. package/dist/types/src/web/table.d.ts +20 -0
  175. package/dist/types/src/web/theme-css.d.ts +69 -0
  176. package/dist/types/src/web/urls.d.ts +21 -0
  177. package/dist/web/index.js +2303 -0
  178. package/dist/web/index.js.map +26 -0
  179. package/dist/web/primitives/index.js +1450 -0
  180. package/dist/web/primitives/index.js.map +57 -0
  181. package/docs/components.generated.json +6238 -0
  182. package/docs/round-1-contract.md +679 -0
  183. package/docs/round-2-contract.md +476 -0
  184. package/docs/round-3-contract.md +174 -0
  185. package/docs/themes.generated.json +3503 -0
  186. package/fixtures/animations.json +2890 -0
  187. package/fixtures/bench-list.json +58 -0
  188. package/fixtures/bind-time.json +30664 -0
  189. package/fixtures/catalog-basic-map.json +1692 -0
  190. package/fixtures/catalog-components.json +9323 -0
  191. package/fixtures/catalog-extension.json +620 -0
  192. package/fixtures/catalog-macros.json +36370 -0
  193. package/fixtures/code-tokens.json +1993 -0
  194. package/fixtures/conformance-baseline.json +55544 -0
  195. package/fixtures/conformance-cases.json +49 -0
  196. package/fixtures/conformance-known.json +2123 -0
  197. package/fixtures/control-geometry.json +4200 -0
  198. package/fixtures/dashboard.data.json +74 -0
  199. package/fixtures/dashboard.json +752 -0
  200. package/fixtures/demo-surface.json +47 -0
  201. package/fixtures/format.json +870 -0
  202. package/fixtures/host-policy.json +1067 -0
  203. package/fixtures/host-router.json +1152 -0
  204. package/fixtures/host-transport.json +590 -0
  205. package/fixtures/interactions-round1.json +773 -0
  206. package/fixtures/kitchen-sink.expanded.json +10844 -0
  207. package/fixtures/kitchen-sink.json +3049 -0
  208. package/fixtures/layout-geometry-round1.json +7278 -0
  209. package/fixtures/layout-geometry.json +2072 -0
  210. package/fixtures/overlay-geometry.json +272 -0
  211. package/fixtures/primitive-specimens.json +58 -0
  212. package/fixtures/prompt-budget.json +33 -0
  213. package/fixtures/resizable.json +714 -0
  214. package/fixtures/round4-contract.json +2985 -0
  215. package/fixtures/specimens.json +9832 -0
  216. package/fixtures/style-conditions.json +336 -0
  217. package/fixtures/template-items.json +2215 -0
  218. package/fixtures/text-direction.json +309 -0
  219. package/fixtures/text-shimmer.json +96 -0
  220. package/fixtures/theme-extends.json +573 -0
  221. package/fixtures/theme-invalid.json +1296 -0
  222. package/fixtures/theme-recipes.json +58600 -0
  223. package/fixtures/theme-resolved.json +23949 -0
  224. package/fixtures/toast-stack.json +215 -0
  225. package/fixtures/tree-guides.json +224 -0
  226. package/fixtures/virtual-list.json +733 -0
  227. package/generated/ExponentialUICatalog.generated.kt +67 -0
  228. package/generated/ExponentialUICatalog.generated.swift +67 -0
  229. package/generated/ExponentialUIThemes.generated.kt +23 -0
  230. package/generated/ExponentialUIThemes.generated.swift +23 -0
  231. package/generated/catalog.descriptions.generated.rs +6 -0
  232. package/generated/catalog.generated.rs +80 -0
  233. package/generated/catalog.themes.generated.rs +34 -0
  234. package/generated/core.descriptions.json +2505 -0
  235. package/generated/core.runtime.json +3609 -0
  236. package/package.json +87 -4
  237. package/themes/exponential.recipes.json +49 -0
  238. package/themes/exponential.theme.json +755 -0
  239. package/themes/neutral.theme.json +5676 -0
  240. package/themes/orange.theme.json +43 -0
  241. package/themes/playful.theme.json +219 -0
  242. package/vendor/a2ui/LICENSE.txt +203 -0
  243. package/vendor/a2ui/README.md +27 -0
  244. package/vendor/a2ui/v0_9/basic_catalog.json +1387 -0
  245. package/vendor/a2ui/v0_9/basic_catalog_rules.txt +5 -0
  246. package/vendor/a2ui/v0_9/client_capabilities.json +97 -0
  247. package/vendor/a2ui/v0_9/client_to_server.json +104 -0
  248. package/vendor/a2ui/v0_9/common_types.json +315 -0
  249. package/vendor/a2ui/v0_9/server_to_client.json +132 -0
  250. package/vendor/json-render/LICENSE.txt +201 -0
  251. package/vendor/json-render/README.md +13 -0
@@ -0,0 +1,668 @@
1
+ {
2
+ "$comment": "Round 1 (docs/round-1-contract.md §6): the ACCESSIBILITY contract every renderer keeps. `roles` = the MACHINE-READABLE role vocabulary (ARIA names, plus `text` = static text and `hidden` = out of the accessibility tree; SwiftUI traits / Compose semantics / AccessKit roles map from them), used by every `role` here and by the expanded tree's `accessibility.role`. `components` = per component its `role` (one of `roles`: the role of the component's main accessible object), `notes` (prose: composite parts, states, which strings name it) and the KEYBOARD expectations, one line per key group (arrows flip in RTL; a roving tab stop = one Tab stop for the group, arrows move inside it). Every component is listed (round1.test.ts gates it). `commands` = what a HOST may ask of a surface at runtime. `rules` = what holds for every component. Round 2 (docs/round-2-contract.md): Resizable, `scrollToIndex`, sections, the per-node direction rule. Append-only; docs/components.generated.json carries each component's entry.",
3
+ "roles": [
4
+ "alert",
5
+ "alertdialog",
6
+ "banner",
7
+ "button",
8
+ "checkbox",
9
+ "combobox",
10
+ "dialog",
11
+ "document",
12
+ "form",
13
+ "group",
14
+ "heading",
15
+ "hidden",
16
+ "img",
17
+ "link",
18
+ "list",
19
+ "listitem",
20
+ "main",
21
+ "menu",
22
+ "meter",
23
+ "navigation",
24
+ "none",
25
+ "progressbar",
26
+ "radio",
27
+ "radiogroup",
28
+ "region",
29
+ "separator",
30
+ "slider",
31
+ "spinbutton",
32
+ "status",
33
+ "switch",
34
+ "tablist",
35
+ "table",
36
+ "text",
37
+ "textbox",
38
+ "tooltip",
39
+ "tree",
40
+ "treeitem"
41
+ ],
42
+ "rules": [
43
+ "Every interactive node is reachable by Tab in reading order (tree order; a node's resolved `direction` flips its rows) and shows a focus ring only for keyboard focus (`:focus-visible`, recipe state `focus`).",
44
+ "A field's label, description and every error are linked to it (aria-labelledby / aria-describedby, contentDescription, accessibilityLabel/Hint); an error has the id `<node id>.error`.",
45
+ "`visible: false` removes the node from the accessibility tree; `visibility: hidden` hides it too; `display: none` likewise.",
46
+ "Icon-only buttons and standalone Icons take their `label` (or `accessibility.label`) as the accessible name; decorative icons are hidden.",
47
+ "`accessibility.label`/`description` on any node override the computed name/description.",
48
+ "Animations honour reduced motion: with `prefers-reduced-motion: reduce` transitions run at 0 ms, the Spinner/Skeleton shimmer stops and every style `animation` shows its rest keyframe.",
49
+ "Text and accessible names follow the NODE's direction (an inner `direction` box included): reading order, `textAlign` start/end and the bidi paragraph direction."
50
+ ],
51
+ "commands": {
52
+ "focus": {
53
+ "args": [
54
+ "id"
55
+ ],
56
+ "description": "Moves keyboard focus to the node with this id (the first focusable descendant of a non-focusable node); ignored when it is not rendered."
57
+ },
58
+ "announce": {
59
+ "args": [
60
+ "text",
61
+ "live"
62
+ ],
63
+ "description": "Speaks the text through the platform's live region (`polite` waits, `assertive` interrupts) without showing anything."
64
+ },
65
+ "scrollIntoView": {
66
+ "args": [
67
+ "id"
68
+ ],
69
+ "description": "Scrolls the nearest scrolling ancestor (List, ScrollArea, the surface) so the node is visible."
70
+ },
71
+ "scrollToIndex": {
72
+ "args": [
73
+ "id",
74
+ "index",
75
+ "align"
76
+ ],
77
+ "description": "Scrolls the List or Table `id` so its item (data index, before any local sort) is in view: `align` start | center | end | nearest (default), the pinned section header subtracted; a windowed list renders it first (src/list.ts scrollOffsetForIndex)."
78
+ }
79
+ },
80
+ "components": {
81
+ "Box": {
82
+ "role": "none",
83
+ "notes": "group (button when pressable). A pressable Box is a button.",
84
+ "keys": [
85
+ "Enter, Space: press (pressable only)"
86
+ ]
87
+ },
88
+ "Stack": {
89
+ "role": "none",
90
+ "notes": "none (layout only)",
91
+ "keys": []
92
+ },
93
+ "Grid": {
94
+ "role": "none",
95
+ "notes": "none (layout only)",
96
+ "keys": []
97
+ },
98
+ "Card": {
99
+ "role": "group",
100
+ "notes": "group labelled by its title",
101
+ "keys": []
102
+ },
103
+ "Separator": {
104
+ "role": "separator",
105
+ "notes": "separator",
106
+ "keys": []
107
+ },
108
+ "ScrollArea": {
109
+ "role": "region",
110
+ "notes": "region (scrollable, focusable when it overflows)",
111
+ "keys": [
112
+ "Arrow keys, PageUp/PageDown, Home/End scroll while focused"
113
+ ]
114
+ },
115
+ "Section": {
116
+ "role": "group",
117
+ "notes": "group; the header a heading (level 3) with the caption and count in its name, or a button with aria-expanded when collapsible; the rows a list (a tree when `tree`) of listitems",
118
+ "keys": [
119
+ "Enter, Space: fold when collapsible"
120
+ ]
121
+ },
122
+ "Group": {
123
+ "role": "group",
124
+ "notes": "group labelled by its title, described by its footer",
125
+ "keys": []
126
+ },
127
+ "Heading": {
128
+ "role": "heading",
129
+ "notes": "heading (level from h1–h4)",
130
+ "keys": []
131
+ },
132
+ "Kbd": {
133
+ "role": "text",
134
+ "notes": "text (the shortcut spelled out)",
135
+ "keys": []
136
+ },
137
+ "Label": {
138
+ "role": "text",
139
+ "notes": "label of the control named by `for`",
140
+ "keys": [
141
+ "Pressing it focuses that control"
142
+ ]
143
+ },
144
+ "Badge": {
145
+ "role": "text",
146
+ "notes": "text (status)",
147
+ "keys": []
148
+ },
149
+ "Alert": {
150
+ "role": "alert",
151
+ "notes": "alert for warning/error, status otherwise. alert for warning/error, status otherwise ($a11y).",
152
+ "keys": []
153
+ },
154
+ "EmptyState": {
155
+ "role": "status",
156
+ "notes": "status; the action = button",
157
+ "keys": [
158
+ "Enter, Space on the action"
159
+ ]
160
+ },
161
+ "Progress": {
162
+ "role": "progressbar",
163
+ "notes": "progressbar (valuenow/valuemax, labelled by its label)",
164
+ "keys": []
165
+ },
166
+ "Meter": {
167
+ "role": "meter",
168
+ "notes": "meter (value of max, labelled by its label)",
169
+ "keys": []
170
+ },
171
+ "Sparkline": {
172
+ "role": "img",
173
+ "notes": "img with a generated summary (first, last, min, max). The Chart painter names it with `sparklineSummary` (first, last, min, max).",
174
+ "keys": []
175
+ },
176
+ "List": {
177
+ "role": "list",
178
+ "notes": "list; each item a listitem with its position in the WHOLE list (aria-setsize/posinset, also when windowed); a section header is a heading (level 3) and stays first in reading order while pinned",
179
+ "keys": [
180
+ "Tab moves through the rows' controls; the list itself is one scroll region"
181
+ ]
182
+ },
183
+ "Resizable": {
184
+ "role": "group",
185
+ "notes": "group; each handle a focusable separator (aria-orientation = the line's, valuenow = the size of the panel before it, valuemin/max = its limits, controls = that panel), named `$string.resize`",
186
+ "keys": [
187
+ "Arrow keys on a handle: move it on screen by 10 points (Left/Right horizontal, Up/Down vertical; rtl: ArrowRight shrinks the first panel)",
188
+ "Home / End: the panel before the handle to its min / max",
189
+ "Enter: collapse or reopen a collapsible panel"
190
+ ]
191
+ },
192
+ "Text": {
193
+ "role": "text",
194
+ "notes": "text (a live region when `live` is not off)",
195
+ "keys": []
196
+ },
197
+ "Markdown": {
198
+ "role": "document",
199
+ "notes": "document fragment (headings, lists, links, tables keep their roles)",
200
+ "keys": [
201
+ "Tab moves through the links"
202
+ ]
203
+ },
204
+ "CodeBlock": {
205
+ "role": "region",
206
+ "notes": "region (code), copy = button",
207
+ "keys": [
208
+ "Tab reaches the copy button; Enter, Space: copy and announce `copied`"
209
+ ]
210
+ },
211
+ "Image": {
212
+ "role": "img",
213
+ "notes": "img (alt = name; decorative when alt is empty)",
214
+ "keys": []
215
+ },
216
+ "Icon": {
217
+ "role": "img",
218
+ "notes": "img when labelled, hidden otherwise",
219
+ "keys": []
220
+ },
221
+ "Video": {
222
+ "role": "group",
223
+ "notes": "video with the platform's controls",
224
+ "keys": [
225
+ "Space: play/pause; ArrowLeft/ArrowRight: seek 5 s"
226
+ ]
227
+ },
228
+ "AudioPlayer": {
229
+ "role": "group",
230
+ "notes": "audio with the platform's controls",
231
+ "keys": [
232
+ "Space: play/pause; ArrowLeft/ArrowRight: seek 5 s"
233
+ ]
234
+ },
235
+ "Avatar": {
236
+ "role": "img",
237
+ "notes": "img (name)",
238
+ "keys": []
239
+ },
240
+ "Carousel": {
241
+ "role": "region",
242
+ "notes": "region, roledescription carousel; each page a group `page i of n`",
243
+ "keys": [
244
+ "ArrowLeft/ArrowRight: previous/next page while focus is inside",
245
+ "Home/End: first/last page"
246
+ ]
247
+ },
248
+ "Tabs": {
249
+ "role": "tablist",
250
+ "notes": "tablist / tab / tabpanel",
251
+ "keys": [
252
+ "Roving tab stop on the tabs",
253
+ "ArrowLeft/ArrowRight: previous/next tab, activating it (wraps)",
254
+ "Home/End: first/last tab",
255
+ "Tab: into the active panel",
256
+ "Each close glyph (labelled `closeTab`, revealed by keyboard focus too) is a button after its tab; the + button (labelled `newTab`) follows the last tab"
257
+ ]
258
+ },
259
+ "Segmented": {
260
+ "role": "radiogroup",
261
+ "notes": "radiogroup (single) or toolbar of toggle buttons (multiple); `bar` = navigation of buttons, the selected one aria-current=page",
262
+ "keys": [
263
+ "Roving tab stop",
264
+ "ArrowLeft/ArrowRight (ArrowUp/ArrowDown): move focus (wraps)",
265
+ "Home/End: first/last",
266
+ "Space, Enter: toggle the focused item"
267
+ ]
268
+ },
269
+ "Accordion": {
270
+ "role": "group",
271
+ "notes": "headers = buttons with aria-expanded controlling regions",
272
+ "keys": [
273
+ "Enter, Space: toggle the focused section",
274
+ "ArrowDown/ArrowUp: next/previous header",
275
+ "Home/End: first/last header"
276
+ ]
277
+ },
278
+ "Dialog": {
279
+ "role": "dialog",
280
+ "notes": "dialog (modal)",
281
+ "keys": [
282
+ "Opening moves focus to the first focusable child (else the dialog)",
283
+ "Tab cycles inside the dialog (focus trap)",
284
+ "Escape: close when dismissible",
285
+ "Closing returns focus to the trigger"
286
+ ]
287
+ },
288
+ "Drawer": {
289
+ "role": "dialog",
290
+ "notes": "dialog (modal)",
291
+ "keys": [
292
+ "As Dialog; a swipe toward the edge closes when dragToDismiss"
293
+ ]
294
+ },
295
+ "DockCard": {
296
+ "role": "button",
297
+ "notes": "trigger = button named `label: title` ($a11y); the sheet is a Drawer (dialog, modal).",
298
+ "keys": [
299
+ "Enter, Space: open the sheet",
300
+ "As Drawer once open"
301
+ ]
302
+ },
303
+ "Popover": {
304
+ "role": "dialog",
305
+ "notes": "dialog (non-modal)",
306
+ "keys": [
307
+ "Enter, Space on the trigger: open",
308
+ "Escape: close and return focus to the trigger",
309
+ "openOn hover also opens on trigger focus"
310
+ ]
311
+ },
312
+ "Tooltip": {
313
+ "role": "tooltip",
314
+ "notes": "tooltip describing its anchor",
315
+ "keys": [
316
+ "Shows on hover AND keyboard focus of the anchor (after the platform delay); Escape hides"
317
+ ]
318
+ },
319
+ "Menu": {
320
+ "role": "menu",
321
+ "notes": "menu / menuitem / menuitemcheckbox / group / separator; `openOn: contextmenu` opens at the pointer",
322
+ "keys": [
323
+ "Enter, Space, ArrowDown on the trigger: open on the first item; ArrowUp: open on the last",
324
+ "Shift+F10 or the Menu key on the focused child (contextmenu): open at the child",
325
+ "ArrowDown/ArrowUp: next/previous item (wraps, skips disabled)",
326
+ "Home/End: first/last item",
327
+ "Enter, Space: run the item (a checkbox item toggles and stays open)",
328
+ "ArrowRight on a submenu: open it; ArrowLeft or Escape inside: close it",
329
+ "A searchable submenu opens with its filter input focused: typing filters, ArrowDown/ArrowUp move the active row, Enter picks it, ArrowLeft with the caret at the start or Escape closes it",
330
+ "Escape: close and return focus to the trigger",
331
+ "Typing a letter: the next item starting with it"
332
+ ]
333
+ },
334
+ "Toast": {
335
+ "role": "status",
336
+ "notes": "status (polite); alert (assertive) for type error",
337
+ "keys": [
338
+ "Never takes focus on appear; Tab reaches its action and close",
339
+ "Escape on a focused toast: dismiss",
340
+ "Hover or focus pauses the duration timer"
341
+ ]
342
+ },
343
+ "Ring": {
344
+ "role": "progressbar",
345
+ "notes": "progressbar (value 0..1 as percent)",
346
+ "keys": []
347
+ },
348
+ "Spinner": {
349
+ "role": "progressbar",
350
+ "notes": "progressbar (indeterminate) labelled `loading` by default",
351
+ "keys": []
352
+ },
353
+ "Skeleton": {
354
+ "role": "hidden",
355
+ "notes": "hidden (the parent announces busy)",
356
+ "keys": []
357
+ },
358
+ "Table": {
359
+ "role": "table",
360
+ "notes": "table (grid when selectable): columnheader with aria-sort, row with aria-selected",
361
+ "keys": [
362
+ "Enter, Space on a sortable header: cycle the sort (asc, desc)",
363
+ "Space on a row checkbox: toggle the row; on the header checkbox: select all",
364
+ "Enter on a focused row: rowPress",
365
+ "Tab moves through headers, checkboxes and cell controls"
366
+ ]
367
+ },
368
+ "Chart": {
369
+ "role": "img",
370
+ "notes": "img with a generated summary (kind, series, ranges); a data table fallback for screen readers. The painter names it with `chartSummary` (series, min, max) and offers a data table fallback.",
371
+ "keys": [
372
+ "ArrowLeft/ArrowRight while focused: move the tooltip between categories"
373
+ ]
374
+ },
375
+ "Button": {
376
+ "role": "button",
377
+ "notes": "button (aria-busy while loading)",
378
+ "keys": [
379
+ "Enter, Space: press",
380
+ "A `submit` button submits the enclosing Form"
381
+ ]
382
+ },
383
+ "Link": {
384
+ "role": "link",
385
+ "notes": "link",
386
+ "keys": [
387
+ "Enter: open / press"
388
+ ]
389
+ },
390
+ "Toggle": {
391
+ "role": "button",
392
+ "notes": "button with aria-pressed",
393
+ "keys": [
394
+ "Enter, Space: toggle"
395
+ ]
396
+ },
397
+ "Form": {
398
+ "role": "form",
399
+ "notes": "form",
400
+ "keys": [
401
+ "Enter in a single-line field: submit",
402
+ "A failed submit focuses the first invalid field and announces `invalidFields`"
403
+ ]
404
+ },
405
+ "Input": {
406
+ "role": "textbox",
407
+ "notes": "textbox",
408
+ "keys": [
409
+ "Enter: submit (fires `submit`, submits the Form)"
410
+ ]
411
+ },
412
+ "Textarea": {
413
+ "role": "textbox",
414
+ "notes": "textbox (multiline)",
415
+ "keys": [
416
+ "Enter: newline"
417
+ ]
418
+ },
419
+ "NumberField": {
420
+ "role": "spinbutton",
421
+ "notes": "spinbutton (valuemin/valuemax/valuenow)",
422
+ "keys": [
423
+ "ArrowUp/ArrowDown: ± step (Shift: ×10)",
424
+ "PageUp/PageDown: ± 10 steps",
425
+ "Home/End: min/max",
426
+ "Enter or blur: commit and clamp"
427
+ ]
428
+ },
429
+ "Checkbox": {
430
+ "role": "checkbox",
431
+ "notes": "checkbox",
432
+ "keys": [
433
+ "Space: toggle"
434
+ ]
435
+ },
436
+ "Radio": {
437
+ "role": "radiogroup",
438
+ "notes": "radiogroup / radio",
439
+ "keys": [
440
+ "Roving tab stop on the checked option",
441
+ "ArrowDown/ArrowRight: next option, selecting it (wraps)",
442
+ "ArrowUp/ArrowLeft: previous option"
443
+ ]
444
+ },
445
+ "ChoiceTiles": {
446
+ "role": "radiogroup",
447
+ "notes": "radiogroup of radio tiles (single) or a group of checkbox tiles (multiple); the picture is decorative, the label names the tile",
448
+ "keys": [
449
+ "Roving tab stop on the picked tile (the first when none)",
450
+ "ArrowRight/ArrowLeft, ArrowDown/ArrowUp: move focus (wraps); single: picks",
451
+ "Space, Enter: toggle the focused tile"
452
+ ]
453
+ },
454
+ "Switch": {
455
+ "role": "switch",
456
+ "notes": "switch; the label (and description) first, the switch at the end; the whole row toggles",
457
+ "keys": [
458
+ "Space, Enter: toggle"
459
+ ]
460
+ },
461
+ "Slider": {
462
+ "role": "slider",
463
+ "notes": "slider",
464
+ "keys": [
465
+ "ArrowRight/ArrowUp: + step; ArrowLeft/ArrowDown: - step",
466
+ "PageUp/PageDown: ± 10 steps",
467
+ "Home/End: min/max"
468
+ ]
469
+ },
470
+ "Select": {
471
+ "role": "combobox",
472
+ "notes": "combobox + listbox / option",
473
+ "keys": [
474
+ "Enter, Space, ArrowDown: open on the selected option",
475
+ "ArrowDown/ArrowUp: move the active option; Home/End: first/last",
476
+ "Enter: choose (multiple: toggle and stay open)",
477
+ "Escape: close without change",
478
+ "Typing: jump to the next matching option; with `searchable`, typing filters, focus stays in the search field and arrows move the active option (aria-activedescendant)"
479
+ ]
480
+ },
481
+ "SearchList": {
482
+ "role": "combobox",
483
+ "notes": "combobox (the input) controlling a listbox of options; the highlighted row = aria-activedescendant, the count a polite status",
484
+ "keys": [
485
+ "Focus stays in the input",
486
+ "ArrowDown/ArrowUp: move the highlighted row (no wrap, no animation)",
487
+ "Enter or Tab: pick the highlighted row (fires `select`)",
488
+ "Typing: filters; the top row is highlighted again"
489
+ ]
490
+ },
491
+ "ChipInput": {
492
+ "role": "textbox",
493
+ "notes": "textbox with a list of removable chips",
494
+ "keys": [
495
+ "Enter or comma: add the typed entry",
496
+ "Backspace in an empty field: focus the last chip, again: remove it",
497
+ "ArrowLeft/ArrowRight: move between chips; Delete, Backspace: remove the focused chip",
498
+ "ArrowDown: open the suggestions (as Select)"
499
+ ]
500
+ },
501
+ "DatePicker": {
502
+ "role": "combobox",
503
+ "notes": "combobox opening a dialog with a grid of days",
504
+ "keys": [
505
+ "Enter, Space, ArrowDown: open on the selected (else today's) day",
506
+ "Arrow keys: ± 1 day / ± 1 week",
507
+ "PageUp/PageDown: previous/next month (Shift: year)",
508
+ "Home/End: start/end of the week (locale week start)",
509
+ "Enter, Space: choose; Escape: close"
510
+ ]
511
+ },
512
+ "DateRangePicker": {
513
+ "role": "combobox",
514
+ "notes": "as DatePicker; the second choice ends the range",
515
+ "keys": [
516
+ "As DatePicker; the first Enter sets the start, the second the end"
517
+ ]
518
+ },
519
+ "TimePicker": {
520
+ "role": "combobox",
521
+ "notes": "combobox + listbox",
522
+ "keys": [
523
+ "As Select; typing `HH:mm` into the field commits on Enter or blur"
524
+ ]
525
+ },
526
+ "FileUpload": {
527
+ "role": "button",
528
+ "notes": "button (the drop zone) + a list of files with remove buttons",
529
+ "keys": [
530
+ "Enter, Space on the drop zone: open the file picker",
531
+ "Tab reaches each file's remove button"
532
+ ]
533
+ },
534
+ "Composer": {
535
+ "role": "textbox",
536
+ "notes": "textbox (multiline) + send button",
537
+ "keys": [
538
+ "Enter: submit; Shift+Enter: newline",
539
+ "Escape while busy: stop"
540
+ ]
541
+ },
542
+ "TreeGuides": {
543
+ "role": "hidden",
544
+ "notes": "hidden (decorative; a Row part)",
545
+ "keys": []
546
+ },
547
+ "Unknown": {
548
+ "role": "group",
549
+ "notes": "group labelled `unknownComponent`",
550
+ "keys": []
551
+ },
552
+ "Collapsible": {
553
+ "role": "group",
554
+ "notes": "trigger = button with aria-expanded. The trigger is a button with aria-expanded = open ($a11y).",
555
+ "keys": [
556
+ "Enter, Space: toggle"
557
+ ]
558
+ },
559
+ "Pagination": {
560
+ "role": "navigation",
561
+ "notes": "navigation of two buttons and a status. Labelled `pagination`; previous/next buttons and a status labelled `pageOf` ($a11y).",
562
+ "keys": [
563
+ "Enter, Space on previous/next"
564
+ ]
565
+ },
566
+ "Breadcrumb": {
567
+ "role": "navigation",
568
+ "notes": "navigation (breadcrumb); the last item aria-current=page. Labelled `breadcrumb`; the last item aria-current=page ($a11y).",
569
+ "keys": [
570
+ "Tab through the links; Enter: select"
571
+ ]
572
+ },
573
+ "Stepper": {
574
+ "role": "list",
575
+ "notes": "list; the current step aria-current=step. Each step a listitem labelled `stepDone`/`stepCurrent`/`stepUpcoming`; the current one aria-current=step ($a11y).",
576
+ "keys": []
577
+ },
578
+ "Rating": {
579
+ "role": "group",
580
+ "notes": "A group of star buttons: each labelled `ratingStar` (\"3 of 5\"), the chosen one aria-pressed; read-only stars leave the tree and the group is an img labelled `ratingValue` ($a11y).",
581
+ "keys": [
582
+ "Tab through the stars; Enter, Space: rate"
583
+ ]
584
+ },
585
+ "AlertDialog": {
586
+ "role": "alertdialog",
587
+ "notes": "alertdialog. The cancel button takes focus on open (`autoFocus`, $a11y).",
588
+ "keys": [
589
+ "Opening focuses the cancel button",
590
+ "Escape: cancel; clicks outside are ignored"
591
+ ]
592
+ },
593
+ "Sidebar": {
594
+ "role": "none",
595
+ "notes": "navigation landmark (the sidebar slot) beside main. Layout only; its `sidebar` part is a navigation landmark, its `main` part the main landmark ($a11y).",
596
+ "keys": []
597
+ },
598
+ "AppBar": {
599
+ "role": "banner",
600
+ "notes": "banner (heading level 1 = the title). The title is heading level 1; the back button is labelled `back` ($a11y).",
601
+ "keys": [
602
+ "Enter, Space on back"
603
+ ]
604
+ },
605
+ "Row": {
606
+ "role": "button",
607
+ "notes": "button (aria-selected when selected) when pressable, a group of its texts otherwise ($a11y); the guides are decorative",
608
+ "keys": [
609
+ "Enter, Space: press (pressable only)"
610
+ ]
611
+ },
612
+ "Trace": {
613
+ "role": "none",
614
+ "notes": "Layout only: a column of TraceItem lines.",
615
+ "keys": []
616
+ },
617
+ "TraceItem": {
618
+ "role": "group",
619
+ "notes": "A collapsible line is a button with aria-expanded = open ($a11y); a plain line is text; the icon is decorative.",
620
+ "keys": [
621
+ "Enter, Space: toggle (collapsible only)"
622
+ ]
623
+ },
624
+ "Chip": {
625
+ "role": "button",
626
+ "notes": "button with aria-pressed (= selected) when pressable, text otherwise ($a11y); remove = button labelled `remove`",
627
+ "keys": [
628
+ "Enter, Space: press; Delete, Backspace: remove when removable"
629
+ ]
630
+ },
631
+ "Page": {
632
+ "role": "none",
633
+ "notes": "Layout only: its header is the AppBar (banner, the title heading level 1), its body the main landmark ($a11y).",
634
+ "keys": [
635
+ "Enter, Space on back"
636
+ ]
637
+ },
638
+ "Toolbar": {
639
+ "role": "group",
640
+ "notes": "group of controls in reading order; the trailing action last",
641
+ "keys": []
642
+ },
643
+ "SplitView": {
644
+ "role": "none",
645
+ "notes": "Layout only: the `list` part is a navigation landmark, the `detail` part the main landmark; the phone back button is labelled `back` ($a11y).",
646
+ "keys": [
647
+ "Enter, Space on back"
648
+ ]
649
+ },
650
+ "FieldGroup": {
651
+ "role": "group",
652
+ "notes": "group of fields; each field keeps its own label",
653
+ "keys": []
654
+ },
655
+ "FormActions": {
656
+ "role": "group",
657
+ "notes": "group: Cancel, then the submit (the last in focus order)",
658
+ "keys": [
659
+ "Enter, Space on a button"
660
+ ]
661
+ },
662
+ "StatTile": {
663
+ "role": "group",
664
+ "notes": "group labelled by its label; the sparkline is an img with the generated summary",
665
+ "keys": []
666
+ }
667
+ }
668
+ }