Storybook
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」。From its SKILL.md
npx -y skills add Syo-M/fable-frontend-skills --skill storybookAssembled 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.
SKILL.md
4.6 KB, 961 tokens by cl100k_base, 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/testvs@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
playfor each key behavior: submit success, validation error, keyboard operation. - Vary stories via
args, not copy-pasted render functions. Customrenderonly 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();
});
},
};
awaitevery interaction and assertion — a missing await passes locally and flakes in CI.- Same query rules as Testing Library:
getByRolefirst (seetesting-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.tsxdecorators — 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
playfunctions in a real browser (Playwright provider) — keepnpm run testcovering 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 testwarning 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*, retriedexpect) — 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 (seevisual-regression). - Reuse stories in plain Vitest tests with
composeStorieswhen you need extra assertions beyond the play function.
A11y
- Keep
@storybook/addon-a11yenabled 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.
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.
Gives 0 of the 12 instructions most docs writing skills give in 961 tokens
Counted across 1,951 of the 3,904 authors here whose files we hold, read 2026-09-06
- Use third-person for skill descriptionsin 54 of 1951, across 35 files
- Start descriptions with Use whenin 43 of 1951, across 29 files
- Run baseline scenarios before writing any skillin 40 of 1951, across 26 files
- Use active voicein 40 of 1951, across 36 files
- Map file responsibilities before defining tasksin 36 of 1951, across 29 files
- Use checkbox syntax for tracking stepsin 35 of 1951, across 27 files
- Ask one question at a timein 35 of 1951
- Offer execution options after saving the planin 33 of 1951, across 24 files
- Include complete code in every stepin 33 of 1951, across 27 files
- Design units with clear boundaries and interfacesin 31 of 1951, across 23 files
- Announce the skill usage at the startin 30 of 1951
- Verify agent compliance after adding the skillin 29 of 1951, across 17 files
Said here and by no other author read
- Use CSF3 shape with full inference
- Write one story per meaningful state
- Use args to vary stories
- Await every interaction and assertion
- Use step for multi-phase plays
- Assert outcomes not just no-crash
Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.