DEV Community

Cover image for Use a ThemeProvider component in Storybook
Ryan Lanciaux
Ryan Lanciaux

Posted on

Use a ThemeProvider component in Storybook

Storybook is awesome for building components

I frequently use Storybook and styled components / Emotion when building component libraries. The ability to apply a consistent theme to all components is very powerful but it requires wrapping your components in a ThemeProvider.

Thankfully, there is a straight-forward way to apply a consistent theme object to all of our components in Storybook by using a Storybook Decorator.

Create a theme decorator

We will start by creating a new decorator. In my current projects, this decorator lives in the .storybook folder.

// themeDecorator.js
import React from "react"
import { ThemeProvider, theme } from "./pathToThemeProvider"

const ThemeDecorator = storyFn => (
  <ThemeProvider theme={theme}>{storyFn()}</ThemeProvider>
)

export default ThemeDecorator
Enter fullscreen mode Exit fullscreen mode

Here we include our custom theme provider and define a component that receives a storyFn as a prop. This storyFn is where the Storybook content will be rendered. We wrap the Storybook content in our provider and export our decorator.

Next, in our project's .storybook/config.js, we need to specify that Storybook should use this decorator for all stories.

Use the theme decorator in Storybook config

We'll start by importing our newly created decorator and make sure that we're using the addDecorator method from Storybook.

import { configure, addDecorator } from "@storybook/react"
import themeDecorator from "./themeDecorator"
Enter fullscreen mode Exit fullscreen mode

Next, we'll want to call the following to apply our decorator.

addDecorator(themeDecorator);
Enter fullscreen mode Exit fullscreen mode

Storybook should now be wrapping all stories with a custom decorator. While this article is specifically about CSS-in-JS themes, this strategy works with other types Providers / Wrapper components as well (like Redux).

Top comments (7)

Collapse
 
semoal profile image
Sergio M

github.com/semoal/themeprovider-st...

You can try an addon i built, you can toggle between themes, add background, and easily see all the keys-values of your theme.

Collapse
 
pv profile image
paul vincent

You are importing configure but not using it. Also you could make more explicit where you are adding the code in the last section of the article (I assume preview.js).

Collapse
 
tiwarishubham profile image
Shubham Tiwari

What is pathToThemeProvider? What is defined in it in the below snippet??

import { ThemeProvider, theme } from "./pathToThemeProvider"

Collapse
 
brycesnyder profile image
S N Y D E R H A U S • Edited

I ended up doing this within the themeDecorator.js..

import React from "react";
import { ThemeProvider } from "styled-components";

const theme = {
  colors: {
    red: "#900",
  },
};

const ThemeDecorator = (storyFn) => (
  <ThemeProvider theme={theme}>{storyFn()}</ThemeProvider>
);

export default ThemeDecorator;
Collapse
 
remjx profile image
Mark Jackson

In the preview.js file where I have addDecorator(), I had to add import React from 'react' to get it to work

Collapse
 
stevepepple profile image
Steve Pepple

Ryan, long time no see! This technique was really helpful thanks!

Collapse
 
ajr_dev profile image
Andrew Roberts

Works like a charm, nice writeup