storybook-story-writing

Storybook - Story Writing

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "storybook-story-writing" with this command: npx skills add thebushidocollective/han/thebushidocollective-han-storybook-story-writing

Storybook - Story Writing

Write well-structured, maintainable Storybook stories using Component Story Format 3 (CSF3) that showcase component variations and ensure consistent rendering.

Key Concepts

Component Story Format 3 (CSF3)

CSF3 is the modern Storybook format that uses object syntax for stories:

import type { Meta, StoryObj } from '@storybook/react'; import { Button } from './Button';

const meta = { title: 'Components/Button', component: Button, parameters: { layout: 'centered', }, tags: ['autodocs'], argTypes: { backgroundColor: { control: 'color' }, }, } satisfies Meta<typeof Button>;

export default meta; type Story = StoryObj<typeof meta>;

export const Primary: Story = { args: { primary: true, label: 'Button', }, };

export const Secondary: Story = { args: { label: 'Button', }, };

Story Organization

  • One story file per component: Component.stories.tsx

  • Use descriptive story names: Primary , Secondary , Large , Disabled

  • Group related stories under a title hierarchy: Components/Forms/Input

Default Export (Meta)

The default export defines metadata for all stories:

const meta = { title: 'Components/Button', // Navigation path component: Button, // Component reference parameters: {}, // Story-level config tags: ['autodocs'], // Enable auto-documentation argTypes: {}, // Control types decorators: [], // Wrappers for stories } satisfies Meta<typeof Button>;

Best Practices

  1. Use TypeScript for Type Safety

import type { Meta, StoryObj } from '@storybook/react';

const meta = { component: Button, } satisfies Meta<typeof Button>;

type Story = StoryObj<typeof meta>;

  1. Show All Component States

Create stories for each meaningful state:

export const Default: Story = { args: { label: 'Click me', }, };

export const Loading: Story = { args: { label: 'Loading...', loading: true, }, };

export const Disabled: Story = { args: { label: 'Disabled', disabled: true, }, };

export const WithIcon: Story = { args: { label: 'Download', icon: 'download', }, };

  1. Use Sensible Defaults

export const Primary: Story = { args: { primary: true, label: 'Button', size: 'medium', }, };

// Extend existing stories export const PrimaryLarge: Story = { ...Primary, args: { ...Primary.args, size: 'large', }, };

  1. Add Descriptive Parameters

export const WithTooltip: Story = { args: { label: 'Hover me', tooltip: 'Click to submit', }, parameters: { docs: { description: { story: 'Shows a tooltip on hover to provide additional context.', }, }, }, };

  1. Use Decorators for Context

import { RouterDecorator } from '../decorators';

const meta = { component: Navigation, decorators: [ (Story) => ( <div style={{ padding: '3rem' }}> <Story /> </div> ), RouterDecorator, ], } satisfies Meta<typeof Navigation>;

Common Patterns

Form Components

export const EmptyForm: Story = { args: { onSubmit: (data) => console.log(data), }, };

export const PrefilledForm: Story = { args: { defaultValues: { email: 'user@example.com', name: 'John Doe', }, }, };

export const WithValidationErrors: Story = { args: { errors: { email: 'Invalid email format', name: 'Name is required', }, }, };

Layout Components

export const WithSidebar: Story = { args: { sidebar: <Sidebar items={sidebarItems} />, children: <Content />, }, parameters: { layout: 'fullscreen', }, };

Data-Driven Components

const mockData = [ { id: 1, name: 'Item 1' }, { id: 2, name: 'Item 2' }, { id: 3, name: 'Item 3' }, ];

export const WithData: Story = { args: { items: mockData, }, };

export const Empty: Story = { args: { items: [], emptyMessage: 'No items found', }, };

Responsive Components

export const Mobile: Story = { args: { variant: 'mobile', }, parameters: { viewport: { defaultViewport: 'mobile1', }, }, };

export const Desktop: Story = { args: { variant: 'desktop', }, parameters: { viewport: { defaultViewport: 'desktop', }, }, };

Anti-Patterns

❌ Don't Use Template Binding (CSF2)

// Bad - Old CSF2 format const Template = (args) => <Button {...args} />; export const Primary = Template.bind({}); Primary.args = { label: 'Button' };

// Good - CSF3 format export const Primary: Story = { args: { label: 'Button' }, };

❌ Don't Mix Logic in Stories

// Bad export const Complex: Story = { render: (args) => { const [state, setState] = useState(false); useEffect(() => { // Complex side effects }, []); return <Component {...args} />; }, };

// Good - Move logic to component or use play functions export const Complex: Story = { args: { initialState: false }, };

❌ Don't Hardcode Repetitive Props

// Bad export const Story1: Story = { args: { label: 'Button', size: 'medium', theme: 'light' }, }; export const Story2: Story = { args: { label: 'Submit', size: 'medium', theme: 'light' }, };

// Good - Use meta-level defaults const meta = { component: Button, args: { size: 'medium', theme: 'light', }, } satisfies Meta<typeof Button>;

export const Story1: Story = { args: { label: 'Button' }, }; export const Story2: Story = { args: { label: 'Submit' }, };

❌ Don't Skip Story Types

// Bad - Missing type annotation export const Primary = { args: { label: 'Button' }, };

// Good - With type export const Primary: Story = { args: { label: 'Button' }, };

Related Skills

  • storybook-args-controls: Advanced arg configuration and interactive controls

  • storybook-play-functions: Automated interaction testing within stories

  • storybook-component-documentation: Auto-generating component documentation

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

android-jetpack-compose

No summary provided by upstream source.

Repository SourceNeeds Review
General

fastapi-async-patterns

No summary provided by upstream source.

Repository SourceNeeds Review
General

atomic-design-fundamentals

No summary provided by upstream source.

Repository SourceNeeds Review
General

angular-rxjs-patterns

No summary provided by upstream source.

Repository SourceNeeds Review