New
Storybook for full-stack developersAutomate with Chromatic
Star75,295
Back to integrations
Add your integration
Categories
  • ⭐️ Popular
  • 🧩 Essentials
  • 🛠 Code
  • ⚡️ Data & state
  • ✅ Test
  • 💅 Style
  • 🎨 Design
  • ⚙️ Appearance
  • 🗄 Organize
How to install addons Create an addon
@rize-finance/storybook-addon-dynamic-theme
Match the Storybook UI to the component theme
npm install @rize-finance/storybook-addon-dynamic-theme
Last updated over 2 years ago
1
Downloads per week
Readme View on GitHub

@rize-finance/storybook-addon-dynamic-theme

Match the Storybook UI theme with your dynamic, context-based component theme.

change theme

This addon works together with the excellent contexts addon to apply your custom theme's colors to the Storybook UI theme.

To use it:

  • set up the contexts addon as described in its README.

  • install this addon

    yarn add -D @rize-finance/storybook-addon-dynamic-theme
    
  • register via the addons section of main.js

  • use the addParameters api to set the theme and define the themeTranslation

Example

.storybook/main.js

module.exports = {
  stories: ["../src/**/*.stories.tsx"],
  addons: [
    "@storybook/addon-contexts/register",
    "@rize-finance/storybook-addon-dynamic-theme"
  ]
};

.storybook/contexts.js

import { ThemeProvider } from "emotion-theming";
import { themes } from "../src/style/theme"; // your custom themes

export const themeTitle = "Themes";
export const themePropName = "theme";
export const themeDefault = themes.light;

export const contexts = [
  {
    icon: "mirror", // a icon displayed in the Storybook toolbar to control contextual props
    title: themeTitle, // an unique name of a contextual environment
    components: [
      // an array of components that is going to be injected to wrap stories
      ThemeProvider
    ],
    params: [
      // an array of params contains a set of predefined `props` for `components`
      {
        name: "Light Theme",
        props: { [themePropName]: themes.light },
        default: true
      },
      { name: "Dark Theme", props: { [themePropName]: themes.dark } }
    ],
    options: {
      deep: true, // pass the `props` deeply into all wrapping components
      disable: false, // disable this contextual environment completely
      cancelable: false // allow this contextual environment to be opt-out optionally in toolbar
    }
  }
];

.storybook/preview.js

import React from "react";
import { addDecorator, addParameters } from "@storybook/react";
import { create } from "@storybook/theming";
import { withContexts } from "@storybook/addon-contexts/react";
import { translateTheme } from "@rize-finance/storybook-addon-dynamic-theme";
import { contexts, themeTitle, themePropName, themeDefault } from "./contexts";

const baseTheme = create({
  brandTitle: "Components"
});

const themeTranslation = {
  contextPath: [themeTitle, themePropName],
  static: baseTheme,
  dynamic: {
    base: "colors.base",
    colorPrimary: "colors.main",
    appContentBg: "colors.background",
    appBg: "colors.lineWeak",
    colorSecondary: "colors.secondary",
    appBorderColor: "colors.lineStrong",
    appBorderRadius: "borderRadius",
    fontBase: "fontBase",
    fontCode: "monospace",
    textColor: "colors.text",
    textInverseColor: "colors.textInverse",
    barTextColor: "colors.text",
    barSelectedColor: "colors.textStrong",
    barBg: "colors.line",
    inputBg: "colors.background",
    inputBorder: "colors.line",
    inputTextColor: "colors.text"
  }
};

const theme = translateTheme(themeDefault, themeTranslation);

addParameters({
  options: { theme },
  themeTranslation
});
addDecorator(withContexts(contexts));

src/style/theme.js

const light = {
  colors: {
    base: "light",
    main: "red",
    secondary: "blue",
    background: "white",
    lineWeak: "#eee",
    line: "#ddd",
    lineStrong: "#ccc",
    text: "#222",
    textStrong: "#111",
    textInverse: "#eee"
  },
  borderRadius: 0,
  fontBase: '"Open Sans", sans-serif'
};

const dark = {
  colors: {
    base: "dark",
    main: "blue",
    secondary: "red",
    background: "black",
    lineWeak: "#111",
    line: "#222",
    lineStrong: "#333",
    text: "#ddd",
    textStrong: "#eee",
    textInverse: "#111"
  },
  borderRadius: 0,
  fontBase: '"Open Sans", sans-serif'
};

export const themes = {
  light,
  dark
};

The important part is the themeTranslation object.

  • contextPath : locates the theme within the full context

  • static : parts of the Storybook theme which don't change with context

  • dynamic : mapping from custom theme to Storybook theme

Join the community
5,867 developers and counting
WhyWhy StorybookComponent-driven UI
Open source software
Storybook

Maintained by
Chromatic
Special thanks to Netlify and CircleCI