Use this when you need to document a new or existing UI component for a design system -- its variants, states, behavior rules, accessibility requirements, and usage guidelines. Produces a specification that designers and engineers can build from consistently.
Related skills: Pair with
/style-guidefor foundational tokens. Feed accessibility requirements from/accessibility-audit. Use/interaction-pattern-libraryfor cross-component interaction consistency.
Process
Step 1: Gather inputs
Ask the user to provide:
- Component name -- what is this component called in the design system?
- Purpose -- what problem does this component solve? When should someone use it vs. alternatives?
- Visual reference -- Figma link, screenshot, or description of the component
- Existing implementation -- is there a current version? What's wrong with it or missing?
- Design tokens -- does the team have a token system (colors, spacing, typography)?
Step 2: Define anatomy
Break the component into its constituent parts:
## {{Component Name}}
**Purpose:** (One sentence -- when and why to use this component)
**Category:** (Navigation / Input / Feedback / Layout / Data Display / Action)
### Anatomy
| Part | Required? | Description |
|------|-----------|-------------|
| (e.g., Label) | Yes / No | (What it is and where it appears) |
| (e.g., Icon) | No | (Leading or trailing icon slot) |
| (e.g., Helper text) | No | (Supplementary text below the input) |
Step 3: Define variants
### Variants
| Variant | When to use | Visual difference |
|---------|-------------|-------------------|
| Primary | Default, main actions | (describe) |
| Secondary | Supporting actions alongside primary | (describe) |
| Destructive | Irreversible actions (delete, remove) | (describe) |
| Ghost/Tertiary | Low-emphasis actions, inline links | (describe) |
Step 4: Define states
### States
| State | Visual treatment | Behavior |
|-------|-----------------|----------|
| Default | (describe) | Ready for interaction |
| Hover | (describe change) | Cursor changes, visual feedback |
| Focus | (describe focus indicator) | Keyboard navigation indicator, meets 3:1 contrast |
| Active/Pressed | (describe) | Visual feedback during click/tap |
| Disabled | (describe -- reduced opacity, no pointer) | Non-interactive, skip in tab order |
| Loading | (describe -- spinner, skeleton, progress) | Blocks re-submission, shows progress |
| Error | (describe -- border color, icon, message) | Connected to error message via aria-describedby |
| Success | (describe) | Confirmation feedback |
Step 5: Accessibility specification
### Accessibility
| Requirement | Implementation |
|------------|----------------|
| **Role** | (ARIA role if not implicit -- e.g., role="dialog") |
| **Keyboard** | (How to operate -- Enter, Space, Escape, Arrow keys) |
| **Focus management** | (Tab order, focus trap if modal, return focus on close) |
| **Screen reader** | (What is announced -- label, state, live region updates) |
| **Color independence** | (Icons, borders, or text supplement color indicators) |
| **Target size** | (Minimum 24x24px per WCAG 2.5.8, 44x44px recommended for touch) |
| **Motion** | (Respects prefers-reduced-motion? Describe reduced behavior) |
Step 6: Usage guidelines
### Do / Don't
| Do | Don't |
|----|-------|
| (Correct usage example) | (Common misuse to avoid) |
| (Correct usage example) | (Common misuse to avoid) |
### Content guidelines
- Label text: (rules -- e.g., "2-4 words, sentence case, start with verb")
- Helper text: (rules -- e.g., "One sentence max, no period")
- Error text: (rules -- e.g., "State what went wrong and how to fix it")
### When to use vs. alternatives
- Use **{{this component}}** when: (scenario)
- Use **{{alternative}}** instead when: (scenario)
Step 7: Review
Present the spec and ask:
- Does this cover all the variants your team needs?
- Are there states or interactions I missed?
- Does the accessibility spec match your team's standards?
- Should I spec related components that pair with this one?
Output location
Present the spec as formatted text in the conversation. For design system documentation, export to Notion, Storybook, or the team's component docs.
Example Output
Input
- Component name:
InlineAlert— used across the Meridian Health patient portal design system - Purpose: Surfaces contextual feedback messages (errors, warnings, info, success) directly within a form or content area, without interrupting the user with a modal or toast
- Visual reference: Four color-coded banners with a left-border accent, leading icon, bold title, and optional body text + dismiss button; current Figma file at figma.com/meridian/inline-alert-v2
- Existing implementation: A legacy
<div class="alert alert-danger">Bootstrap component with no icon slots, no dismiss state, missing ARIA roles, and no success or warning variants - Design tokens: Yes — Meridian uses a full token system:
color.feedback.*,spacing.*,typography.body-sm,radius.sm,shadow.none
Output
InlineAlert
Purpose: Use to communicate contextual feedback — errors, warnings, informational guidance, or success confirmation — inline within a page or form without blocking the user's workflow. Category: Feedback
Anatomy
| Part | Required? | Description |
|---|---|---|
| Container | Yes | Full-width banner with left border accent (4px) and background fill; uses radius.sm and spacing.md padding |
| Leading icon | Yes | 20×20px semantic icon (error, warning, info, check-circle) reinforces meaning independent of color |
| Title | Yes | Bold label summarizing the message; typography.label-md |
| Body text | No | One or two sentences of supporting detail; typography.body-sm, color.text.secondary |
| Action link | No | Single inline text link for a direct recovery action (e.g., "Review fields") |
| Dismiss button | No | Icon-only × button; only present when the alert is user-dismissible |
Variants
| Variant | When to use | Visual difference |
|---|---|---|
| Error | Form validation failures, system errors blocking progress | Left border + background: color.feedback.error.*; error icon |
| Warning | Non-blocking issues the user should address | Left border + background: color.feedback.warning.*; warning triangle icon |
| Info | Helpful context, policy notes, neutral guidance | Left border + background: color.feedback.info.*; info circle icon |
| Success | Confirmed action completion inline (e.g., saved preferences) | Left border + background: color.feedback.success.*; check-circle icon |
States
| State | Visual treatment | Behavior |
|---|---|---|
| Default | Full color per variant; border, icon, and background all visible | Static; renders on condition trigger |
| Dismiss hover | Dismiss button background shifts to color.neutral.100; cursor pointer | Signals interactivity |
| Dismiss focus | 2px offset focus ring in color.focus.ring; meets 3:1 contrast against all variant backgrounds | Keyboard-navigable dismiss |
| Dismiss active | Button background color.neutral.200 | Immediate press feedback |
| Dismissed | Component unmounts or collapses with height transition (100ms ease-out) | Focus returns to trigger element or next logical element in DOM |
| Reduced-motion dismissed | Component unmounts instantly with no transition | Triggered when prefers-reduced-motion: reduce is detected |
Accessibility
| Requirement | Implementation |
|---|---|
| Role | role="alert" for Error and Warning (live region, assertive); role="status" for Info and Success (polite) |
| Keyboard | Dismiss button reachable via Tab; activated with Enter or Space |
| Focus management | On dismiss, return focus to the element that triggered the alert or the previous focusable element |
| Screen reader | Full title + body text announced on render; dismiss button labeled aria-label="Dismiss [variant] alert" |
| Color independence | Semantic icon present on all variants; left border accent provides secondary non-color cue |
| Target size | Dismiss button minimum 44×44px touch target; visible hit area 24×24px padded to meet WCAG 2.5.8 |
| Motion | Collapse transition disabled under prefers-reduced-motion: reduce; component removes instantly |
Do / Don't
| Do | Don't |
|---|---|
| Render the alert adjacent to the content it describes (e.g., directly above a form section) | Place all alerts at the top of the page when the error is deep in a long form |
| Use Error variant when the user must fix something before proceeding | Use Warning for hard blockers — reserve Warning for advisory, non-blocking issues |
| Keep title to 5–8 words; include an action link if there's a clear recovery step | Write paragraph-length titles or duplicate the body text in the title |
| Dismiss button for alerts the user has acknowledged and no longer needs | Make errors dismissible before the user has resolved the underlying issue |
Content guidelines
- Title: 5–8 words, sentence case, state the condition plainly ("Payment method is missing")
- Body text: 1–2 sentences max, no trailing period on single sentences, explain impact and next step
- Action link: Verb phrase, 2–4 words ("Review billing info" not "Click here")
- Error text: Always state what went wrong and how to fix it — never "An error occurred."
When to use vs. alternatives
- Use InlineAlert when: feedback is tied to a specific section, form, or content block and the user must see it in context
- Use Toast instead when: feedback is a transient response to a global action (file uploaded, settings saved) with no required follow-up
- Use Modal instead when: the situation requires the user to make a decision before proceeding and context cannot be preserved behind a banner
Open questions for team review
- Should the Success variant auto-dismiss after a timeout (e.g., 5s), or always require explicit dismissal? Recommend explicit for patient-facing health contexts.
- Does the action link slot need to support a button (for JS actions) in addition to an
<a>tag? - Should
role="alert"inject a visually hidden prefix like "Error:" for screen readers, or is the iconaria-labelsufficient?