Theming Storybook

Storybook is theme-able! Just set a theme in the options parameter!

Global theming

It’s really easy to theme Storybook globally.

We’ve created two basic themes that look good of the box: “normal” (a light theme) and “dark” (a dark theme).

As the simplest example, you can tell Storybook to use the “dark” theme by modifying .storybook/config.js:

  1. import { addParameters } from '@storybook/react';
  2. import { themes } from '@storybook/theming';
  3. // Option defaults.
  4. addParameters({
  5. options: {
  6. theme: themes.dark,
  7. },
  8. });

When setting a theme, set a full theme object. The theme is replaced, not combined.

Dynamic theming

You can also theme dynamically based on the story you’re viewing or based on UI in an addon (e.g. a theme picker).

For example, you can update the theme when the user is viewing a specific component:

  1. import { storiesOf } from '@storybook/react';
  2. import yourTheme from './yourTheme';
  3. storiesOf('MyComponent', module)
  4. .addParameters({ options: { theme: yourTheme } })
  5. .add(...)
  6. });

Read on for more on how to create your own theme.

Create a theme quickstart

The easiest way to customize Storybook is to generate a new theme using the create() function from storybook/theming. This function includes shorthands for the most common theme variables. Here’s how to use it:

First create a new file in .storybook called yourTheme.js.

Next paste the code below and tweak the variables.

  1. import { create } from '@storybook/theming';
  2. export default create({
  3. base: 'light',
  4. colorPrimary: 'hotpink',
  5. colorSecondary: 'deepskyblue',
  6. // UI
  7. appBg: 'white',
  8. appContentBg: 'silver',
  9. appBorderColor: 'grey',
  10. appBorderRadius: 4,
  11. // Typography
  12. fontBase: '"Open Sans", sans-serif',
  13. fontCode: 'monospace',
  14. // Text colors
  15. textColor: 'black',
  16. textInverseColor: 'rgba(255,255,255,0.9)',
  17. // Toolbar default and active colors
  18. barTextColor: 'silver',
  19. barSelectedColor: 'black',
  20. barBg: 'hotpink',
  21. // Form colors
  22. inputBg: 'white',
  23. inputBorder: 'silver',
  24. inputTextColor: 'black',
  25. inputBorderRadius: 4,
  26. brandTitle: 'My custom storybook',
  27. brandUrl: 'https://example.com',
  28. brandImage: 'https://placehold.it/350x150',
  29. });

Finally, import your theme into .storybook/config and add it to your Storybook parameters.

  1. import yourTheme from './yourTheme';
  2. addParameters({
  3. options: {
  4. theme: yourTheme,
  5. },
  6. });

The storybook/theming package is built using TypeScript, so this should help create a valid theme for typescript users. The types are part of the package itself.

Many theme variables are optional, the base property is NOT. This is a perfectly valid theme:

  1. import { create } from '@storybook/theming';
  2. export default create({
  3. base: 'light',
  4. brandTitle: 'My custom storybook',
  5. brandUrl: 'https://example.com',
  6. brandImage: 'https://placehold.it/350x150',
  7. });

Addons and theme creation

Some addons require specific theme variables that a Storybook user must add. If you share your theme with the community, make sure to support the official and other popular addons so your users have a consistent experience.

For example, the popular Actions addon uses react-inspector which has themes of its own. Supply additional theme variables to style it like so:

  1. addonActionsTheme: {
  2. ...chromeLight,
  3. BASE_FONT_FAMILY: typography.fonts.mono,
  4. BASE_BACKGROUND_COLOR: 'transparent',
  5. }

Using the theme for addon authors

For a native Storybook experience, we encourage addon authors to reuse the theme variables above. The theming engine relies on emotion, a CSS-in-JS library.

  1. import { styled } from '@storybook/theming';

Use the theme variables in object notation:

  1. const Component = styled.div(({ theme }) => ({
  2. background: theme.background.app,
  3. width: 0,
  4. }));

Or with template literals:

  1. const Component = styled.div`
  2. background: `${props => props.theme.background.app}`
  3. width: 0;
  4. `;