Set Storybook Themes With Decorator Global Values and Parameters
Making decorators smarter with the use of globals and parameters to allow for an interactive theme switching experience.
In the previous lesson, we created a decorator to add theme support to Storybook. Although it's working well, in order to switch the themes (e.g. from light to dark), we need to make code changes which aren't that great.
Storybook decorators not only have access to the story element, but also to the story context. The context is an object that contains a lot of useful information about a story, including globals and parameters. With that information, we can improve the withTheme
decorator we created, allowing users to change the theme directly in the Storybook interface.
Creating our custom toolbar with addon-toolbars#
Storybook addon-essentials includes an addon called addon-toolbars, and that addon allows you to create a new item in Storybook's toolbar that defines global values which can be changed from there, so you have an experience similar to the other addons such as backgrounds and viewport.
In order to create a toolbar item of our own, we can follow the documentation here and export a globalTypes
object in .storybook/preview.tsx
:
// .storybook/preview.tsx
// ... the rest of the code here
export const globalTypes = {
theme: {
name: 'Theme',
description: 'Global theme for components',
defaultValue: 'light',
toolbar: {
icon: 'circlehollow',
// Array of plain string values or MenuItem shape (see below)
items: ['light', 'dark'],
// Property that specifies if the name of the item will be displayed
showName: true,
},
},
}
Now when checking Storybook, we see that there is a new button in the toolbar:

As we interact with it, nothing really happens. That makes sense, as we didn't wire our decorator to use those global values! Let's do that.
Setting themes via globals#
Let's open .storybook/decorators.tsx
and check our withTheme
decorator:
// .storybook/decorators.tsx
import { ThemeProvider } from 'styled-components'
import { DecoratorFn } from '@storybook/react'
import { GlobalStyle } from '../src/styles/GlobalStyle'
import { lightTheme } from '../src/styles/theme'
const withTheme: DecoratorFn = (StoryFn) => (
<ThemeProvider theme={lightTheme}>
<GlobalStyle />
<StoryFn />
</ThemeProvider>
)
export const globalDecorators = [
withTheme
]
This page is a preview of Storybook for React Apps