Skill: Modern Storybook Mastery (CSF 3.0)
Professional Storybook authoring using Component Story Format 3 (CSF 3), TypeScript, and best-in-class architectural patterns.
When to use
Use this skill when:
-
Creating or updating Storybook stories for React components
-
Setting up Storybook 7/8+ projects
-
Implementing Component Story Format 3.0 (CSF 3)
-
Configuring argTypes, decorators, or parameters
-
Working with TypeScript in Storybook
-
Ensuring type safety with satisfies operator
-
Setting up interactive controls and documentation
Instructions
- Core Structure & Type Safety
Always use CSF 3.0 with the satisfies operator for maximum type safety and auto-completion.
import type { Meta, StoryObj } from '@storybook/react'; import { Button } from './Button';
const meta = { title: 'Components/Common/Button', // Path-based hierarchy component: Button, tags: ['autodocs'], parameters: { layout: 'centered', }, // Global args for all stories in this file args: { label: 'Click Me', }, } satisfies Meta<typeof Button>;
export default meta; type Story = StoryObj<typeof meta>;
// Basic Story export const Primary: Story = { args: { variant: 'primary', }, };
// Derived Story (Reusing args) export const PrimaryDisabled: Story = { args: { ...Primary.args, disabled: true, }, };
- Exhaustive ArgTypes (The UI Control Panel)
Configure argTypes to provide a rich, interactive playground for designers.
Control Type Definition
Select variant: { control: 'select', options: ['primary', 'secondary'] }
Radio size: { control: 'radio', options: ['sm', 'md', 'lg'] }
Boolean disabled: { control: 'boolean' }
Text/Number label: { control: 'text' } or count: { control: 'number' }
Range opacity: { control: { type: 'range', min: 0, max: 1, step: 0.1 } }
Color bgColor: { control: 'color' }
Date expiry: { control: 'date' }
Actions onClick: { action: 'clicked' }
Hide internalID: { table: { disable: true } }
- Decorators (Providing Context)
Use decorators to wrap components in Providers (Theme, Router, State) or Layout wrappers.
// Local Decorator (specific to this component) const meta = { component: UserProfile, decorators: [ (Story) => ( <div style={{ padding: '3rem', background: '#eee' }}> <Story /> </div> ), ], } satisfies Meta<typeof UserProfile>;
// Context Provider Decorator export const WithDarkTheme: Story = { decorators: [ (Story) => ( <ThemeProvider theme="dark"> <Story /> </ThemeProvider> ), ], };
- Advanced Patterns
A. Form Components
Showcase various states: Empty, Filled, Validation Error.
export const ValidationError: Story = { args: { label: 'Email', error: 'Please enter a valid email address', value: 'invalid-email', }, };
B. Mocking Data-Driven Components
const MOCK_ITEMS = [{ id: 1, name: 'Item 1' }, { id: 2, name: 'Item 2' }];
export const Loaded: Story = { args: { items: MOCK_ITEMS }, };
export const Empty: Story = { args: { items: [] }, };
C. Responsive Viewports
export const MobileView: Story = { parameters: { viewport: { defaultViewport: 'mobile1' }, }, };
- Project Configuration
.storybook/preview.ts (Global Config)
import type { Preview } from '@storybook/react';
const preview: Preview = { parameters: { actions: { argTypesRegex: '^on[A-Z].*' }, // Auto-log onEvent props controls: { matchers: { color: /(background|color)$/i, date: /Date$/, }, }, }, }; export default preview;
- Anti-Patterns (What to Avoid)
-
❌ No CSF 2.0: Don't use Template.bind({}) . It is verbose and lacks type-inference.
-
❌ No Hardcoded Props: Avoid render: () => <Button label="Fix" /> . Use args so the Controls panel works.
-
❌ No Logic in Stories: Don't put useState or useEffect inside a story. Use play functions for interactions or mock the state via props.
-
❌ No Flat Hierarchies: Don't name every story Primary . Use groups like Components/Inputs/Checkbox .
-
❌ No Missing Types: Never export a story without the Story (StoryObj) type annotation.
- File Naming & Organization
-
Component.tsx (Logic)
-
Component.stories.tsx (Stories - same folder)
-
Component.test.tsx (Unit tests)
-
Component.module.css (Styles)
Why this approach is better
-
Satisfies Keyword: Ensures that your meta object is strictly typed while still allowing TypeScript to "remember" the specific literal types of your args .
-
Explicit ArgTypes: Provides a checklist of UI controls, ensuring the generated Storybook isn't just a static image but a functional tool.
-
Hierarchy Focus: Emphasizes title paths (e.g., Components/Common/Button ) for better sidebar organization in large projects.
-
Action Automation: Uses argTypesRegex so you don't have to manually mock every single onClick or onChange .
-
Anti-Pattern Guardrails: Prevents falling back on outdated 2020-era Storybook syntax.