Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
storybook-dark-mode
Advanced tools
storybook-dark-mode is an addon for Storybook that allows you to toggle between light and dark themes within your Storybook environment. This can be particularly useful for testing and demonstrating how your components look in different themes.
Toggle between light and dark mode
This feature allows you to toggle between light and dark themes in your Storybook environment. The code sample demonstrates how to add the dark mode toggle using the `withThemesProvider` decorator.
import { addDecorator } from '@storybook/react';
import { withThemesProvider } from 'storybook-addon-styled-component-theme';
import { themes } from '@storybook/theming';
const themes = [themes.light, themes.dark];
addDecorator(withThemesProvider(themes));
Persist theme selection
This feature allows the selected theme to persist across sessions. The code sample shows how to enable persistence by passing an options object with `persist: true` to the `withThemesProvider` decorator.
import { addDecorator } from '@storybook/react';
import { withThemesProvider } from 'storybook-addon-styled-component-theme';
import { themes } from '@storybook/theming';
const themes = [themes.light, themes.dark];
addDecorator(withThemesProvider(themes, { persist: true }));
Custom themes
This feature allows you to define and use custom themes. The code sample demonstrates how to create custom themes and add them to the `withThemesProvider` decorator.
import { addDecorator } from '@storybook/react';
import { withThemesProvider } from 'storybook-addon-styled-component-theme';
const customThemes = [
{ name: 'Light', backgroundColor: '#ffffff', color: '#000000' },
{ name: 'Dark', backgroundColor: '#000000', color: '#ffffff' }
];
addDecorator(withThemesProvider(customThemes));
storybook-addon-themes is another Storybook addon that allows you to switch between different themes. It provides a similar functionality to storybook-dark-mode but with more flexibility in defining and managing multiple themes.
storybook-addon-styled-component-theme is an addon specifically designed for use with styled-components. It allows you to switch between different styled-component themes within Storybook, offering a more tailored solution for projects using styled-components.
storybook-addon-designs is an addon that allows you to embed Figma, Sketch, and other design tool frames directly into your Storybook. While it doesn't provide dark mode functionality, it offers a way to visually compare your components with design specifications, which can be complementary to theme switching.
A storybook addons that lets your users toggle between dark and light mode.
Install the following npm module:
npm i --save-dev storybook-dark-mode
or with yarn:
yarn add -D storybook-dark-mode
Then, add following content to .storybook/main.js
module.exports = {
addons: ['storybook-dark-mode']
};
Change in .storybook/main.js
module.exports = {
- addons: ['storybook-dark-mode/register']
+ addons: ['storybook-dark-mode']
};
Configure the dark and light mode by adding the following to your .storybook/preview.js
file:
import { themes } from '@storybook/theming';
export const parameters = {
darkMode: {
// Override the default dark theme
dark: { ...themes.dark, appBg: 'black' },
// Override the default light theme
light: { ...themes.normal, appBg: 'red' }
}
};
Order of precedence for the initial color scheme:
current
parameter in your storybookOnce the initial color scheme has been set, subsequent reloads will use this value.
To clear the cached color scheme you have to localStorage.clear()
in the chrome console.
export const parameters = {
darkMode: {
// Set the initial theme
current: 'light'
}
};
This plugin will apply a dark and light class name to the manager. This allows you to easily write dark mode aware theme overrides for the storybook UI.
You can override the classNames applied when switching between light and dark mode using the darkClass
and lightClass
parameters.
export const parameters = {
darkMode: {
darkClass: 'lights-out',
lightClass: 'lights-on'
}
};
You can also pass an array to apply multiple classes.
export const parameters = {
darkMode: {
darkClass: ['lights-out', 'foo'],
lightClass: ['lights-on', 'bar']
}
};
This plugin will apply the dark/light class to the <body>
element of the preview iframe. This can be configured with the classTarget
parameter.
The value will be passed to a querySelector()
inside the iframe.
This is useful if the <body>
is styled according to a parent's class, in that case it can be set to html
.
export const parameters = {
darkMode: {
classTarget: 'html'
}
};
This plugin will apply the darkClass
and lightClass
classes to the preview iframe if you turn on the stylePreview
option.
export const parameters = {
darkMode: {
stylePreview: true
}
};
If your components use a custom Theme provider, you can integrate it by using the provided hook.
import { useDarkMode } from 'storybook-dark-mode';
import { addDecorator } from '@storybook/react';
// your theme provider
import ThemeContext from './theme';
// create a component that uses the dark mode hook
function ThemeWrapper(props) {
// render your custom theme provider
return (
<ThemeContext.Provider value={useDarkMode() ? darkTheme : defaultTheme}>
{props.children}
</ThemeContext.Provider>
);
}
export const decorators = [renderStory => <ThemeWrapper>{renderStory()}</ThemeWrapper>)];
If you want to have you UI's dark mode separate from you components' dark mode, implement this global decorator:
import { themes } from '@storybook/theming';
// Add a global decorator that will render a dark background when the
// "Color Scheme" knob is set to dark
const knobDecorator = storyFn => {
// A knob for color scheme added to every story
const colorScheme = select('Color Scheme', ['light', 'dark'], 'light');
// Hook your theme provider with some knobs
return React.createElement(ThemeProvider, {
// A knob for theme added to every story
theme: select('Theme', Object.keys(themes), 'default'),
colorScheme,
children: [
React.createElement('style', {
dangerouslySetInnerHTML: {
__html: `html { ${
colorScheme === 'dark' ? 'background-color: rgb(35,35,35);' : ''
} }`
}
}),
storyFn()
]
});
};
export const decorators = [knobDecorator];
You can also listen for the DARK_MODE
event via the addons channel.
import { addons } from '@storybook/preview-api';
import { addDecorator } from '@storybook/react';
import { DARK_MODE_EVENT_NAME } from 'storybook-dark-mode';
// your theme provider
import ThemeContext from './theme';
// get channel to listen to event emitter
const channel = addons.getChannel();
// create a component that listens for the DARK_MODE event
function ThemeWrapper(props) {
// this example uses hook but you can also use class component as well
const [isDark, setDark] = useState(false);
useEffect(() => {
// listen to DARK_MODE event
channel.on(DARK_MODE_EVENT_NAME, setDark);
return () => channel.off(DARK_MODE_EVENT_NAME, setDark);
}, [channel, setDark]);
// render your custom theme provider
return (
<ThemeContext.Provider value={isDark ? darkTheme : defaultTheme}>
{props.children}
</ThemeContext.Provider>
);
}
export const decorators = [renderStory => <ThemeWrapper>{renderStory()}</ThemeWrapper>)];
Since in docs mode, Storybook will not display its toolbar,
You can also trigger the UPDATE_DARK_MODE
event via the addons channel if you want to control that option in docs mode,
By editing your .storybook/preview.js
.
import React from 'react';
import { addons } from '@storybook/preview-api';
import { DocsContainer } from '@storybook/addon-docs';
import { themes } from '@storybook/theming';
import {
DARK_MODE_EVENT_NAME,
UPDATE_DARK_MODE_EVENT_NAME
} from 'storybook-dark-mode';
const channel = addons.getChannel();
export const parameters = {
darkMode: {
current: 'light',
dark: { ...themes.dark },
light: { ...themes.light }
},
docs: {
container: props => {
const [isDark, setDark] = React.useState();
const onChangeHandler = () => {
channel.emit(UPDATE_DARK_MODE_EVENT_NAME);
};
React.useEffect(() => {
channel.on(DARK_MODE_EVENT_NAME, setDark);
return () => channel.removeListener(DARK_MODE_EVENT_NAME, setDark);
}, [channel, setDark]);
return (
<div>
<input type="checkbox" onChange={onChangeHandler} />
<DocsContainer {...props} />
</div>
);
}
}
};
Thanks goes to these wonderful people (emoji key):
This project follows the all-contributors specification. Contributions of any kind welcome!
FAQs
Toggle between light and dark mode in Storybook
We found that storybook-dark-mode demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago.ย It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.