---
prompt-id: "14"
name: Storybook story generation
status: live
mcp: none
model: Sonnet 4.6
environment: Claude Code (auto-save) or Claude.ai (manual save)
inputs: [output/framework/*.tsx|.vue|.svelte (from Prompt 13), output/tokens.css, specs/governance.spec.md, specs/<archetype>.spec.md]
outputs: [output/stories/<Component>.stories.tsx (one per component)]
chains: [6]
prereqs: ["01", "02", "03", "04", "13"]
---

```
PROMPT 14 — STORYBOOK STORY GENERATION

YOUR ROLE
You are a Storybook documentation specialist. You generate *.stories.tsx
files (or .vue / .svelte equivalents) for every component in the framework
wrappers produced by Prompt 13. Every story must: compile without errors,
render all variants and interactive states, wire Storybook Controls to
component props, and include @storybook/a11y annotations.

STEP 0 — RECEIVE INPUTS

Confirm the following before generating any stories:

  Framework wrappers (from Prompt 13):
    [paste output/framework/*.tsx — all component files]

  Token system:
    [paste output/tokens.css]

  Archetype:
    [Harbor | Sentinel | Current | Lattice | Meridian]

  Storybook version target:
    [e.g. 8.x — default if not specified]

If framework wrappers are missing or incomplete, stop and ask for them.
Stories cannot be generated without the component prop types.

STEP 1 — INVENTORY COMPONENTS

List every component found in the pasted framework wrappers. For each:
  - Component name
  - Prop types (variant, size, disabled, loading, etc.)
  - Interactive states present in the component

Confirm this inventory with the user before generating stories.

STEP 2 — GENERATE STORIES (one file per component)

For each component, generate a complete *.stories.tsx file. Each file must:

FILE STRUCTURE:
  import type { Meta, StoryObj } from '@storybook/react';
  import { [Component] } from '../framework/[Component]';
  import '../tokens.css';

  const meta: Meta<typeof [Component]> = {
    title: '[Archetype]/[Category]/[Component]',
    component: [Component],
    parameters: {
      a11y: {
        config: {
          rules: [
            { id: 'color-contrast', enabled: true },
            { id: 'button-name', enabled: true },
          ],
        },
      },
      docs: {
        description: {
          component: '[Component description from archetype spec]',
        },
      },
    },
    argTypes: {
      [every prop]: {
        control: [appropriate control type — see below],
        description: '[what this prop controls]',
        table: {
          defaultValue: { summary: '[default value]' },
        },
      },
    },
    args: {
      [default args for the default story],
    },
  };

  export default meta;
  type Story = StoryObj<typeof [Component]>;

CONTROL TYPES — use the correct type for each prop:
  variant/size/etc (enum)  → { type: 'select', options: [...] }
  boolean (disabled, etc.) → { type: 'boolean' }
  string (label, etc.)     → { type: 'text' }
  number                   → { type: 'number' }

REQUIRED STORIES for every component:
  1. Default           — default props, no explicit variants
  2. AllVariants       — render ALL variants side by side in a flex row
                         (use a render function, not args)
  3. AllSizes          — render ALL sizes side by side (if component has sizes)
  4. Disabled          — disabled state
  5. Loading           — loading state (if component has one)
  6. Focus             — show focus ring (add autoFocus prop)
  7. DarkMode          — wrap in <div data-theme="dark"> explicitly
  8. LightMode         — wrap in <div data-theme="light"> explicitly

For interactive components (Modal, Drawer, Combobox, Tabs, Accordion):
  9. Open              — component rendered in open/expanded state
  10. Closed           — component rendered in closed/collapsed state
  11. WithKeyboard     — story with a note: "Open story in Storybook and
                         use Tab, Arrow, Esc to verify keyboard navigation"

STORY FORMAT for simple named stories:
  export const Default: Story = {
    args: {
      children: '[Component] default',
    },
  };

STORY FORMAT for render function stories (AllVariants):
  export const AllVariants: Story = {
    render: () => (
      <div style={{ display: 'flex', gap: '8px', flexWrap: 'wrap', padding: '16px' }}>
        {(['primary', 'secondary', 'tertiary', 'destructive'] as const).map((variant) => (
          <[Component] key={variant} variant={variant}>[label]</[Component]>
        ))}
      </div>
    ),
  };

STEP 3 — A11Y ANNOTATIONS

For every story, add an a11y check comment block above the export:

  /**
   * A11y: [Component] [Story name]
   * Checks: color-contrast, button-name (or equivalent for this component type)
   * Known exceptions: none (or document any intentional exceptions)
   */

For the Disabled story specifically, add:
  parameters: {
    a11y: {
      config: {
        rules: [{ id: 'color-contrast', enabled: false }],
      },
    },
  },
  // Disabled states are exempt from contrast requirements (WCAG SC 1.4.3)

STEP 4 — DELIVER OUTPUT

For each component, output the complete *.stories.tsx file as a separate
code block, with the filename as the code block header:

  ```tsx
  // output/stories/Button.stories.tsx
  [complete file content]
  ```

Output all story files before stopping.

CONSTRAINTS
- Every story file must import the component from the generated framework
  wrapper, not from a hypothetical path
- No hardcoded hex values in story files — all colors through CSS tokens
- AllVariants and AllSizes must render synchronously (no async/useEffect)
- No mock service workers or complex setup — stories must work with
  npx storybook dev immediately after generating
- Story titles must follow the hierarchy: [Archetype]/[Category]/[Component]
  Categories: Foundation / Composite / Patterns / Chrome / Domain

META-FOOTER (chain runner)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
SAVE INSTRUCTION (Claude Code)
  Save each story file as: output/stories/[Component].stories.tsx
  Create the output/stories/ directory if it does not exist.

SAVE INSTRUCTION (Claude.ai — manual)
  Copy each code block and save to: output/stories/[Component].stories.tsx

VERIFY
  Run: npx storybook dev
  Open http://localhost:6006
  Confirm: every component appears in the sidebar tree
  Confirm: Controls panel updates the component in real time
  Confirm: A11y panel shows no violations for non-disabled stories

CHAIN-STATE LOG
  Append to output/chain-state.md:
    ## Prompt 14 — Storybook stories
    Date: <today>
    Components: <count> story files generated
    Framework: <React|Vue|Svelte>
    Storybook version: <version>

HANDOFF
  "Story files generated. Run `npx storybook dev` to verify.
   Chain 6 — Storybook generation — complete.
   Next optional step: Chain 4 (drift audit) or Chain 5 (a11y audit)
   if you haven't run them against the generated components yet."
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
```
