component-spec-writer — playbook¶
Produce a developer-ready spec sheet for a single UI component. Output is a markdown document that a frontend engineer can implement against without asking follow-up questions.
When to use¶
- "Spec a
Bannercomponent for me." - "We're adding a
MultiSelect. Document the API." - "Help me design the anatomy of a
CommandPalette."
Inputs (ask if missing)¶
- Component name (canonical, kebab-case).
- Goal — what user need it serves.
- Target framework —
react,vue,svelte, framework-agnostic. Default: react. - Style system —
tailwind,css vars,mui theme,antd token. Default: css vars. - Existing components in the system? — to check naming consistency.
Steps¶
1. Find references¶
Open knowledge/components/INDEX.md. For the canonical name, locate the row. Open the source files for all three libraries that have it. Read enough to understand:
- Required vs optional props.
- Variants (size, color, type).
- States (default, hover, active, focus, disabled, loading, error).
- Composition (does it have sub-components like
Card.Header,Card.Body?). - Edge cases the libraries handle (empty state, overflow, RTL, long text).
If the component is not in the index, find the closest analogous component (e.g., MultiSelect ≈ shadcn Select + custom multi-mode).
2. Choose the canonical API¶
Compare APIs across the three references. Pick the cleanest. Bias rules:
- Boolean flags > enum strings when there are ≤ 2 options. (
disablednotstate="disabled".) - Enum strings > booleans when there are 3+ options. (
size="sm" | "md" | "lg"notsmall={bool}, medium={bool}.) - Composition > prop overload for layout-rich components. (
<Card><Card.Header /></Card>not<Card title={...} />.) - One callback per event type. (
onChange(value)notonChange(event)for form fields where event is rarely needed.)
3. Define anatomy¶
Diagram the component's parts in markdown. Name each part:
Each part needs: - A purpose sentence. - Whether it's required. - Default content if omitted.
4. Define states¶
For every interactive component, enumerate:
| State | Trigger | Visual change |
|---|---|---|
| Default | resting | base styles |
| Hover | mouse over | slight bg shift, cursor change |
| Focus-visible | keyboard tab | 2px focus ring (cite keyboard-and-focus.md) |
| Active | press | deeper bg shift |
| Disabled | disabled prop |
reduced opacity, no events, aria-disabled="true" |
| Loading | loading prop |
spinner replaces or overlays content |
| Error | error prop or invalid value |
red border + error text |
| Read-only | readOnly prop |
no border emphasis, no edit affordance |
Not every state applies to every component. Mark N/A.
5. Define variants¶
| Variant axis | Values | When to use |
|---|---|---|
size |
sm / md / lg |
sm in dense forms, md default, lg in marketing |
color |
primary / secondary / danger / ghost |
one CTA per surface uses primary |
shape |
(component-specific) |
6. Accessibility requirements¶
For each component, list:
- Semantic element (e.g.,
<button>not<div role="button">). - ARIA attributes (
aria-label,aria-expanded,aria-haspopup,aria-controls). - Keyboard interactions (cite keyboard-and-focus.md for the canonical pattern).
- Screen reader announcement on state change.
- Touch target size (≥ 44×44 for primary actions).
7. Tokens consumed¶
List every design token the component reads:
--color-primary-default
--color-primary-hover
--color-on-primary
--space-md
--radius-md
--transition-default
If a token does not exist in the system, flag it — don't silently invent.
8. Edge cases¶
- Empty state (no data, no value).
- Overflow (text too long, list too tall).
- Long content (truncate vs wrap).
- RTL behavior.
- Reduced motion (
prefers-reduced-motion). - High contrast mode.
- Print.
9. Output¶
Use TEMPLATE.md. Verify:
- Every prop has a type, default, and one-line description.
- Every state has a visual rule.
- Every keyboard interaction is listed.
- Code example covers the most common usage.
- Don't section addresses 2–3 misuses.
Source files this skill reads¶
knowledge/components/INDEX.mdknowledge/components/shadcn-registry.mdknowledge/a11y/keyboard-and-focus.mdknowledge/a11y/contrast.mdknowledge/motion/principles.md— for animation specsknowledge/i18n/korean-typography.md— when Korean IME is relevantknowledge/platforms/react-native.md— when target is RN- Source files in
refs/(cite the exact paths). - Existing worked specs in
examples/README.md— reference for shape and depth.
Verification phase (run before declaring done)¶
- Did I cite at least 2 of the 3 reference libraries (Ant / MUI / shadcn)?
- Are API choices explained ("API choices made" section) — not just listed?
- Do all states (default/hover/focus/active/disabled/loading/error) have visual rules?
- Is every keyboard interaction listed for the WAI-ARIA pattern this component implements?
- Are the required ARIA attributes spelled out (not just "use ARIA")?
- Is there a touch-target size note (≥ 44pt mobile / ≥ 24px web AA)?
- Does the spec address reduced-motion handling?
- Are at least 3 edge cases covered (empty, long content, RTL, etc.)?
- Does the "Don't" section have at least 2 specific misuses?
- If RN-targeted: are tokens as numbers and is
Pressableused (not<button>)? - If Korean-relevant input: is IME composition handling addressed?
Done when¶
- One markdown file, < 600 lines.
- Anatomy diagram + parts table.
- API table (props, types, defaults, descriptions).
- States table.
- Variants table.
- Tokens consumed list.
- Keyboard interactions.
- ARIA requirements.
- Code example.
- Edge cases section.
- "Don't" section.
- The verification phase checklist passes.