SKILL.md
Component Documentation Generator
Overview
Generate comprehensive component documentation including API references, usage examples, accessibility guidelines, and design specifications. Create documentation that serves both designers and developers.
When to Use
- Documenting new components
- Creating component API references
- Writing usage guidelines
- Building a design system documentation site
Quick Reference: Documentation Sections
| Section | Purpose | Audience |
|---|---|---|
| Overview | What the component does | All |
| When to Use | Decision guidance | Designers |
| Props/API | Technical reference | Developers |
| Examples | Code snippets | Developers |
| Variants | Visual options | All |
| States | Interactive states | Designers |
| Accessibility | A11y guidelines | All |
| Design Specs | Spacing, tokens used | Designers |
| Do/Don't | Usage guidance | All |
The Process
- Identify component scope: What does it do, what doesn't it do?
- Define props interface: All configurable options
- Create examples: Basic, advanced, edge cases
- Document variants: Visual variations
- Add accessibility: ARIA, keyboard, screen reader
- Include design specs: Spacing, colors, typography tokens
- Write guidelines: When to use, when not to
Component Documentation Template
# Button
Buttons allow users to take actions and make choices with a single tap.
## Overview
The Button component is used for triggering actions. Use buttons to submit forms,
navigate between pages, or trigger in-page functionality.
## When to Use
| Scenario | Recommendation |
|----------|----------------|
| Primary action | Use `variant="primary"` |
| Secondary action | Use `variant="secondary"` |
| Destructive action | Use `variant="danger"` |
| Navigation | Consider using a Link instead |
| In forms | Use `type="submit"` |
## Import
import { Button } from '@acme/design-system';
## Basic Usage
<Button onClick={handleClick}>Click me</Button>
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `variant` | `'primary' \| 'secondary' \| 'ghost' \| 'danger'` | `'primary'` | Visual style variant |
| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Button size |
| `disabled` | `boolean` | `false` | Disables the button |
| `loading` | `boolean` | `false` | Shows loading spinner |
| `fullWidth` | `boolean` | `false` | Makes button 100% width |
| `leftIcon` | `ReactNode` | - | Icon before text |
| `rightIcon` | `ReactNode` | - | Icon after text |
| `type` | `'button' \| 'submit' \| 'reset'` | `'button'` | HTML button type |
| `onClick` | `(event: MouseEvent) => void` | - | Click handler |
| `children` | `ReactNode` | - | Button label |
## Variants
### Primary
Use for the main action on a page or in a form.
<Button variant="primary">Save changes</Button>
### Secondary
Use for secondary actions that support the primary action.
<Button variant="secondary">Cancel</Button>
### Ghost
Use for tertiary actions or in dense UIs.
<Button variant="ghost">Learn more</Button>
### Danger
Use for destructive actions like delete.
<Button variant="danger">Delete account</Button>
## Sizes
<Button size="sm">Small</Button> <Button size="md">Medium</Button> <Button size="lg">Large</Button>
| Size | Height | Font Size | Use Case |
|------|--------|-----------|----------|
| `sm` | 32px | 14px | Compact UIs, tables |
| `md` | 40px | 16px | Default, most uses |
| `lg` | 48px | 18px | Hero sections, emphasis |
## States
### Default
<Button>Default</Button>
### Hover
Slightly darkened background. Applied automatically on mouse hover.
### Active
Pressed state with slight scale reduction.
### Focus
Focus ring appears on keyboard focus (focus-visible).
### Disabled
<Button disabled>Disabled</Button>
- 50% opacity
- Cursor changes to not-allowed
- Click events are ignored
### Loading
<Button loading>Saving...</Button>
- Shows spinner icon
- Button is disabled
- Label remains for width consistency
- `aria-busy="true"` for screen readers
## With Icons
// Icon before text <Button leftIcon={<PlusIcon />}>Add item</Button>
// Icon after text <Button rightIcon={<ArrowRightIcon />}>Continue</Button>
// Icon only (use aria-label) <Button aria-label="Settings"> <SettingsIcon /> </Button>
## Full Width
<Button fullWidth>Sign up</Button>
## Button Groups
<div className="button-group"> <Button variant="secondary">Cancel</Button> <Button variant="primary">Save</Button> </div>
## Accessibility
### Keyboard Navigation
| Key | Action |
|-----|--------|
| `Tab` | Move focus to button |
| `Enter` | Activate button |
| `Space` | Activate button |
### ARIA
- Uses native `<button>` element
- `aria-disabled` when disabled (maintains focusability)
- `aria-busy` when loading
- `aria-pressed` for toggle buttons
### Screen Readers
- Ensure button has accessible name (text content or aria-label)
- Loading state announced via aria-busy
- Icon-only buttons require aria-label
### Focus Management
- Focus ring visible on keyboard focus (not mouse)
- 2px outline with 2px offset
- Meets WCAG 2.4.7 Focus Visible
## Design Specifications
### Spacing
| Element | Token | Value |
|---------|-------|-------|
| Horizontal padding (sm) | `--spacing-sm` | 8px |
| Horizontal padding (md) | `--spacing-md` | 16px |
| Horizontal padding (lg) | `--spacing-lg` | 24px |
| Icon gap | `--spacing-xs` | 4px |
| Button group gap | `--spacing-sm` | 8px |
### Colors
| Variant | Background | Text | Border |
|---------|------------|------|--------|
| Primary | `--color-primary-500` | white | - |
| Primary:hover | `--color-primary-600` | white | - |
| Secondary | transparent | `--color-gray-700` | `--color-gray-300` |
| Ghost | transparent | `--color-gray-700` | - |
| Danger | `--color-error-500` | white | - |
### Typography
| Size | Token | Weight |
|------|-------|--------|
| sm | `--text-sm` (14px) | 500 |
| md | `--text-base` (16px) | 500 |
| lg | `--text-lg` (18px) | 500 |
### Other
| Property | Token | Value |
|----------|-------|-------|
| Border radius | `--radius-md` | 8px |
| Focus ring | `--color-primary-500` | 2px solid |
| Transition | - | 150ms ease |
## Do's and Don'ts
### Do ✅
- Use clear, action-oriented labels ("Save", "Delete", "Continue")
- Place primary action on the right in button groups
- Use loading state for async actions
- Provide aria-label for icon-only buttons
### Don't ❌
- Don't use vague labels ("Click here", "Submit")
- Don't use more than one primary button per view
- Don't disable buttons without explanation
- Don't use buttons for navigation (use Links)
## Related Components
- [Link](/components/link) - For navigation
- [IconButton](/components/icon-button) - Icon-only variant
- [ButtonGroup](/components/button-group) - Multiple buttons together
- [ToggleButton](/components/toggle-button) - Stateful toggle
## Changelog
| Version | Changes |
|---------|---------|
| 1.2.0 | Added `loading` prop |
| 1.1.0 | Added `ghost` variant |
| 1.0.0 | Initial release |
API Documentation Template
For TypeScript components:
## API Reference
### ButtonProps
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> { /** Visual style variant @default 'primary' */ variant?: 'primary' | 'secondary' | 'ghost' | 'danger';
/** Button size @default 'md' */ size?: 'sm' | 'md' | 'lg';
/** Shows loading spinner and disables button @default false */ loading?: boolean;
/** Makes button full width of container @default false */ fullWidth?: boolean;
/** Icon element to display before text / leftIcon?: React.ReactNode;
/** Icon element to display after text / rightIcon?: React.ReactNode;
/** Button content (label) / children: React.ReactNode; }
### Ref
The Button component forwards its ref to the underlying `<button>` element.
const buttonRef = useRef<HTMLButtonElement>(null); <Button ref={buttonRef}>Click me</Button>
### CSS Classes
| Class | Description |
|-------|-------------|
| `.btn` | Base button styles |
| `.btn--primary` | Primary variant |
| `.btn--secondary` | Secondary variant |
| `.btn--ghost` | Ghost variant |
| `.btn--danger` | Danger variant |
| `.btn--sm` | Small size |
| `.btn--md` | Medium size |
| `.btn--lg` | Large size |
| `.btn--loading` | Loading state |
| `.btn--full-width` | Full width modifier |
Auto-Generation from TypeScript
generate-component-docs.ts:
import ts from 'typescript';
import fs from 'fs';
interface PropDoc {
name: string;
type: string;
description: string;
defaultValue?: string;
required: boolean;
}
function extractPropsFromInterface(
sourceFile: ts.SourceFile,
interfaceName: string
): PropDoc[] {
const props: PropDoc[] = [];
function visit(node: ts.Node) {
if (ts.isInterfaceDeclaration(node) && node.name.text === interfaceName) {
node.members.forEach((member) => {
if (ts.isPropertySignature(member) && member.name) {
const name = member.name.getText(sourceFile);
const type = member.type?.getText(sourceFile) || 'unknown';
const required = !member.questionToken;
// Extract JSDoc
const jsDoc = ts.getJSDocTags(member);
const description = ts.getJSDocCommentsAndTags(member)
.map((c) => c.getText())
.join(' ')
.replace(/\/\*\*|\*\/|\*/g, '')
.trim();
const defaultTag = jsDoc.find((t) => t.tagName.text === 'default');
const defaultValue = defaultTag?.comment?.toString();
props.push({ name, type, description, defaultValue, required });
}
});
}
ts.forEachChild(node, visit);
}
visit(sourceFile);
return props;
}
function generatePropsTable(props: PropDoc[]): string {
let md = '| Prop | Type | Default | Required | Description |\n';
md += '|------|------|---------|----------|-------------|\n';
for (const prop of props) {
const required = prop.required ? 'Yes' : 'No';
const defaultVal = prop.defaultValue || '-';
md += `| \`${prop.name}\` | \`${prop.type}\` | ${defaultVal} | ${required} | ${prop.description} |\n`;
}
return md;
}
// Usage
const sourceCode = fs.readFileSync('./components/Button.tsx', 'utf-8');
const sourceFile = ts.createSourceFile(
'Button.tsx',
sourceCode,
ts.ScriptTarget.Latest,
true
);
const props = extractPropsFromInterface(sourceFile, 'ButtonProps');
const table = generatePropsTable(props);
console.log(table);
Documentation Site Structure
docs/
├── getting-started/
│ ├── installation.md
│ ├── quick-start.md
│ └── theming.md
├── foundations/
│ ├── colors.md
│ ├── typography.md
│ ├── spacing.md
│ └── icons.md
├── components/
│ ├── primitives/
│ │ ├── button.md
│ │ ├── input.md
│ │ └── text.md
│ ├── composite/
│ │ ├── card.md
│ │ ├── modal.md
│ │ └── dropdown.md
│ └── layout/
│ ├── stack.md
│ ├── grid.md
│ └── container.md
├── patterns/
│ ├── forms.md
│ ├── navigation.md
│ └── data-display.md
└── resources/
├── changelog.md
├── migration.md
└── contributing.md
Best Practices
- Lead with examples: Show code before explaining
- Be consistent: Use same structure for all components
- Include visuals: Screenshots, diagrams, live demos
- Document edge cases: Empty states, long text, RTL
- Keep it updated: Automate where possible
- Cross-reference: Link related components
- Show context: Include realistic usage scenarios
- Test your examples: Ensure code snippets work