Skip to main content
The Auction Platform uses Storybook for isolated component development and testing. Storybook provides a dedicated environment to build, document, and test UI components.

Quick Start

Start the Storybook development server:
npm run storybook
This will launch Storybook at http://localhost:6006.

Configuration

Storybook is configured in the .storybook/ directory:

Main Configuration

.storybook/main.ts
import type { StorybookConfig } from '@storybook/react-vite';

const config: StorybookConfig = {
  "stories": [
    '../src/shared/ui/**/*.stories.@(js|jsx|ts|tsx)'
  ],
  "addons": [
    "@chromatic-com/storybook",
    "@storybook/addon-vitest",
    "@storybook/addon-a11y",
    "@storybook/addon-docs"
  ],
  "framework": "@storybook/react-vite"
};
export default config;

Configuration Details

stories
array
Glob pattern to find story files. Currently configured to discover stories in src/shared/ui/
addons
array
Storybook addons:
  • @chromatic-com/storybook - Visual testing integration
  • @storybook/addon-vitest - Run Vitest tests in Storybook
  • @storybook/addon-a11y - Accessibility testing
  • @storybook/addon-docs - Auto-generated documentation
framework
string
Uses React with Vite for fast HMR and builds

Preview Configuration

The preview configuration sets up global decorators and parameters:
.storybook/preview.ts
import type { Preview } from '@storybook/react-vite';
import '../src/shared/styles/global.css';
import '../src/shared/styles/themes.css';
import '../src/shared/styles/tokens.css';

const preview: Preview = {
  decorators: [
    (Story, context) => {
      document.documentElement.dataset.theme = context.globals.theme ?? 'white';
      return Story();
    },
  ],
  parameters: {
    controls: {
      matchers: {
        color: /(background|color)$/i,
        date: /Date$/i,
      },
    },
    a11y: {
      test: 'todo'  // 'todo' | 'error' | 'off'
    }
  },
};

export default preview;

Key Features

  • Theme Decorator - Automatically applies the selected theme to stories
  • Global Styles - Imports design tokens, themes, and global styles
  • Accessibility Testing - Set to ‘todo’ mode (shows violations without failing)
  • Control Matchers - Auto-detects color and date controls

Writing Stories

Stories are written using Component Story Format (CSF).

Basic Story Structure

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

const meta: Meta<typeof Button> = {
  title: 'Shared/Button',
  component: Button,
  argTypes: {
    size: {
      control: 'select',
      options: ['sm', 'md', 'lg'],
    },
    variant: {
      control: 'select',
      options: ['primary', 'secondary', 'danger', 'outline'],
    },
    disabled: {
      control: 'boolean',
    },
  },
};

export default meta;

type Story = StoryObj<typeof Button>;

export const Primary: Story = {
  args: {
    children: 'Primary Button',
    variant: 'primary',
    size: 'md',
  },
};

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

Story Anatomy

1

Define Meta

The meta object configures the story:
const meta: Meta<typeof Button> = {
  title: 'Shared/Button',  // Sidebar navigation path
  component: Button,        // Component to render
  argTypes: {              // Control types for props
    size: {
      control: 'select',
      options: ['sm', 'md', 'lg'],
    },
  },
};
2

Export Default

Export the meta as the default export:
export default meta;
3

Create Stories

Each named export is a story:
export const Primary: Story = {
  args: {
    children: 'Primary Button',
    variant: 'primary',
  },
};

Example Stories

The project includes example stories in src/shared/ui/:

Button Stories

Primary, Secondary, Danger, Outline variants with size and state options

TextField Stories

Text input variations with labels, placeholders, and validation states

Typography Stories

Typography system with headings, body text, and text variants

CardContainer Stories

Card layouts and container patterns

Advanced Patterns

Stories with Decorators

Wrap stories with additional context:
export const WithLayout: Story = {
  args: {
    children: 'Button',
  },
  decorators: [
    (Story) => (
      <div style={{ padding: '40px', background: 'var(--color-bg)' }}>
        <Story />
      </div>
    ),
  ],
};

Stories with Play Functions

Simulate user interactions:
import { userEvent, within } from '@storybook/test';

export const Clicked: Story = {
  args: {
    children: 'Click Me',
  },
  play: async ({ canvasElement }) => {
    const canvas = within(canvasElement);
    const button = canvas.getByRole('button');
    
    await userEvent.click(button);
  },
};

Stories with Multiple Variants

Show multiple states at once:
export const AllVariants: Story = {
  render: () => (
    <div style={{ display: 'flex', gap: '12px' }}>
      <Button variant="primary">Primary</Button>
      <Button variant="secondary">Secondary</Button>
      <Button variant="danger">Danger</Button>
      <Button variant="outline">Outline</Button>
    </div>
  ),
};

Controls

Storybook automatically generates controls based on prop types and argTypes:

Control Types

argTypes: {
  disabled: {
    control: 'boolean',
  },
}

Accessibility Testing

Storybook includes the @storybook/addon-a11y addon for accessibility testing:
1

View a11y panel

Open the “Accessibility” tab in the Storybook addons panel
2

Review violations

The panel shows WCAG violations with descriptions and remediation steps
3

Configure tests

Set the test mode in .storybook/preview.ts:
a11y: {
  test: 'todo'   // 'todo' - show violations
             // 'error' - fail CI
             // 'off' - disable
}
Currently set to 'todo' mode. Set to 'error' to enforce accessibility standards in CI.

Building Storybook

Build a static version for deployment:
npm run build-storybook
This creates a production build in storybook-static/ that can be deployed to any static hosting service.

Testing with Vitest

Storybook integrates with Vitest through the @storybook/addon-vitest addon:
.storybook/vitest.setup.ts
import * as a11yAddonAnnotations from "@storybook/addon-a11y/preview";
import { setProjectAnnotations } from '@storybook/react-vite';
import * as projectAnnotations from './preview';

setProjectAnnotations([a11yAddonAnnotations, projectAnnotations]);
Run tests:
npm run test  # Runs Vitest with Storybook integration

Best Practices

Use consistent title paths:
// Good
title: 'Shared/Button'
title: 'Features/Auth/LoginForm'

// Avoid
title: 'Button'
title: 'Login'
Provide controls and descriptions for all props:
argTypes: {
  size: {
    control: 'select',
    options: ['sm', 'md', 'lg'],
    description: 'Button size variant',
  },
}
Show loading, error, empty, and success states:
export const Loading: Story = { args: { isLoading: true } };
export const Error: Story = { args: { error: 'Failed to load' } };
export const Empty: Story = { args: { items: [] } };
Simulate user flows:
play: async ({ canvasElement }) => {
  const canvas = within(canvasElement);
  const input = canvas.getByRole('textbox');
  await userEvent.type(input, '[email protected]');
}

Scripts Reference

npm run storybook
# Starts dev server on http://localhost:6006

Resources

Storybook Docs

Official Storybook documentation

CSF 3.0 Spec

Component Story Format specification

Addon A11y

Accessibility testing addon docs

Vitest Integration

Storybook Vitest addon documentation
Storybook stories are located in src/shared/ui/ following the pattern ComponentName.stories.tsx.

Build docs developers (and LLMs) love