designengineering
Component Design Spec
Write component design specifications — defining props, states, interactions, accessibility requirements, and visual variants for design system components.
componentsdesign-systemsspecificationsUIaccessibility
Works well with agents
Works well with skills
component-design-spec/
SKILL.md
Markdown| 1 | |
| 2 | # Component Design Spec |
| 3 | |
| 4 | ## Before you start |
| 5 | |
| 6 | Gather the following from the user. If anything is missing, ask before proceeding: |
| 7 | |
| 8 | 1. **What component is being specified?** — Name and one-sentence purpose |
| 9 | 2. **Where does it appear?** — Pages, layouts, or parent components that will consume it |
| 10 | 3. **What design system does it belong to?** — Existing system with tokens, or standalone |
| 11 | 4. **What are the usage scenarios?** — The 2-5 most common ways this component will be used |
| 12 | 5. **Are there existing implementations?** — Current components being replaced or extended |
| 13 | 6. **What are the constraints?** — Framework, browser support, performance budgets, package size limits |
| 14 | |
| 15 | ## Spec template |
| 16 | |
| 17 | ### 1. Component Overview |
| 18 | |
| 19 | ``` |
| 20 | Name: [PascalCase component name] |
| 21 | Purpose: [One sentence — what it does and why it exists] |
| 22 | Category: [Primitive / Composite / Pattern] |
| 23 | Status: [Proposed / In Review / Approved / Implemented] |
| 24 | ``` |
| 25 | |
| 26 | Categories: **Primitive** (low-level, no domain logic: Button, Input), **Composite** (combines primitives: SearchField, DatePicker), **Pattern** (opinionated layout: DataTable, NavigationBar). |
| 27 | |
| 28 | ### 2. Props API |
| 29 | |
| 30 | Define every prop with type, default, and description. Example format: |
| 31 | |
| 32 | ```typescript |
| 33 | interface ComponentProps { |
| 34 | children: React.ReactNode; |
| 35 | variant: 'primary' | 'secondary' | 'ghost' | 'danger'; |
| 36 | size?: 'sm' | 'md' | 'lg'; // default: 'md' |
| 37 | disabled?: boolean; // default: false |
| 38 | loading?: boolean; // default: false |
| 39 | onClick?: (event: React.MouseEvent) => void; |
| 40 | } |
| 41 | ``` |
| 42 | |
| 43 | Rules: name props after what they control (`variant="danger"` not `color="red"`), default booleans to `false`, use string literal enums, follow `onAction` callback convention. If >10 props, consider composition. |
| 44 | |
| 45 | ### 3. States |
| 46 | |
| 47 | | State | Trigger | Visual Change | Behavior Change | |
| 48 | |-------|---------|---------------|-----------------| |
| 49 | | Default | Initial render | Base styling | Fully interactive | |
| 50 | | Hover | Mouse enter | Background darkens | Tooltip may appear | |
| 51 | | Focus | Keyboard tab | Focus ring visible | Accepts Enter/Space | |
| 52 | | Active | Mouse down / Enter | Scale down slightly | Action fires on release | |
| 53 | | Disabled | `disabled={true}` | Opacity reduced | No events fire | |
| 54 | | Loading | `loading={true}` | Spinner replaces icon | No events fire | |
| 55 | | Error | Validation failure | Red border, error icon | Error message shown | |
| 56 | |
| 57 | Every interactive state must be visually distinguishable. Focus must be visible without hover. Disabled and loading must look different from each other. |
| 58 | |
| 59 | ### 4. Visual Variants |
| 60 | |
| 61 | Map each variant to design tokens (never hardcoded values). For each variant, specify: background token, text token, border token, and usage guidance (e.g., "primary: one per view," "danger: destructive actions only"). Define a size scale mapping each size to height, horizontal padding, font size, and icon size. |
| 62 | |
| 63 | ### 5. Interaction Behavior |
| 64 | |
| 65 | **Keyboard**: `Tab` to focus (skip if disabled), `Enter`/`Space` to activate, `Escape` to close associated popover. |
| 66 | |
| 67 | **Mouse**: Single click activates. Double click behaves as single click unless specified otherwise. |
| 68 | |
| 69 | **Touch**: Tap activates. Minimum 44x44px touch target. |
| 70 | |
| 71 | **Focus management**: Focus follows DOM order. After activation, focus stays unless navigation occurs. Opening a popover/modal moves focus to the opened content. |
| 72 | |
| 73 | ### 6. Accessibility Requirements |
| 74 | |
| 75 | Non-negotiable minimums: |
| 76 | |
| 77 | - [ ] Correct ARIA role (e.g., `role="button"` for non-button elements acting as buttons) |
| 78 | - [ ] Accessible name via visible label, `aria-label`, or `aria-labelledby` |
| 79 | - [ ] State changes announced: `aria-disabled`, `aria-expanded`, `aria-pressed` |
| 80 | - [ ] Color contrast WCAG 2.1 AA: 4.5:1 text, 3:1 interactive borders |
| 81 | - [ ] Focus indicator with 3:1 contrast against adjacent colors |
| 82 | - [ ] Motion respects `prefers-reduced-motion` |
| 83 | |
| 84 | Document expected screen reader output for each state (default, loading, disabled). |
| 85 | |
| 86 | ### 7. Composition Examples |
| 87 | |
| 88 | Show common usage and at least one anti-pattern: |
| 89 | |
| 90 | ```jsx |
| 91 | {/* Correct: semantic variant */} |
| 92 | <Button variant="danger" onClick={handleDelete}>Delete Account</Button> |
| 93 | |
| 94 | {/* WRONG: visual prop instead of semantic */} |
| 95 | <Button color="red" onClick={handleDelete}>Delete</Button> |
| 96 | ``` |
| 97 | |
| 98 | Include examples for: basic usage, loading state, with icon, and the most complex supported composition. |
| 99 | |
| 100 | ## Quality checklist |
| 101 | |
| 102 | Before delivering a component design spec, verify: |
| 103 | |
| 104 | - [ ] Props API uses semantic names, not visual descriptions |
| 105 | - [ ] Every prop has a type, default value (if optional), and description |
| 106 | - [ ] All interactive states are documented with visual and behavioral changes |
| 107 | - [ ] Keyboard interactions are specified for every supported action |
| 108 | - [ ] Accessibility includes ARIA attributes, contrast ratios, and screen reader output |
| 109 | - [ ] Visual variants reference design tokens, not hardcoded values |
| 110 | - [ ] Examples show common use cases and at least one anti-pattern |
| 111 | |
| 112 | ## Common mistakes |
| 113 | |
| 114 | - **Specifying visuals without states.** A spec showing only the default appearance is incomplete. Every component has hover, focus, active, disabled, and loading states at minimum. |
| 115 | - **Hardcoding colors instead of tokens.** `background: #3B82F6` breaks when the theme changes. Use token references. |
| 116 | - **Ignoring keyboard interaction.** Mouse-only components are broken for keyboard and screen reader users. Keyboard support is not optional. |
| 117 | - **Prop APIs that leak implementation.** Props like `className` or `style` break encapsulation. Expose semantic props instead. |
| 118 | - **Missing anti-pattern examples.** Developers learn from what NOT to do. Show incorrect usage alongside correct usage. |
| 119 | - **No screen reader verification.** Listing ARIA attributes is not enough. Document what the screen reader announces per state. |
| 120 |