Skip to main content
Design/component-spec

Component Spec

You need a design system component specification with variants, states, and accessibility.

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-guide for foundational tokens. Feed accessibility requirements from /accessibility-audit. Use /interaction-pattern-library for cross-component interaction consistency.

Process

Step 1: Gather inputs

Ask the user to provide:

  1. Component name -- what is this component called in the design system?
  2. Purpose -- what problem does this component solve? When should someone use it vs. alternatives?
  3. Visual reference -- Figma link, screenshot, or description of the component
  4. Existing implementation -- is there a current version? What's wrong with it or missing?
  5. 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

PartRequired?Description
ContainerYesFull-width banner with left border accent (4px) and background fill; uses radius.sm and spacing.md padding
Leading iconYes20×20px semantic icon (error, warning, info, check-circle) reinforces meaning independent of color
TitleYesBold label summarizing the message; typography.label-md
Body textNoOne or two sentences of supporting detail; typography.body-sm, color.text.secondary
Action linkNoSingle inline text link for a direct recovery action (e.g., "Review fields")
Dismiss buttonNoIcon-only × button; only present when the alert is user-dismissible

Variants

VariantWhen to useVisual difference
ErrorForm validation failures, system errors blocking progressLeft border + background: color.feedback.error.*; error icon
WarningNon-blocking issues the user should addressLeft border + background: color.feedback.warning.*; warning triangle icon
InfoHelpful context, policy notes, neutral guidanceLeft border + background: color.feedback.info.*; info circle icon
SuccessConfirmed action completion inline (e.g., saved preferences)Left border + background: color.feedback.success.*; check-circle icon

States

StateVisual treatmentBehavior
DefaultFull color per variant; border, icon, and background all visibleStatic; renders on condition trigger
Dismiss hoverDismiss button background shifts to color.neutral.100; cursor pointerSignals interactivity
Dismiss focus2px offset focus ring in color.focus.ring; meets 3:1 contrast against all variant backgroundsKeyboard-navigable dismiss
Dismiss activeButton background color.neutral.200Immediate press feedback
DismissedComponent unmounts or collapses with height transition (100ms ease-out)Focus returns to trigger element or next logical element in DOM
Reduced-motion dismissedComponent unmounts instantly with no transitionTriggered when prefers-reduced-motion: reduce is detected

Accessibility

RequirementImplementation
Rolerole="alert" for Error and Warning (live region, assertive); role="status" for Info and Success (polite)
KeyboardDismiss button reachable via Tab; activated with Enter or Space
Focus managementOn dismiss, return focus to the element that triggered the alert or the previous focusable element
Screen readerFull title + body text announced on render; dismiss button labeled aria-label="Dismiss [variant] alert"
Color independenceSemantic icon present on all variants; left border accent provides secondary non-color cue
Target sizeDismiss button minimum 44×44px touch target; visible hit area 24×24px padded to meet WCAG 2.5.8
MotionCollapse transition disabled under prefers-reduced-motion: reduce; component removes instantly

Do / Don't

DoDon'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 proceedingUse 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 stepWrite paragraph-length titles or duplicate the body text in the title
Dismiss button for alerts the user has acknowledged and no longer needsMake 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 icon aria-label sufficient?