Storybook
Storybook is the interactive workshop for the React components in this library. Every component is rendered in isolation with live controls for its props, an auto-generated API table, and an accessibility audit.
Running Storybook
Section titled “Running Storybook”-
Install dependencies, if you have not already:
Terminal window npm install -
Start the Storybook dev server:
Terminal window npm run storybook -
Open http://localhost:6006.
To produce a static build — for deploying the component documentation, or for a CI artifact:
npm run build-storybookThe output lands in storybook-static/, which is gitignored.
What you get
Section titled “What you get”Pick a component in the sidebar and you land on its Docs page, which assembles:
- The component description, taken from the JSDoc on the story file.
- An API table generated from the exported
Propstype, including each prop’s JSDoc comment, its accepted values, and its default. - Every story, each with its own description.
Switch to the Canvas tab for a single story and you get:
- Controls — change any prop live and watch the component re-render.
- Accessibility — an axe audit of the rendered output.
- Show code — the exact JSX for the current prop combination.
What is covered
Section titled “What is covered”Storybook renders src/components/react/ only.
astro-breadcrumb is also excluded. The @fpkit/react Breadcrumb it wraps
builds its trail from window.location.pathname and uses the routes prop only
as a segment-to-label lookup, so inside Storybook’s iframe it would always show
Storybook’s own path rather than a realistic trail.
Adding a story
Section titled “Adding a story”Colocate the story next to its component as Thing.stories.tsx:
import type { Meta, StoryObj } from '@storybook/react-vite'
import Thing from '#components/react/Thing'
/** This JSDoc becomes the component's description on the Docs page. */const meta = { title: 'React/Thing', component: Thing, argTypes: { variant: { control: 'inline-radio', options: ['primary', 'secondary'], description: 'Visual style of the component.', }, }, args: { variant: 'primary' },} satisfies Meta<typeof Thing>
export default meta
type Story = StoryObj<typeof meta>
/** This JSDoc becomes the story's description. */export const Primary: Story = {}
export const Secondary: Story = { args: { variant: 'secondary' },}Follow these conventions so stories stay consistent with the rest of the codebase:
- Import through the mandatory
#alias, never a relative path. - Type
metawithsatisfies Meta<typeof Thing>and stories withStoryObj<typeof meta>, soargsare checked against the real props. - Title stories
React/<ComponentName>to keep the sidebar grouped. - Treat the JSDoc as the documentation — autodocs renders it verbatim.
Styling
Section titled “Styling”Stories load the same stylesheets as src/layouts/Base.astro, so what you see
matches the real site:
@fpkit/acss/stylessrc/styles/index.scss
The SCSS entry point is imported directly, so editing any partial under
src/styles/ hot-reloads the canvas — no separate npm run sass needed.
Accessibility
Section titled “Accessibility”The Accessibility panel runs axe on every story. This project targets WCAG 2.1 Level AA, so treat reported violations as defects in the component rather than in the story. Violations are surfaced but do not fail a story.
Configuration
Section titled “Configuration”Configuration lives in .storybook/:
Story discovery, addons, the @storybook/react-vite framework, and
react-docgen-typescript for prop tables.
The MDX glob is scoped to src/stories/ deliberately — a broad src/**/*.mdx also
matches the Starlight content collection you are reading right now, and Storybook
refuses to index it.
A Vite config used only by Storybook, wired up through viteConfigPath.
This is load-bearing. The repository root has a vite.config.ts that wraps
getViteConfig() from astro/config for Vitest. Left to auto-discovery, Vite would
load that file and pull the whole Astro pipeline into the Storybook build — which
still exits zero but emits no iframe.html and renders no stories.
It also mirrors the #* subpath imports from package.json.
Global stylesheets, control matchers, sidebar ordering, the a11y addon, and the
global autodocs tag.
For the full technical reference, including troubleshooting, see
project-docs/04-integrations/storybook.md.