Accessible component showcase
Five core widgets built to the WAI-ARIA Authoring Practices — correct focus management, live state, and honest ARIA wiring. No mouse required: Tab through the page and try the keys listed in each contract.
- Vanilla JS
- Zero dependencies
- Reduced-motion aware
Modal dialog
A modal that owns focus while open: Tab and Shift+Tab cycle inside, the page behind goes inert, and focus lands back on the trigger when it closes.
Dialog has not been opened yet.
Tab / Shift+Tab cycle inside Esc closes backdrop click closes focus returns to trigger
Tabs
One tab in the tab order, arrows to travel, and the hidden attribute — not CSS — keeping inactive panels out of the accessibility tree.
Praxis UI ships five core primitives. Each one exposes its state through ARIA that mirrors what you see on screen — if it looks open, it announces open.
- Exactly one tab carries
tabindex="0"; the rest sit at-1. - Arrow keys move focus and selection together (automatic activation).
- Inactive panels use
hidden, so their content is unreachable by Tab.
<div role="tablist">
<button role="tab" aria-selected="true"
aria-controls="p1" tabindex="0">…</button>
<button role="tab" aria-selected="false"
aria-controls="p2" tabindex="-1">…</button>
</div>
<div role="tabpanel" id="p1" aria-labelledby="tab1">…</div>
Jump back to the live example
←→ switch tabs Home/End first / last only the active tab is tabbable panel content reachable by Tab
Combobox
An autocomplete input using the aria-activedescendant pattern — the listbox is never focusable; the highlight is announced through the input's own ARIA state.
- Apple
- Apricot
- Avocado
- Banana
- Blackberry
- Blueberry
- Cherry
- Coconut
- Cranberry
- Dragonfruit
- Fig
- Grape
- Grapefruit
- Kiwi
- Lemon
- Mango
- Papaya
- Peach
- Pineapple
- Raspberry
- No matches
↓ opens the list type to filter ↑↓ move highlight Enter selects Esc closes + reverts focus-out closes
Accordion
Disclosure buttons that animate height with the Web Animations API — hidden is only toggled when the animation finishes, so assistive tech never sees a half-open region.
While a modal is open, Tab and Shift+Tab are intercepted and wrapped inside the dialog. Combined with inert on the background, keyboard focus can never leak into the page behind the dialog.
With tabindex="-1" on inactive tabs, a single Tab press reaches the tablist; arrows do the traveling. Adding every tab to the tab order would force N-1 extra stops before reaching the panel content.
Height is animated with WAAPI while the region stays visible; hidden is applied only on finish. When prefers-reduced-motion is set, the animation is skipped and the attribute toggles immediately.
Enter / Space toggle
multiple panels may stay open
animation respects prefers-reduced-motion