@verndale/accessibility-standards 2.0.0 → 3.0.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 (165) hide show
  1. package/OPERATING.md +1 -1
  2. package/README.md +1 -1
  3. package/dist/manifest.json +156 -116
  4. package/dist/profiles/ai-orchestration/coverage-manifest.json +702 -153
  5. package/dist/profiles/ai-orchestration/implementation/accessibility.md +523 -42
  6. package/dist/profiles/ai-orchestration/pattern-contracts.json +892 -306
  7. package/dist/profiles/ai-orchestration/patterns/accordion.md +6 -1
  8. package/dist/profiles/ai-orchestration/patterns/alert.md +6 -1
  9. package/dist/profiles/ai-orchestration/patterns/carousel.md +6 -1
  10. package/dist/profiles/ai-orchestration/patterns/checkbox.md +27 -0
  11. package/dist/profiles/ai-orchestration/patterns/combobox.md +6 -1
  12. package/dist/profiles/ai-orchestration/patterns/consequential-submission.md +8 -3
  13. package/dist/profiles/ai-orchestration/patterns/dialog.md +6 -1
  14. package/dist/profiles/ai-orchestration/patterns/disclosure.md +6 -1
  15. package/dist/profiles/ai-orchestration/patterns/dynamic-status.md +6 -1
  16. package/dist/profiles/ai-orchestration/patterns/field.md +7 -1
  17. package/dist/profiles/ai-orchestration/patterns/image.md +6 -1
  18. package/dist/profiles/ai-orchestration/patterns/listbox.md +6 -1
  19. package/dist/profiles/ai-orchestration/patterns/media-player.md +9 -1
  20. package/dist/profiles/ai-orchestration/patterns/menu-button.md +6 -1
  21. package/dist/profiles/ai-orchestration/patterns/menu.md +30 -0
  22. package/dist/profiles/ai-orchestration/patterns/pagination.md +6 -1
  23. package/dist/profiles/ai-orchestration/patterns/popover.md +7 -1
  24. package/dist/profiles/ai-orchestration/patterns/progress.md +7 -1
  25. package/dist/profiles/ai-orchestration/patterns/radio-group.md +27 -0
  26. package/dist/profiles/ai-orchestration/patterns/slider.md +31 -0
  27. package/dist/profiles/ai-orchestration/patterns/spinbutton.md +28 -0
  28. package/dist/profiles/ai-orchestration/patterns/tabs.md +6 -1
  29. package/dist/profiles/ai-orchestration/patterns/tooltip.md +6 -1
  30. package/dist/profiles/ai-orchestration/patterns/tree-view.md +31 -0
  31. package/dist/profiles/ai-orchestration/patterns/validation.md +7 -1
  32. package/dist/profiles/ai-orchestration/review/accessibility.md +14 -6
  33. package/dist/profiles/ai-orchestration/semantics/accessible-authentication.md +13 -0
  34. package/dist/profiles/ai-orchestration/semantics/accessible-name.md +8 -2
  35. package/dist/profiles/ai-orchestration/semantics/alert.md +7 -1
  36. package/dist/profiles/ai-orchestration/semantics/consequential-action.md +6 -2
  37. package/dist/profiles/ai-orchestration/semantics/consistent-help.md +13 -0
  38. package/dist/profiles/ai-orchestration/semantics/data-table.md +7 -2
  39. package/dist/profiles/ai-orchestration/semantics/dragging-alternative.md +13 -0
  40. package/dist/profiles/ai-orchestration/semantics/expanded-state.md +6 -1
  41. package/dist/profiles/ai-orchestration/semantics/focus.initial.md +4 -1
  42. package/dist/profiles/ai-orchestration/semantics/focus.return.md +4 -1
  43. package/dist/profiles/ai-orchestration/semantics/focus.visible.md +8 -2
  44. package/dist/profiles/ai-orchestration/semantics/form-error.md +8 -2
  45. package/dist/profiles/ai-orchestration/semantics/form-label.md +7 -1
  46. package/dist/profiles/ai-orchestration/semantics/form-required.md +7 -1
  47. package/dist/profiles/ai-orchestration/semantics/headings.md +7 -1
  48. package/dist/profiles/ai-orchestration/semantics/keyboard.escape.md +4 -1
  49. package/dist/profiles/ai-orchestration/semantics/keyboard.md +7 -1
  50. package/dist/profiles/ai-orchestration/semantics/landmarks.md +6 -1
  51. package/dist/profiles/ai-orchestration/semantics/live-status.md +7 -2
  52. package/dist/profiles/ai-orchestration/semantics/media-alternatives.md +11 -1
  53. package/dist/profiles/ai-orchestration/semantics/motion-control.md +8 -2
  54. package/dist/profiles/ai-orchestration/semantics/name-role-value.md +6 -2
  55. package/dist/profiles/ai-orchestration/semantics/native-dialog.md +7 -1
  56. package/dist/profiles/ai-orchestration/semantics/native-elements.md +5 -1
  57. package/dist/profiles/ai-orchestration/semantics/non-text-alternative.md +5 -1
  58. package/dist/profiles/ai-orchestration/semantics/redundant-entry.md +13 -0
  59. package/dist/profiles/ai-orchestration/semantics/roles-states-properties.md +6 -1
  60. package/dist/profiles/ai-orchestration/semantics/selected-state.md +6 -1
  61. package/dist/profiles/ai-orchestration/semantics/target-size.md +6 -2
  62. package/dist/profiles/ai-orchestration/semantics.json +826 -130
  63. package/dist/profiles/ai-orchestration/testing/accessibility.md +33 -3
  64. package/dist/profiles/ai-orchestration/ui-design-brain-bindings.json +287 -307
  65. package/dist/profiles/conductor/a11y-semantics.md +249 -10
  66. package/dist/profiles/conductor/accessibility-quality.md +275 -33
  67. package/dist/profiles/conductor/applicability-matrix.json +226 -269
  68. package/dist/profiles/conductor/coverage-manifest.json +702 -153
  69. package/dist/profiles/conductor/pattern-contracts.json +892 -306
  70. package/dist/profiles/conductor/patterns/accordion.json +35 -27
  71. package/dist/profiles/conductor/patterns/alert.json +29 -21
  72. package/dist/profiles/conductor/patterns/carousel.json +36 -28
  73. package/dist/profiles/conductor/patterns/checkbox.json +67 -0
  74. package/dist/profiles/conductor/patterns/combobox.json +37 -29
  75. package/dist/profiles/conductor/patterns/consequential-submission.json +34 -25
  76. package/dist/profiles/conductor/patterns/dialog.json +37 -29
  77. package/dist/profiles/conductor/patterns/disclosure.json +33 -25
  78. package/dist/profiles/conductor/patterns/dynamic-status.json +31 -22
  79. package/dist/profiles/conductor/patterns/field.json +41 -25
  80. package/dist/profiles/conductor/patterns/image.json +31 -22
  81. package/dist/profiles/conductor/patterns/listbox.json +35 -27
  82. package/dist/profiles/conductor/patterns/media-player.json +59 -29
  83. package/dist/profiles/conductor/patterns/menu-button.json +34 -26
  84. package/dist/profiles/conductor/patterns/menu.json +78 -0
  85. package/dist/profiles/conductor/patterns/pagination.json +34 -25
  86. package/dist/profiles/conductor/patterns/popover.json +42 -26
  87. package/dist/profiles/conductor/patterns/progress.json +38 -23
  88. package/dist/profiles/conductor/patterns/radio-group.json +69 -0
  89. package/dist/profiles/conductor/patterns/slider.json +84 -0
  90. package/dist/profiles/conductor/patterns/spinbutton.json +74 -0
  91. package/dist/profiles/conductor/patterns/tabs.json +34 -26
  92. package/dist/profiles/conductor/patterns/tooltip.json +31 -23
  93. package/dist/profiles/conductor/patterns/tree-view.json +77 -0
  94. package/dist/profiles/conductor/patterns/validation.json +42 -26
  95. package/dist/profiles/conductor/semantics.json +826 -130
  96. package/dist/profiles/conductor/ui-design-brain-bindings.json +287 -307
  97. package/dist/projection-manifest.json +120 -104
  98. package/dist/requirements-to-implementation.md +7 -1
  99. package/lib/build.mjs +3 -3
  100. package/lib/digest.mjs +8 -0
  101. package/lib/load.mjs +13 -0
  102. package/lib/provenance.mjs +2 -0
  103. package/lib/render.mjs +51 -7
  104. package/lib/sync.mjs +2 -2
  105. package/lib/validate.mjs +335 -33
  106. package/package.json +6 -2
  107. package/profiles/ai-orchestration/profile.json +1 -1
  108. package/profiles/ai-orchestration/templates/patterns/README.md +1 -1
  109. package/profiles/ai-orchestration/templates/review/README.md +1 -1
  110. package/profiles/ai-orchestration/templates/semantics/README.md +1 -1
  111. package/profiles/ai-orchestration/templates/testing/README.md +1 -1
  112. package/profiles/conductor/profile.json +1 -1
  113. package/profiles/conductor/templates/evidence/README.md +1 -1
  114. package/profiles/conductor/templates/patterns/README.md +1 -1
  115. package/profiles/conductor/templates/semantics/README.md +1 -1
  116. package/schemas/consumer-config.schema.json +1 -1
  117. package/schemas/contract.schema.json +1 -1
  118. package/schemas/manifest.schema.json +1 -1
  119. package/schemas/pattern.schema.json +98 -1
  120. package/schemas/profile.schema.json +1 -1
  121. package/schemas/projection-manifest.schema.json +6 -6
  122. package/schemas/semantic.schema.json +26 -1
  123. package/schemas/standards-reference.schema.json +105 -0
  124. package/schemas/wcag-coverage.schema.json +93 -0
  125. package/src/applicability/facts.yml +3 -5
  126. package/src/applicability/matrix.yml +5 -7
  127. package/src/applicability/ui-design-brain-bindings.yml +8 -22
  128. package/src/contract.yml +1 -1
  129. package/src/coverage/wcag-2.2.yml +68 -0
  130. package/src/patterns/disclosure/accordion.yml +1 -1
  131. package/src/patterns/disclosure/disclosure.yml +1 -1
  132. package/src/patterns/feedback/alert.yml +1 -1
  133. package/src/patterns/feedback/dynamic-status.yml +1 -1
  134. package/src/patterns/feedback/progress.yml +1 -1
  135. package/src/patterns/forms/consequential-submission.yml +1 -1
  136. package/src/patterns/forms/field.yml +1 -1
  137. package/src/patterns/forms/spinbutton.yml +1 -0
  138. package/src/patterns/forms/validation.yml +1 -1
  139. package/src/patterns/media/carousel.yml +1 -1
  140. package/src/patterns/media/image.yml +1 -1
  141. package/src/patterns/media/media-player.yml +1 -1
  142. package/src/patterns/navigation/menu-button.yml +1 -1
  143. package/src/patterns/navigation/menu.yml +1 -0
  144. package/src/patterns/navigation/pagination.yml +1 -1
  145. package/src/patterns/navigation/tabs.yml +1 -1
  146. package/src/patterns/navigation/tree-view.yml +1 -0
  147. package/src/patterns/overlays/dialog.yml +1 -1
  148. package/src/patterns/overlays/popover.yml +1 -1
  149. package/src/patterns/overlays/tooltip.yml +1 -1
  150. package/src/patterns/selection/checkbox.yml +1 -0
  151. package/src/patterns/selection/combobox.yml +1 -1
  152. package/src/patterns/selection/listbox.yml +1 -1
  153. package/src/patterns/selection/radio-group.yml +1 -0
  154. package/src/patterns/selection/slider.yml +1 -0
  155. package/src/semantics/accessible-names.yml +1 -1
  156. package/src/semantics/forms.yml +1 -1
  157. package/src/semantics/headings-landmarks.yml +1 -1
  158. package/src/semantics/keyboard-focus.yml +1 -1
  159. package/src/semantics/live-regions.yml +1 -1
  160. package/src/semantics/media.yml +1 -1
  161. package/src/semantics/native-elements.yml +1 -1
  162. package/src/semantics/roles-states-properties.yml +1 -1
  163. package/src/semantics/tables.yml +1 -1
  164. package/src/semantics/wcag-2.2.yml +1 -0
  165. package/src/sources.yml +1 -1
@@ -1,237 +1,321 @@
1
1
  {
2
2
  "_generated": "GENERATED by @verndale/accessibility-standards; DO NOT EDIT",
3
3
  "_provenance": {
4
- "package": "@verndale/accessibility-standards@2.0.0",
4
+ "package": "@verndale/accessibility-standards@3.0.0",
5
5
  "profile": "conductor",
6
- "profile_version": "2.0.0",
7
- "profile_digest": "4840ac3a4910f8dc3a850df266a141e0e4df94ca3c8935ae4531c56f6be91e65",
8
- "schema_version": 2,
9
- "source_digest": "e4bf4272751c21e417ddd3e6c52308bf804fab097629ba843964532e7f97d9f0"
6
+ "profile_digest": "beadcb5fe8151303b3e3241de4fee0ece3be9ff2f4dbdb3a6f93a363b0a2d491",
7
+ "profile_version": "3.0.0",
8
+ "schema_version": 3,
9
+ "source_digest": "708ac82783bfb5ebcce31e4dada15d8580863f5e37b32d1807adf61e415ed5af"
10
10
  },
11
- "schema_version": 2,
12
11
  "patterns": [
13
12
  {
14
- "id": "pattern.accordion",
15
- "version": "1.0.0",
16
- "title": "Accordion",
17
- "kind": "pattern",
18
- "requires": [
19
- "semantics.native-elements",
20
- "semantics.accessible-name",
21
- "semantics.expanded-state",
22
- "semantics.keyboard",
23
- "semantics.focus.visible"
24
- ],
25
13
  "activation": {
26
14
  "contains": {
27
15
  "fact": "component.accessibility_pattern_ids",
28
16
  "value": "pattern.accordion"
29
17
  }
30
18
  },
31
- "scope": "Grouped disclosure sections",
32
19
  "behavior": [
33
20
  "Toggle only the controlled panel",
34
21
  "Preserve DOM and focus order"
35
22
  ],
36
- "product_decisions": [
37
- "single_or_multiple_open"
23
+ "evidence_routes": [
24
+ "unit",
25
+ "axe",
26
+ "e2e",
27
+ "human"
38
28
  ],
39
29
  "functional_spec_bindings": [
40
30
  "behavior",
41
31
  "states",
42
32
  "keyboard"
43
33
  ],
34
+ "id": "pattern.accordion",
44
35
  "implementation_outcomes": [
45
36
  "accordion-control",
46
37
  "accordion-panel"
47
38
  ],
48
- "evidence_routes": [
49
- "unit",
50
- "axe",
51
- "e2e",
52
- "human"
53
- ]
54
- },
55
- {
56
- "id": "pattern.alert",
57
- "version": "1.0.0",
58
- "title": "Alert",
59
39
  "kind": "pattern",
40
+ "product_decisions": [
41
+ "single_or_multiple_open"
42
+ ],
60
43
  "requires": [
61
- "semantics.alert"
44
+ "semantics.native-elements",
45
+ "semantics.accessible-name",
46
+ "semantics.expanded-state",
47
+ "semantics.keyboard",
48
+ "semantics.focus.visible"
49
+ ],
50
+ "scope": "Grouped disclosure sections",
51
+ "standards_refs": [
52
+ {
53
+ "authority": "aria-apg",
54
+ "identifier": "accordion",
55
+ "normative": false,
56
+ "url": "https://www.w3.org/WAI/ARIA/apg/patterns/accordion/"
57
+ }
62
58
  ],
59
+ "title": "Accordion",
60
+ "version": "1.0.0"
61
+ },
62
+ {
63
63
  "activation": {
64
64
  "contains": {
65
65
  "fact": "component.accessibility_pattern_ids",
66
66
  "value": "pattern.alert"
67
67
  }
68
68
  },
69
- "scope": "Urgent message",
70
69
  "behavior": [
71
70
  "Announce once without moving focus"
72
71
  ],
73
- "product_decisions": [
74
- "urgency"
72
+ "evidence_routes": [
73
+ "unit",
74
+ "human"
75
75
  ],
76
76
  "functional_spec_bindings": [
77
77
  "messaging"
78
78
  ],
79
+ "id": "pattern.alert",
79
80
  "implementation_outcomes": [
80
81
  "alert-announcement"
81
82
  ],
82
- "evidence_routes": [
83
- "unit",
84
- "human"
85
- ]
86
- },
87
- {
88
- "id": "pattern.carousel",
89
- "version": "1.0.0",
90
- "title": "Carousel",
91
83
  "kind": "pattern",
84
+ "product_decisions": [
85
+ "urgency"
86
+ ],
92
87
  "requires": [
93
- "semantics.accessible-name",
94
- "semantics.keyboard",
95
- "semantics.focus.visible",
96
- "semantics.motion-control",
97
- "semantics.live-status"
88
+ "semantics.alert"
89
+ ],
90
+ "scope": "Urgent message",
91
+ "standards_refs": [
92
+ {
93
+ "authority": "aria-apg",
94
+ "identifier": "alert",
95
+ "normative": false,
96
+ "url": "https://www.w3.org/WAI/ARIA/apg/patterns/alert/"
97
+ }
98
98
  ],
99
+ "title": "Alert",
100
+ "version": "1.0.0"
101
+ },
102
+ {
99
103
  "activation": {
100
104
  "contains": {
101
105
  "fact": "component.accessibility_pattern_ids",
102
106
  "value": "pattern.carousel"
103
107
  }
104
108
  },
105
- "scope": "Rotating content set",
106
109
  "behavior": [
107
110
  "Pause rotation on interaction",
108
111
  "Provide named controls and current position"
109
112
  ],
110
- "product_decisions": [
111
- "auto_rotation",
112
- "looping"
113
+ "evidence_routes": [
114
+ "unit",
115
+ "axe",
116
+ "e2e",
117
+ "human"
113
118
  ],
114
119
  "functional_spec_bindings": [
115
120
  "behavior",
116
121
  "states",
117
122
  "controls"
118
123
  ],
124
+ "id": "pattern.carousel",
119
125
  "implementation_outcomes": [
120
126
  "carousel-controls",
121
127
  "carousel-rotation"
122
128
  ],
129
+ "kind": "pattern",
130
+ "product_decisions": [
131
+ "auto_rotation",
132
+ "looping"
133
+ ],
134
+ "requires": [
135
+ "semantics.accessible-name",
136
+ "semantics.keyboard",
137
+ "semantics.focus.visible",
138
+ "semantics.motion-control",
139
+ "semantics.live-status"
140
+ ],
141
+ "scope": "Rotating content set",
142
+ "standards_refs": [
143
+ {
144
+ "authority": "aria-apg",
145
+ "identifier": "carousel",
146
+ "normative": false,
147
+ "url": "https://www.w3.org/WAI/ARIA/apg/patterns/carousel/"
148
+ }
149
+ ],
150
+ "title": "Carousel",
151
+ "version": "1.0.0"
152
+ },
153
+ {
154
+ "activation": {
155
+ "contains": {
156
+ "fact": "component.accessibility_pattern_ids",
157
+ "value": "pattern.checkbox"
158
+ }
159
+ },
160
+ "behavior": [
161
+ "Use a native checkbox when it provides the required behavior; otherwise expose checkbox semantics and synchronize checked, unchecked, or mixed state",
162
+ "Space toggles the focused checkbox without changing unrelated controls",
163
+ "Associate logical groups and any relevant descriptions with programmatic group labels"
164
+ ],
123
165
  "evidence_routes": [
124
166
  "unit",
125
167
  "axe",
126
168
  "e2e",
127
169
  "human"
128
- ]
129
- },
130
- {
131
- "id": "pattern.combobox",
132
- "version": "1.0.0",
133
- "title": "Combobox",
170
+ ],
171
+ "functional_spec_bindings": [
172
+ "fields",
173
+ "states",
174
+ "keyboard"
175
+ ],
176
+ "id": "pattern.checkbox",
177
+ "implementation_outcomes": [
178
+ "checkbox-group-semantics",
179
+ "checkbox-state-machine"
180
+ ],
134
181
  "kind": "pattern",
182
+ "product_decisions": [
183
+ "dual_or_tri_state",
184
+ "group_labeling",
185
+ "mixed_state_cycle"
186
+ ],
135
187
  "requires": [
136
188
  "semantics.accessible-name",
137
- "semantics.expanded-state",
138
- "semantics.selected-state",
189
+ "semantics.focus.visible",
190
+ "semantics.form-label",
139
191
  "semantics.keyboard",
140
- "semantics.live-status"
192
+ "semantics.name-role-value",
193
+ "semantics.native-elements",
194
+ "semantics.roles-states-properties"
195
+ ],
196
+ "scope": "Standalone, grouped, dual-state, or tri-state checkboxes",
197
+ "standards_refs": [
198
+ {
199
+ "authority": "aria-apg",
200
+ "identifier": "checkbox",
201
+ "normative": false,
202
+ "url": "https://www.w3.org/WAI/ARIA/apg/patterns/checkbox/"
203
+ }
141
204
  ],
205
+ "title": "Checkbox",
206
+ "version": "1.0.0"
207
+ },
208
+ {
142
209
  "activation": {
143
210
  "contains": {
144
211
  "fact": "component.accessibility_pattern_ids",
145
212
  "value": "pattern.combobox"
146
213
  }
147
214
  },
148
- "scope": "Input with selectable popup",
149
215
  "behavior": [
150
216
  "Keyboard controls popup, option, and input independently"
151
217
  ],
152
- "product_decisions": [
153
- "editable",
154
- "autocomplete",
155
- "selection_commit"
218
+ "evidence_routes": [
219
+ "unit",
220
+ "axe",
221
+ "e2e",
222
+ "human"
156
223
  ],
157
224
  "functional_spec_bindings": [
158
225
  "behavior",
159
226
  "states",
160
227
  "keyboard"
161
228
  ],
229
+ "id": "pattern.combobox",
162
230
  "implementation_outcomes": [
163
231
  "combobox-state-machine"
164
232
  ],
165
- "evidence_routes": [
166
- "unit",
167
- "axe",
168
- "e2e",
169
- "human"
170
- ]
171
- },
172
- {
173
- "id": "pattern.consequential-submission",
174
- "version": "1.0.0",
175
- "title": "Consequential submission",
176
233
  "kind": "pattern",
234
+ "product_decisions": [
235
+ "editable",
236
+ "autocomplete",
237
+ "selection_commit"
238
+ ],
177
239
  "requires": [
178
- "semantics.consequential-action",
179
- "semantics.form-error",
180
- "semantics.keyboard"
240
+ "semantics.accessible-name",
241
+ "semantics.expanded-state",
242
+ "semantics.selected-state",
243
+ "semantics.keyboard",
244
+ "semantics.live-status"
181
245
  ],
246
+ "scope": "Input with selectable popup",
247
+ "standards_refs": [
248
+ {
249
+ "authority": "aria-apg",
250
+ "identifier": "combobox",
251
+ "normative": false,
252
+ "url": "https://www.w3.org/WAI/ARIA/apg/patterns/combobox/"
253
+ }
254
+ ],
255
+ "title": "Combobox",
256
+ "version": "1.0.0"
257
+ },
258
+ {
182
259
  "activation": {
183
260
  "contains": {
184
261
  "fact": "component.submission_consequence",
185
262
  "value": "consequential"
186
263
  }
187
264
  },
188
- "scope": "Legal, financial, destructive, or irreversible submission",
189
265
  "behavior": [
190
- "Support review, correction, confirmation, or reversal"
266
+ "Provide at least one declared safeguard: make the submission reversible; check user-entered data for errors and let the user correct them; or let the user review, confirm, and correct information before finalizing"
191
267
  ],
192
- "product_decisions": [
193
- "safeguard",
194
- "reversal_window"
268
+ "evidence_routes": [
269
+ "e2e",
270
+ "human"
195
271
  ],
196
272
  "functional_spec_bindings": [
197
273
  "submission",
198
274
  "confirmation"
199
275
  ],
276
+ "id": "pattern.consequential-submission",
200
277
  "implementation_outcomes": [
201
278
  "submission-safeguard"
202
279
  ],
203
- "evidence_routes": [
204
- "e2e",
205
- "human"
206
- ]
207
- },
208
- {
209
- "id": "pattern.dialog",
210
- "version": "1.0.0",
211
- "title": "Dialog",
212
280
  "kind": "pattern",
281
+ "product_decisions": [
282
+ "safeguard",
283
+ "reversal_window"
284
+ ],
213
285
  "requires": [
214
- "semantics.native-dialog",
215
- "semantics.accessible-name",
216
- "semantics.keyboard.escape",
217
- "semantics.focus.initial",
218
- "semantics.focus.return"
286
+ "semantics.consequential-action",
287
+ "semantics.form-error",
288
+ "semantics.keyboard"
219
289
  ],
290
+ "scope": "Legal commitments, financial transactions, stored user-controllable data changes, or user test-response submissions",
291
+ "standards_refs": [
292
+ {
293
+ "authority": "wcag-2.2",
294
+ "identifier": "3.3.4",
295
+ "level": "AA",
296
+ "normative": true,
297
+ "url": "https://www.w3.org/TR/WCAG22/#error-prevention-legal-financial-data"
298
+ }
299
+ ],
300
+ "title": "Consequential submission",
301
+ "version": "1.0.0"
302
+ },
303
+ {
220
304
  "activation": {
221
305
  "contains": {
222
306
  "fact": "component.accessibility_pattern_ids",
223
307
  "value": "pattern.dialog"
224
308
  }
225
309
  },
226
- "scope": "Modal and non-modal dialogs",
227
310
  "behavior": [
228
311
  "Manage initial, contained, and return focus",
229
312
  "Dismiss topmost dialog with Escape"
230
313
  ],
231
- "product_decisions": [
232
- "modal",
233
- "initial_focus",
234
- "dismissal"
314
+ "evidence_routes": [
315
+ "unit",
316
+ "axe",
317
+ "e2e",
318
+ "human"
235
319
  ],
236
320
  "functional_spec_bindings": [
237
321
  "behavior",
@@ -239,98 +323,125 @@
239
323
  "focus",
240
324
  "keyboard"
241
325
  ],
326
+ "id": "pattern.dialog",
242
327
  "implementation_outcomes": [
243
328
  "dialog-semantics",
244
329
  "dialog-focus-lifecycle"
245
330
  ],
246
- "evidence_routes": [
247
- "unit",
248
- "axe",
249
- "e2e",
250
- "human"
251
- ]
252
- },
253
- {
254
- "id": "pattern.disclosure",
255
- "version": "1.0.0",
256
- "title": "Disclosure",
257
331
  "kind": "pattern",
332
+ "product_decisions": [
333
+ "modal",
334
+ "initial_focus",
335
+ "dismissal"
336
+ ],
258
337
  "requires": [
259
- "semantics.native-elements",
338
+ "semantics.native-dialog",
260
339
  "semantics.accessible-name",
261
- "semantics.expanded-state",
262
- "semantics.keyboard"
340
+ "semantics.keyboard.escape",
341
+ "semantics.focus.initial",
342
+ "semantics.focus.return"
343
+ ],
344
+ "scope": "Modal and non-modal dialogs",
345
+ "standards_refs": [
346
+ {
347
+ "authority": "aria-apg",
348
+ "identifier": "dialog-modal",
349
+ "normative": false,
350
+ "url": "https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/"
351
+ }
263
352
  ],
353
+ "title": "Dialog",
354
+ "version": "1.0.0"
355
+ },
356
+ {
264
357
  "activation": {
265
358
  "contains": {
266
359
  "fact": "component.accessibility_pattern_ids",
267
360
  "value": "pattern.disclosure"
268
361
  }
269
362
  },
270
- "scope": "Show and hide supplementary content",
271
363
  "behavior": [
272
364
  "Control toggles one region"
273
365
  ],
274
- "product_decisions": [
275
- "initial_state"
366
+ "evidence_routes": [
367
+ "unit",
368
+ "axe",
369
+ "e2e"
276
370
  ],
277
371
  "functional_spec_bindings": [
278
372
  "behavior",
279
373
  "states"
280
374
  ],
375
+ "id": "pattern.disclosure",
281
376
  "implementation_outcomes": [
282
377
  "disclosure-control"
283
378
  ],
284
- "evidence_routes": [
285
- "unit",
286
- "axe",
287
- "e2e"
288
- ]
289
- },
290
- {
291
- "id": "pattern.dynamic-status",
292
- "version": "1.0.0",
293
- "title": "Dynamic status",
294
379
  "kind": "pattern",
295
- "requires": [
296
- "semantics.live-status"
380
+ "product_decisions": [
381
+ "initial_state"
382
+ ],
383
+ "requires": [
384
+ "semantics.native-elements",
385
+ "semantics.accessible-name",
386
+ "semantics.expanded-state",
387
+ "semantics.keyboard"
388
+ ],
389
+ "scope": "Show and hide supplementary content",
390
+ "standards_refs": [
391
+ {
392
+ "authority": "aria-apg",
393
+ "identifier": "disclosure",
394
+ "normative": false,
395
+ "url": "https://www.w3.org/WAI/ARIA/apg/patterns/disclosure/"
396
+ }
297
397
  ],
398
+ "title": "Disclosure",
399
+ "version": "1.0.0"
400
+ },
401
+ {
298
402
  "activation": {
299
403
  "equals": {
300
404
  "fact": "component.has_dynamic_status",
301
405
  "value": true
302
406
  }
303
407
  },
304
- "scope": "Asynchronous status message",
305
408
  "behavior": [
306
409
  "Announce meaningful changes once"
307
410
  ],
308
- "product_decisions": [
309
- "announcement_copy"
411
+ "evidence_routes": [
412
+ "unit",
413
+ "e2e",
414
+ "human"
310
415
  ],
311
416
  "functional_spec_bindings": [
312
417
  "messaging",
313
418
  "states"
314
419
  ],
420
+ "id": "pattern.dynamic-status",
315
421
  "implementation_outcomes": [
316
422
  "status-live-region"
317
423
  ],
318
- "evidence_routes": [
319
- "unit",
320
- "e2e",
321
- "human"
322
- ]
323
- },
324
- {
325
- "id": "pattern.field",
326
- "version": "1.0.0",
327
- "title": "Form field",
328
424
  "kind": "pattern",
425
+ "product_decisions": [
426
+ "announcement_copy"
427
+ ],
329
428
  "requires": [
330
- "semantics.form-label",
331
- "semantics.form-required",
332
- "semantics.focus.visible"
429
+ "semantics.live-status"
430
+ ],
431
+ "scope": "Asynchronous status message",
432
+ "standards_refs": [
433
+ {
434
+ "authority": "wcag-2.2",
435
+ "identifier": "4.1.3",
436
+ "level": "AA",
437
+ "normative": true,
438
+ "url": "https://www.w3.org/TR/WCAG22/#status-messages"
439
+ }
333
440
  ],
441
+ "title": "Dynamic status",
442
+ "version": "1.0.0"
443
+ },
444
+ {
334
445
  "activation": {
335
446
  "any": [
336
447
  {
@@ -347,35 +458,53 @@
347
458
  }
348
459
  ]
349
460
  },
350
- "scope": "Labeled form input",
351
461
  "behavior": [
352
462
  "Expose label, instructions, and requiredness before interaction"
353
463
  ],
354
- "product_decisions": [
355
- "required",
356
- "instructions"
464
+ "evidence_routes": [
465
+ "unit",
466
+ "axe",
467
+ "human"
357
468
  ],
358
469
  "functional_spec_bindings": [
359
470
  "fields",
360
471
  "requiredness"
361
472
  ],
473
+ "id": "pattern.field",
362
474
  "implementation_outcomes": [
363
475
  "field-associations"
364
476
  ],
365
- "evidence_routes": [
366
- "unit",
367
- "axe",
368
- "human"
369
- ]
370
- },
371
- {
372
- "id": "pattern.image",
373
- "version": "1.0.0",
374
- "title": "Image",
375
477
  "kind": "pattern",
478
+ "product_decisions": [
479
+ "required",
480
+ "instructions"
481
+ ],
376
482
  "requires": [
377
- "semantics.non-text-alternative"
483
+ "semantics.form-label",
484
+ "semantics.form-required",
485
+ "semantics.focus.visible"
486
+ ],
487
+ "scope": "Labeled form input",
488
+ "standards_refs": [
489
+ {
490
+ "authority": "wcag-2.2",
491
+ "identifier": "3.3.2",
492
+ "level": "A",
493
+ "normative": true,
494
+ "url": "https://www.w3.org/TR/WCAG22/#labels-or-instructions"
495
+ },
496
+ {
497
+ "authority": "wcag-2.2",
498
+ "identifier": "4.1.2",
499
+ "level": "A",
500
+ "normative": true,
501
+ "url": "https://www.w3.org/TR/WCAG22/#name-role-value"
502
+ }
378
503
  ],
504
+ "title": "Form field",
505
+ "version": "1.0.0"
506
+ },
507
+ {
379
508
  "activation": {
380
509
  "any": [
381
510
  {
@@ -392,78 +521,91 @@
392
521
  }
393
522
  ]
394
523
  },
395
- "scope": "Informative, functional, complex, or decorative image",
396
524
  "behavior": [
397
525
  "Alternative follows image purpose"
398
526
  ],
399
- "product_decisions": [
400
- "purpose",
401
- "long_description"
527
+ "evidence_routes": [
528
+ "axe",
529
+ "human"
402
530
  ],
403
531
  "functional_spec_bindings": [
404
532
  "content"
405
533
  ],
534
+ "id": "pattern.image",
406
535
  "implementation_outcomes": [
407
536
  "image-alternative"
408
537
  ],
409
- "evidence_routes": [
410
- "axe",
411
- "human"
412
- ]
413
- },
414
- {
415
- "id": "pattern.listbox",
416
- "version": "1.0.0",
417
- "title": "Listbox",
418
538
  "kind": "pattern",
539
+ "product_decisions": [
540
+ "purpose",
541
+ "long_description"
542
+ ],
419
543
  "requires": [
420
- "semantics.accessible-name",
421
- "semantics.selected-state",
422
- "semantics.keyboard",
423
- "semantics.focus.visible"
544
+ "semantics.non-text-alternative"
545
+ ],
546
+ "scope": "Informative, functional, complex, or decorative image",
547
+ "standards_refs": [
548
+ {
549
+ "authority": "wcag-2.2",
550
+ "identifier": "1.1.1",
551
+ "level": "A",
552
+ "normative": true,
553
+ "url": "https://www.w3.org/TR/WCAG22/#non-text-content"
554
+ }
424
555
  ],
556
+ "title": "Image",
557
+ "version": "1.0.0"
558
+ },
559
+ {
425
560
  "activation": {
426
561
  "contains": {
427
562
  "fact": "component.accessibility_pattern_ids",
428
563
  "value": "pattern.listbox"
429
564
  }
430
565
  },
431
- "scope": "Single or multi-select option list",
432
566
  "behavior": [
433
567
  "Arrow keys move active option",
434
568
  "Selection follows declared model"
435
569
  ],
436
- "product_decisions": [
437
- "single_or_multi",
438
- "selection_follows_focus"
570
+ "evidence_routes": [
571
+ "unit",
572
+ "axe",
573
+ "e2e",
574
+ "human"
439
575
  ],
440
576
  "functional_spec_bindings": [
441
577
  "behavior",
442
578
  "states",
443
579
  "keyboard"
444
580
  ],
581
+ "id": "pattern.listbox",
445
582
  "implementation_outcomes": [
446
583
  "listbox-keyboard-model"
447
584
  ],
448
- "evidence_routes": [
449
- "unit",
450
- "axe",
451
- "e2e",
452
- "human"
453
- ]
454
- },
455
- {
456
- "id": "pattern.media-player",
457
- "version": "1.0.0",
458
- "title": "Media player",
459
585
  "kind": "pattern",
586
+ "product_decisions": [
587
+ "single_or_multi",
588
+ "selection_follows_focus"
589
+ ],
460
590
  "requires": [
461
- "semantics.media-alternatives",
462
591
  "semantics.accessible-name",
592
+ "semantics.selected-state",
463
593
  "semantics.keyboard",
464
- "semantics.focus.visible",
465
- "semantics.motion-control"
594
+ "semantics.focus.visible"
595
+ ],
596
+ "scope": "Single or multi-select option list",
597
+ "standards_refs": [
598
+ {
599
+ "authority": "aria-apg",
600
+ "identifier": "listbox",
601
+ "normative": false,
602
+ "url": "https://www.w3.org/WAI/ARIA/apg/patterns/listbox/"
603
+ }
466
604
  ],
605
+ "title": "Listbox",
606
+ "version": "1.0.0"
607
+ },
608
+ {
467
609
  "activation": {
468
610
  "any": [
469
611
  {
@@ -480,265 +622,683 @@
480
622
  }
481
623
  ]
482
624
  },
483
- "scope": "Audio or video playback",
484
625
  "behavior": [
485
626
  "Provide keyboard-operable named controls and required alternatives"
486
627
  ],
487
- "product_decisions": [
488
- "captions",
489
- "transcript",
490
- "audio_description",
491
- "autoplay"
628
+ "evidence_routes": [
629
+ "axe",
630
+ "e2e",
631
+ "human"
492
632
  ],
493
633
  "functional_spec_bindings": [
494
634
  "content",
495
635
  "controls",
496
636
  "behavior"
497
637
  ],
638
+ "id": "pattern.media-player",
498
639
  "implementation_outcomes": [
499
640
  "media-alternatives",
500
641
  "media-controls"
501
642
  ],
643
+ "kind": "pattern",
644
+ "product_decisions": [
645
+ "captions",
646
+ "transcript",
647
+ "audio_description",
648
+ "autoplay"
649
+ ],
650
+ "requires": [
651
+ "semantics.media-alternatives",
652
+ "semantics.accessible-name",
653
+ "semantics.keyboard",
654
+ "semantics.focus.visible",
655
+ "semantics.motion-control"
656
+ ],
657
+ "scope": "Audio or video playback",
658
+ "standards_refs": [
659
+ {
660
+ "authority": "wcag-2.2",
661
+ "identifier": "1.2.1",
662
+ "level": "A",
663
+ "normative": true,
664
+ "url": "https://www.w3.org/TR/WCAG22/#audio-only-and-video-only-prerecorded"
665
+ },
666
+ {
667
+ "authority": "wcag-2.2",
668
+ "identifier": "1.2.2",
669
+ "level": "A",
670
+ "normative": true,
671
+ "url": "https://www.w3.org/TR/WCAG22/#captions-prerecorded"
672
+ },
673
+ {
674
+ "authority": "wcag-2.2",
675
+ "identifier": "1.2.3",
676
+ "level": "A",
677
+ "normative": true,
678
+ "url": "https://www.w3.org/TR/WCAG22/#audio-description-or-media-alternative-prerecorded"
679
+ },
680
+ {
681
+ "authority": "wcag-2.2",
682
+ "identifier": "1.2.5",
683
+ "level": "AA",
684
+ "normative": true,
685
+ "url": "https://www.w3.org/TR/WCAG22/#audio-description-prerecorded"
686
+ }
687
+ ],
688
+ "title": "Media player",
689
+ "version": "1.0.0"
690
+ },
691
+ {
692
+ "activation": {
693
+ "contains": {
694
+ "fact": "component.accessibility_pattern_ids",
695
+ "value": "pattern.menu"
696
+ }
697
+ },
698
+ "behavior": [
699
+ "Expose menu or menubar containers with menuitem, menuitemcheckbox, or menuitemradio children; synchronize submenu expanded state, checkable-item checked state, orientation, and disabled state",
700
+ "When a popup menu opens, move focus to its first item; when a persistent menubar receives focus through Tab or Shift+Tab, restore its declared last-focused item or use its first enabled item; Tab and Shift+Tab do not move among items and, from an item, exit the composite and close all open menus",
701
+ "For the default horizontal menubar with vertical popup menus, Right and Left move among menubar items, Down opens a submenu and focuses its first item, Up may open it and focus its last item, Down and Up move among popup items, Right opens a child submenu, and Left closes a child submenu and returns focus to its parent item; reverse the declared axes for alternate orientations",
702
+ "Enter opens an item's submenu and focuses its first item, or otherwise activates the item and closes the menu; declare whether Space mirrors Enter on plain items, toggles menuitemcheckbox without closing, and checks a menuitemradio while unchecking its group peers without closing",
703
+ "Keep disabled menu items focusable but non-activatable, keep separators non-focusable, and apply Home, End, optional type-ahead, and the declared wrapping policy within the current menu or menubar",
704
+ "Escape closes the menu containing focus and restores focus to its parent item, menu button, or invoking context"
705
+ ],
502
706
  "evidence_routes": [
707
+ "unit",
503
708
  "axe",
504
709
  "e2e",
505
710
  "human"
506
- ]
507
- },
508
- {
509
- "id": "pattern.menu-button",
510
- "version": "1.0.0",
511
- "title": "Menu button",
711
+ ],
712
+ "functional_spec_bindings": [
713
+ "behavior",
714
+ "states",
715
+ "keyboard",
716
+ "focus"
717
+ ],
718
+ "id": "pattern.menu",
719
+ "implementation_outcomes": [
720
+ "menu-composite-focus",
721
+ "menu-keyboard-model",
722
+ "menu-state-model"
723
+ ],
512
724
  "kind": "pattern",
725
+ "product_decisions": [
726
+ "entry_focus",
727
+ "focus_strategy",
728
+ "menu_or_menubar",
729
+ "orientation",
730
+ "space_behavior",
731
+ "submenu_model",
732
+ "typeahead",
733
+ "wrap_navigation"
734
+ ],
513
735
  "requires": [
514
736
  "semantics.accessible-name",
515
737
  "semantics.expanded-state",
516
- "semantics.keyboard",
517
738
  "semantics.focus.initial",
518
- "semantics.focus.return"
739
+ "semantics.focus.return",
740
+ "semantics.focus.visible",
741
+ "semantics.keyboard",
742
+ "semantics.keyboard.escape",
743
+ "semantics.roles-states-properties"
744
+ ],
745
+ "scope": "Command menus, submenus, and persistent menubars",
746
+ "standards_refs": [
747
+ {
748
+ "authority": "aria-apg",
749
+ "identifier": "menubar",
750
+ "normative": false,
751
+ "url": "https://www.w3.org/WAI/ARIA/apg/patterns/menubar/"
752
+ }
519
753
  ],
754
+ "title": "Menu and menubar",
755
+ "version": "1.0.0"
756
+ },
757
+ {
520
758
  "activation": {
521
759
  "contains": {
522
760
  "fact": "component.accessibility_pattern_ids",
523
761
  "value": "pattern.menu-button"
524
762
  }
525
763
  },
526
- "scope": "Button opening a command menu",
527
764
  "behavior": [
528
765
  "Open and navigate menu by keyboard"
529
766
  ],
530
- "product_decisions": [
531
- "focus_strategy"
767
+ "evidence_routes": [
768
+ "unit",
769
+ "e2e",
770
+ "human"
532
771
  ],
533
772
  "functional_spec_bindings": [
534
773
  "behavior",
535
774
  "keyboard",
536
775
  "focus"
537
776
  ],
777
+ "id": "pattern.menu-button",
538
778
  "implementation_outcomes": [
539
779
  "menu-button-keyboard"
540
780
  ],
541
- "evidence_routes": [
542
- "unit",
543
- "e2e",
544
- "human"
545
- ]
546
- },
547
- {
548
- "id": "pattern.pagination",
549
- "version": "1.0.0",
550
- "title": "Pagination",
551
781
  "kind": "pattern",
782
+ "product_decisions": [
783
+ "focus_strategy"
784
+ ],
552
785
  "requires": [
553
- "semantics.native-elements",
554
786
  "semantics.accessible-name",
555
- "semantics.landmarks",
556
- "semantics.focus.visible"
787
+ "semantics.expanded-state",
788
+ "semantics.keyboard",
789
+ "semantics.focus.initial",
790
+ "semantics.focus.return"
791
+ ],
792
+ "scope": "Button opening a command menu",
793
+ "standards_refs": [
794
+ {
795
+ "authority": "aria-apg",
796
+ "identifier": "menu-button",
797
+ "normative": false,
798
+ "url": "https://www.w3.org/WAI/ARIA/apg/patterns/menu-button/"
799
+ }
557
800
  ],
801
+ "title": "Menu button",
802
+ "version": "1.0.0"
803
+ },
804
+ {
558
805
  "activation": {
559
806
  "contains": {
560
807
  "fact": "component.accessibility_pattern_ids",
561
808
  "value": "pattern.pagination"
562
809
  }
563
810
  },
564
- "scope": "Paged result navigation",
565
811
  "behavior": [
566
812
  "Expose current page and named navigation"
567
813
  ],
568
- "product_decisions": [
569
- "url_behavior"
814
+ "evidence_routes": [
815
+ "unit",
816
+ "axe",
817
+ "human"
570
818
  ],
571
819
  "functional_spec_bindings": [
572
820
  "states",
573
821
  "navigation"
574
822
  ],
823
+ "id": "pattern.pagination",
575
824
  "implementation_outcomes": [
576
825
  "pagination-current-page"
577
826
  ],
578
- "evidence_routes": [
579
- "unit",
580
- "axe",
581
- "human"
582
- ]
583
- },
584
- {
585
- "id": "pattern.popover",
586
- "version": "1.0.0",
587
- "title": "Popover",
588
827
  "kind": "pattern",
828
+ "product_decisions": [
829
+ "url_behavior"
830
+ ],
589
831
  "requires": [
590
832
  "semantics.native-elements",
591
833
  "semantics.accessible-name",
592
- "semantics.keyboard.escape",
593
- "semantics.focus.return"
834
+ "semantics.landmarks",
835
+ "semantics.focus.visible"
594
836
  ],
837
+ "scope": "Paged result navigation",
838
+ "standards_refs": [
839
+ {
840
+ "authority": "wcag-2.2",
841
+ "identifier": "2.4.4",
842
+ "level": "A",
843
+ "normative": true,
844
+ "url": "https://www.w3.org/TR/WCAG22/#link-purpose-in-context"
845
+ }
846
+ ],
847
+ "title": "Pagination",
848
+ "version": "1.0.0"
849
+ },
850
+ {
595
851
  "activation": {
596
852
  "contains": {
597
853
  "fact": "component.accessibility_pattern_ids",
598
854
  "value": "pattern.popover"
599
855
  }
600
856
  },
601
- "scope": "Non-modal transient surface",
602
857
  "behavior": [
603
858
  "Dismiss without trapping focus"
604
859
  ],
605
- "product_decisions": [
606
- "dismissal",
607
- "focus_entry"
860
+ "evidence_routes": [
861
+ "unit",
862
+ "e2e",
863
+ "human"
608
864
  ],
609
865
  "functional_spec_bindings": [
610
866
  "behavior",
611
867
  "focus"
612
868
  ],
869
+ "id": "pattern.popover",
613
870
  "implementation_outcomes": [
614
871
  "popover-dismissal"
615
872
  ],
873
+ "kind": "pattern",
874
+ "product_decisions": [
875
+ "dismissal",
876
+ "focus_entry"
877
+ ],
878
+ "requires": [
879
+ "semantics.native-elements",
880
+ "semantics.accessible-name",
881
+ "semantics.keyboard.escape",
882
+ "semantics.focus.return"
883
+ ],
884
+ "scope": "Non-modal transient surface",
885
+ "standards_refs": [
886
+ {
887
+ "authority": "wcag-2.2",
888
+ "identifier": "2.1.1",
889
+ "level": "A",
890
+ "normative": true,
891
+ "url": "https://www.w3.org/TR/WCAG22/#keyboard"
892
+ },
893
+ {
894
+ "authority": "wcag-2.2",
895
+ "identifier": "2.4.3",
896
+ "level": "A",
897
+ "normative": true,
898
+ "url": "https://www.w3.org/TR/WCAG22/#focus-order"
899
+ }
900
+ ],
901
+ "title": "Popover",
902
+ "version": "1.0.0"
903
+ },
904
+ {
905
+ "activation": {
906
+ "contains": {
907
+ "fact": "component.accessibility_pattern_ids",
908
+ "value": "pattern.progress"
909
+ }
910
+ },
911
+ "behavior": [
912
+ "Expose value and completion changes without announcement noise"
913
+ ],
616
914
  "evidence_routes": [
617
915
  "unit",
618
- "e2e",
916
+ "axe",
619
917
  "human"
620
- ]
621
- },
622
- {
918
+ ],
919
+ "functional_spec_bindings": [
920
+ "states",
921
+ "messaging"
922
+ ],
623
923
  "id": "pattern.progress",
624
- "version": "1.0.0",
625
- "title": "Progress",
924
+ "implementation_outcomes": [
925
+ "progress-value"
926
+ ],
626
927
  "kind": "pattern",
928
+ "product_decisions": [
929
+ "determinate"
930
+ ],
627
931
  "requires": [
628
932
  "semantics.name-role-value",
629
933
  "semantics.live-status"
630
934
  ],
935
+ "scope": "Determinate or indeterminate progress",
936
+ "standards_refs": [
937
+ {
938
+ "authority": "wai-aria-1.2",
939
+ "identifier": "progressbar",
940
+ "normative": true,
941
+ "url": "https://www.w3.org/TR/wai-aria-1.2/#progressbar"
942
+ },
943
+ {
944
+ "authority": "wcag-2.2",
945
+ "identifier": "4.1.2",
946
+ "level": "A",
947
+ "normative": true,
948
+ "url": "https://www.w3.org/TR/WCAG22/#name-role-value"
949
+ }
950
+ ],
951
+ "title": "Progress",
952
+ "version": "1.0.0"
953
+ },
954
+ {
631
955
  "activation": {
632
956
  "contains": {
633
957
  "fact": "component.accessibility_pattern_ids",
634
- "value": "pattern.progress"
958
+ "value": "pattern.radio-group"
635
959
  }
636
960
  },
637
- "scope": "Determinate or indeterminate progress",
638
961
  "behavior": [
639
- "Expose value and completion changes without announcement noise"
962
+ "Use native grouped radio inputs when they provide the required behavior; otherwise expose a named radiogroup containing named radio controls with exactly one checked item when selected",
963
+ "Use one tab stop for group entry, focusing the checked radio or the first radio when none is checked",
964
+ "Outside a toolbar, Space selects the focused radio and arrow keys move focus and selection with wrapping; inside a toolbar, toolbar navigation moves focus without changing selection, while Space or optionally Enter checks the focused radio"
640
965
  ],
641
- "product_decisions": [
642
- "determinate"
966
+ "evidence_routes": [
967
+ "unit",
968
+ "axe",
969
+ "e2e",
970
+ "human"
643
971
  ],
644
972
  "functional_spec_bindings": [
973
+ "fields",
645
974
  "states",
646
- "messaging"
975
+ "keyboard",
976
+ "focus"
647
977
  ],
978
+ "id": "pattern.radio-group",
648
979
  "implementation_outcomes": [
649
- "progress-value"
980
+ "radio-group-keyboard-model",
981
+ "radio-group-labeling",
982
+ "radio-group-selection-model"
983
+ ],
984
+ "kind": "pattern",
985
+ "product_decisions": [
986
+ "initial_selection",
987
+ "native_or_custom",
988
+ "toolbar_context",
989
+ "wrap_navigation"
990
+ ],
991
+ "requires": [
992
+ "semantics.accessible-name",
993
+ "semantics.focus.visible",
994
+ "semantics.form-label",
995
+ "semantics.keyboard",
996
+ "semantics.native-elements",
997
+ "semantics.roles-states-properties"
998
+ ],
999
+ "scope": "Mutually exclusive choices presented as a radio group",
1000
+ "standards_refs": [
1001
+ {
1002
+ "authority": "aria-apg",
1003
+ "identifier": "radio",
1004
+ "normative": false,
1005
+ "url": "https://www.w3.org/WAI/ARIA/apg/patterns/radio/"
1006
+ }
1007
+ ],
1008
+ "title": "Radio group",
1009
+ "version": "1.0.0"
1010
+ },
1011
+ {
1012
+ "activation": {
1013
+ "contains": {
1014
+ "fact": "component.accessibility_pattern_ids",
1015
+ "value": "pattern.slider"
1016
+ }
1017
+ },
1018
+ "behavior": [
1019
+ "Use a native input[type=range] for a single-thumb slider when it supplies the required range, step, orientation, labeling, and value presentation; use a custom slider only when native behavior cannot satisfy the declared interaction",
1020
+ "Expose every focusable thumb as a distinct named slider with synchronized current, minimum, maximum, orientation, and user-friendly value text when the numeric value is insufficient",
1021
+ "Right and Up increase by one step while Left and Down decrease by one step unless a documented orientation and value presentation makes reversal more intuitive; Home and End move to range bounds, and optional Page Up and Page Down apply the declared larger step",
1022
+ "Provide an equivalent single-pointer method for every drag operation that does not require dragging, such as track activation or an adjacent value input",
1023
+ "Keep every thumb in a constant tab order for multi-thumb sliders and update dependent thumb bounds whenever another thumb changes them",
1024
+ "Verify operation with touch-based assistive technology on target devices before production use"
650
1025
  ],
651
1026
  "evidence_routes": [
652
1027
  "unit",
653
1028
  "axe",
1029
+ "e2e",
654
1030
  "human"
655
- ]
1031
+ ],
1032
+ "functional_spec_bindings": [
1033
+ "fields",
1034
+ "states",
1035
+ "keyboard",
1036
+ "controls"
1037
+ ],
1038
+ "id": "pattern.slider",
1039
+ "implementation_outcomes": [
1040
+ "slider-keyboard-model",
1041
+ "slider-native-control-selection",
1042
+ "slider-range-state",
1043
+ "slider-touch-at-compatibility"
1044
+ ],
1045
+ "kind": "pattern",
1046
+ "product_decisions": [
1047
+ "direction_mapping",
1048
+ "large_step",
1049
+ "native_or_custom",
1050
+ "orientation",
1051
+ "single_or_multi_thumb",
1052
+ "step",
1053
+ "thumb_constraints",
1054
+ "value_text"
1055
+ ],
1056
+ "requires": [
1057
+ "semantics.accessible-name",
1058
+ "semantics.dragging-alternative",
1059
+ "semantics.focus.visible",
1060
+ "semantics.keyboard",
1061
+ "semantics.name-role-value",
1062
+ "semantics.native-elements",
1063
+ "semantics.roles-states-properties"
1064
+ ],
1065
+ "scope": "Single-thumb or multi-thumb bounded range input",
1066
+ "standards_refs": [
1067
+ {
1068
+ "authority": "aria-apg",
1069
+ "identifier": "slider",
1070
+ "normative": false,
1071
+ "url": "https://www.w3.org/WAI/ARIA/apg/patterns/slider/"
1072
+ },
1073
+ {
1074
+ "authority": "aria-apg",
1075
+ "identifier": "slider-multithumb",
1076
+ "normative": false,
1077
+ "url": "https://www.w3.org/WAI/ARIA/apg/patterns/slider-multithumb/"
1078
+ }
1079
+ ],
1080
+ "title": "Slider",
1081
+ "version": "1.0.0"
656
1082
  },
657
1083
  {
658
- "id": "pattern.tabs",
659
- "version": "1.0.0",
660
- "title": "Tabs",
1084
+ "activation": {
1085
+ "contains": {
1086
+ "fact": "component.accessibility_pattern_ids",
1087
+ "value": "pattern.spinbutton"
1088
+ }
1089
+ },
1090
+ "behavior": [
1091
+ "Use a native number input when it supplies the required range, step, editing, labeling, and validation behavior; otherwise expose a named spinbutton with synchronized current, minimum, maximum, user-friendly value text, and invalid state when a value is outside the allowed range",
1092
+ "Keep focus on the spinbutton while Up and Down change its value, Home and End apply known bounds, and optional Page Up and Page Down apply the declared larger step",
1093
+ "Treat the editable decision as permission for direct text entry, not as whether the spinbutton is adjustable; when direct editing is disabled, the declared increment and decrement controls still change the value and the spinbutton is not exposed as read-only",
1094
+ "When direct editing is allowed, preserve platform text editing commands and do not intercept keys needed to enter, navigate, select, or modify text"
1095
+ ],
1096
+ "evidence_routes": [
1097
+ "unit",
1098
+ "axe",
1099
+ "e2e",
1100
+ "human"
1101
+ ],
1102
+ "functional_spec_bindings": [
1103
+ "fields",
1104
+ "states",
1105
+ "keyboard",
1106
+ "validation"
1107
+ ],
1108
+ "id": "pattern.spinbutton",
1109
+ "implementation_outcomes": [
1110
+ "spinbutton-keyboard-model",
1111
+ "spinbutton-native-control-selection",
1112
+ "spinbutton-range-state",
1113
+ "spinbutton-validation"
1114
+ ],
661
1115
  "kind": "pattern",
1116
+ "product_decisions": [
1117
+ "editable",
1118
+ "large_step",
1119
+ "native_or_custom",
1120
+ "range_bounds",
1121
+ "step",
1122
+ "value_text"
1123
+ ],
662
1124
  "requires": [
663
1125
  "semantics.accessible-name",
664
- "semantics.selected-state",
1126
+ "semantics.focus.visible",
1127
+ "semantics.form-label",
665
1128
  "semantics.keyboard",
666
- "semantics.focus.visible"
1129
+ "semantics.name-role-value",
1130
+ "semantics.native-elements",
1131
+ "semantics.roles-states-properties"
1132
+ ],
1133
+ "scope": "Value input constrained to a discrete set or range, with optional direct text editing",
1134
+ "standards_refs": [
1135
+ {
1136
+ "authority": "aria-apg",
1137
+ "identifier": "spinbutton",
1138
+ "normative": false,
1139
+ "url": "https://www.w3.org/WAI/ARIA/apg/patterns/spinbutton/"
1140
+ }
667
1141
  ],
1142
+ "title": "Spinbutton",
1143
+ "version": "1.0.0"
1144
+ },
1145
+ {
668
1146
  "activation": {
669
1147
  "contains": {
670
1148
  "fact": "component.accessibility_pattern_ids",
671
1149
  "value": "pattern.tabs"
672
1150
  }
673
1151
  },
674
- "scope": "Tabbed interfaces",
675
1152
  "behavior": [
676
1153
  "Arrow keys move between tabs",
677
1154
  "Selection and activation follow the documented model"
678
1155
  ],
679
- "product_decisions": [
680
- "automatic_or_manual_activation"
1156
+ "evidence_routes": [
1157
+ "unit",
1158
+ "axe",
1159
+ "e2e",
1160
+ "human"
681
1161
  ],
682
1162
  "functional_spec_bindings": [
683
1163
  "behavior",
684
1164
  "states",
685
1165
  "keyboard"
686
1166
  ],
1167
+ "id": "pattern.tabs",
687
1168
  "implementation_outcomes": [
688
1169
  "tabs-keyboard-model"
689
1170
  ],
690
- "evidence_routes": [
691
- "unit",
692
- "axe",
693
- "e2e",
694
- "human"
695
- ]
696
- },
697
- {
698
- "id": "pattern.tooltip",
699
- "version": "1.0.0",
700
- "title": "Tooltip",
701
1171
  "kind": "pattern",
1172
+ "product_decisions": [
1173
+ "automatic_or_manual_activation"
1174
+ ],
702
1175
  "requires": [
703
1176
  "semantics.accessible-name",
704
- "semantics.keyboard.escape"
1177
+ "semantics.selected-state",
1178
+ "semantics.keyboard",
1179
+ "semantics.focus.visible"
1180
+ ],
1181
+ "scope": "Tabbed interfaces",
1182
+ "standards_refs": [
1183
+ {
1184
+ "authority": "aria-apg",
1185
+ "identifier": "tabs",
1186
+ "normative": false,
1187
+ "url": "https://www.w3.org/WAI/ARIA/apg/patterns/tabs/"
1188
+ }
705
1189
  ],
1190
+ "title": "Tabs",
1191
+ "version": "1.0.0"
1192
+ },
1193
+ {
706
1194
  "activation": {
707
1195
  "contains": {
708
1196
  "fact": "component.accessibility_pattern_ids",
709
1197
  "value": "pattern.tooltip"
710
1198
  }
711
1199
  },
712
- "scope": "Supplementary description",
713
1200
  "behavior": [
714
1201
  "Available on hover and focus",
715
1202
  "Never contains interactive content"
716
1203
  ],
717
- "product_decisions": [
718
- "delay"
1204
+ "evidence_routes": [
1205
+ "unit",
1206
+ "e2e",
1207
+ "human"
719
1208
  ],
720
1209
  "functional_spec_bindings": [
721
1210
  "behavior"
722
1211
  ],
1212
+ "id": "pattern.tooltip",
723
1213
  "implementation_outcomes": [
724
1214
  "tooltip-description"
725
1215
  ],
1216
+ "kind": "pattern",
1217
+ "product_decisions": [
1218
+ "delay"
1219
+ ],
1220
+ "requires": [
1221
+ "semantics.accessible-name",
1222
+ "semantics.keyboard.escape"
1223
+ ],
1224
+ "scope": "Supplementary description",
1225
+ "standards_refs": [
1226
+ {
1227
+ "authority": "aria-apg",
1228
+ "identifier": "tooltip",
1229
+ "normative": false,
1230
+ "url": "https://www.w3.org/WAI/ARIA/apg/patterns/tooltip/"
1231
+ }
1232
+ ],
1233
+ "title": "Tooltip",
1234
+ "version": "1.0.0"
1235
+ },
1236
+ {
1237
+ "activation": {
1238
+ "contains": {
1239
+ "fact": "component.accessibility_pattern_ids",
1240
+ "value": "pattern.tree-view"
1241
+ }
1242
+ },
1243
+ "behavior": [
1244
+ "Expose tree, treeitem, and group relationships, set aria-multiselectable for a multi-select tree, and provide level, position, and set-size metadata when the complete hierarchy is not represented in the DOM",
1245
+ "On tree entry, focus the selected node or first selected node when one exists and otherwise focus the first node; keep one composite tab stop and keep focus visually distinct from selection",
1246
+ "In a vertical tree, Right Arrow opens a closed parent without moving focus, moves from an open parent to its first child, and does nothing on an end node; Left Arrow closes an open parent, moves from a closed parent or end node to its parent, and does nothing on a root node that cannot close",
1247
+ "In a vertical tree, Down Arrow moves to the next visible focusable node and Up Arrow moves to the previous visible focusable node without changing expansion; Home and End move to the first and last visible focusable nodes, Enter performs the node's declared default action, and type-ahead moves to the next matching node",
1248
+ "For a horizontal tree, remap Down Arrow to the vertical Right Arrow behavior, Right Arrow to vertical Down Arrow, Up Arrow to vertical Left Arrow, and Left Arrow to vertical Up Arrow",
1249
+ "Keep focus distinct from selection and synchronize expansion and the declared aria-selected or aria-checked state model without exposing both states for the same selection purpose",
1250
+ "For a multi-select tree using the recommended modifier-free model, navigation does not clear selection, Space toggles selection of the focused node, and declared Shift combinations extend contiguous selection; for the alternative modifier-required model, unmodified navigation selects only the focused node while Control plus an arrow moves focus without changing selection and Control plus Space toggles the focused node"
1251
+ ],
726
1252
  "evidence_routes": [
727
1253
  "unit",
1254
+ "axe",
728
1255
  "e2e",
729
1256
  "human"
730
- ]
731
- },
732
- {
733
- "id": "pattern.validation",
734
- "version": "1.0.0",
735
- "title": "Form validation",
1257
+ ],
1258
+ "functional_spec_bindings": [
1259
+ "behavior",
1260
+ "states",
1261
+ "keyboard",
1262
+ "focus"
1263
+ ],
1264
+ "id": "pattern.tree-view",
1265
+ "implementation_outcomes": [
1266
+ "tree-hierarchy-semantics",
1267
+ "tree-keyboard-model",
1268
+ "tree-selection-model"
1269
+ ],
736
1270
  "kind": "pattern",
1271
+ "product_decisions": [
1272
+ "focus_strategy",
1273
+ "multi_select_keyboard_model",
1274
+ "orientation",
1275
+ "selection_follows_focus",
1276
+ "selection_state",
1277
+ "single_or_multi_select",
1278
+ "typeahead",
1279
+ "virtualization"
1280
+ ],
737
1281
  "requires": [
738
- "semantics.form-error",
739
- "semantics.live-status",
740
- "semantics.focus.initial"
1282
+ "semantics.accessible-name",
1283
+ "semantics.expanded-state",
1284
+ "semantics.focus.visible",
1285
+ "semantics.keyboard",
1286
+ "semantics.roles-states-properties",
1287
+ "semantics.selected-state"
1288
+ ],
1289
+ "scope": "Hierarchical single-select or multi-select tree widgets",
1290
+ "standards_refs": [
1291
+ {
1292
+ "authority": "aria-apg",
1293
+ "identifier": "treeview",
1294
+ "normative": false,
1295
+ "url": "https://www.w3.org/WAI/ARIA/apg/patterns/treeview/"
1296
+ }
741
1297
  ],
1298
+ "title": "Tree view",
1299
+ "version": "1.0.0"
1300
+ },
1301
+ {
742
1302
  "activation": {
743
1303
  "any": [
744
1304
  {
@@ -755,29 +1315,55 @@
755
1315
  }
756
1316
  ]
757
1317
  },
758
- "scope": "Client or server validation",
759
1318
  "behavior": [
760
1319
  "Identify, associate, summarize, and focus errors deterministically"
761
1320
  ],
762
- "product_decisions": [
763
- "validation_timing",
764
- "error_summary"
1321
+ "evidence_routes": [
1322
+ "unit",
1323
+ "axe",
1324
+ "e2e",
1325
+ "human"
765
1326
  ],
766
1327
  "functional_spec_bindings": [
767
1328
  "validation",
768
1329
  "messaging",
769
1330
  "focus"
770
1331
  ],
1332
+ "id": "pattern.validation",
771
1333
  "implementation_outcomes": [
772
1334
  "validation-associations",
773
1335
  "error-summary"
774
1336
  ],
775
- "evidence_routes": [
776
- "unit",
777
- "axe",
778
- "e2e",
779
- "human"
780
- ]
1337
+ "kind": "pattern",
1338
+ "product_decisions": [
1339
+ "validation_timing",
1340
+ "error_summary"
1341
+ ],
1342
+ "requires": [
1343
+ "semantics.form-error",
1344
+ "semantics.live-status",
1345
+ "semantics.focus.initial"
1346
+ ],
1347
+ "scope": "Client or server validation",
1348
+ "standards_refs": [
1349
+ {
1350
+ "authority": "wcag-2.2",
1351
+ "identifier": "3.3.1",
1352
+ "level": "A",
1353
+ "normative": true,
1354
+ "url": "https://www.w3.org/TR/WCAG22/#error-identification"
1355
+ },
1356
+ {
1357
+ "authority": "wcag-2.2",
1358
+ "identifier": "3.3.3",
1359
+ "level": "AA",
1360
+ "normative": true,
1361
+ "url": "https://www.w3.org/TR/WCAG22/#error-suggestion"
1362
+ }
1363
+ ],
1364
+ "title": "Form validation",
1365
+ "version": "1.0.0"
781
1366
  }
782
- ]
1367
+ ],
1368
+ "schema_version": 3
783
1369
  }