Foundations

Accessibility

Accessibility isn’t a mode in juxt.ui. It’s part of how each component was designed — and what every one of them guarantees.

What every component guarantees #

  • Semantic HTML first. Buttons are <button>, checkboxes are native checkboxes, labels are <label>. ARIA fills gaps; it never replaces the platform.
  • A visible focus ring. Every interactive element shows the same accent ring on keyboard focus — and only on keyboard focus.
  • Complete keyboard support. Composite widgets follow the WAI-ARIA Authoring Practices. Each component page lists its keys.
  • Correct disabled behaviour. Disabled controls are skipped by keyboard navigation and can’t be activated. Loading buttons stay focusable instead, so focus is never lost mid-action.
  • SSR-safe ids. Label, description and error relationships use ids from Vue’s useId(), identical on server and client.
  • Contrast. Text tokens meet WCAG AA against their surfaces in both themes. The accent has a separate -text variant for exactly this reason.

Focus management #

Overlays move focus in deliberately and give it back when they close. Dialogs and the command palette trap Tab inside themselves; menus and selects keep focus where the pattern expects it — on the items for a menu, on the trigger (via aria-activedescendant) for a select.

When a dialog opens it focuses an element marked autofocus, then the first form field, then the dialog itself — never an arbitrary button that a stray Enter could trigger.

Layers and Escape #

Overlays register on a shared stack. Escape and outside clicks go to the top-most layer only, so nested overlays close one at a time, in the order you’d expect:

Copy
<JDialog v-model:open="open" title="Invite">
  <!-- Escape closes the open select first, then the dialog. -->
  <JSelect v-model="role" label="Role" :options="roles" />
</JDialog>

Reduced motion #

With prefers-reduced-motion: reduce, nothing travels or scales. Fades remain, because a fade signals a change of state without movement. See Motion.

Your part #

Components can guarantee their own behaviour. A few things only you can provide:

  • Give icon-only buttons an aria-label.
  • Give fields a visible label. Placeholders disappear as soon as someone types.
  • Write error messages that say how to fix the problem, not just that there is one.
  • Don’t put essential information only in a tooltip or a toast — both go away.
  • Use one JToaster per app, so announcements come from a single live region.