如何在 Storybook 中设置主题 Material UI
How to theme Material UI inside Storybook
目前这就是我正在做的,在我的组件文件上方传递一个 ThemeProvider
:
import React from 'react';
import { ThemeProvider, createMuiTheme } from '@material-ui/core/styles';
import MUIButton from '@material-ui/core/Button';
const theme = createMuiTheme({
palette: {
primary: {
main: "#ff0000"
}
},
typography: {
fontFamily: 'Nunito Sans, sans-serif',
button: {
textTransform: 'none'
}
},
shape: {
borderRadius: 3
}
})
export default ({ variant, children }) => {
return (
<ThemeProvider theme={theme}>
<MUIButton
color="primary"
variant={variant}
>
{children}
</MUIButton>
</ThemeProvider>
)
}
我想弄清楚如何在 Storybook 中在全球范围内做到这一点。这是我构建的第一个组件,名为 Button
。所以我希望能够将主题放在外部文件中,并让 ThemeProvider
进入更高级别,这样我就不必包装每个组件。希望这是有道理的,如果有人有任何想法。
首先,我建议您将主题移动到一个单独的文件中(例如 src/stylesheet
,这样您就可以从不同的文件(全局 App
组件和故事书预览文件)访问它。
// src/stylesheet.ts
import { createMuiTheme } from '@material-ui/core/styles';
export const muiTheme = createMuiTheme({
palette: {
primary: {
main: "#ff0000"
}
},
typography: {
fontFamily: 'Nunito Sans, sans-serif',
button: {
textTransform: 'none'
}
},
shape: {
borderRadius: 3
}
})
然后,您需要像设置 React 应用程序一样设置您的故事书。为此,请尝试创建一个名为:
.storybook/preview.js
并将其放入其中:
// .storybook/preview.js
import React from 'react';
import { addDecorator } from '@storybook/react';
import { ThemeProvider } from '@material-ui/core/styles';
import { muiTheme } from '../src/stylesheet';
addDecorator((story) => (
<ThemeProvider theme={muiTheme}>{story()}</ThemeProvider>
));
它会将您所有的故事都包装在 ThemeProvider
中。
在您的应用中,您还可以拥有一个全局 App
组件,它将整个应用封装在 ThemeProvider
对于 Storybook 6.3+,它应该如下所示
更新 preview.js 为:
import React from 'react';
import { theme } from './src/theme'; // whereever you have defined your material ui theme
export const decorators = [
Story => (
<ThemeProvider theme={theme}>
<Story />
</ThemeProvider>
),
];
有关如何装饰您的故事的更多详细信息,请点击此处:
https://storybook.js.org/docs/react/writing-stories/decorators
并在此处为 Material UI 创建主题:
https://material-ui.com/customization/theming/
这是唯一适用于 MUI v5 的解决方案:
// .storybook/main.js
const path = require('path');
const toPath = (filePath) => path.join(process.cwd(), filePath);
module.exports = {
webpackFinal: async (config) => {
return {
...config,
resolve: {
...config.resolve,
alias: {
...config.resolve.alias,
'@emotion/core': toPath('node_modules/@emotion/react'),
'emotion-theming': toPath('node_modules/@emotion/react'),
},
},
};
},
};
// .storybook/preview.js
import { ThemeProvider, createTheme } from '@mui/material/styles';
import { ThemeProvider as Emotion10ThemeProvider } from 'emotion-theming';
const defaultTheme = createTheme(); // or your custom theme
const withThemeProvider = (Story, context) => {
return (
<Emotion10ThemeProvider theme={defaultTheme}>
<ThemeProvider theme={defaultTheme}>
<Story {...context} />
</ThemeProvider>
</Emotion10ThemeProvider>
);
};
export const decorators = [withThemeProvider];
// ...other storybook exports
它来自 MUI 迁移指南,但我花了不必要的时间才找到它,所以我想在这里分享它:
https://mui.com/guides/migration-v4/
这适用于我 react-router 和 mui V5
我的preview.js=>
import React from 'react';
import { addDecorator } from '@storybook/react';
import { MemoryRouter } from 'react-router';
import { ThemeProvider } from '@mui/material/styles';
import { ThemeProvider as Emotion10ThemeProvider } from 'emotion-theming';
import customTheme from '../src/theme/index';
addDecorator((story) => (
<Emotion10ThemeProvider theme={customTheme}>
<ThemeProvider theme={customTheme}>
<MemoryRouter initialEntries={['/']}>{story()}</MemoryRouter>
</ThemeProvider>
</Emotion10ThemeProvider>
));
export const parameters = {
actions: { argTypesRegex: '^on[A-Z].*' },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
};
目前这就是我正在做的,在我的组件文件上方传递一个 ThemeProvider
:
import React from 'react';
import { ThemeProvider, createMuiTheme } from '@material-ui/core/styles';
import MUIButton from '@material-ui/core/Button';
const theme = createMuiTheme({
palette: {
primary: {
main: "#ff0000"
}
},
typography: {
fontFamily: 'Nunito Sans, sans-serif',
button: {
textTransform: 'none'
}
},
shape: {
borderRadius: 3
}
})
export default ({ variant, children }) => {
return (
<ThemeProvider theme={theme}>
<MUIButton
color="primary"
variant={variant}
>
{children}
</MUIButton>
</ThemeProvider>
)
}
我想弄清楚如何在 Storybook 中在全球范围内做到这一点。这是我构建的第一个组件,名为 Button
。所以我希望能够将主题放在外部文件中,并让 ThemeProvider
进入更高级别,这样我就不必包装每个组件。希望这是有道理的,如果有人有任何想法。
首先,我建议您将主题移动到一个单独的文件中(例如 src/stylesheet
,这样您就可以从不同的文件(全局 App
组件和故事书预览文件)访问它。
// src/stylesheet.ts
import { createMuiTheme } from '@material-ui/core/styles';
export const muiTheme = createMuiTheme({
palette: {
primary: {
main: "#ff0000"
}
},
typography: {
fontFamily: 'Nunito Sans, sans-serif',
button: {
textTransform: 'none'
}
},
shape: {
borderRadius: 3
}
})
然后,您需要像设置 React 应用程序一样设置您的故事书。为此,请尝试创建一个名为:
.storybook/preview.js
并将其放入其中:
// .storybook/preview.js
import React from 'react';
import { addDecorator } from '@storybook/react';
import { ThemeProvider } from '@material-ui/core/styles';
import { muiTheme } from '../src/stylesheet';
addDecorator((story) => (
<ThemeProvider theme={muiTheme}>{story()}</ThemeProvider>
));
它会将您所有的故事都包装在 ThemeProvider
中。
在您的应用中,您还可以拥有一个全局 App
组件,它将整个应用封装在 ThemeProvider
对于 Storybook 6.3+,它应该如下所示
更新 preview.js 为:
import React from 'react';
import { theme } from './src/theme'; // whereever you have defined your material ui theme
export const decorators = [
Story => (
<ThemeProvider theme={theme}>
<Story />
</ThemeProvider>
),
];
有关如何装饰您的故事的更多详细信息,请点击此处: https://storybook.js.org/docs/react/writing-stories/decorators
并在此处为 Material UI 创建主题: https://material-ui.com/customization/theming/
这是唯一适用于 MUI v5 的解决方案:
// .storybook/main.js
const path = require('path');
const toPath = (filePath) => path.join(process.cwd(), filePath);
module.exports = {
webpackFinal: async (config) => {
return {
...config,
resolve: {
...config.resolve,
alias: {
...config.resolve.alias,
'@emotion/core': toPath('node_modules/@emotion/react'),
'emotion-theming': toPath('node_modules/@emotion/react'),
},
},
};
},
};
// .storybook/preview.js
import { ThemeProvider, createTheme } from '@mui/material/styles';
import { ThemeProvider as Emotion10ThemeProvider } from 'emotion-theming';
const defaultTheme = createTheme(); // or your custom theme
const withThemeProvider = (Story, context) => {
return (
<Emotion10ThemeProvider theme={defaultTheme}>
<ThemeProvider theme={defaultTheme}>
<Story {...context} />
</ThemeProvider>
</Emotion10ThemeProvider>
);
};
export const decorators = [withThemeProvider];
// ...other storybook exports
它来自 MUI 迁移指南,但我花了不必要的时间才找到它,所以我想在这里分享它: https://mui.com/guides/migration-v4/
这适用于我 react-router 和 mui V5
我的preview.js=>
import React from 'react';
import { addDecorator } from '@storybook/react';
import { MemoryRouter } from 'react-router';
import { ThemeProvider } from '@mui/material/styles';
import { ThemeProvider as Emotion10ThemeProvider } from 'emotion-theming';
import customTheme from '../src/theme/index';
addDecorator((story) => (
<Emotion10ThemeProvider theme={customTheme}>
<ThemeProvider theme={customTheme}>
<MemoryRouter initialEntries={['/']}>{story()}</MemoryRouter>
</ThemeProvider>
</Emotion10ThemeProvider>
));
export const parameters = {
actions: { argTypesRegex: '^on[A-Z].*' },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
};