Accessibility checklist
Each row lists the semantics the primitive provides.
Each row lists the semantics the primitive provides. Preserve these attributes and keyboard interactions when adapting its presentation.
| Widget | Roles and attributes | Keyboard and focus |
|---|---|---|
| Dialog | role="dialog", aria-modal="true", aria-labelledby (title), aria-describedby (description), trigger aria-haspopup and aria-expanded |
Focus moves in on open; Tab and Shift+Tab stay inside; Escape or an outside press closes; focus returns to the trigger. The page behind gets aria-hidden while open. |
| AlertDialog | role="alertdialog" |
Focus starts on Cancel; an outside press does not close it; Escape does. |
| Popover | role="dialog", no aria-modal unless modal; give it aria-label or a Title |
Focus moves in; Escape or an outside press closes; the trigger toggles; focus returns to the trigger. |
| Tabs | tablist, tab (aria-selected, aria-controls), tabpanel (aria-labelledby) |
Selected tab is the only tab stop; arrows, Home and End move (and select, unless activationMode="manual"); disabled tabs are skipped. |
| Accordion | Trigger aria-expanded; the panel is role="region" with aria-labelledby pointing at its trigger |
A click toggles; the arrow keys and Home move focus between triggers. |
| Collapsible | Trigger aria-expanded; the content is mounted while open |
A click toggles. |
| Checkbox | role="checkbox", aria-checked ("mixed" when indeterminate) |
Space activates the native button and toggles; Enter is prevented and does not; a hidden native input carries the form value. |
| Switch | role="switch", aria-checked, data-state |
The native button's click toggles it (Space and Enter produce a click). |
| RadioGroup | radiogroup of radio (aria-checked) |
One tab stop; the arrow keys move focus and check. |
| Toggle, ToggleGroup | aria-pressed; items of a single group are role="radio" with aria-checked |
Roving focus inside a group. |
| DropdownMenu, ContextMenu, Menubar | aria-haspopup="menu" on the trigger, menu with menuitem, menuitemcheckbox, menuitemradio |
Enter or ArrowDown opens on the first item; arrows skip disabled items; typeahead jumps; Enter selects and closes; Escape closes and returns focus. A context menu opens on contextmenu; a menubar moves between menus with the arrow keys. |
| Select | Trigger role="combobox" with aria-haspopup="listbox", listbox with option |
ArrowDown opens; arrows move; Enter selects and closes; a hidden native control carries the form value. |
| Combobox | role="combobox" input with aria-expanded and aria-activedescendant |
The input keeps focus; arrows highlight, Enter selects. |
| Tooltip | role="tooltip", trigger aria-describedby |
Opens on keyboard focus; Escape closes. |
| Slider | role="slider" with aria-valuenow, aria-valuemin, aria-valuemax |
Arrows step by step; End jumps to the maximum. |
| Toast | The viewport is a labeled region; announcements go through a live region (role="status" or "alert") |
Escape, the close button, or the duration dismisses it. |
A port can regress accessibility in two ways: by replacing a part with a plain element (a div instead of
Dialog.Title, so aria-labelledby disappears), or by styling away focus (outline-none without a focus-visible
ring). Keep the accessible name, keyboard behavior and visible focus states when changing a component.