> ## Documentation Index
> Fetch the complete documentation index at: https://ship.paralect.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Storybook

> Develop and review UI components in isolation. Opt-in, colocated with your shadcn primitives.

[Storybook](https://storybook.js.org/) lets you build, test, and review UI components in isolation, and [Chromatic](https://www.chromatic.com/) automates visual review of UI changes on every PR.

<Note>
  Storybook is **not preinstalled** in `apps/web`. It's an opt-in addition — set it up with the official guide below, then follow the conventions on this page so stories sit naturally next to your components.
</Note>

## Setup

Storybook is stack-agnostic and works with the Vite-based `apps/web` out of the box. Initialise it from the web app:

```bash theme={null}
cd apps/web
npx storybook@latest init
```

For visual review, follow the [Chromatic GitHub Actions guide](https://www.chromatic.com/docs/github-actions/).

* [Storybook — Getting started](https://storybook.js.org/docs/get-started)
* [Chromatic — GitHub Actions](https://www.chromatic.com/docs/github-actions/)

## Conventions

Keep stories where Ship keeps components:

* **shadcn/ui primitives** — `src/components/ui/` (e.g. `button.tsx`, `input.tsx`, `card.tsx`)
* **Shared app components** — `src/components/`

Point Storybook at both directories and label them so the sidebar mirrors the codebase:

```ts .storybook/main.ts theme={null}
stories: [
  {
    directory: '../src/components',
    titlePrefix: 'Application Components',
  },
  {
    directory: '../src/components/ui',
    titlePrefix: 'UI Kit',
  },
],
```

## Example: a Button story

Colocate the story with the primitive and import it through the `@/` alias. Mirror the component's real variants — Ship's `Button` exposes `default`, `destructive`, `outline`, `secondary`, `ghost`, and `link`, with `default`, `sm`, `lg`, and `icon` sizes:

```tsx src/components/ui/button.stories.tsx theme={null}
import type { Meta, StoryObj } from '@storybook/react';

import { Button } from '@/components/ui/button';

const meta = {
  component: Button,
  args: {
    children: 'Button',
    variant: 'default',
    size: 'default',
  },
  argTypes: {
    variant: {
      options: ['default', 'destructive', 'outline', 'secondary', 'ghost', 'link'],
      control: { type: 'radio' },
    },
    size: {
      options: ['default', 'sm', 'lg', 'icon'],
      control: { type: 'radio' },
    },
  },
} satisfies Meta<typeof Button>;

export default meta;

type Story = StoryObj<typeof Button>;

export const Basic: Story = {};
```

<Tip>
  Stories render in isolation, so they pick up your Tailwind theme tokens only if the global stylesheet is loaded. Import `src/globals.css` in `.storybook/preview.ts` to get the same `bg-background` / `text-foreground` tokens you see in the app.
</Tip>
