Creating and modifying Storybook 10 stories using atomic design hierarchy. Covers atom stories (src/stories/atoms/), molecule stories (src/stories/molecules/), organism stories (src/stories/organisms/), template stories (src/stories/templates/), page stories (src/stories/pages/), and test stories (src/stories/tests/). Includes naming conventions (kebab-case .stories.tsx), autodocs setup, controls matching component.yml props and slots, placeholder images via placehold.co, real asset handling with index.ts exports, PageLayout usage for fullscreen page stories, and rules against direct HTML markup in story arguments. Use when creating, updating, or fixing any Storybook story file.
From drupal-canvasnpx claudepluginhub ajv009/drupal-devkit --plugin drupal-canvasThis skill uses the workspace's default tool permissions.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Guides agent creation for Claude Code plugins with file templates, frontmatter specs (name, description, model), triggering examples, system prompts, and best practices.
Stories prove your components work. They are living documentation, visual regression references, and the first place structural problems become visible. A story that renders correctly with realistic content gives confidence; a story that only works with placeholder text hides structural gaps.
Stories fall into a few categories:
Stories are organized by atomic design level:
| Level | Location | Components |
|---|---|---|
| Atoms | src/stories/atoms/ | Your project's atom-level components (e.g. button, heading, text, image, spacer, logo, video) |
| Molecules | src/stories/molecules/ | Your project's molecule-level components (e.g. card, blockquote, search_form, breadcrumb) |
| Organisms | src/stories/organisms/ | Your project's organism-level components (e.g. hero, card_container, grid_container, header, footer, section) |
<component-name>.stories.tsx using kebab-caseAtoms/Button, Molecules/Card, Organisms/HeroAuto documentation should be used, and all parameter types must be explicitly defined with appropriate controls. Always cross-reference the story parameters with the component.yml props and slots.
Non-interactive tests (e.g. expects) can be added to component stories, but interactive tests that simulate user input MUST NOT be included in stories.
Both props and slots arguments MUST be either scalar values, an image object type, or a React fragment of public components. You must never use direct markup.
src/stories/tests/<component-name>.stories.tsx using kebab-case, although
if a component has a large number of tests, they can be grouped using
<component-name>-<group>.stories.tsx.These are intended to provide automated tests for components and other UI elements.
Auto documentation MUST be disabled.
If a component makes use of the canvas parsing to directly inspect or manipulate components in props, a test should be added to ensure that the component correctly parses the canvas island.
src/stories/templates/Templates/src/stories/pages/<page-name>.stories.tsx using kebab-case.Pages/These provide an example of how a page could be built using components.
Autodocs must be disabled and the fullscreen layout must be used. There must only be one story per page.
The PageLayout component from the templates story (src/stories/templates/PageLayout.stories.tsx) should be used to ensure consistent wrapping of the page.
Both props and slots arguments MUST be either scalar values, an image object type, or a React fragment of public components. You must never use direct markup.
Placeholder.io can be used to generate placeholder images for components:
{
src: "https://placehold.co/800x600",
alt: "Example image placeholder",
width: 800,
height: 600,
}
Page stories MUST only import and compose existing components.
@/components/<name><div>, <span>, <section>) for layoutclassName prop (not available in Canvas editor)If you need a wrapper <div>, find the existing component that provides that layout (e.g., section for width constraints, grid_container for columns). If none exists, create a component first.
Control spacing between components using the spacer component, NOT margins, padding, or wrapper divs.
// Correct
<Hero title="About Us" />
<Spacer height="large" />
<Section width="normal" content={<Text text="<p>Our story...</p>" />} />
// Wrong — raw HTML and className for spacing
<Hero title="About Us" />
<div className="mt-16">
<Section width="normal" content={<Text text="<p>Our story...</p>" />} />
</div>
Page stories should export only ONE story (typically Default) with a name property matching the page title. This creates flat sidebar navigation instead of nested folders.
export const Default: Story = {
name: 'Home Page',
render: () => (
<PageLayout>
<Hero ... />
<Spacer height="large" />
<Section ... />
</PageLayout>
),
};
When migrating a site, every migrated page should have a corresponding page story that serves as a visual regression reference.
text: "Footer" instead of 3 menu columns with social links, it won't catch a structurally inadequate footer component.Stories are the first line of defense — if a component crashes in Storybook, it will crash on the live site.
npm run build (Storybook static build) fails, fix before uploading.Assets should be stored in the src/stories/assets directory, in suitable
subdirectories depending on the scope of the asset. An index.ts file must be
created to export the assets with the correct image type. Real assets must never
be directly imported in stories without their image type. The image type must
include the correct dimensions and provide alt text.
When building stories for components deployed to Drupal CMS, consult the official documentation to understand how props, slots, and component patterns work on the platform. Use the canvas-docs-explorer skill:
/canvas-docs-explorer components props slots patterns
This helps ensure your stories test against realistic platform constraints, not just local rendering.
The canvas-starter's get-examples.js utility pattern parses component.yml to extract example prop values automatically for stories. See .claude/reference/canvas-starter/ for this pattern. Consider adopting if you want auto-generated story variants from component.yml examples.
This skill covers the Canvas variant of Storybook, which uses React components (.tsx). This is different from drupal-storybook (Layer 1), which targets SDC/Twig-based components. Canvas stories import from @/components/ and render React fragments; drupal-storybook stories render Twig templates with SDC YAML definitions.