Accessibility
The target is WCAG 2.2 level AA for the standalone editor (standalone.html and the component tree under StandAlone.vue). The demo app (index.html, BackendDemo.vue) is an internal developer surface and out of scope.
The evidence lives in the repository, in app/sidedoc-frontend/doc/accessibility/. Those files are the source of truth; this page is a summary.
| Document | Contents |
|---|---|
| README | Index and the automated commands. |
| WCAG 2.2 applicability matrix | Applicable, gap or not applicable, with rationale and test evidence, for every A and AA criterion. |
| Manual assistive-technology protocol | Release-candidate journeys with VoiceOver and Safari, and NVDA with Chrome or Firefox. |
| Automated test exception policy | How a known failure is recorded: visible, owned and time-bounded. |
| Structural navigation findings | Findings from the first manual screen-reader pass: headings, landmarks, what was fixed and what is open. |
| Colour inventory | Semantic colour roles and the SCSS/CSS source-of-truth issue. |
Current state
The matrix records two open level A gaps:
- 1.3.1 Info and Relationships: field labelling is in place across all renderers, but the document form has no heading hierarchy and visual nesting is not exposed programmatically (finding S1).
- 3.1.2 Language of Parts: a user can show a field in another language than the page language, but the rendered value gets no matching
langattribute.
Automated results are evidence, not a conformance claim. They do not replace the manual protocol.
The merge gate
npm run test:a11y -w sidedoc-frontend runs the Playwright and axe-core suite in tests/accessibility/ against the standalone editor. Colour contrast, duplicate ids (4.1.1) and reflow (1.4.10) were opt-in diagnostics until they passed and are now part of the gate. See Testing for how to run it.
Patterns to reuse
When you add or change UI, use the existing building blocks:
useDialogFocus(src/composables/useDialogFocus.js) for every dialog: focus trap, Escape closes the topmost layer only, focus returns to the trigger.useDismissLayerfor menus that close on Escape but do not trap focus.fieldAccessibility.jsandpathFieldId.tsfor control, label, help and error ids and thearia-describedbyandaria-errormessagewiring. Ids are derived from the value path, so they are unique per field.- Convey state (validation, empty values, selection) with text or an icon as well as colour.
- Style changes go into both the SCSS source and the committed
src/assets/tcc.css(see the colour inventory for why). - Add a test to
tests/accessibility/for a new dialog, renderer family or keyboard flow.