Component library · light theme
Accessible components, done properly
Five interactive primitives — modal, menu, tabs, combobox, accordion — with correct focus management, live ARIA state, and full keyboard support. No mouse required anywhere.
- 100% keyboard operable
- Focus is never lost
- prefers-reduced-motion aware
- Zero dependencies
01
Modal Dialog
A focus-trapped dialog that freezes the page behind it and restores focus on close.
While open, Tab cycles inside the dialog and the rest of the page is inert.
Keyboard Tab/⇧ Tab cycle in dialog · Esc close · click backdrop closes
03
Tabs
Roving tabindex with a roving-tabindex tab strip — only the active tab is in the tab order.
What this is
A dependency-free tab component following the WAI-ARIA Tabs pattern. Inactive panels carry the hidden attribute, so their content is removed from both the accessibility tree and the tab order.
- Only the active tab is focusable (
tabindex="0") - Arrow keys move between tabs without leaving the strip
- Every
aria-controlsresolves to a real panel
How to use it
Copy the markup, attach the behaviour, done. Panels may contain any interactive content — links, buttons, forms — and once a tab is activated you can Tab straight into its panel.
API surface
| Attribute | Role |
|---|---|
aria-selected | true on the active tab, false on the rest |
aria-controls | tab → its panel |
aria-labelledby | panel → its tab |
tabindex | roving: 0 active, −1 others |
Keyboard ←/→ switch tabs (wraps) · Home/End jump · Tab enters the panel
04
Combobox (Autocomplete)
A typeahead select using the aria-activedescendant pattern — the listbox is never focusable.
No selection yet. Arrow keys move the highlight; the input stays focused the whole time.
Keyboard type to filter · ↓/↑ highlight · Enter select · Esc close & revert · Tab/click away closes
05
Accordion / Disclosure Group
Independent regions that can all be open at once, with height animations that never hide content from assistive tech.
When a transient widget opens, focus moves into it; when it closes, focus returns to the control that opened it. The accordion follows the same contract on a smaller scale: its header button keeps focus while its region animates.
aria-expanded and aria-controls describe the region from the button; the region itself needs no role in this pattern. Both attributes flip atomically with the animation, so screen readers never describe a state the user cannot see.
Regions animate by interpolating height with overflow: hidden. The hidden attribute is only toggled once the transition settles — never mid-flight — and under prefers-reduced-motion the animation is skipped entirely.
Keyboard Tab to a header · Enter/Space toggles it · multiple regions can be open simultaneously