Gathering detailed insights and metrics for storybook-addon-themes
Gathering detailed insights and metrics for storybook-addon-themes
Gathering detailed insights and metrics for storybook-addon-themes
Gathering detailed insights and metrics for storybook-addon-themes
npm install storybook-addon-themes
Typescript
Module System
Node Version
NPM Version
80.1
Supply Chain
90.2
Quality
74.2
Maintenance
100
Vulnerability
99.6
License
TypeScript (70.61%)
JavaScript (25.32%)
Svelte (4.07%)
Total Downloads
13,533,857
Last Day
1,874
Last Week
42,964
Last Month
284,522
Last Year
2,348,706
MIT License
85 Stars
108 Commits
29 Forks
4 Watchers
18 Branches
6 Contributors
Updated on Mar 06, 2025
Latest Version
6.1.0
Package Id
storybook-addon-themes@6.1.0
Unpacked Size
216.46 kB
Size
146.20 kB
File Count
84
NPM Version
6.14.8
Node Version
14.15.1
Cumulative downloads
Total Downloads
Last Day
-37.7%
1,874
Compared to previous day
Last Week
-17.1%
42,964
Compared to previous week
Last Month
-3.4%
284,522
Compared to previous month
Last Year
-34.7%
2,348,706
Compared to previous year
8
25
Greatly inspired by @storybook/addon-backgrounds.
This Storybook Theme Decorator can be used to add a custom HTML class or classes to the preview in Storybook.
This version is compatible with storybook version 6.0.x
.
1npm i -D storybook-addon-themes
Then activate the addon by adding it to the storybook main.js
file (located in the Storybook config directory):
1module.exports = { 2 addons: [ 3 // Maybe other addons here... 4 'storybook-addon-themes' 5 // Or here... 6 ], 7};
See the storybook documentation for more informations.
The themes
parameter accept an array of Theme
object.
Each Theme
is an object with the following properties:
name
(string
): Name of the themeclass
(string | string[]
- optional): HTML class(es) associated with the themecolor
(string
): The color of the badge in the theme selectordefault
[deprecated] (boolean
- optional): Is the theme selected by default?The themes
parameter also accept an object with the following properties:
default
(string
- optional): Name of theme selected by defaultlist
(Theme[]
- required): The list of themesclearable
(boolean
- optional - default is true
): Can the user clear the selected theme ?disable
(boolean
- optional): Disable the addon for a storyDecorator
(Component
- optional): A component to use as the decorator component (see below for more information)onChange
((themeName: Theme) => void
- optional): A callback that will be executed when the theme changestarget
(string
- optional): Target element selected with document.querySelector()
to which classes are applied. Defaults to body
, root
if classes should be applied to documentElement
.You can configure the themes globally in the storybook preview.js
file:
1export const parameters = { 2 themes: { 3 default: 'twitter', 4 list: [ 5 { name: 'twitter', class: 'theme-twt', color: '#00aced' }, 6 { name: 'facebook', class: 'theme-fb', color: '#3b5998' } 7 ], 8 }, 9};
For backward compatibility default
(boolean
) can also be set directly on Theme
object.
This has been deprecated because of the difficulty of changing the default theme due to the need to redefine all Theme
objects.
1// deprecated 2export const parameters = { 3 themes: [ 4 { name: 'twitter', class: 'theme-twt', color: '#00aced', default: true }, 5 { name: 'facebook', class: 'theme-fb', color: '#3b5998' } 6 ], 7};
See the storybook documentation for more informations.
Or configure the themes in your story file like this:
1export default { 2 title: 'CSF|Button', 3 component: Button, 4 parameters: { 5 themes: { 6 default: 'twitter', 7 list: [ 8 { name: 'twitter', class: ['theme-twt', 'light-mode'], color: '#00aced' }, 9 { name: 'facebook', class: ['theme-fb', 'dark-mode'], color: '#3b5998' }, 10 ], 11 }, 12 }, 13};
If you only want to activate the addon or override the themes for a specific story you can write:
1export default { 2 title: 'CSF|Button', 3 component: Button, 4}; 5 6export const withText = () => <Button onClick={action('clicked')}>Hello Button</Button>; 7withText.story = { 8 parameters: { 9 themes: { 10 default: 'twitter', 11 list: [ 12 { name: 'twitter', class: ['theme-twt', 'light-mode'], color: '#00aced' }, 13 { name: 'facebook', class: ['theme-fb', 'dark-mode'], color: '#3b5998' }, 14 ], 15 }, 16 }, 17};
Alternatively with the old StoriesOf API:
1import { storiesOf } from '@storybook/react'; // <- or your storybook framework 2 3storiesOf('StoriesOf|Button', module) 4 .addParameters({ 5 themes: { 6 default: 'twitter', 7 list: [ 8 { name: 'twitter', class: ['theme-twt', 'light-mode'], color: '#00aced' }, 9 { name: 'facebook', class: ['theme-fb', 'dark-mode'], color: '#3b5998' }, 10 ], 11 }, 12 }) 13 .add('with text', () => <button>Click me</button>);
And for a single story:
1import { storiesOf } from '@storybook/react'; 2 3storiesOf('StoriesOf|Button', module) 4 .add('with text', () => <button>Click me</button>, { 5 themes: { 6 list: [ 7 { name: 'red', class: 'theme-red', color: 'rgba(255, 0, 0)' }, 8 ], 9 }, 10 }); 11
You can also only override a single key on the themes parameter, for instance to set a different default value for a single story:
1export default { 2 title: 'CSF|Button', 3 component: Button, 4}; 5 6export const withText = () => <Button onClick={action('clicked')}>Hello Button</Button>; 7withText.story = { 8 parameters: { 9 themes: { 10 default: 'facebook', 11 }, 12 }, 13};
By default the classes will be added to the body
element or the element configured with target
.
But in this case your theme will not be visible by other addons (like @storybook/addon-storyshots).
To fix this you can add the withThemes
decorator in your stories.
But the decorator method is not available for all frameworks
See here for the list of supported framework.
Setup the decorator globally in the preview.js
file:
1import { addDecorator } from '@storybook/react'; // <- or your storybook framework 2import { withThemes } from 'storybook-addon-themes/react'; // <- or your storybook framework 3 4addDecorator(withThemes); 5 6export const parameters = { 7 actions: { argTypesRegex: "^on[A-Z].*" }, 8 themes: { 9 default: 'twitter', 10 list: [ 11 { name: 'twitter', class: ['theme-twt', 'light-mode'], color: '#00aced' }, 12 { name: 'facebook', class: ['theme-fb', 'dark-mode'], color: '#3b5998' }, 13 ], 14 }, 15};
Or in your story file (for all stories in that file):
1export default { 2 title: 'CSF|Button', 3 component: Button, 4 decorators: [ withThemes ], 5 parameters: { 6 themes: { 7 default: 'twitter', 8 list: [ 9 { name: 'twitter', class: ['theme-twt', 'light-mode'], color: '#00aced' }, 10 { name: 'facebook', class: ['theme-fb', 'dark-mode'], color: '#3b5998' }, 11 ], 12 }, 13 }, 14};
Or just for a specific story:
1export const withText = () => <Button onClick={action('clicked')}>Hello Button</Button>; 2withText.story = { 3 decorators: [ withThemes ], 4 parameters: { 5 themes: { 6 default: 'twitter', 7 list: [ 8 { name: 'twitter', class: ['theme-twt', 'light-mode'], color: '#00aced' }, 9 { name: 'facebook', class: ['theme-fb', 'dark-mode'], color: '#3b5998' }, 10 ], 11 }, 12 }, 13};
And alternatively with the old StoriesOf API:
1import { storiesOf } from '@storybook/react'; // <- or your storybook framework 2import { withThemes } from 'storybook-addon-themes/react'; 3 4storiesOf('StoriesOf|Button', module) 5 .addDecorator(withThemes) 6 .add('with text', () => <button>Click me</button>);
You can provide a component that will be used as decorator using the Decorator
option in the theme
parameter.
The decorator will get the following properties :
theme
: The selected theme or undefined
if none is selected.themes
: The list of themes as provided in the list
option of the theme
parameter.themeClasses
: The formatted theme classes of the selected theme (if the class
option exists on the selected theme).themeName
: The name of the selected theme (equal to none
if none is selected).Don't forget to render the story using the children
prop (React/HTML) or the <slot></slot>
element (Vue/Svelte).
To manage reactivity with the HTML storybook your decorator must return an array containing two elements :
children
).Example of a customized decorator that use a CSS file for changing the theme:
1function getOrCreate(id) {
2 const elementOnDom = document.getElementById(id);
3 if (elementOnDom) {
4 return elementOnDom;
5 }
6
7 const element = document.createElement('link');
8 element.setAttribute('id', id);
9 element.setAttribute('rel', 'stylesheet');
10 return element;
11}
12
13function Decorator(props) {
14 const { children } = props;
15
16 function setStyles({ theme, themeName }) {
17 const link = getOrCreate('theme-stylesheet');
18 if (!theme) {
19 link.parentNode && link.parentNode.removeChild(link);
20 } else {
21 link.href = themeName === 'facebook' ? 'Button-fb.css' : 'Button-twt.css';
22 children.appendChild(link);
23 }
24 }
25 setStyles(props);
26
27 return [children, setStyles];
28}
Same example as above for React:
1function Decorator(props) { 2 const { children, themeName } = props; 3 return ( 4 <> 5 {children} 6 {themeName === 'twitter' && <link rel="stylesheet" href="twitter.css"/>} 7 {themeName === 'facebook' && <link rel="stylesheet" href="facebook.css"/>} 8 </> 9 ); 10};
React | React Native | Vue | Angular | Polymer | Mithril | HTML | Marko | Svelte | Riot | Ember | Preact | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
Usage without decorator | + | + | + | + | + | + | + | + | + | + | + | |
Usage with decorator | + | + | + | + |
No vulnerabilities found.
@storybook/addon-themes
Storybook Themes addon: Switch between themes from the toolbar
@storybook/addon-styling
A base addon for configuring popular styling tools
@react-theming/storybook-addon
Develop themes and themable components with Emotion, Styled Components, Material-UI and your custom solution
@hitagi/storybook-addon-themes
storybook themes addon can be used to change storybook and story theme with within dropdown menu