Como usar
- Copie o comando e verifique o pacote antes de instalar no seu ambiente de agente.
- Consulte no original as ferramentas, credenciais e ambientes necessários.
- Descreva os dados de entrada e a entrega esperada; confira a saída com as fontes.
npx skills add https://github.com/param087/saas-ui-skills --skill accessible-componentsAntes de começar
- A instalação não inclui assinatura de modelo, franquia API ou acesso aos seus arquivos.
- Estrelas e instalações indicam atividade, não um teste independente de qualidade ou segurança.
Renderizado do repositório de origem, preservando títulos, exemplos, código, tabelas, links e imagens.
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
// ✗ 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
<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:
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). Esccloses overlays;Enter/Spaceactivate; 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:
<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 onesalt=""/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.




