Accessibility
The accessibility target for @azmr/ui, what is tested automatically, what is not tested yet, and how to build accessible screens with it.
Accessibility is a design goal of @azmr/ui, not an add-on. The target is WCAG 2.2 level AA: components are keyboard-complete, name themselves to assistive technology, keep a visible focus ring and follow the reduced-motion setting.
This page says what is checked, and where the checking stops. Every component page has its own Accessibility section with a keyboard map, and the accessibility reference lists all of them in one place.
What is tested automatically
- Every component runs axe in its tests. More than thirty of the package's test files render components and fail on any axe violation, in the states the tests reach, such as a menu closed and open.
- Every live demo on this site is checked. The docs tests render every demo and fail the build on an axe violation, so a demo cannot ship inaccessible.
- Keyboard use is exercised. Tests drive components with simulated key presses (Tab, arrows, Home, End, Enter, Space, Escape) and check where focus goes and what happens.
- Colour contrast is computed. Every foreground and background token pair is calculated from the tokens and tested for WCAG contrast in light and dark mode. The token reference lists the ratios.
- Reduced motion is tested. The motion tokens collapse under
prefers-reduced-motion, and the tests check it. See reduced motion.
What is not tested yet
- Real devices. Animation playback, touch gestures (such as swiping a toast away) and hover behaviour are verified by unit and CSS tests in a simulated browser, not on real devices.
- Screen readers. Results of manual screen-reader testing are not published here yet. The design plans a manual pass for each phase of the library.
- Everything axe cannot see. Automated checks find only part of the problems. They do not replace trying a screen on a keyboard and with a screen reader.
If you find a barrier, please open an issue.
Building accessible screens
Name every icon-only control
A control with no text needs an accessible name. IconButton requires a label, and a Button with size="icon" must be given aria-label or aria-labelledby: TypeScript enforces both. If you add a tooltip, keep the label too, because a tooltip is not an accessible name on touch devices. See Button.
Pair errors with text
Input exposes an invalid state through aria-invalid, not through colour alone. Always show a text message next to the field as well. See Input.
Return focus after a dialog
A dialog traps focus, makes the page behind it inert and returns focus to the control that opened it when it closes. An alert dialog starts focus on its cancel button, so pressing Enter by reflex cannot confirm something destructive. Give every dialog a title. See Modal.
Announce changes
Toasts live in a polite live region named "Notifications", and errors are also written to a separate alert so they are spoken at once. A button with loading sets aria-busy instead of changing its label silently. See Toast.
Respect the motion setting
Animation follows the operating system's reduced-motion setting automatically. Mark only motion that is genuinely essential with data-motion="essential". See Theming and Motion.