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
-textvariant 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:
<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
JToasterper app, so announcements come from a single live region.