param087/saas-ui-skills

accessible-components

Use when building or reviewing interactive UI that must meet WCAG 2.2 AA — focus management, ARIA roles and states, keyboard navigation, labels, and visible focus.

Voir la source

Mode d’emploi

  1. Copiez la commande et examinez le paquet avant de l’installer dans votre environnement agent.
  2. Consultez le document original pour les outils, identifiants et environnements requis.
  3. Décrivez les entrées et le livrable souhaité ; comparez la sortie aux sources.
npx skills add https://github.com/param087/saas-ui-skills --skill accessible-components

Avant de commencer

  • L’installation n’inclut ni abonnement au modèle, ni quota API, ni accès aux fichiers.
  • Étoiles et installations reflètent l’activité, pas un test indépendant de qualité ou de sécurité.
Document Skill original

Rendu depuis le dépôt source en conservant titres, exemples, code, tableaux, liens et images.

Accessible Components

Overview

Accessibility is not a feature you add later — it's how you build interactive elements from the start. The single best move in a SaaS app is to use real semantic elements and Radix/shadcn primitives, which ship correct ARIA and keyboard behavior. Most a11y bugs come from re-inventing a button or dropdown with a <div>.

When to use

  • Building any interactive control (menus, dialogs, tabs, toggles).
  • Reviewing UI for keyboard and screen-reader support.
  • A <div onClick> is standing in for a button.

Rule 1: Use the right element

tsx
// ✗ Inaccessible: no focus, no Enter/Space, no role
<div onClick={save} className="btn">Save</div>

// ✓ Accessible for free
<button type="button" onClick={save} className="btn">Save</button>

A native <button> is focusable, fires on Enter/Space, and announces as a button. Same for <a> (navigation), <label> (form association), <nav>/<main>/<header> (landmarks).

Rule 2: Every input has a label

tsx
<Label htmlFor="email">Email</Label>
<Input id="email" type="email" />

// Icon-only buttons need an accessible name:
<Button size="icon" aria-label="Close">
  <X className="h-4 w-4" aria-hidden />
</Button>

Decorative icons get aria-hidden; the control gets aria-label.

Rule 3: Visible focus, always

Never outline-none without a replacement. Use a focus ring on every interactive element:

tsx
className="focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"

:focus-visible shows the ring for keyboard users without flashing it on mouse clicks.

Rule 4: Keyboard support

  • All actions reachable via Tab; logical order (don't fight the DOM with tabindex > 0).
  • Esc closes overlays; Enter/Space activate; arrow keys move within menus/tabs/radios.
  • Radix/shadcn primitives (DropdownMenu, Dialog, Tabs, Select) implement these — prefer them over hand-rolled widgets.

Rule 5: Announce dynamic changes

Screen readers miss silent DOM updates. Use live regions for async status:

tsx
<p role="status" aria-live="polite">{saving ? "Saving…" : "All changes saved"}</p>

Toasts should render in an aria-live region (sonner/shadcn handle this — see notifications-and-toasts).

Quick checklist

  • [ ] Color contrast ≥ 4.5:1 for text (3:1 for large/UI).
  • [ ] Every control reachable and operable by keyboard.
  • [ ] Visible focus indicator on each control.
  • [ ] Inputs have associated labels; icon buttons have aria-label.
  • [ ] State conveyed beyond color alone (icon/text too).
  • [ ] Images have alt; decorative ones alt=""/aria-hidden.

Pitfalls

  • `<div onClick>` instead of <button> — no keyboard, no role.
  • `outline-none` with no focus replacement — keyboard users get lost.
  • Placeholder as label — disappears on input, fails screen readers.
  • Color-only state (red border, no message) fails colorblind users.
  • Hand-rolled dropdowns/modals missing focus trap and arrow keys — use primitives.

Hand-off

The accessibility baseline every other skill assumes — forms-and-validation, modals-and-dialogs, and navigation-patterns all build on these rules.

Tâches connexes

du même dépôt

Autres Skills

Tous les Skills