Skip to content

Conversation

@ammar-agent
Copy link
Collaborator

Fixes flaky visual diffs in Storybook where the theme would flash from default (light) to selected (dark) on load.

Changes

  • Modified ThemeProvider to accept a forcedTheme prop that overrides internal state and persistence.
  • Updated Storybook preview.tsx to use forcedTheme instead of a useEffect-based synchronization component.

This ensures the correct theme is applied during the first render pass, eliminating the flash and preventing Storybook from polluting local storage.

@ammar-agent
Copy link
Collaborator Author

Updated ThemeProvider to check for a parent theme context. This allows the inner ThemeProvider (e.g., inside App.tsx used in a story) to inherit the theme forced by the outer ThemeProvider (from preview.tsx). This resolves theme mismatches in nested scenarios.

@ammar-agent
Copy link
Collaborator Author

Updated preview.tsx to remove the default dark override and fallback behavior.

  • Now, if no global theme is set (e.g., local Storybook without toolbar interaction), ThemeProvider uses its internal persistence/system preference. This restores the ability to toggle themes via the app's UI or OS settings during development.
  • Chromatic builds continue to work deterministically because modes explicitly set the global theme, which is respected by the forcedTheme prop.
  • This ensures "Latest" doesn't get stuck on Dark and both themes are reviewable.

@ammar-agent
Copy link
Collaborator Author

Added a manual theme toggle button to the Storybook preview decorator.

Why:
Since addon-essentials is missing, the standard Storybook toolbar is unavailable, leaving users unable to toggle themes in the default "Latest" view (which now respects system preference instead of forcing Dark).

Behavior:

  • Chromatic / Forced Modes: The button is hidden (!mode check), ensuring clean snapshots.
  • Local / Default View: A floating toggle button appears in the bottom-right corner, allowing developers to switch between Light and Dark themes freely.

@ammar-agent ammar-agent force-pushed the fix-storybook-theme-flakiness branch from 771f588 to 5c1acee Compare November 24, 2025 02:44
@ammario
Copy link
Member

ammario commented Nov 24, 2025

@ethanndickson gonna turn in soon for the night if this is bothering you and this PR seems dead for more than 10m feel free to take it over.

@ethanndickson ethanndickson force-pushed the fix-storybook-theme-flakiness branch from e0d907a to 5e375d1 Compare November 24, 2025 09:08
@ammar-agent ammar-agent force-pushed the fix-storybook-theme-flakiness branch 4 times, most recently from d8a5e4b to 95b8022 Compare November 24, 2025 19:47
ThemeProvider now detects when it's nested under a parent with forcedTheme
and defers to that parent's theme value. This ensures Storybook/Chromatic's
forced theme decorator isn't overridden by the app's own ThemeProvider.

Changes:
- ThemeProvider accepts forcedTheme prop and tracks isForced in context
- Nested providers inherit parent's theme when parent has forcedTheme
- Storybook decorator applies theme synchronously before React renders
- Added tests for ThemeContext forced theme behavior

_Generated with `mux`_
@ammar-agent ammar-agent force-pushed the fix-storybook-theme-flakiness branch from 1bfa4a0 to 2dbc126 Compare November 24, 2025 20:36
@ammario ammario merged commit 90db7eb into main Nov 24, 2025
18 of 19 checks passed
@ammario ammario deleted the fix-storybook-theme-flakiness branch November 24, 2025 20:42
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