name: add-story
description: Use this skill when the user asks to add a Ladle story, create a storybook story, document a component visually, or add component examples. Trigger phrases: "add story", "create story", "component story", "ladle story".
version: 1.0.0
Add Ladle Story
⚠️ CRITICAL ANTI-HALLUCINATION PROMPT:
Even though the npm scripts use the word storybook (e.g., npm run storybook:serve), this project uses Ladle, NOT Storybook.
- NEVER import from
@storybook/*.
- ALWAYS import
type { Story } from @ladle/react.
- NEVER create
.storybook/main.js or similar config files.
Adds a visual story for a component using Ladle (the project's Storybook alternative).
Story File Location
Stories live alongside the component they document:
src/shared/ui/Button/
├── Button.tsx
├── Button.stories.tsx ← here
└── index.ts
src/features/auth/ui/
├── LoginForm.tsx
├── LoginForm.stories.tsx ← here
File naming: ComponentName.stories.tsx
Basic Story Template
import type { Story } from "@ladle/react";
import { Button } from "./Button";
export const Default: Story = () => <Button>Click me</Button>;
export const WithControls: Story<{ label: string; disabled: boolean }> = ({
label,
disabled,
}) => <Button disabled={disabled}>{label}</Button>;
WithControls.args = {
label: "Button",
disabled: false,
};
Story with Context (Auth, Router)
For components that need providers (router context, auth state):
import type { Story } from "@ladle/react";
import { createMemoryHistory, createRouter, RouterProvider } from "@tanstack/react-router";
import { routeTree } from "@generated/routeTree.gen";
import { Header } from "./Header";
const router = createRouter({ routeTree, history: createMemoryHistory() });
export const Default: Story = () => (
<RouterProvider router={router}>
<Header />
</RouterProvider>
);
Story with Multiple Variants
import type { Story } from "@ladle/react";
import { Badge } from "./Badge";
export const Success: Story = () => <Badge variant="success">Active</Badge>;
export const Warning: Story = () => <Badge variant="warning">Pending</Badge>;
export const Error: Story = () => <Badge variant="error">Failed</Badge>;
export const Info: Story = () => <Badge variant="info">Draft</Badge>;
Running Ladle
npm run storybook:serve
npm run storybook:build
npm run storybook:preview
Verifying it visually (agents can't see Ladle)
storybook:serve opens a browser an agent can't watch. To confirm the rendered
output, use the screenshot harness instead: most components show up on a real
page, so npm run test:e2e:screens and read the PNG
(test-results/screenshots/*.png) with the Read tool — in both cmyk and dark.
For a state only the story shows, capture it via a temporary route. See
docs/DEBUGGING.md.
Checklist