Scope and target
Adonia targets WCAG 2.2 Level AA for the generic React pages and framework-owned controls in @adonia/ui. This report describes the executable coverage in the repository; it is not a third-party certification and does not claim that every host application or plugin is conformant. Ejected pages, host CSS, host-provided content, and plugin components remain the host application’s responsibility.
The generic dashboard, resource index, resource detail, resource form, login, and error pages use native landmarks and controls. Action, relation, inline-create, and command-palette overlays expose modal dialog semantics, move focus into the dialog, contain Tab and Shift+Tab, close on Escape, and restore the invoking control. The command palette uses the combobox/listbox/option active-descendant pattern. Options are removed from the page Tab sequence while remaining pointer-operable.
Data tables use a named native table, caption, scoped headers, aria-sort, named selection checkboxes, a resource-named pagination landmark, aria-busy, and persistent live status regions for loading, selection, and result ranges. Schema fields expose labels or legends, required state in both the accessible name and native control state, linked help and errors, aria-invalid, and alert semantics. Uploads retain a native file input and provide named progress with numeric and textual values. The tenant switcher remains a native select. Development unknown-component fallbacks are contextual notes.
Packaged styles provide a common :focus-visible outline, logical-direction utilities for generic chrome, and a prefers-reduced-motion: reduce override that reduces animation and transition durations and disables smooth scrolling. Native controls inherit document direction; code editing remains intentionally left-to-right where the content itself is code.
Executable evidence
The shared axe harness is packages/ui/tests/axe.ts. It runs WCAG 2.0/2.1 A and AA plus WCAG 2.2 AA-tagged axe rules against rendered markup. It deliberately disables axe’s color-contrast rule because jsdom has no layout or pixel-compositing model; this is a harness limitation, not a claim that contrast has been manually verified.
Run the focused contracts from the repository root:
pnpm --filter @adonia/ui exec vitest run \
tests/accessibility.test.tsx \
tests/actions.test.tsx \
tests/relation_manager.test.tsx \
tests/command_palette.test.tsx \
tests/fields/relation.test.tsx \
tests/fields/upload.test.tsx \
tests/data_table.test.tsx \
tests/tenant_switcher.test.tsx| Test ID | Executable contract |
|---|---|
A11Y-PAGE-001 |
Dashboard generic page is axe-clean. |
A11Y-PAGE-002 |
Resource index and populated DataTable page are axe-clean. |
A11Y-PAGE-003 |
Resource detail page is axe-clean. |
A11Y-PAGE-004 |
Resource create form and schema fields are axe-clean. |
A11Y-PAGE-005 |
Login page is axe-clean. |
A11Y-PAGE-006 |
Generic error page is axe-clean. |
A11Y-DIALOG-001 |
Action modal traps forward/reverse Tab, closes on Escape, and restores its trigger. |
A11Y-DIALOG-002 |
Relation modal traps forward/reverse Tab, closes on Escape, and restores its row trigger. |
A11Y-DIALOG-003 |
Inline-create modal traps forward/reverse Tab, closes on Escape, restores its picker trigger, and remains operable after reopening. |
A11Y-PALETTE-001 |
Command palette focuses its input, traps Tab, closes on Escape, and restores its trigger. |
A11Y-PALETTE-002 |
Command palette exposes combobox ownership, active descendant, selected option, and arrow/Enter navigation without adding option Tab stops. |
A11Y-TABLE-001 |
DataTable exposes its name, sort state, selection controls, resource pagination, busy state, and live result/loading text. |
A11Y-FORM-001 |
Required field name/state and linked help, invalid state, and validation alert remain coherent. |
A11Y-UPLOAD-001 |
Upload progress has a file-specific name plus numeric and percentage values. |
A11Y-UPLOAD-002 |
File constraints are connected to the native input as help text. |
A11Y-CHROME-001 |
Tenant switching retains native select semantics and inherits RTL direction. |
A11Y-UNKNOWN-001 |
Development unknown-component fallback has a contextual note name. |
Field-specific suites under packages/ui/tests/fields/ also run the same axe harness against native, collection, relation, editor, error, and upload states. packages/ui/tests/data_table.test.tsx, cells.test.tsx, actions.test.tsx, and relation_manager.test.tsx cover composite states.
Manual checks and current observation status
The following checks are required before making a release-level conformance claim. They were not observed during this implementation, so this report makes no screen-reader sign-off claim:
- NVDA with Firefox and Chrome: landmarks, DataTable navigation/sort/selection announcements, form required/help/error reading order, upload progress, modal focus, and command palette.
- JAWS with Chrome: the same task flows.
- VoiceOver with Safari on macOS and iOS: the same task flows, including native tenant select interaction.
- TalkBack with Chrome on Android: generic-page reading order and form/upload controls.
- Windows forced-colors/high-contrast mode.
- Browser zoom/reflow at 200% and 400%, text spacing overrides, and pointer target inspection.
- Visual contrast measurement for every theme/accent/host-CSS combination.
- Reduced-motion behavior in a real browser with the operating-system preference enabled.
- Full RTL interaction in a real browser with translated production content.
Automated axe and DOM keyboard contracts reduce regressions but do not substitute for these assistive-technology and visual checks.