@codepress/design-kit 0.2.2 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +127 -15
- package/package.json +1 -1
- package/schema/design-kit.config.schema.json +11 -1
- package/skills/design-kit-setup/SKILL.md +14 -10
- package/skills/storybook-setup/SKILL.md +389 -0
- package/src/capture-stories.mjs +1 -1
- package/src/ci.mjs +463 -0
- package/src/cli.mjs +52 -2
- package/src/init.mjs +224 -41
- package/src/templates/design-kit-skill.md +16 -5
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: storybook-setup
|
|
3
|
+
description: "Add Storybook to a repository, or extend the one it has, with a stories file for every existing component and a tokens story, as one reviewable pull request: survey the components and tokens, install a pinned Storybook that matches the repo's React, Next and TypeScript, fix the usual first-build failures, write stories for every variant and state, typecheck, build, and check the stories capture in a design kit. Use when asked to set up Storybook, add Storybook, add stories for our components, backfill missing stories, or build a component catalog."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Set up Storybook with stories for your components
|
|
7
|
+
|
|
8
|
+
Your job is **one reviewable pull request** that gives this repository a
|
|
9
|
+
working Storybook with a stories file for every component it already has,
|
|
10
|
+
plus a tokens story, so people can browse the library and a design kit
|
|
11
|
+
(`@codepress/design-kit`) can capture it. You never merge it.
|
|
12
|
+
|
|
13
|
+
Run the steps in order. The survey comes first because the most common
|
|
14
|
+
failure is a Storybook that ignores what the repository already has: the wrong
|
|
15
|
+
folders, no styles, a second Storybook next to the first.
|
|
16
|
+
|
|
17
|
+
Supported first: **React with Vite or Next.js.** On another renderer (Vue,
|
|
18
|
+
Svelte, Angular, web components) you may still install Storybook and write
|
|
19
|
+
stories under the same rules, but say plainly in the pull request that this
|
|
20
|
+
guide has not been tried on that stack.
|
|
21
|
+
|
|
22
|
+
## 1. Survey the repository
|
|
23
|
+
|
|
24
|
+
A bounded read, so you extend what exists instead of competing with it:
|
|
25
|
+
|
|
26
|
+
- **Stack and versions.** Read `react`, `react-dom`, `next`, `typescript`,
|
|
27
|
+
`vite` and the Node version (`engines`, `.nvmrc`, `.node-version`; when
|
|
28
|
+
none is recorded, the version its CI workflows use) from `package.json` and
|
|
29
|
+
the lockfile. In a monorepo, find the package that holds
|
|
30
|
+
the components; Storybook goes there.
|
|
31
|
+
- **Package manager.** Use the one the repository uses: the `packageManager`
|
|
32
|
+
field, or the lockfile (`pnpm-lock.yaml` pnpm, `yarn.lock` yarn,
|
|
33
|
+
`bun.lock`/`bun.lockb` bun, `package-lock.json` npm). Never add a second
|
|
34
|
+
lockfile.
|
|
35
|
+
- **The component library: every folder, not just `ui/`.** Components live in
|
|
36
|
+
`components/`, `ui/`, `features/*/components/`, `app/**/_components/`,
|
|
37
|
+
`src/shared/`, workspace packages and more. List every file that exports a
|
|
38
|
+
component that renders something, and note the conventions: file naming,
|
|
39
|
+
default or named exports, how props are typed.
|
|
40
|
+
- **The token layer.** CSS custom properties (`:root { --… }`), a Tailwind
|
|
41
|
+
theme (`tailwind.config.*`, or `@theme` in CSS for Tailwind 4), a theme
|
|
42
|
+
object for a CSS-in-JS `ThemeProvider`, or a design-tokens file.
|
|
43
|
+
- **The global stylesheet and providers.** What the app's entry imports
|
|
44
|
+
(`main.tsx`, `app/layout.tsx`, `pages/_app.tsx`): global CSS, fonts, and
|
|
45
|
+
providers components need to render (theme, router, i18n, data clients).
|
|
46
|
+
- **An existing Storybook.** `.storybook/`, `*.stories.*` files, `storybook`
|
|
47
|
+
or `@storybook/*` dependencies, a `storybook` script. **If Storybook already
|
|
48
|
+
exists, extend it: never run `storybook init` again** and never upgrade it
|
|
49
|
+
in this pull request (one older than Storybook 7 cannot be captured into a
|
|
50
|
+
design kit; say so). Match its story format exactly (CSF version, typing,
|
|
51
|
+
decorators, titles), keep its stories, and add stories only where they are
|
|
52
|
+
missing. A component with a stories file that lacks states gets those
|
|
53
|
+
states added to that file, never a second file.
|
|
54
|
+
- **A design kit.** A `design-kit.config.json` means stories will be captured
|
|
55
|
+
into a kit; step 6 checks they are.
|
|
56
|
+
|
|
57
|
+
Write the survey as one short paragraph (it goes in the pull request) before
|
|
58
|
+
you change anything.
|
|
59
|
+
|
|
60
|
+
## 2. Install Storybook (only when there is none)
|
|
61
|
+
|
|
62
|
+
**Pick the version.** Use **Storybook 9** (`storybook@9`): it is the newest
|
|
63
|
+
major that `design-kit capture stories` is checked against, and it supports
|
|
64
|
+
Next.js 14.1 through 16. Never use `storybook@latest`. Use **Storybook 8**
|
|
65
|
+
(`storybook@8`) instead when the app is below Storybook 9's floors: Node 20,
|
|
66
|
+
Vite 5, Next.js 14.1 or TypeScript 4.9. Check a framework's peer ranges with
|
|
67
|
+
`npm view @storybook/<framework>@9 peerDependencies`.
|
|
68
|
+
|
|
69
|
+
**Pick the builder deliberately, and record the choice for the pull request.**
|
|
70
|
+
|
|
71
|
+
- Vite app: `@storybook/react-vite`.
|
|
72
|
+
- Next.js app: `@storybook/nextjs` (webpack) is the default and handles
|
|
73
|
+
`next/font`, `next/image`, `next/navigation` and the app's PostCSS and
|
|
74
|
+
Tailwind setup. `@storybook/nextjs-vite` is faster and fits when the app
|
|
75
|
+
has no custom `webpack()` in `next.config.*` that its components depend on
|
|
76
|
+
(SVGR, raw loaders, aliases). When unsure, take `@storybook/nextjs`.
|
|
77
|
+
|
|
78
|
+
**Run init with the repository's package manager**, in the package that holds
|
|
79
|
+
the components:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
pnpm dlx storybook@9 init --yes --no-dev --disable-telemetry --features docs
|
|
83
|
+
# npm: npx --yes storybook@9 init ... yarn: yarn dlx storybook@9 init ...
|
|
84
|
+
# bun: bunx storybook@9 init ...
|
|
85
|
+
# add --type nextjs, or --builder vite, when init detects the wrong one
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
`--features docs` keeps init from adding its test-runner setup; step 3
|
|
89
|
+
removes docs (and the onboarding addon init adds anyway) unless the person
|
|
90
|
+
asked for docs pages. Ignore init's banner telling you to cancel and use
|
|
91
|
+
`@latest`: the pin is deliberate.
|
|
92
|
+
|
|
93
|
+
**Then check what init changed: `git diff package.json`.**
|
|
94
|
+
|
|
95
|
+
- Only Storybook packages may be added (`storybook`, `@storybook/*`, and
|
|
96
|
+
`eslint-plugin-storybook` when the repository uses ESLint). All of
|
|
97
|
+
them must be on the **same exact version**; write it without a `^` or `~`
|
|
98
|
+
range.
|
|
99
|
+
- `react`, `react-dom`, `next`, `typescript`, `vite` and every other existing
|
|
100
|
+
dependency must be unchanged. **Never downgrade or upgrade the app** to fit
|
|
101
|
+
Storybook; choose the Storybook version that fits the app.
|
|
102
|
+
- A `storybook` and a `build-storybook` script are fine, and so are the
|
|
103
|
+
`storybook-static` and `*storybook.log` lines init adds to `.gitignore`.
|
|
104
|
+
|
|
105
|
+
## 3. Configure it
|
|
106
|
+
|
|
107
|
+
Keep the configuration small and make it render the components as the app
|
|
108
|
+
does. When Storybook already existed, change its configuration only where the
|
|
109
|
+
stories need it to render and build (styles, providers, env placeholders,
|
|
110
|
+
loaders, `staticDirs`), and keep its addons as they are.
|
|
111
|
+
|
|
112
|
+
- **Addons.** Keep only what init added for the framework itself. Remove the
|
|
113
|
+
onboarding addon (`@storybook/addon-onboarding`) and its package, and
|
|
114
|
+
delete init's example stories folder (`stories/` or `src/stories/`, with
|
|
115
|
+
its Button, Header and Page examples). Remove `@storybook/addon-docs` (from
|
|
116
|
+
`addons` and `package.json`), any `tags: ["autodocs"]` and the `*.mdx`
|
|
117
|
+
glob unless the person asked for docs pages. Add no other addons. Set
|
|
118
|
+
`core: { disableTelemetry: true }` in `main.*` so builds stay quiet (for
|
|
119
|
+
builds you run against an existing Storybook, set
|
|
120
|
+
`STORYBOOK_DISABLE_TELEMETRY=1` instead).
|
|
121
|
+
- **Story globs.** Point `stories` in `.storybook/main.*` at the real
|
|
122
|
+
component folders from the survey, for example
|
|
123
|
+
`["../src/**/*.stories.@(ts|tsx)"]`, or one entry per folder or package.
|
|
124
|
+
- **Styles and tokens.** Import the global stylesheet or token layer in
|
|
125
|
+
`.storybook/preview.*` (`import "../src/styles/globals.css";`). With
|
|
126
|
+
Tailwind 3, make sure its `content` globs cover the stories files too. If
|
|
127
|
+
the app sets fonts or a theme class in its layout, reproduce that with a
|
|
128
|
+
decorator in `preview.*` (rename init's `preview.ts` to `preview.tsx` for
|
|
129
|
+
JSX). Wrap stories in the providers components need, the same way the app
|
|
130
|
+
does. **An unstyled Storybook is worse than none**: check one built story
|
|
131
|
+
actually looks like the app.
|
|
132
|
+
- **Landing page.** Land the sidebar on a real story, not a docs page. The
|
|
133
|
+
tokens story from step 4 works well: in `preview.*`, set
|
|
134
|
+
`parameters.options.storySort` to `{ order: ["Foundations", "*"] }`.
|
|
135
|
+
|
|
136
|
+
**Fix the first build's failures yourself.** These four hit almost every
|
|
137
|
+
fresh Storybook; fix them rather than report them:
|
|
138
|
+
|
|
139
|
+
1. **Peer-dependency conflicts.** Put every Storybook package on one exact
|
|
140
|
+
version, and pick the Storybook major whose peer ranges include the app's
|
|
141
|
+
React, Next and TypeScript (step 2). If init's own install fails, re-run
|
|
142
|
+
it with `--skip-install` and install with the repository's package manager.
|
|
143
|
+
Drop an addon that conflicts rather than force it. Never use `--force`,
|
|
144
|
+
and never change the app's versions. If a conflict is only in a transitive
|
|
145
|
+
Storybook dependency, an `overrides` (npm), `resolutions` (yarn) or
|
|
146
|
+
`pnpm.overrides` entry for that one package is acceptable; say so in the
|
|
147
|
+
pull request.
|
|
148
|
+
2. **Modules that throw at import on a missing environment variable**, for
|
|
149
|
+
example a config module that throws when `NEXT_PUBLIC_API_URL` or
|
|
150
|
+
`VITE_API_URL` is unset. Give Storybook placeholder values. **Never edit
|
|
151
|
+
the app's own validation.** Bundlers inline these variables at build time,
|
|
152
|
+
so pass them through Storybook's `env` option in `.storybook/main.*`, which
|
|
153
|
+
reaches `process.env` and `import.meta.env` in both the webpack and Vite
|
|
154
|
+
builders. Setting `process.env` at the top of `main.*` does not: the
|
|
155
|
+
webpack builder replaces `process.env` in the bundle.
|
|
156
|
+
|
|
157
|
+
```ts
|
|
158
|
+
// Storybook only: placeholders so modules that validate env at import
|
|
159
|
+
// time load. Never real values.
|
|
160
|
+
env: (config = {}) => ({
|
|
161
|
+
...config,
|
|
162
|
+
NEXT_PUBLIC_API_URL: config.NEXT_PUBLIC_API_URL ?? "https://api.example.invalid",
|
|
163
|
+
}),
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Never commit a real key, and never copy the app's `.env` files.
|
|
167
|
+
|
|
168
|
+
3. **`next/font`, `next/image` and SVGR imports.** Keep a Next.js framework
|
|
169
|
+
(`@storybook/nextjs` or `@storybook/nextjs-vite`), which handles
|
|
170
|
+
`next/font` and `next/image`. Components that use `next/navigation` need
|
|
171
|
+
`parameters: { nextjs: { appDirectory: true } }` in `preview.*`. A font
|
|
172
|
+
the app's layout applies (`className={inter.variable}` on `<html>`) needs
|
|
173
|
+
the same class in a `preview.*` decorator. With `next/font/google` the
|
|
174
|
+
font files load from Google when a story is viewed, so a captured kit
|
|
175
|
+
falls back to the system font; say so in the pull request
|
|
176
|
+
(`next/font/local` fonts are served by Storybook and captured). Storybook
|
|
177
|
+
does not run the app's custom `webpack()` from `next.config.*`, so an SVG
|
|
178
|
+
imported as a component (`import Logo from "./logo.svg"`) needs the loader
|
|
179
|
+
added in `webpackFinal`, the app's own `@svgr/webpack`:
|
|
180
|
+
|
|
181
|
+
```ts
|
|
182
|
+
webpackFinal: async (config) => {
|
|
183
|
+
const rules = config.module?.rules ?? [];
|
|
184
|
+
for (const rule of rules)
|
|
185
|
+
if (rule && typeof rule === "object" && rule.test instanceof RegExp && rule.test.test(".svg"))
|
|
186
|
+
rule.exclude = /\.svg$/i;
|
|
187
|
+
rules.push({ test: /\.svg$/i, use: ["@svgr/webpack"] });
|
|
188
|
+
return config;
|
|
189
|
+
},
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
With a Vite builder, the app's `vite.config.*` plugins (such as
|
|
193
|
+
`vite-plugin-svgr`) are merged in; add the plugin or alias in `viteFinal`
|
|
194
|
+
only when the app configures it somewhere Storybook does not read.
|
|
195
|
+
|
|
196
|
+
4. **`public/` assets.** Images and fonts the components load by absolute
|
|
197
|
+
path (`/logo.svg`) 404 until `.storybook/main.*` has
|
|
198
|
+
`staticDirs: ["../public"]` (the path to the app's public folder).
|
|
199
|
+
|
|
200
|
+
## 4. Write the stories
|
|
201
|
+
|
|
202
|
+
**One stories file per component, next to the component**, named the way
|
|
203
|
+
the repository names files (`Button.tsx` and `Button.stories.tsx`). Use CSF 3
|
|
204
|
+
in the repository's typing style, for example:
|
|
205
|
+
|
|
206
|
+
```tsx
|
|
207
|
+
import type { Meta, StoryObj } from "@storybook/react-vite"; // or @storybook/nextjs, @storybook/nextjs-vite; @storybook/react on Storybook 8
|
|
208
|
+
import { Button } from "./Button";
|
|
209
|
+
|
|
210
|
+
const meta = {
|
|
211
|
+
component: Button,
|
|
212
|
+
args: { children: "Save" },
|
|
213
|
+
} satisfies Meta<typeof Button>;
|
|
214
|
+
export default meta;
|
|
215
|
+
type Story = StoryObj<typeof meta>;
|
|
216
|
+
|
|
217
|
+
export const Primary: Story = {};
|
|
218
|
+
export const Secondary: Story = { args: { variant: "secondary" } };
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Each file covers, where it applies:
|
|
222
|
+
|
|
223
|
+
- **the default**, and **every variant and every size** the props allow;
|
|
224
|
+
- **hover, focus and disabled** for anything interactive. Disabled is a prop.
|
|
225
|
+
Focus is a `play` function that focuses the element
|
|
226
|
+
(`play: async ({ canvasElement }) => canvasElement.querySelector("button")?.focus()`).
|
|
227
|
+
Hover that the component drives itself (a tooltip, a menu) is a `play`
|
|
228
|
+
function too. A pure CSS `:hover` cannot be shown without a pseudo-state
|
|
229
|
+
addon, so say so in the coverage note instead of adding one;
|
|
230
|
+
- **empty, loading and error** states for anything that shows data or
|
|
231
|
+
results;
|
|
232
|
+
- **long text or overflow** for anything that holds text: a long label, a
|
|
233
|
+
long unbroken word or address, many items.
|
|
234
|
+
|
|
235
|
+
Name state stories so they do not shadow globals: `ErrorState` with
|
|
236
|
+
`name: "Error"`, never `export const Error`. A captured kit is static HTML, so
|
|
237
|
+
focus rings and other live states show in Storybook but not in the kit.
|
|
238
|
+
|
|
239
|
+
Use made-up fixture data (`example.com` addresses, invented names), never
|
|
240
|
+
real customer data. Write stories through the component's props; do not
|
|
241
|
+
refactor the app to make a state reachable. A state no prop can reach is
|
|
242
|
+
skipped for cause and listed.
|
|
243
|
+
|
|
244
|
+
**Add a tokens (foundations) story**, for example
|
|
245
|
+
`src/foundations/Tokens.stories.tsx` with the title `Foundations/Tokens`.
|
|
246
|
+
It renders the design language from the token layer the survey found: the
|
|
247
|
+
palette as labelled swatches (`background: var(--color-primary)`, or Tailwind
|
|
248
|
+
classes), the type scale (each size with its name), and the spacing ramp
|
|
249
|
+
(bars of each width). Radii and shadows can go in too. List the token names
|
|
250
|
+
from the token source, so a new token is one line.
|
|
251
|
+
|
|
252
|
+
**"Every component" means the whole catalog**: the shared primitives and
|
|
253
|
+
the composites and feature components (lists, panels, cards, headers,
|
|
254
|
+
forms). Skip a component **only for cause**: it cannot render apart from
|
|
255
|
+
live data (it fetches on its own and has no way to pass data in), it is
|
|
256
|
+
deprecated, or it is an internal detail of another component that is
|
|
257
|
+
already covered. Route files (`page.tsx`, `layout.tsx`) and the app root are
|
|
258
|
+
screens, not catalog components: give one a story when it renders from props
|
|
259
|
+
alone, and otherwise list it as skipped. List every skip, with its reason, in
|
|
260
|
+
the pull request. A large backfill may be split into several pull requests by
|
|
261
|
+
component family; say which family each covers and what is left. Silently
|
|
262
|
+
leaving components out is not allowed.
|
|
263
|
+
|
|
264
|
+
While you read the screens, note **inline UI that should become shared
|
|
265
|
+
components**: the same markup repeated across pages. Name each one under
|
|
266
|
+
"Recommended next" in the pull request. Do not extract it in this pull
|
|
267
|
+
request.
|
|
268
|
+
|
|
269
|
+
## 5. Typecheck, then build
|
|
270
|
+
|
|
271
|
+
1. **Typecheck first.** It is cheaper than a build, and it catches story type
|
|
272
|
+
errors that `storybook build` lets through. Run the repository's own
|
|
273
|
+
typecheck (`pnpm typecheck`, `pnpm exec tsc --noEmit`, `tsc -b`). Check
|
|
274
|
+
that its `include` covers the stories files and `.storybook/`. TypeScript
|
|
275
|
+
skips dot-folders in wildcards, so name the files: add
|
|
276
|
+
`".storybook/*.ts", ".storybook/*.tsx"` to the `include` the typecheck
|
|
277
|
+
uses. Fix every error.
|
|
278
|
+
2. **Build.** Run `storybook build` with the repository's package manager
|
|
279
|
+
(`pnpm exec storybook build --quiet`, `npx storybook build --quiet`). Fix
|
|
280
|
+
every error and warning that points at a story or the config. Then check
|
|
281
|
+
`storybook-static/index.json`: its story entries should match what you
|
|
282
|
+
wrote, and none of init's examples should be left.
|
|
283
|
+
3. Run the repository's lint and its other pull request checks that the
|
|
284
|
+
change touches (ESLint on the stories, a format check), and fix what this
|
|
285
|
+
change broke.
|
|
286
|
+
|
|
287
|
+
## 6. Check the design kit captures it
|
|
288
|
+
|
|
289
|
+
`design-kit capture stories` renders every story in a headless browser, so it
|
|
290
|
+
also proves each story renders without throwing. Write the kit to a scratch
|
|
291
|
+
folder **outside the repository**, never into it.
|
|
292
|
+
|
|
293
|
+
- **With a `design-kit.config.json`:** give it a `stories` section if it has
|
|
294
|
+
none:
|
|
295
|
+
|
|
296
|
+
```json
|
|
297
|
+
"stories": {
|
|
298
|
+
"root": ".",
|
|
299
|
+
"buildCommand": "pnpm exec storybook build --quiet -o storybook-static",
|
|
300
|
+
"staticDir": "storybook-static",
|
|
301
|
+
"gaps": { "componentGlob": "src/**/[A-Z]*.{tsx,jsx}" }
|
|
302
|
+
}
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
(`root` is the folder holding `.storybook/`, relative to the config; use
|
|
306
|
+
the repository's package manager in `buildCommand`.) If the repository's
|
|
307
|
+
`.github/workflows/design-kit.yml` and `.claude/skills/design-kit/SKILL.md`
|
|
308
|
+
were written before Storybook existed, they skip stories too. To update
|
|
309
|
+
them, copy the repository (without `node_modules`) to a scratch folder,
|
|
310
|
+
run `npx --yes @codepress/design-kit init --force` there, and port only
|
|
311
|
+
the Storybook parts of those two files back: the "Build Storybook and
|
|
312
|
+
capture stories" step and the stories capture line. Then run, from the
|
|
313
|
+
folder that holds `design-kit.config.json`:
|
|
314
|
+
|
|
315
|
+
```bash
|
|
316
|
+
npx --yes @codepress/design-kit capture stories --out "$TMPDIR/design-kit-check"
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
- **Without one:** check anyway with a scratch config outside the repository:
|
|
320
|
+
|
|
321
|
+
```bash
|
|
322
|
+
cat > "$TMPDIR/design-kit-check.json" <<EOF
|
|
323
|
+
{"version": 1, "stories": {"root": "$PWD", "storybookDir": "$PWD/storybook-static",
|
|
324
|
+
"gaps": {"componentGlob": "src/**/[A-Z]*.{tsx,jsx}"}}}
|
|
325
|
+
EOF
|
|
326
|
+
npx --yes @codepress/design-kit capture stories --config "$TMPDIR/design-kit-check.json" --out "$TMPDIR/design-kit-check"
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
Capture needs Playwright and Chromium. When the repository has neither,
|
|
330
|
+
run `npx --yes -p @playwright/test playwright install chromium`, then
|
|
331
|
+
`npx --yes -p @codepress/design-kit -p @playwright/test design-kit capture stories ...`;
|
|
332
|
+
install nothing into the repository for it.
|
|
333
|
+
|
|
334
|
+
Capture what you just built: the `buildCommand` rebuilds Storybook, and with
|
|
335
|
+
a `storybookDir` rebuild first, because a stale build hides missing stories.
|
|
336
|
+
Read what it printed (`stories N, ... failed M`) and
|
|
337
|
+
`$TMPDIR/design-kit-check/gaps.json`:
|
|
338
|
+
|
|
339
|
+
- a **failed story** (it threw, or never rendered) is a bug in the story or
|
|
340
|
+
the config: fix it and capture again;
|
|
341
|
+
- a **`no story`** row names a component file with no stories file: write
|
|
342
|
+
one, or make sure it is in your skip list with its reason. Its path is
|
|
343
|
+
relative to the config file's folder.
|
|
344
|
+
|
|
345
|
+
Aim for zero failures and every `no story` row explained. The files in
|
|
346
|
+
`html/` are bare markup without CSS; to look at one story styled, find its id
|
|
347
|
+
and compose it into a page, then open that page in a browser:
|
|
348
|
+
|
|
349
|
+
```bash
|
|
350
|
+
KIT="$TMPDIR/design-kit-check"
|
|
351
|
+
node "$KIT/kit.mjs" --kit "$KIT" find <component name> # ids like story:<storybook-id>@1280
|
|
352
|
+
node "$KIT/kit.mjs" --kit "$KIT" compose --frame <id> --out "$TMPDIR/story.html"
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
Check it looks like the app, and take a screenshot for the pull request.
|
|
356
|
+
|
|
357
|
+
## 7. Open the pull request
|
|
358
|
+
|
|
359
|
+
One pull request; never merge it. When the survey and the checks found
|
|
360
|
+
nothing missing (Storybook builds, every component has its stories, the
|
|
361
|
+
capture has no failures and no unexplained `no story` rows), open no pull
|
|
362
|
+
request: report that proof instead. Otherwise the description says:
|
|
363
|
+
|
|
364
|
+
- **The survey**: where the components and tokens live, and whether
|
|
365
|
+
Storybook existed (extended, not re-initialised).
|
|
366
|
+
- **Versions and builder**: the Storybook version and why (9, or 8 because of
|
|
367
|
+
which floor), the framework package and why, and that React, Next and
|
|
368
|
+
TypeScript are unchanged.
|
|
369
|
+
- **First-build fixes**: each one you made (env placeholders, loaders,
|
|
370
|
+
`staticDirs`, overrides) and why.
|
|
371
|
+
- **Coverage**: the components covered, counted per folder ("14 of 15 in
|
|
372
|
+
`src/components`"), with the states each covers, and the tokens story.
|
|
373
|
+
- **Skipped**: every component or state left out, each with its reason.
|
|
374
|
+
- **Proof**: the typecheck and `storybook build` results, the capture's
|
|
375
|
+
story count, failures and `gaps.json` rows, and the screenshot.
|
|
376
|
+
- **Recommended next**: inline UI that should become shared components, and,
|
|
377
|
+
when the repository has no design kit yet, that
|
|
378
|
+
`npx --yes @codepress/design-kit setup-guide` sets one up.
|
|
379
|
+
- **Not tried**: anything this guide does not cover on this stack, said
|
|
380
|
+
plainly.
|
|
381
|
+
|
|
382
|
+
Never commit `storybook-static/`, a captured kit, or a real secret.
|
|
383
|
+
|
|
384
|
+
## Keeping stories current
|
|
385
|
+
|
|
386
|
+
After this pull request, when you add a component or change what one
|
|
387
|
+
renders, add or update its story in the same pull request, covering the
|
|
388
|
+
states in step 4, so the next design kit captures it. Say in the pull request
|
|
389
|
+
which stories you added or changed.
|
package/src/capture-stories.mjs
CHANGED