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:
This will launch Storybook at http://localhost:6006.
Configuration
Storybook is configured in the .storybook/ directory:
Main Configuration
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
Glob pattern to find story files. Currently configured to discover stories in src/shared/ui/
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
Uses React with Vite for fast HMR and builds
Preview Configuration
The preview configuration sets up global decorators and parameters:
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
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
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' ],
},
},
};
Export Default
Export the meta as the default export:
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:
View a11y panel
Open the “Accessibility” tab in the Storybook addons panel
Review violations
The panel shows WCAG violations with descriptions and remediation steps
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:
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'
Document all props with argTypes
Provide controls and descriptions for all props: argTypes : {
size : {
control : 'select' ,
options : [ 'sm' , 'md' , 'lg' ],
description : 'Button size variant' ,
},
}
Create stories for all states
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: [] } };
Test interactions with play functions
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.