new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Storybook · Setup · all subjects

configuration & options

52 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

Story accessibility best practices

Use semantic roles and labels in stories. Ensure focusable and keyboard interactions are test-covered where relevant to support accessibility.

Component breakdown strategy

When writing UI, prefer breaking larger components up into smaller parts.

Do not use within(canvas) in play functions

Do not wrap the `canvas` parameter with the `within()` function in play functions, as `canvas` already has query methods and `within()` is redundant. Using `within(canvas)` will cause an error. Instead, use `canvas` directly with query methods like `canvas.getByLabelText('Submit').click();`.

Play function parameters: canvas vs canvasElement

Play functions receive both a `canvas` parameter with query methods and a `canvasElement` parameter which is the actual DOM element. The `within()` function from `storybook/test` can transform `canvasElement` into an object with query methods: `const canvas = within(canvasElement);`. This is an acceptable alternative to using `canvas` directly, though using `canvas` directly is preferred.

Story writing best practices for coverage

When writing Storybook stories, aim to cover every distinct piece of business logic and state the component can reach. Include happy paths, error and edge states, loading states, permissions and roles, empty states, and variations from props and context. Avoid redundant stories that show the same logic.

Interactive story best practices with play functions

For interactive components, add Interaction tests using play functions. Use storybook/test utilities to drive the UI and simulate key user flows such as clicking buttons and links, typing, focus and blur, keyboard navigation, form submission, async responses, toggle and selection changes, and pagination and filters. When passing `fn` functions as callback function args, add a play function that interacts with the component and asserts whether the callback function was actually called.

Story data and setup best practices

Provide realistic props, state, and mocked data in stories. Include meaningful labels and text to make behaviors observable. Stub network and services with deterministic fixtures to keep stories reliable.

Story assertions best practices

In play functions, assert the visible outcome of the interaction including text, aria state, enabled/disabled status, class and state changes, and emitted events. Prefer using role-based and label-based queries for assertions.

Story naming and structure best practices

Use clear story names that describe the scenario, such as 'Error state after failed submit'. Group related variants logically and do not duplicate stories. Select variants to include only those that change behavior, such as default vs alternate themes, loading vs loaded vs empty vs error, validated vs invalid input, permissions/roles/capabilities, feature flags, and size/density/layout variants that alter logic.

Find Nx project names for modified packages

To identify the Nx project names for modified packages in the Storybook monorepo, look in the project.json file located in each modified package's directory and use the 'name' field value, not the name from package.json. For example, if code/addons/review and code/addons/vitest were modified, the Nx project names would be 'addon-review' and 'addon-vitest'.

Use NODE_OPTIONS preserve-symlinks when starting Storybook UI

When starting Storybook in the background for development, use the environment variable NODE_OPTIONS="--preserve-symlinks" with the command 'yarn storybook:ui --no-open' to ensure proper module resolution.

Rebuild and restart Storybook workflow for internal code changes

After making changes to internal Storybook code (core, addons, frameworks, renderers, libs, etc.), follow this workflow: First, determine which monorepo packages were modified by finding their Nx project names in the project.json file (using the 'name' field, not package.json). Then run 'rm -rf node_modules/.cache', 'yarn', and 'yarn build storybook <extra packages>' in the code directory. Finally, run 'NODE_OPTIONS="--preserve-symlinks" yarn storybook:ui --no-open' in the background to start Storybook.

Handle occupied port when restarting Storybook

If a Storybook instance is already running and the port is occupied, cancel the start command, kill the old process to free the port, then start Storybook again using the same start command.

Interpreting startup benchmark timing regressions

If `server` grows, the regression is likely server/build-side. If `browser` grows, it is likely in manager boot, preview boot, or first-story render. If averages are close but `p95` grows significantly, the feature likely increases variability or tail latency. If newer Storybook without a feature is much faster than older Storybook, but enabling the feature returns timings to older levels, the feature likely erases the newer startup gains.

Recommended benchmark output format

When reporting results, clearly separate `server`, `browser`, and `total`. Call out averages and p95 first, with min/max as supporting bounds. Highlight whether the regression affects common-case latency, tail latency, or both. Avoid claiming root cause unless the benchmark isolates server vs render behavior.

Startup benchmark measurement boundaries

Start timing immediately before spawning `storybook dev`. Open Storybook at `/`, not `iframe.html`. Stop timing on first story mount plus one `requestAnimationFrame()`. Do not measure only CLI output; server listening is not the same as first story rendered.

Three timing segments in startup benchmark

The startup benchmark measures three segments: server (process spawn to Storybook server responds), browser (server responds to first story rendered), and total (process spawn to first story rendered).

Disable Storybook auto-open for benchmarking

Use `storybook dev --no-open` when benchmarking startup to ensure the external harness launches the browser, not Storybook itself.

Preview-side signal for first story render

Add a global preview decorator or component that waits one `requestAnimationFrame()` on first story mount, then sets a global value like `window.__sbStartupBenchmark` and mirrors it to `window.top` when same-origin. Optionally call `performance.mark('sb:first-story-rendered')`. The preferred payload is `{firstStoryRenderedAt: performance.now(), storyId: id}`.

Benchmark harness implementation steps

The benchmark script should: (1) fail fast if the target Storybook port is already in use, (2) spawn Storybook with `--no-open`, (3) start timing immediately before spawn, (4) wait for HTTP readiness on the Storybook URL, (5) launch a controlled browser to `/`, (6) wait for the preview-side signal, (7) print JSON results, (8) kill the full spawned process group during cleanup.

Repeated benchmark run summary statistics

For `--repeat N`, print per-run results and summary stats grouped by `server`, `browser`, and `total`. Each group should include `average`, `min`, `max`, and `p95` fields with human-readable durations like `5.2s` or `2m15s`, not raw millisecond field names.

Common pitfalls in startup benchmarking

Watch for: existing Storybook already running on the benchmark port, Storybook auto-opening a separate browser window, measuring direct `iframe.html` loads instead of normal `/`, leaving child Storybook processes alive between runs, and treating warm repeated runs as cold-start data. If repeated benchmark reports unrealistically low `server.average`, first check for a stale Storybook server on the same port.

TypeScript is zero-config in Storybook Docs

As of Storybook 6, TypeScript is zero-config and works with Storybook Docs out of the box without additional configuration needed.

Configure addon-docs in main.js

Add '@storybook/addon-docs' to the addons array in .storybook/main.js. Also add '../src/**/*.mdx' to the stories array to match your project's structure.

Addon-docs preset options for babel/webpack configuration

The addon-docs preset has two configuration options: csfPluginOptions (object for configuring @storybook/csf-plugin; set to null to disable it) and mdxPluginOptions (object for MDX plugin configuration). Configure in main.js with: { name: '@storybook/addon-docs', options: { csfPluginOptions: null, mdxPluginOptions: {} } }

Component parameter in CSF format

In Component Story Format (CSF), set the component parameter in the default export to help DocsPage extract the component's description and props. Example: import { Badge } from './Badge'; export default { title: 'Path/to/Badge', component: Badge, };

Override docs.page parameter to remove or customize DocsPage

DocsPage can be replaced or removed at global, component, or story level by overriding the docs.page parameter. Set it to null to remove docs, use MDX docs, or provide a custom React component.

Remove DocsPage globally in preview.js

To disable DocsPage for all stories globally, add this to preview.js: import { addParameters } from '@storybook/react'; addParameters({ docs: { page: null } });

Remove DocsPage at component level

To disable DocsPage for a specific component, add the parameter in the default export: export default { title: 'Demo/Button', component: Button, parameters: { docs: { page: null } }, };

Remove DocsPage at story level

To disable DocsPage for a specific story, set the parameter on the story function: export const basic = () => <Button>Basic</Button>; basic.parameters = { docs: { page: null } };

Story file naming convention

Story files should follow the naming pattern *.stories.@(j|t)sx?, for example: Button.stories.js, Badge.stories.tsx. This convention is required by the docs preset's source-loader setup unless using a custom webpack configuration.

Compodoc updates not dynamic during development

It is not currently possible to update Compodoc metadata dynamically as you edit your components, though there is an open issue to support this with improvements to Compodoc.

Manual Compodoc setup with setCompodocJson

For manual Compodoc setup, import setCompodocJson from '@storybook/addon-docs/angular' and import the documentation.json file in .storybook/preview.ts, then call setCompodocJson(docJson).

Configure Compodoc in angular.json for documentation.json

In angular.json under projects.<project>.architect.<storybook|build-storybook>, add "compodoc": true and "compodocArgs": ["-e", "json", "-d", "."] to generate a documentation.json metadata file each time you run storybook. The "-d" argument specifies the root folder of your project.

Set component field in Angular story metadata

For props tables to work with Compodoc, the component field must be filled in the story metadata: export default { title: 'App Component', component: AppComponent };

Default IFrame height for Angular stories

Storybook Docs renders all Angular stories inside IFrames with a default height of 60px.

Angular stories render inline by default in Docs

Storybook Docs renders all Angular stories inline by default.

Add addon-docs to addons configuration

Add '@storybook/addon-docs' to the addons array in .storybook/main.js to enable Docs.

Load generated JSON doc file in preview.js

To use Props tables in Ember Storybook, add the following to .storybook/preview.js to load the generated JSON documentation: import { setJSONDoc } from '@storybook/addon-docs/ember'; import docJson from '../dist/storybook-docgen/index.json'; setJSONDoc(docJson);

Configure stories pattern to include MDX files

To enable MDX files in Ember Storybook, update .storybook/main.js to load MDX files: export default { stories: ['../src/stories/**/*.stories.@(js|mdx)'] };

Add addon-docs to .storybook/main.js

To enable Storybook Docs for Ember, add '@storybook/addon-docs' to the addons array in .storybook/main.js: export default { addons: ['@storybook/addon-docs'] }

Enable ember-cli-storybook addon docs integration

To get Props tables for Ember components, enable the ember-cli-storybook addon docs integration by adding the following to ember-cli-build.js: let app = new EmberApp(defaults, { 'ember-cli-storybook': { enableAddonDocsIntegration: true } });

react-docgen-typescript vs react-docgen comparison

react-docgen-typescript produces great results for props table experience with good Storybook docs support but is slow (33s build time) and has some corner case bugs. react-docgen is blazing fast (29s build time) with OK features and support, also with some corner case bugs. Using neither option adds 28s build time.

Default TypeScript docgen option

The default TypeScript props generation option in Storybook is react-docgen.

Configure addon-docs in main.js

Add '@storybook/addon-docs' to the addons list in .storybook/main.js configuration file.

Configure TypeScript props generation in main.js

To switch between TypeScript props generation options, add to .storybook/main.js: export default { typescript: { reactDocgen: 'react-docgen-typescript' } }. Valid values are 'react-docgen-typescript', 'react-docgen', or false to disable docgen.

Configure addon-docs in main.js

Add '@storybook/addon-docs' to the addons array in .storybook/main.js to enable Storybook Docs for Vue.

Configure vue-docgen-api via addon-docs preset options

The addon-docs preset can be configured with vueDocgenOptions to configure vue-docgen-api. Example: { name: '@storybook/addon-docs', options: { vueDocgenOptions: { alias: { '@': path.resolve(process.cwd(), 'src') } } } }. The vueDocgenOptions object passes configuration directly to vue-docgen-api.

Configure stories glob pattern to include MDX files

To load MDX files in Storybook, update the stories configuration in .storybook/main.js to include MDX files: export default { stories: ['../src/stories/**/*.stories.@(js|mdx)'] };

Add addon-docs to .storybook/main.js

After installing @storybook/addon-docs, add the addon to the addons array in .storybook/main.js. The configuration should be: export default { addons: ['@storybook/addon-docs'] };

Configure Web Components stories to render in iframe

To render Web Components stories in an iframe instead of inline, set the docs.story.inline parameter to false in .storybook/preview.js: export const parameters = { docs: { story: { inline: false } } };. The default iframe height is 60px, configurable using the docs.story.iframeHeight story parameter.

Web Components stories inline rendering default

Storybook Docs renders all Web Components stories inline by default.

Give your agent this brain