Search

PythonReactSEOPDF
GitHub Skill

storybook-patterns

Component documentation, visual testing, interaction testing

mcgilly17☆ 1 Repository stars1 Repository forks

Installation

Follow the repository instructions for this skill and your agent. Review the files and dependencies before adding it to your workflow.

View source ↗Guides

Skill instructions

Storybook Development Patterns

Component development and documentation with Storybook 7+.

Story Basics

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

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

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

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

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

// Large button
export const Large: Story = {
  args: {
    size: 'large',
    label: 'Button',
  },
};

Args and Controls

const meta = {
  component: Button,
  args: {
    // Default args for all stories
    label: 'Click me',
    variant: 'primary'
  },
  argTypes: {
    // Control types
    variant: {
      control: { type: 'select' },
      options: ['primary', 'secondary', 'tertiary'],
    },
    size: {
      control: { type: 'radio' },
      options: ['small', 'medium', 'large'],
    },
    disabled: {
      control: 'boolean',
    },
    onClick: { action: 'clicked' },
  },
} satisfies Meta<typeof Button>;

Decorators

// Global decorator
export const decorators = [
  (Story) => (
    <div style={{ margin: '3em' }}>
      <Story />
    </div>
  ),
];

// Component-level decorator
const meta = {
  component: Button,
  decorators: [
    (Story) => (
      <ThemeProvider>
        <Story />
      </ThemeProvider>
    ),
  ],
};

Play Functions (Interaction Testing)

import { within, userEvent, expect } from '@storybook/test';

export const FillForm: Story = {
  play: async ({ canvasElement }) => {
    const canvas = within(canvasElement);

    // Find form elements
    const emailInput = canvas.getByLabelText('Email');
    const passwordInput = canvas.getByLabelText('Password');
    const submitButton = canvas.getByRole('button');

    // Interact
    await userEvent.type(emailInput, 'user@example.com');
    await userEvent.type(passwordInput, 'password123');
    await userEvent.click(submitButton);

    // Assert
    await expect(canvas.getByText('Success')).toBeInTheDocument();
  },
};

Visual Testing

Snapshot Tests
export const AllStates: Story = {
  render: () => (
    <div>
      <Button variant="primary">Primary</Button>
      <Button variant="secondary">Secondary</Button>
      <Button disabled>Disabled</Button>
    </div>
  ),
};
Responsive Testing
export const Mobile: Story = {
  parameters: {
    viewport: {
      defaultViewport: 'mobile1',
    },
  },
};

export const Tablet: Story = {
  parameters: {
    viewport: {
      defaultViewport: 'tablet',
    },
  },
};

Documentation

MDX Stories
import { Meta, Story, Canvas } from '@storybook/blocks';
import * as ButtonStories from './Button.stories';

<Meta of={ButtonStories} />

# Button

Buttons allow users to take actions.

<Canvas of={ButtonStories.Primary} />

## Usage

```tsx
import { Button } from './Button';

<Button variant="primary">Click me</Button>

Variants

Auto-generated Docs
const meta = {
  component: Button,
  tags: ['autodocs'], // Auto-generate docs page
  parameters: {
    docs: {
      description: {
        component: 'A versatile button component',
      },
    },
  },
};

Loaders

export const WithData: Story = {
  loaders: [
    async () => ({
      user: await fetchUser(),
    }),
  ],
  render: (args, { loaded: { user } }) => (
    <UserProfile user={user} />
  ),
};

Best Practices

✅ Do:

  • Write stories for all component states
  • Use args for interactive controls
  • Document usage with MDX
  • Test interactions with play functions
  • Use decorators for common wrappers
  • Keep stories focused and simple

❌ Don't:

  • Put business logic in stories
  • Duplicate setup across stories
  • Skip edge cases and error states
  • Forget responsive variants
  • Ignore accessibility testing

Examples

Read the usage examples in the source repository.

View source ↗

Source history

Indexed on
2026-01-20
Index updated
2026-01-26
Branch
main

Index and sync dates describe this directory. View the source repository for code history.

GitHub ↗

chat Comments (0)

chat_bubble_outline

No comments yet. Be the first to share your thoughts!