Skip to content

Commit fc8d4d0

Browse files
pratikbuildsclaude
andcommitted
build(deps): replace ladle with storybook 10 as the component workbench
Ladle has had no release since Nov 2025 and is pinned to Vite 6. Storybook 10 (react-vite) indexes the existing CSF stories unchanged. The e2e axe sweep now loads each story from the Storybook index and fails on render errors. It sees violations the Ladle sweep missed, because that sweep ran before stories mounted; those are recorded in a checked-in baseline to fix later, and only new ones fail the run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 4edc88e commit fc8d4d0

16 files changed

Lines changed: 408 additions & 687 deletions

‎.ladle/components.tsx‎

Lines changed: 0 additions & 33 deletions
This file was deleted.

‎.ladle/config.mjs‎

Lines changed: 0 additions & 14 deletions
This file was deleted.

‎.storybook/main.ts‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import type { StorybookConfig } from "@storybook/react-vite";
2+
3+
const config: StorybookConfig = {
4+
stories: ["../stories/**/*.stories.@(ts|tsx)"],
5+
// Stories argue state through separate exports, not knobs.
6+
features: { controls: false },
7+
framework: {
8+
name: "@storybook/react-vite",
9+
options: { builder: { viteConfigPath: "vite.stories.config.mjs" } },
10+
},
11+
core: {
12+
disableTelemetry: true,
13+
// Reachable through a tailnet proxy; Storybook overrides Vite's
14+
// `server.allowedHosts`, so this lives here rather than in the Vite config.
15+
allowedHosts: [".ts.net"],
16+
},
17+
};
18+
19+
export default config;

‎.storybook/preview.tsx‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import type { Decorator, Preview } from "@storybook/react-vite";
2+
3+
import "../src/styles.css";
4+
5+
// Flip the real `.dark`/`.light` class on `<html>` that `src/theme.css` keys
6+
// off, during render so a story's first paint uses the selected theme. Light
7+
// is pinned with `.light`: with neither class the tokens follow the OS.
8+
const applyTheme: Decorator = (Story, { globals }) => {
9+
const dark = globals["theme"] === "dark";
10+
document.documentElement.classList.toggle("dark", dark);
11+
document.documentElement.classList.toggle("light", !dark);
12+
return <Story />;
13+
};
14+
15+
const preview: Preview = {
16+
globalTypes: {
17+
theme: {
18+
description: "Theme",
19+
toolbar: {
20+
title: "Theme",
21+
icon: "mirror",
22+
items: ["light", "dark"],
23+
dynamicTitle: true,
24+
},
25+
},
26+
},
27+
initialGlobals: { theme: "light" },
28+
decorators: [applyTheme],
29+
};
30+
31+
export default preview;

‎AGENTS.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ arrives as props.
1919
- `src/index.ts`: the hand-written root barrel.
2020
- `src/theme.css`, `src/styles.css`: tokens and keyframes; the prebuilt sheet
2121
entry.
22-
- `stories/`: Ladle stories, kept out of `src/` so they never ship in `dist/`.
22+
- `stories/`: Storybook stories, kept out of `src/` so they never ship in `dist/`.
2323
- `scripts/dep-guard.mjs`, `scripts/contrast-test.mjs`: the CI gates.
2424
- `scripts/test-dom-setup.ts`: happy-dom preload for unit tests (`bunfig.toml`).
2525
- `e2e/`: checks against the built package.

‎CONTRIBUTING.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ Contributors sign the [CLA](CLA.md) on their first PR; the CLA bot explains how.
1414
`bun run test:e2e` checks the built package: every `exports` target exists and the
1515
root entry loads under Node with every optional peer blocked, then packs the
1616
package into a Vite host and runs the Playwright specs in `e2e/` against it. Each
17-
scenario is a route in `e2e/fixtures.tsx`. The same run builds the Ladle stories
17+
scenario is a route in `e2e/fixtures.tsx`. The same run builds the Storybook stories
1818
and fails on any serious or critical axe violation in any story. Run `bun run build` first, and
1919
`bunx playwright install chromium` once. CI also runs `bun run contrast-test` (theme contrast floors, reads
2020
`dist/styles.css`) and `bun run dep-guard` (forbidden imports, see `AGENTS.md`)
@@ -26,7 +26,7 @@ Change tokens in `src/theme.css`, then run `bun run build`; `dist/` is generated
2626
A failing contrast pair prints `FAIL <ratio>:1 (>=<floor>) <mode> <pair>`. Fix it
2727
with a naming rule in `checksFor`, never a hardcoded hex pair.
2828

29-
`bun run stories` starts the Ladle workbench over every component against
29+
`bun run stories` starts the Storybook workbench over every component against
3030
`src/theme.css`; `bun run stories:build` writes a static copy to `build/`. A new
3131
component ships with a story for each meaningful state (loading, empty, error).
3232

0 commit comments

Comments
 (0)