Skip to content

chore: SW-2124 fix Storybook dark mode in autodocs (previews + docs chrome)#178

Open
boramyi-ts wants to merge 2 commits into
mainfrom
SW-2124-storybook-dark-mode
Open

chore: SW-2124 fix Storybook dark mode in autodocs (previews + docs chrome)#178
boramyi-ts wants to merge 2 commits into
mainfrom
SW-2124-storybook-dark-mode

Conversation

@boramyi-ts

Copy link
Copy Markdown
Contributor

What

Makes Storybook render correctly in dark mode across canvas stories and autodocs pages — component previews, prose, the ArgsTable (incl. table.category rows), Controls widgets, and code blocks.

Addresses SW-2124 (part 2 — "ensure dark mode is properly represented in Storybook"). Also closes the gap flagged in a prior audit review: the docs theme wasn't synced to dark, so any component with a table.category row (or a Controls <select>/<textarea>) showed a white band on the otherwise-dark page.

Why it was broken

Autodocs pages rendered light regardless of the theme toggle, for three reasons:

  1. withThemeByClassName only toggles .dark from a per-story decorator, which never runs for the autodocs page container — and its useEffect re-derived light from each block's own globals, fighting any external sync.
  2. Autodocs renders each story block in an isolated <iframe> that loads with the default (light) globals.
  3. The docs chrome (ArgsTable, category rows, Controls, code blocks) is emotion-styled from Storybook's docs theme object, which the design tokens / .dark class can't reach.

The fix (.storybook/preview.ts)

  • Own the .dark class via a preview channel sync (globals + render events), mirroring the chrome sync already in .storybook/manager.ts. Register the theme toolbar via DecoratorHelpers.initializeThemeState instead of the fighting withThemeByClassName decorator.
  • Inherit the parent doc's theme inside the isolated autodocs story iframes (same-origin) so embedded previews match the page.
  • Sync the docs chrome by driving parameters.docs.container's DocsContainer theme from the same signal, reusing the existing tetra-science light/dark Storybook themes.

Storybook tooling only — no change to the published package output.

Screenshots (theme set to dark)

Component preview (Alert Dialog docs)

Before After
before after

Docs chrome — ArgsTable + table.category + Controls (TdpSearch docs)

Before After
before after

Testing

  • Docs (dark): previews + prose + ArgsTable + table.category rows + Controls all render dark ✅
  • Docs (light): renders light ✅
  • Live theme toggle on a docs page re-themes chrome + previews ✅
  • Canvas stories (dark/light) + theme toolbar switcher ✅
  • yarn lint (zero-warning) + yarn typecheck clean ✅
  • Full dark-mode sweep of all 681 stories / 102 components: no light-surface leaks or contrast failures (only an intentionally-light Code Editor story and one hardcoded PlateMap "Blank" category color) ✅

Note: an initial yarn test:all reported 13 story files failing to import with "Vitest failed to find the current suite. This is a bug in Vitest" — flaky browser-runner collection errors under resource contention (dev server + audit browser running concurrently). A clean re-run of yarn test:storybook passed 681/681 (110/110 files). Not related to this change (which touches one config file).

🤖 Generated with Claude Code

Autodocs pages rendered light regardless of the theme toggle:
- withThemeByClassName only toggled `.dark` from a per-story decorator,
  which never runs for the autodocs page container, and fought any external
  sync (its useEffect re-derived light from each block's own globals).
- autodocs renders each story block in an isolated iframe that loads with
  the default (light) globals.
- the docs chrome (argstable, `table.category` rows, Controls widgets, code
  blocks) is emotion-styled from Storybook's docs theme object, which the
  design tokens / `.dark` class cannot reach.

Fix:
- Own the `.dark` class via a preview channel sync (globals + render events);
  register the theme toolbar via DecoratorHelpers instead of the fighting
  withThemeByClassName decorator.
- Inherit the parent preview document's theme inside the isolated autodocs
  story iframes (same-origin), so embedded previews match the page.
- Drive parameters.docs.container's DocsContainer theme from the same signal,
  reusing the existing tetra-science light/dark Storybook themes, so the docs
  chrome (incl. `table.category` rows and Controls widgets) follows too.

Storybook tooling only; no change to shipped package output.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@boramyi-ts
boramyi-ts requested review from a team as code owners July 15, 2026 14:53
@vercel

vercel Bot commented Jul 15, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
ts-lib-ui-kit-storybook Ready Ready Preview, Comment Jul 15, 2026 3:26pm

Request Review

@boramyi-ts
boramyi-ts temporarily deployed to artifactory-prod July 15, 2026 14:53 — with GitHub Actions Inactive
Follow-up to the dark-mode Storybook fix, resolving self-review findings:

- Reactive docs container: extract `ThemedDocsContainer`, which subscribes to
  theme globals via useState/useEffect instead of reading a module value once
  at render. The Docs chrome now re-themes on toggle even if Storybook doesn't
  re-render the container, and always reflects the latest theme on mount
  (fixes the re-render-dependency and initial-load ordering races).
- Pre-paint theming: read the initial theme synchronously from the URL
  `globals` param and apply `.dark` at module load, avoiding a light flash
  before the first `setGlobals` event.
- HMR cleanup: dispose the channel listeners via `import.meta.hot.dispose` so
  they don't accumulate on hot updates.
- Drop `docs.story.inline: true` — it was a documented no-op under the global
  `layout: "fullscreen"`; the parent-theme inheritance already covers iframes.

Verified: docs dark/light, live toggle re-themes chrome (incl. table.category),
canvas dark, inline previews dark. lint + typecheck clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

Coverage Report

Status Category Percentage Covered / Total
🟢 Lines 96.52% (🎯 83%)
🟰 ±0%
22474 / 23282
🟢 Statements 96.52% (🎯 83%)
🟰 ±0%
22474 / 23282
🟢 Functions 95.75% (🎯 74%)
🟰 ±0%
970 / 1013
🟢 Branches 90.15% (🎯 81%)
⬆️ +0.04%
4268 / 4734
File CoverageNo changed files found.
Generated in workflow #1004 for commit 75314d0 by the Vitest Coverage Report Action

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants