agentsclimarketplace

Storybook

Skill Syo-M/fable-frontend-skills/plugin/skills/storybook

Measured, opinionated Claude Code rules for frontend work (React / Next.js / Vite / Astro) — skills, path rules, review agents, sign-off hooks, installer & plugin. Every claim backed by committed eval reports.

Install
npx -y skills add Syo-M/fable-frontend-skills --skill storybook

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 3 stars3 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Storybook conventions — CSF3 stories, play functions as Vitest component tests, decorators, a11y. Use when writing or editing *.stories.tsx or Storybook config, AND whenever asked to write tests for a component — stories with play functions are this repo's component-test layer. 日本語の依頼例:「Storybook/ストーリー書いて」「コンポーネントのテスト書いて」「play関数」「interaction test」。

SKILL.md

4.6 KB, as published. Nobody here has run it

Storybook

Stories are the component-test layer: every story renders in the UI catalog AND runs as a Vitest browser-mode test via the Storybook Vitest addon. Write them as both documentation and test.

CSF3 shape

import type { Meta, StoryObj } from '@storybook/react'; // or framework package per installed SB version
import { expect, fn, userEvent, within } from 'storybook/test';
import { LoginForm } from './LoginForm';

const meta = {
  component: LoginForm,
  args: { onSubmit: fn() },          // fn() for every callback prop — assertable, visible in Actions panel
} satisfies Meta<typeof LoginForm>;
export default meta;

type Story = StoryObj<typeof meta>;
  • Colocate: LoginForm.tsx + LoginForm.stories.tsx. satisfies Meta<…> + StoryObj<typeof meta> — full inference, no casts.
  • Check installed Storybook major version before using version-specific imports (storybook/test vs @storybook/test).

Which stories to write

  • One story per meaningful state: default, empty, loading, error, edge content (long text, many items). Each renders without interaction → these are your visual states, and the VRT snapshot surface (see visual-regression).
  • Plus interaction stories with play for each key behavior: submit success, validation error, keyboard operation.
  • Vary stories via args, not copy-pasted render functions. Custom render only when composition is needed.

Play functions

export const ShowsValidationError: Story = {
  play: async ({ canvas, step, args }) => {
    await step('submit empty form', async () => {
      await userEvent.click(canvas.getByRole('button', { name: /log in/i }));
    });
    await step('shows error, does not submit', async () => {
      await expect(canvas.getByRole('alert')).toHaveTextContent(/required/i);
      await expect(args.onSubmit).not.toHaveBeenCalled();
    });
  },
};
  • await every interaction and assertion — a missing await passes locally and flakes in CI.
  • Same query rules as Testing Library: getByRole first (see testing-vitest).
  • step() for multi-phase plays — failures pinpoint the phase.
  • Assert outcomes: error visible AND callback not called; not just "no crash".
  • Portals/modals render outside the canvas — query via within(canvasElement.parentElement!) or screen-level helpers.

Decorators & data

  • Global providers (theme, i18n, MemoryRouter) once in .storybook/preview.tsx decorators — never per-story copies.
  • Network-dependent components: MSW (msw-storybook-addon), sharing handler definitions with Vitest tests. No fetch stubbing inside stories.
  • A story requiring 30 lines of setup is telling you the component's dependencies are too broad.

Running as tests

  • The Vitest addon turns every story into a test (render check) and runs play functions in a real browser (Playwright provider) — keep npm run test covering them in CI.
  • Pin the React runtime (and any animation lib) in the Storybook test project's optimizeDeps.include: react, react-dom, react-dom/client, react/jsx-runtime, react/jsx-dev-runtime, plus e.g. motion/react. Otherwise Vite discovers a dep mid-run, re-optimizes, and reloads the page — the play function then queries an unmounted tree: an intermittent "unable to find element" that often only shows in CI. The [vitest] Vite unexpectedly reloaded a test warning is the tell.
  • A story that can't pass headlessly (depends on viewport quirks, real network) is broken — fix the story, don't exclude it.
  • Plays that follow an animation (modal close, exit transitions) assert post-animation state with auto-retrying queries (findBy*, retried expect) — do NOT disable animations or emulate reduced motion in interaction tests; that executes a different motion code path than users get. Animations-off belongs to VRT only (see visual-regression).
  • Reuse stories in plain Vitest tests with composeStories when you need extra assertions beyond the play function.

A11y

  • Keep @storybook/addon-a11y enabled with serious/critical violations failing the test run (same threshold as the Playwright axe gate), not just warnings in the panel. Fix or explicitly (with reason) disable specific rules per story — never globally.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.