
Storybook で複数 Theme の切り替えを可能にする
この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
Storybook のアドオン、React Themingを使うと Storybook 上で複数の Theme 切り替えができるようになります。
できたもの
前提条件
React + Typescript で実装された既存のプロジェクトに Storybook を導入し、Theme 切り替えができるようにします。
- React(CRA) 17.0.2
- Typescript 4.1.2
- emotion 11
- Storybook 6.3.8
React のプロジェクトをクローン
こちらの既存の React プロジェクトをクローンします。
左のメニューから Zip で落とすことができるので、VSCode で開いてyarnコマンドで依存をダウンロードします。
Storybook
先ほど落としてきたプロジェクトに Storybook を導入します
npx sb init
yarn storybookを実行して以下の画面が立ち上がれば OK です。
Story を追加
クローンしたサンプルに Story を追加します。
不要なファイルを削除
Introduction.stories.mdx以外のファイルは利用しないので削除します。Introductionもよしなに更新してください。
MembersCard.stories.tsx を追加
以下の Story をstoriesへ追加します。
import React from 'react'
import { Story, Meta } from '@storybook/react/types-6-0'
import { MembersCard } from './../components/MembersCard'
export default {
title: 'pages/MembersCard',
component: MembersCard,
parameters: {
docs: {
description: {
component: 'MembersCard',
},
},
},
} as Meta
const Template: Story = (args: any) => (
<MembersCard {...args}></MembersCard>
)
emotion の Theming を利用しているため、このままだと Theme が正常に読み込まれません。次のステップで.stories/previes.jsでReact Theming アドオン を設定します。
React Theming をインストール
## npm npm i --save-dev @react-theming/storybook-addon ## or yarn yarn add --dev @react-theming/storybook-addon
emotion-themingも利用するのでインストールしておきます。
yarn add --dev emotion-theming
main.js を更新
main.jsを以下のように更新してアドオンを追加します。
module.exports = {
stories: ["../src/**/*.stories.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
addons: [
"@storybook/addon-links",
"@storybook/addon-essentials",
"@storybook/preset-create-react-app",
"@react-theming/storybook-addon",
],
};
preview.js を更新
StorybookのDecorator機能を利用してThemeProviderを設定します。
####preview.js
import React from "react";
import styled from "@emotion/styled";
import {ThemeProvider} from "emotion-theming";
import {addDecorator} from "@storybook/react";
import {withThemes} from "@react-theming/storybook-addon";
import {pink, yellow, sky} from "../src/themes/theme";
addDecorator(withThemes(ThemeProvider, [pink, yellow, sky]));
const PageDefaultStyle = styled.div`
font-family: Hiragino Sans;
`;
export const decorators = [
(Story) => (
<PageDefaultStyle>
<Story />
</PageDefaultStyle>
),
];
Emotionを利用する場合はemotion-themingを使ってください。@emotion/react等だと正常にThemeが読み込まれません。
themes/theme.ts
切り替えたいThemeの定義です。
export const pink = {
fonts: {
mainFont: 'Avenir Next, sans-serif',
subFont: 'Hira Kaku Pro N, sans-serif',
textFont: 'Hiragino Sans',
numberFont: 'Avenir Next, sans-serif',
},
colors: {
mainColor: '#64363C',
subTextColor: '#8E354A',
lineColor: '#E6E5E4',
backgroundColor: '#F8C3CD',
titleBackgroudColor: '#F8F4F4',
accentColor: '#EB7A77',
stageColor: '#CB1B45',
},
}
export const yellow = {
fonts: {
mainFont: 'Times New Roman',
subFont: 'Garamond',
textFont: 'Tahoma',
numberFont: 'Times New Roman',
},
colors: {
mainColor: '#5B622E',
subTextColor: '#8D742A',
lineColor: '#E6E5E4',
backgroundColor: '#DCB879',
titleBackgroudColor: '#EFBB24',
accentColor: '#212121',
stageColor: '#90B44B',
},
}
export const sky = {
fonts: {
mainFont: 'Impact',
subFont: 'Tahoma, sans-serif',
textFont: 'Impact',
numberFont: 'Impact',
},
colors: {
mainColor: '#6c756b',
subTextColor: '#8D8D8D',
lineColor: '#E6E5E4',
backgroundColor: '#F3F4F5',
titleBackgroudColor: '#96C5F7',
accentColor: '#212121',
stageColor: '#4D565D',
},
}
最後に
本記事ではStorybookとReact Themingを使ってThemeを切り替えた表示をStorybook上で実現する方法をまとめました。サンプルはPageのみにStoryを追加しましたが、Atoms, Molecures別にStoryを追加した場合でも同様にThemeを切り替えてStorybook上でUIを確認できるので複数Themeの要件があるプロジェクトではとても便利です。何かの参考になれれば幸いです。









