【React】StorybookにMUIのカスタムテーマを反映させる
MUIのカスタムテーマをStorybookに反映させようとした際に、themeProvider
で囲むだけでは反映されず、設定を変更する必要があったので共有です。
前提
環境
package.json
{
"name": "mui-storybook-sample",
"private": true,
"version": "0.0.0",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"preview": "vite preview",
"storybook": "start-storybook -p 6006",
"build-storybook": "build-storybook"
},
"dependencies": {
"@emotion/react": "^11.8.2",
"@emotion/styled": "^11.8.1",
"@mui/material": "^5.5.2",
"react": "^17.0.2",
"react-dom": "^17.0.2"
},
"devDependencies": {
"@babel/core": "^7.17.8",
"@storybook/addon-actions": "^6.4.19",
"@storybook/addon-essentials": "^6.4.19",
"@storybook/addon-interactions": "^6.4.19",
"@storybook/addon-links": "^6.4.19",
"@storybook/react": "^6.4.19",
"@storybook/testing-library": "^0.0.9",
"@types/react": "^17.0.33",
"@types/react-dom": "^17.0.10",
"@vitejs/plugin-react": "^1.0.7",
"babel-loader": "^8.2.4",
"typescript": "^4.5.4",
"vite": "^2.8.0"
}
}
環境構築ログ
# react, typescript
$ npm create vite@latest mui-storybook-sample -- --template react-ts
$ cd mui-storybook-sample && npm i
# MUI install
$ npm install @mui/material @emotion/react @emotion/styled
# Storybook install
$ npx -p @storybook/cli sb init
MUIのカスタムテーマ
今回はprimaryカラーをデフォルトの青から緑に変更しています。
import { createTheme } from "@mui/material/styles";
import { green } from "@mui/material/colors";
export const theme = createTheme({
palette: {
primary: {
main: green[500],
},
},
});
App.tsx
App.tsx
は今回の本質ではないので無くても良いのですが、カスタムテーマの反映方法として載せておきます。
MUIでカスタムテーマを反映するには、ThemeProvider
コンポーネントで表示領域を囲む必要がります。
import Button from "@mui/material/Button";
import { ThemeProvider } from "@mui/material/styles";
import { theme } from "./theme";
function App() {
return (
<ThemeProvider theme={theme}>
<div className="App">
<Button variant="contained">Contained</Button>
</div>
</ThemeProvider>
);
}
export default App;
プレビューすると以下のようにプライマリーカラーが緑になっていることが確認できます。
Storybookにカスタムテーマを反映させる
ストーリーを作る
MUIのボタンを表示するために、Button.stories.tsx
を作成します。
import { ComponentStory, ComponentMeta } from "@storybook/react";
import Button from "@mui/material/Button";
export default {
title: "MUI/Button",
component: Button,
} as ComponentMeta<typeof Button>;
const Template: ComponentStory<typeof Button> = (args) => <Button {...args} />;
export const Primary = Template.bind({});
Primary.args = {
children: "Button",
color: "primary",
variant: "contained",
};
Button.stories.tsx
を作成したら以下コマンドでプレビューを表示します。
$ npm run storybook
このように、Buttonコンポーネントは表示されますが、カスタムテーマが反映されていないので、カスタムテーマを反映させる設定を追加していきます。
カスタムテーマを反映させる
Storybookの設定を追加するには.storybook
ディレクトリにあるpreciew.js
とmain.js
を修正します。
preview.jsにThemeProviderを記述
Storybookのデコレータという機能を使って、Storybookのプレビュー全体をMUIのThemeProvider
コンポーネントで囲みます。
+ import { ThemeProvider } from "@mui/material/styles";
+ import { theme } from "/src/theme";
+ export const decorators = [
+ (Story) => {
+ return (
+ <ThemeProvider theme={theme}>
+ <Story />
+ </ThemeProvider>
+ );
+ },
+ ];
export const parameters = {
actions: { argTypesRegex: "^on[A-Z].*" },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
};
MaterialUI (v4系)まではこれでカスタムテーマが反映されていたのですが、MUI(v5系)からは更にmain.js
に設定を加える必要があります。
main.jsの設定を変更
features
というプロパティのemotionAlias
をfalse
にします。
module.exports = {
stories: ["../src/**/*.stories.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
addons: [
"@storybook/addon-links",
"@storybook/addon-essentials",
"@storybook/addon-interactions",
],
framework: "@storybook/react",
+ features: {
+ emotionAlias: false,
+ },
};
StorybookのライブサーバをCtrl+Cでキャンセルし、再度npm run storybook
を実行すると、以下のようにカスタムテーマが反映されたプレビューが表示されます。
Discussion