Accessibility

What is guaranteed, and what is not.

The API makes the accessible thing the default

IconButton requires aria-label at the type level, so an icon-only control cannot ship nameless. Alert and Toast pick role="alert" for urgent tones and role="status" for the rest, so they do not talk over the user. RadioGroup is a real <fieldset> with a <legend>, which names the group with no ARIA at all. Divider is a real <hr> unless labelled, and FAQ is native <details> — no ARIA, no JavaScript.

Overlays

Modal and Drawer trap focus, lock body scroll without layout shift, make the rest of the page inert, and return focus to the trigger. Combobox and CommandPalette move the active option with aria-activedescendant while DOM focus stays in the input, which is the pattern the ARIA spec actually prescribes.

The controls that usually have no keyboard story

EditableGrid and FileTree are one tab stop each, with a roving focus - the alternative, a tab stop per cell or per node, makes a twenty-row grid a hundred and sixty stops. VirtualList keeps aria-posinset and aria-setsize honest while it windows, so a screen reader is told how many items there really are rather than how many happen to be rendered.

KanbanBoard is the clearest case. The HTML5 drag-and-drop API has no keyboard equivalent at all - no key starts a drag - so a board built on it is unusable without a pointer, which is why almost every board on the web is. This one ships two complete input paths: dragging, and a pick-up / move / drop model announced through a live region. Scheduler has the same problem in a different shape: a timeline says everything through position, so every booking carries its resource, its times and its duration in its accessible name.

How it is verified

Every component has automated axe assertions in its test suite, and the keyboard maps are covered by tests rather than described in prose.

Back to the introduction