Builds accessible, production-ready frontend components. Use when building UI components, forms, modals, or any React/Vue/Svelte frontend work — before writing component code.
NO COMPONENT CODE WITHOUT PRE-IMPLEMENTATION CHECKLIST FIRST.
Wrote JSX before checking for existing design system components? Delete it. Styled before planning keyboard interaction? Delete it. These aren't optional steps.
Pre-Implementation Checklist
Before writing ANY component code:
Check for existing design system — tokens, components, patterns already in repo
Plan keyboard interaction — focus order, shortcuts, trap requirements
Do NOT skip this for "simple" components. Simple components have accessibility bugs too.
New project with no design system? See references/patterns.md → "Design Thinking" for direction-setting.
Framework selection guidance: See references/patterns.md → "Framework Selection".
Accessibility Essentials (Non-Negotiable)
Modal/Dialog Components
// REQUIRED attributes
<div
role="dialog"
aria-modal="true"
aria-labelledby="modal-title-id"
ref={dialogRef}
>
<h2 id="modal-title-id">{title}</h2>
</div>
// REQUIRED behaviors
// 1. Focus first interactive element on open
// 2. Trap focus within modal (Tab cycles inside)
// 3. Restore focus to trigger element on close
// 4. Close on Escape key
Modals MUST implement focus trap. See references/patterns.md → "Focus Trap Implementation" for copy-paste hook.
Form Components
// REQUIRED: Link errors to fields
<input
id="email"
aria-invalid={errors.email ? 'true' : 'false'}
aria-describedby={errors.email ? 'email-error' : undefined}
/>
{errors.email && (
<span id="email-error" role="alert">
{errors.email.message}
</span>
)}
// REQUIRED: Form identification
<form aria-label="Login form">
{/* or aria-labelledby pointing to a heading */}
</form>
Interactive Elements
Element
Requirements
Button
Visible focus indicator, disabled state styling
Link
Underline or clear affordance, focus visible
Custom control
role, aria-* attributes, keyboard handler
Menu/Dropdown
aria-expanded, aria-haspopup, roving tabindex
Component State Checklist
Every component MUST handle:
Default — Normal display state
Loading — Skeleton or spinner (avoid for <500ms operations)
Empty — Meaningful empty state, not blank
Error — Actionable message with recovery path
Disabled — Visual indication + aria-disabled or disabled
Focus — Visible focus indicator (never outline: none without replacement)
Anti-Patterns (Stop If You See These)
Generic AI Aesthetics
❌ Purple-on-white gradients with no context
❌ Cookie-cutter card layouts (centered hero + three icons)
❌ Flat solid backgrounds lacking atmosphere
✅ Honor existing design system OR establish distinctive direction
Technical Debt
❌ Inline styles scattered throughout (use CSS modules, Tailwind, or tokens)
❌ Magic numbers instead of design tokens
❌ Hardcoded colors like #2563eb without token reference
✅ Use CSS custom properties or design tokens
Accessibility Oversights
❌ Missing role="dialog" and aria-modal on modals
❌ No focus trap in modals/drawers
❌ Error messages without role="alert"
❌ Form fields without aria-invalid / aria-describedby
❌ Interactive elements without visible focus indicators
Common Mistakes from Baseline Testing
What Agent Did
What Was Missing
Modal with Escape handling
No role="dialog", no focus trap, no focus restoration
Form with labels
No aria-invalid, no aria-describedby for errors
Error message display
No role="alert" for screen reader announcement
Inline styles
No design tokens, creates maintenance burden
When NOT to Use This Skill
Pure backend/API work with no UI
Static content pages (use Astro or static HTML instead)
Design system documentation (use the design system's own tooling)
Additional References
For error handling, styling standards, performance, and testing → see references/patterns.md.
Definition of Done
Before marking work complete:
Pre-implementation checklist completed (design system check, requirements, keyboard plan)
All states implemented (default, loading, empty, error, disabled)
Keyboard navigation works (Tab, Shift+Tab, Enter, Escape, arrows)
Screen reader announces all interactive elements
Color contrast meets WCAG AA (4.5:1 text, 3:1 UI)
Responsive at 360px, 768px, 1280px
Works with 200% browser zoom
prefers-reduced-motion respected
Error boundaries catch render failures
No any types, console logs, or TODOs remain
Tests pass (unit, a11y, visual if applicable)
1---2name: building-frontend-components3description: Builds accessible, production-ready frontend components. Use when building UI components, forms, modals, or any React/Vue/Svelte frontend work — before writing component code.4---56# Building Frontend Components78## Iron Law910**NO COMPONENT CODE WITHOUT PRE-IMPLEMENTATION CHECKLIST FIRST.**1112Wrote JSX before checking for existing design system components? Delete it. Styled before planning keyboard interaction? Delete it. These aren't optional steps.1314## Pre-Implementation Checklist1516**Before writing ANY component code:**17181. **Check for existing design system** — tokens, components, patterns already in repo192. **Document component requirements** — states (loading, error, empty), variants, accessibility needs203. **Plan keyboard interaction** — focus order, shortcuts, trap requirements2122Do NOT skip this for "simple" components. Simple components have accessibility bugs too.2324**New project with no design system?** See `references/patterns.md` → "Design Thinking" for direction-setting.2526**Framework selection guidance:** See `references/patterns.md` → "Framework Selection".2728## Accessibility Essentials (Non-Negotiable)2930### Modal/Dialog Components3132```typescript33// REQUIRED attributes34<div35 role="dialog"36 aria-modal="true"37 aria-labelledby="modal-title-id"38 ref={dialogRef}39>40 <h2 id="modal-title-id">{title}</h2>41</div>4243// REQUIRED behaviors44// 1. Focus first interactive element on open45// 2. Trap focus within modal (Tab cycles inside)46// 3. Restore focus to trigger element on close47// 4. Close on Escape key48```4950Modals MUST implement focus trap. See `references/patterns.md` → "Focus Trap Implementation" for copy-paste hook.5152### Form Components5354```typescript55// REQUIRED: Link errors to fields56<input57 id="email"58 aria-invalid={errors.email ? 'true' : 'false'}59 aria-describedby={errors.email ? 'email-error' : undefined}60/>61{errors.email && (62 <span id="email-error" role="alert">63 {errors.email.message}64 </span>65)}6667// REQUIRED: Form identification68<form aria-label="Login form">69 {/* or aria-labelledby pointing to a heading */}70</form>71```7273### Interactive Elements7475| Element | Requirements |76|---------|-------------|77| Button | Visible focus indicator, disabled state styling |78| Link | Underline or clear affordance, focus visible |79| Custom control | `role`, `aria-*` attributes, keyboard handler |80| Menu/Dropdown | `aria-expanded`, `aria-haspopup`, roving tabindex |8182## Component State Checklist8384Every component MUST handle:8586- [ ] **Default** — Normal display state87- [ ] **Loading** — Skeleton or spinner (avoid for <500ms operations)88- [ ] **Empty** — Meaningful empty state, not blank89- [ ] **Error** — Actionable message with recovery path90- [ ] **Disabled** — Visual indication + `aria-disabled` or `disabled`91- [ ] **Focus** — Visible focus indicator (never `outline: none` without replacement)9293## Anti-Patterns (Stop If You See These)9495### Generic AI Aesthetics96- ❌ Purple-on-white gradients with no context97- ❌ Cookie-cutter card layouts (centered hero + three icons)98- ❌ Flat solid backgrounds lacking atmosphere99- ✅ Honor existing design system OR establish distinctive direction100101### Technical Debt102- ❌ Inline styles scattered throughout (use CSS modules, Tailwind, or tokens)103- ❌ Magic numbers instead of design tokens104- ❌ Hardcoded colors like `#2563eb` without token reference105- ✅ Use CSS custom properties or design tokens106107### Accessibility Oversights108- ❌ Missing `role="dialog"` and `aria-modal` on modals109- ❌ No focus trap in modals/drawers110- ❌ Error messages without `role="alert"`111- ❌ Form fields without `aria-invalid` / `aria-describedby`112- ❌ Interactive elements without visible focus indicators113114## Common Mistakes from Baseline Testing115116| What Agent Did | What Was Missing |117|----------------|------------------|118| Modal with Escape handling | No `role="dialog"`, no focus trap, no focus restoration |119| Form with labels | No `aria-invalid`, no `aria-describedby` for errors |120| Error message display | No `role="alert"` for screen reader announcement |121| Inline styles | No design tokens, creates maintenance burden |122123## When NOT to Use This Skill124125- Pure backend/API work with no UI126- Static content pages (use Astro or static HTML instead)127- Design system documentation (use the design system's own tooling)128129## Additional References130131For error handling, styling standards, performance, and testing → see `references/patterns.md`.132133## Definition of Done134135Before marking work complete:136137- [ ] Pre-implementation checklist completed (design system check, requirements, keyboard plan)138- [ ] All states implemented (default, loading, empty, error, disabled)139- [ ] Keyboard navigation works (Tab, Shift+Tab, Enter, Escape, arrows)140- [ ] Screen reader announces all interactive elements141- [ ] Color contrast meets WCAG AA (4.5:1 text, 3:1 UI)142- [ ] Responsive at 360px, 768px, 1280px143- [ ] Works with 200% browser zoom144- [ ] `prefers-reduced-motion` respected145- [ ] Error boundaries catch render failures146- [ ] No `any` types, console logs, or TODOs remain147- [ ] Tests pass (unit, a11y, visual if applicable)
Run npx skillmds@latest add sentry01/building-frontend-components in your terminal (requires Node.js), paste this page's agent-chat prompt into Claude, Cursor, or any MCP-connected agent, or download the SKILL.md file and copy it into your agent's skills directory.
Builds accessible, production-ready frontend components. Use when building UI components, forms, modals, or any React/Vue/Svelte frontend work — before writing component code. It is listed under Web & Frontend on SkillMD.
This skill has not completed SkillMD's automated safety review yet. Capability flags: reads secrets. SkillMD never runs a skill's scripts for you; review the SKILL.md before installing.
This skill is tagged as working with Claude Code, Claude.ai, OpenAI Codex. SKILL.md is an open format, so most agents that read a skills directory can load it too.
Yes. Installing skills from SkillMD is free, and the skill stays under its author's original license.
Sentry01 (@sentry01) published this skill. Their other Agent Skills are listed on their SkillMD profile.