Skip to content

Storybook

Use storymock to generate props for your Storybook stories. Traits map naturally to Storybook story variants.

Define schemas for your component props

typescript
// src/factories.ts
import { schema, text, person, numeric, temporal, choice, collection, lorem } from 'storymock';

interface UserCardProps {
  name: string;
  avatar: string;
  role: 'viewer' | 'editor' | 'admin';
  joinedAt: Date;
  bio: string;
  postCount: number;
}

export const UserCardPropsSchema = schema<UserCardProps>({
  name: person().fullName(),
  avatar: text().template('https://i.pravatar.cc/150?u={{uuid}}'),
  role: choice('viewer', 'editor', 'admin'),
  joinedAt: temporal().past(3, 'years'),
  bio: lorem().sentence(),
  postCount: numeric().min(0).max(500),
})
.trait('admin', {
  role: 'admin' as const,
  postCount: numeric().min(100).max(500),
})
.trait('new', {
  joinedAt: temporal().recent(),
  postCount: numeric().min(0).max(5),
  bio: '',
});

Use in Storybook stories

typescript
// src/components/UserCard.stories.ts
import type { Meta, StoryObj } from '@storybook/react';
import { UserCard } from './UserCard';
import { UserCardPropsSchema } from '../factories';

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

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

// Default — random realistic data
export const Default: Story = {
  args: UserCardPropsSchema.seed(1).create(),
};

// Admin variant — uses the 'admin' trait
export const Admin: Story = {
  args: UserCardPropsSchema.with('admin').seed(2).create(),
};

// New user — uses the 'new' trait
export const NewUser: Story = {
  args: UserCardPropsSchema.with('new').seed(3).create(),
};

// Custom override — trait + inline override
export const SpecificUser: Story = {
  args: UserCardPropsSchema.with('admin', {
    name: 'Eldar Bakerman',
    bio: 'Building storymock',
  }).seed(4).create(),
};

Generating lists

For components that render lists (tables, feeds, grids):

typescript
// src/components/UserList.stories.ts
export const ManyUsers: Story = {
  args: {
    users: UserCardPropsSchema.seed(1).create(12),
  },
};

export const MixedRoles: Story = {
  args: {
    users: [
      ...UserCardPropsSchema.with('admin').seed(1).create(2),
      ...UserCardPropsSchema.with('new').seed(2).create(3),
      ...UserCardPropsSchema.seed(3).create(7),
    ],
  },
};

Tips

  • Use .seed(n) on every story to keep Storybook snapshots stable — different seed per story
  • Traits map 1:1 to Storybook story variants — 'admin', 'new', 'empty', 'error' etc.
  • For component-level factories, co-locate the schema file next to the component: UserCard.factory.ts
  • storymock generates the data, Storybook renders it — no coupling between the two