Accessibility (A11y)
OAS-UI targets WCAG 2.1 AA and is continuously audited with axe.
Automated audits
Playwright + axe-core audit every component demo page; zero serious violations is the passing standard:
bash
pnpm test:e2eThe audits cover the wcag2a / wcag2aa / wcag21aa rule sets and only check the component demo area (.demo-block).
Keyboard flow regression matrix
| Component | Keyboard behavior | Role/ARIA |
|---|---|---|
| Button | Enter/Space triggers | button |
| Input / Textarea | Native input | textbox + label |
| Checkbox / Radio / Switch | Space toggles, arrow keys (Radio) | checkbox / radio / switch |
| Slider | Arrow keys + Home/End | slider (aria-valuenow) |
| InputNumber | Arrow keys inc/dec, Home/End | spinbutton |
| Rate | Arrow keys, Home/End (no Enter) | slider (aria-valuenow) |
| Select / AutoComplete / Cascader / TreeSelect | Arrow navigation, Enter selects, Esc closes | combobox + listbox/tree |
| Menu / Dropdown / ContextMenu | Arrow keys, Home/End, Enter | menu + menuitemradio |
| Tabs | Arrow keys cycle | tablist + tab + aria-selected |
| Tree | Arrow keys + Left/Right expand/collapse | tree + treeitem |
| Modal / Drawer / Confirm | Tab focus trapped, Esc closes | dialog + aria-modal |
| Tooltip / Popover | Esc closes | tooltip / dialog |
| HoverCard | Closes on hover/focus leaving | No role (aria-hidden visibility) |
| Pagination | Tab to page buttons | Semantic buttons + aria-current |
| Carousel | Indicators tabbable | role="tablist" + role="tab" |
| Collapse | Header tabbable + Enter/Space toggles | Button semantics |
| Splitter | Arrow keys adjust | separator + aria-orientation |
| Questionnaire | Header items Enter/Space to jump, native buttons | progressbar + aria-current="step" + aria-live announcements |
Semantic principles
- Every form control has an accessible name (
aria-labelor an associated label) - Overlay components provide
role+aria-modal+ Esc to close - Dynamic regions (loading / opening dialogs) provide
aria-liveor focus management - Colors in principle use semantic tokens only (a few extreme-value/preset exceptions exist) to keep contrast valid in both themes