1---2name: storybook3description: Build component stories with proper args, controls, decorators, and testing patterns.4---5
6## CSF Format (Component Story Format)
7
8- Default export is component meta—title, component, args, decorators
9- Named exports are stories—each export becomes a story in sidebar
10- `satisfies Meta<typeof Component>` for TypeScript type checking
11- CSF3 uses object syntax, not functions—`export const Primary = { args: {...} }`
12
13## Args vs ArgTypes
14
15- `args` are actual prop values passed to component—`args: { label: 'Click me' }`
16- `argTypes` configure controls UI—`argTypes: { size: { control: 'select', options: ['sm', 'lg'] } }`
17- Default args in meta apply to all stories—override in individual stories
18- `argTypes: { onClick: { action: 'clicked' } }` logs events in Actions panel
19
20## Controls
21
22- Auto-inferred from TypeScript props—boolean becomes toggle, string becomes text input
23- Override control type: `argTypes: { color: { control: 'color' } }`
24- Disable control: `argTypes: { children: { control: false } }`
25- Options for select: `control: { type: 'select' }, options: ['a', 'b', 'c']`
26
27## Decorators
28
29- Wrap stories with context—providers, layout wrappers, theme
30- Component-level in meta: `decorators: [(Story) => <Provider><Story /></Provider>]`
31- Global in `.storybook/preview.js`: applies to all stories
32- Order matters—later decorators wrap earlier ones
33
34## Play Functions
35
36- Interactive testing within story: `play: async ({ canvasElement }) => {...}`
37- Use `@storybook/testing-library` for queries—`within(canvasElement).getByRole()`
38- `await userEvent.click(button)` for interactions
39- `expect(element).toBeVisible()` for assertions—tests run in browser
40
41## Actions
42
43- `argTypes: { onClick: { action: 'clicked' } }` auto-logs to Actions panel
44- Or import: `import { action } from '@storybook/addon-actions'`
45- Use `fn()` from `@storybook/test` in Storybook 8+ for spying in play functions
46- Actions help verify event handlers without manual console.log
47
48## Story Organization
49
50- Title path creates hierarchy: `title: 'Components/Forms/Button'`
51- Stories appear in order of export—put Primary first
52- `tags: ['autodocs']` generates docs page automatically
53- `parameters: { docs: { description: { story: 'text' } } }` adds story description
54
55## Common Patterns
56
57- **Default state:** `export const Default = {}`
58- **With all props:** `export const WithIcon = { args: { icon: <Icon /> } }`
59- **Edge cases:** Empty, Loading, Error, Disabled states as separate stories
60- **Responsive:** Use viewport addon parameters per story
61
62## Render Functions
63
64- Custom render: `render: (args) => <Wrapper><Component {...args} /></Wrapper>`
65- Access context in render: `render: (args, { globals }) => ...`
66- Useful when story needs different JSX structure than default
67- Prefer decorators for wrapping, render for restructuring
68
69## Configuration
70
71- `.storybook/main.js`: addons, framework, stories glob patterns
72- `.storybook/preview.js`: global decorators, parameters, argTypes
73- Stories glob: `stories: ['../src/**/*.stories.@(js|jsx|ts|tsx)']`
74- Static assets: `staticDirs: ['../public']` for images/fonts
75
76## Common Mistakes
77
78- Forgetting to install addon AND add to main.js addons array
79- Using `storiesOf` API—deprecated, use CSF exports
80- Missing component in meta—controls won't auto-generate
81- Decorators returning `Story` without calling it: `(Story) => <Story />` not `(Story) => Story`