Skip to content

Commit

Permalink
fix: storybook theme package not working (#27086)
Browse files Browse the repository at this point in the history
## **Description**

This PR removes the `storybook-dark-mode` package and utilizes the
native Storybook Theme API for managing the light and dark modes across
both the documentation and component preview pages.

The motivation behind this change is to fix the bug introduced after
upgrading Storybook to ^7.6.20 and `storybook-dark-mode` to ^4.0.2,
which resulted in the following error:

```
Error: Storybook preview hooks can only be called inside decorators and story functions.
```

Additionally, we have updated the `DocsContainer` to ensure it handles
the theme correctly without throwing errors. The bug prevented Storybook
Docs pages from rendering properly.

Key changes:
1. Removed the `storybook-dark-mode` package.
2. Implemented the native Storybook Theme API to manage light/dark
modes.
3. Added a button to toggle between light, dark and side by side modes
in the component preview area.
4. Ensured the theme context is properly checked and applied,
particularly in the Docs rendering.

Additional Context:
- We will be implementing the shared UI Component library soon and we
can revisit whether having the additional add-on (`storybook-dark-mode`)
is valuable enough to add an additional dependency. We can add it to our
roadmap for discussion when we are working on the storybook portion of
our roadmap.

## Possible Asked Questions
- Did you consider that the app theme is not changing? 
Yes. It is set to the users system, so if the user uses dark mode then
the application will run in dark. Made attempts for a fix
- Did you consider a fix with the existing package? 
Yes. The best solution was to revert to the old package version, but
that stops us from progressing forward. It's nice to remove dependencies
and use built-in options.

 
## **Related issues**

Fixes: 

- #26703 (Introduced the error after upgrading to Storybook 7.6.20)

## **Manual testing steps**

1. Run `yarn storybook`.
2. Visit the [component docs page running
locally](http://localhost:6006/?path=/docs/components-componentlibrary-avataraccount--docs).
3. Verify that no errors related to theme switching appear in the
console.
4. Ensure the docs page renders properly in both light and dark themes.
5. Test theme switching using the button added in the component preview.

---------

Co-authored-by: legobeat <[email protected]>
  • Loading branch information
garrettbear and legobeat authored Sep 13, 2024
1 parent 1d686e2 commit 9668df7
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 68 deletions.
83 changes: 79 additions & 4 deletions .storybook/preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import { createBrowserHistory } from 'history';
import { setBackgroundConnection } from '../ui/store/background-connection';
import { metamaskStorybookTheme } from './metamask-storybook-theme';
import { DocsContainer } from '@storybook/addon-docs';
import { useDarkMode } from 'storybook-dark-mode';
import { themes } from '@storybook/theming';
import { AlertMetricsProvider } from '../ui/components/app/alert-system/contexts/alertMetricsContext';

Expand All @@ -36,7 +35,13 @@ export const parameters = {
},
docs: {
container: (context) => {
const isDark = useDarkMode();
const theme = context?.globals?.theme || 'both';
const systemPrefersDark = window.matchMedia(
'(prefers-color-scheme: dark)',
).matches;

const isDark =
theme === 'dark' || (theme === 'both' && systemPrefersDark);

const props = {
...context,
Expand Down Expand Up @@ -82,6 +87,19 @@ export const globalTypes = {
}),
},
},
theme: {
name: 'Color Theme',
description: 'The color theme for the component',
defaultValue: 'both',
toolbar: {
items: [
{ value: 'light', title: 'Light', icon: 'sun' },
{ value: 'dark', title: 'Dark', icon: 'moon' },
{ value: 'both', title: 'Light/Dark', icon: 'paintbrush' },
],
dynamicTitle: true,
},
},
};

export const getNewState = (state, props) => {
Expand All @@ -104,7 +122,13 @@ const proxiedBackground = new Proxy(
setBackgroundConnection(proxiedBackground);

const metamaskDecorator = (story, context) => {
const isDark = useDarkMode();
const { theme } = context.globals;
const systemPrefersDark = window.matchMedia(
'(prefers-color-scheme: dark)',
).matches;

const isDark = theme === 'dark' || (theme === 'both' && systemPrefersDark);

const currentLocale = context.globals.locale;
const current = allLocales[currentLocale];

Expand Down Expand Up @@ -146,4 +170,55 @@ const metamaskDecorator = (story, context) => {
);
};

export const decorators = [metamaskDecorator];
// Add the withColorScheme decorator
const withColorScheme = (Story, context) => {
const { theme } = context.globals;
const systemPrefersDark = window.matchMedia(
'(prefers-color-scheme: dark)',
).matches;

const isDark = theme === 'dark' || (theme === 'both' && systemPrefersDark);

function Wrapper(props) {
return (
<div
{...props}
style={{
display: 'flex',
padding: '1rem',
backgroundColor: 'var(--color-background-default)',
color: 'var(--color-text-default)',
}}
/>
);
}

if (theme === 'light') {
return (
<Wrapper data-theme="light">
<Story />
</Wrapper>
);
}

if (theme === 'dark') {
return (
<Wrapper data-theme="dark">
<Story />
</Wrapper>
);
}

return (
<div data-theme={isDark ? 'dark' : 'light'}>
<Wrapper data-theme="light">
<Story />
</Wrapper>
<Wrapper data-theme="dark">
<Story />
</Wrapper>
</div>
);
};

export const decorators = [metamaskDecorator, withColorScheme];
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -654,7 +654,6 @@
"source-map-explorer": "^2.4.2",
"sprintf-js": "^1.1.3",
"storybook": "^7.6.20",
"storybook-dark-mode": "^4.0.2",
"stream-browserify": "^3.0.0",
"stream-http": "^3.2.0",
"string.prototype.matchall": "^4.0.2",
Expand Down
63 changes: 0 additions & 63 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -8660,15 +8660,6 @@ __metadata:
languageName: node
linkType: hard

"@storybook/components@npm:^8.0.0":
version: 8.2.9
resolution: "@storybook/components@npm:8.2.9"
peerDependencies:
storybook: ^8.2.9
checksum: 10/32153df19777ea751d1adb33da6e92b5647d19fd924753b2ca1c80bcc102ee0489eac7b02914a2e56406233940f6eca7f1aa3ba0c441a164cabc954679a67869
languageName: node
linkType: hard

"@storybook/core-client@npm:7.6.20":
version: 7.6.20
resolution: "@storybook/core-client@npm:7.6.20"
Expand Down Expand Up @@ -8719,15 +8710,6 @@ __metadata:
languageName: node
linkType: hard

"@storybook/core-events@npm:^8.0.0":
version: 8.2.9
resolution: "@storybook/core-events@npm:8.2.9"
peerDependencies:
storybook: ^8.2.9
checksum: 10/6ac658a75702c645695d82fbd69da5cf4d559050ffa1f0023729ad34c0d84965b2abeeb65efd168b0cdb049314de002c00267eaf692064e3efeae1337cc3ba52
languageName: node
linkType: hard

"@storybook/core-server@npm:7.6.20":
version: 7.6.20
resolution: "@storybook/core-server@npm:7.6.20"
Expand Down Expand Up @@ -8863,16 +8845,6 @@ __metadata:
languageName: node
linkType: hard

"@storybook/icons@npm:^1.2.5":
version: 1.2.10
resolution: "@storybook/icons@npm:1.2.10"
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
checksum: 10/fad929a7e3c7a1a0fbf6b924b0be73f557b1bba9519faa15422482f89513ceb4b649444c224ee3d1dfbdce3616e684063cff23da08f6b1dd96f1aff4381388a6
languageName: node
linkType: hard

"@storybook/manager-api@npm:7.6.20":
version: 7.6.20
resolution: "@storybook/manager-api@npm:7.6.20"
Expand All @@ -8895,15 +8867,6 @@ __metadata:
languageName: node
linkType: hard

"@storybook/manager-api@npm:^8.0.0":
version: 8.2.9
resolution: "@storybook/manager-api@npm:8.2.9"
peerDependencies:
storybook: ^8.2.9
checksum: 10/5ee66ebdc88f886c05425acff2c362681a6f778e2f27023a43c6c36767ef265175c58b8f23f74684dba64477b26b310fad7cf1761e6643325325a8724f53d93c
languageName: node
linkType: hard

"@storybook/manager@npm:7.6.20":
version: 7.6.20
resolution: "@storybook/manager@npm:7.6.20"
Expand Down Expand Up @@ -9176,15 +9139,6 @@ __metadata:
languageName: node
linkType: hard

"@storybook/theming@npm:^8.0.0":
version: 8.2.9
resolution: "@storybook/theming@npm:8.2.9"
peerDependencies:
storybook: ^8.2.9
checksum: 10/13d71e1b69fb254d5de6349c60c7ac0518cbaec0c26a591c820752dd5b25fe66d8a32e4b081bd9470c0b07648e478eb88ab628d10196918ee2806c9640c2ee2f
languageName: node
linkType: hard

"@storybook/types@npm:7.6.20":
version: 7.6.20
resolution: "@storybook/types@npm:7.6.20"
Expand Down Expand Up @@ -26346,7 +26300,6 @@ __metadata:
source-map-explorer: "npm:^2.4.2"
sprintf-js: "npm:^1.1.3"
storybook: "npm:^7.6.20"
storybook-dark-mode: "npm:^4.0.2"
stream-browserify: "npm:^3.0.0"
stream-http: "npm:^3.2.0"
string.prototype.matchall: "npm:^4.0.2"
Expand Down Expand Up @@ -33462,22 +33415,6 @@ __metadata:
languageName: node
linkType: hard

"storybook-dark-mode@npm:^4.0.2":
version: 4.0.2
resolution: "storybook-dark-mode@npm:4.0.2"
dependencies:
"@storybook/components": "npm:^8.0.0"
"@storybook/core-events": "npm:^8.0.0"
"@storybook/global": "npm:^5.0.0"
"@storybook/icons": "npm:^1.2.5"
"@storybook/manager-api": "npm:^8.0.0"
"@storybook/theming": "npm:^8.0.0"
fast-deep-equal: "npm:^3.1.3"
memoizerific: "npm:^1.11.3"
checksum: 10/c9ef7bc6734df7486ff763c9da3c69505269eaf5fd7b5b489553f023b363ea892862241e6d701ad647ca5d1e64fd9a2646b8985c7ea8ac97a3bca87891db6fe5
languageName: node
linkType: hard

"storybook@npm:^7.6.20":
version: 7.6.20
resolution: "storybook@npm:7.6.20"
Expand Down

0 comments on commit 9668df7

Please sign in to comment.