Quick reference for using and contributing to the ClipCash AI Storybook.
# Start development server
npm run storybook
# Build static version
npm run build-storybook
# Preview static build
npx http-server storybook-staticAccess: http://localhost:6006/
- Start Storybook:
npm run storybook - Browse components in left sidebar
- Click on any story to view it
- Use "Controls" tab to modify props
- Check "Accessibility" tab for a11y issues
- View "Docs" tab for auto-generated documentation
Create ComponentName.stories.tsx next to your component:
import type { Meta, StoryObj } from '@storybook/react';
import ComponentName from './ComponentName';
const meta = {
title: 'Category/ComponentName',
component: ComponentName,
parameters: {
layout: 'centered', // or 'padded', 'fullscreen'
},
tags: ['autodocs'],
argTypes: {
propName: {
control: 'text', // or 'boolean', 'select', 'number'
description: 'Description of the prop',
},
},
} satisfies Meta<typeof ComponentName>;
export default meta;
type Story = StoryObj<typeof meta>;
// Default story
export const Default: Story = {
args: {
propName: 'value',
},
};
// Additional variants
export const Variant: Story = {
args: {
propName: 'different value',
},
};argTypes: {
text: { control: 'text' },
number: { control: 'number' },
boolean: { control: 'boolean' },
select: {
control: 'select',
options: ['option1', 'option2']
},
range: {
control: { type: 'range', min: 0, max: 100, step: 1 }
},
color: { control: 'color' },
date: { control: 'date' },
}// Simple variant
export const Loading: Story = {
args: {
isLoading: true,
},
};
// Custom render
export const Complex: Story = {
render: (args) => (
<div className="flex gap-4">
<ComponentName {...args} />
<ComponentName {...args} variant="alt" />
</div>
),
};
// With decorators
export const WithWrapper: Story = {
decorators: [
(Story) => (
<div className="max-w-md">
<Story />
</div>
),
],
};Dashboard/- Dashboard componentsUI/- Generic UI componentsProjects/- Project managementVault/- NFT vault componentsPlatforms/- Social platformsWallet/- Wallet integrationForms/- Form componentsNavigation/- Navigation components
// β
Good
export const Default: Story = {};
export const Loading: Story = {};
export const WithError: Story = {};
export const LargeSize: Story = {};
// β Avoid
export const story1: Story = {};
export const test: Story = {};
export const example: Story = {};export const AllStates: Story = {
render: () => (
<div className="flex flex-col gap-4">
<Component status="idle" />
<Component status="loading" />
<Component status="success" />
<Component status="error" />
</div>
),
};import { useState } from 'react';
export const Interactive: Story = {
render: () => {
const [value, setValue] = useState('');
return (
<Component
value={value}
onChange={setValue}
/>
);
},
};const mockData = {
id: '1',
title: 'Example',
items: [1, 2, 3],
};
export const WithData: Story = {
args: {
data: mockData,
},
};// Always include
<button aria-label="Close dialog">
<input aria-label="Email address" />
<div role="alert" aria-live="polite">- Run Storybook
- Open story
- Click "Accessibility" tab
- Fix any violations
- Test keyboard navigation
# With Chromatic
npx chromatic --project-token=<token># With Vitest
npx vitestconst meta = {
title: 'UI/Button',
component: Button,
parameters: {
docs: {
description: {
component: 'A reusable button component with multiple variants.',
},
},
},
argTypes: {
variant: {
description: 'The visual style of the button',
control: 'select',
options: ['primary', 'secondary', 'ghost'],
},
},
};Create ComponentName.mdx:
import { Meta, Story, Canvas } from '@storybook/blocks';
import * as ComponentStories from './ComponentName.stories';
<Meta of={ComponentStories} />
# Component Name
Description of the component.
## Usage
<Canvas of={ComponentStories.Default} />
## Variants
<Canvas of={ComponentStories.Variant1} />
<Canvas of={ComponentStories.Variant2} /># Automatic on push to main
git push origin main
# Manual
npm run build-storybook
# Push storybook-static/ to gh-pages branchnpx chromatic --project-token=<your-token>npm run build-storybook
vercel --prod storybook-static- Check file name ends with
.stories.tsx - Verify export default meta
- Check for TypeScript errors
- Restart Storybook
- Ensure
globals.cssimported in.storybook/preview.tsx - Check Tailwind classes are correct
- Verify component is wrapped in decorator
- Check argTypes configuration
- Verify prop types in component
- Ensure args are passed to component
# Clear cache
rm -rf node_modules/.cache
# Reinstall
npm install
# Try again
npm run build-storybook- Start simple - Begin with a default story
- Add variants - Show all component states
- Use controls - Make props interactive
- Test accessibility - Check a11y tab
- Document props - Add descriptions
- Show examples - Include real-world usage
- Keep organized - Use consistent categories
- Update regularly - Keep stories in sync with components
- Story file created next to component
- Default story added
- At least 3 variants included
- All props have controls
- Accessibility labels added
- Component documented
- TypeScript types correct
- Story tested in Storybook
- No console errors
- Accessibility checks pass
Need Help? Check STORYBOOK.md for detailed documentation.