Skip to Content
⭐️ Leave a star →
Accessibility

Accessibility

Accessibility is a first-class concern in Wire UI. Every primitive ships with the correct ARIA attributes, keyboard behavior, and focus management — so you can build inclusive interfaces without wiring up semantics from scratch.

Because Wire UI ships zero CSS, the responsibility split is different from styled libraries: Wire UI handles the behavior, you handle the visuals. This page explains both sides of that contract.

Standards we target

Wire UI is built against:

What Wire UI provides

Correct ARIA roles and attributes applied automatically on every component.
Full keyboard navigation out of the box — no extra wiring required.
Focus management — Modal and Drawer trap focus while open and restore it to the trigger on close.
Interactive state exposed via data-* attributes so you can style focus, hover, active, and disabled states with plain CSS.
asChild polymorphism lets you swap any component’s root element without losing accessibility behavior.
No hidden or hardcoded behavior — every a11y-relevant prop is documented on its component page.

What you provide

Visible focus indicators — style [data-focus-visible] so keyboard users always see where focus is.
Color contrast meeting WCAG AA (or APCA / WCAG 3) — Wire UI ships no colors.
Accessible names on icon-only buttons via aria-label.
Visual affordance for [data-disabled] states — disabled should look disabled.
Respect prefers-reduced-motion on any animations or transitions you add.

Keyboard navigation

Every interactive Wire UI component supports keyboard operation. Here are the conventions used across the library:

KeyTypical action
Tab / Shift + TabMove focus to the next / previous focusable element
Enter / SpaceActivate a button, trigger, or selectable item
EscapeClose an overlay (Modal, Drawer, Dropdown, Tooltip)
Arrow keysNavigate between items in menus, radio groups, tabs, and OTP
Home / EndJump to the first / last item in a list-like widget

Component-specific keys (for example, typeahead in Select) are documented on each component’s page under Keyboard Interactions.

Focus management

Focus traps

Modal and Drawer automatically trap focus while open — Tab cycles through focusable elements inside the overlay and can’t escape to the page behind it. When the overlay closes, focus returns to the element that triggered it.

You can customize the entry/exit points with the initialFocus and finalFocus props. See the Modal documentation for details.

Focus-visible styling

Wire UI exposes a data-focus-visible attribute that mirrors the CSS :focus-visible pseudo-class. Style it so keyboard users always see a focus indicator — this is required for WCAG 2.4.7 compliance.

<Button className=" rounded-[8px] border border-black px-4 py-2 [data-focus-visible]:ring-2 [data-focus-visible]:ring-black [data-focus-visible]:ring-offset-2 " > Click me </Button>

The focus ring appears on keyboard navigation but not on mouse click — which matches user expectation and avoids visual noise.

Accessible labels

Interactive components must have an accessible name. Wire UI passes through all standard HTML labeling attributes, so you can use the approach that best fits your UI.

Icon-only buttons

Buttons without visible text need an explicit aria-label:

<Button aria-label="Close dialog"> <CloseIcon /> </Button>

Form fields

Use a native <label> element with htmlFor pointing to the input’s id:

<label htmlFor="email">Email address</label> <Input.Root id="email" type="email" />

Overlays

Modal, Drawer, and Dropdown accept aria-labelledby and aria-describedby to connect to their title and description elements. See each overlay’s docs for the recommended compound pattern.

Color contrast

Because Wire UI ships no colors, meeting contrast requirements is entirely your responsibility. Target:

  • 4.5:1 for body text (WCAG AA)
  • 3:1 for large text (18pt+ or 14pt+ bold) and UI components
  • 3:1 for focus indicators against their background

If you’re evaluating newer standards, the APCA  algorithm — being considered for WCAG 3 — gives more perceptually accurate readings than WCAG 2’s luminance math, especially for dark mode.

Useful tools: browser devtools contrast pickers, Figma contrast plugins, or dedicated tools like Stark and Colour Contrast Analyser.

Reduced motion

Wire UI primitives don’t ship any animations. When you add transitions, gate them behind the user’s motion preference:

@media (prefers-reduced-motion: reduce) { * { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; } }

Or use Tailwind’s motion-safe: / motion-reduce: variants:

<Modal.Content className="motion-safe:transition-all motion-safe:duration-200"> ... </Modal.Content>

Testing

Wire UI is tested against the major screen readers:

  • NVDA (Windows)
  • VoiceOver (macOS / iOS)
  • TalkBack (Android)

For your own applications, combine automated and manual testing:

  • axe-core or Lighthouse catches common issues automatically
  • Keyboard-only navigation — unplug your mouse and work through a full user flow
  • Screen reader spot-checks on critical paths (sign-in, checkout, forms)
  • Zoom to 200% to verify text stays readable and nothing gets clipped

Component-specific details

Every component documentation page has its own Accessibility and Keyboard Interactions section with specifics for that widget. For the most complex a11y patterns, see:

  • Modal — focus trap, labeling, Escape behavior
  • Dropdown — menu roles, typeahead, Arrow key navigation
  • Select — listbox pattern, keyboard filtering
  • OTP — composite input, paste handling
Last updated on

MIT License © 2026 wire-ui

Accessibility – Wire UI