如何在 Storybook 中主题化 Material UI

Asi*_*ani 4 reactjs material-ui 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>
  )
}
Run Code Online (Sandbox Code Playgroud)

我试图弄清楚如何在 Storybook 中在全球范围内做到这一点。这是我构建的第一个组件,名为Button. 所以我希望能够将主题放在一个外部文件中,并ThemeProvider在更高级别上输入,这样我就不必包装每个组件。希望这是有道理的,如果有人有任何想法。

小智 20

这是对我来说唯一适用于 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
Run Code Online (Sandbox Code Playgroud)

它来自 MUI 迁移指南,但我花了不必要的时间才找到,所以我想在这里分享它: https: //mui.com/guides/migration-v4/


Hug*_*ugo 13

首先,我建议您将您的主题移动到一个单独的文件中(例如,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
  }
})
Run Code Online (Sandbox Code Playgroud)

然后,您需要像设置 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>
));
Run Code Online (Sandbox Code Playgroud)

它将把你所有的故事都包裹在ThemeProvider.

在您的应用程序中,您还可以拥有一个全局App组件,它将整个应用程序封装在ThemeProvider

更多帮助:https : //storybook.js.org/docs/basics/writing-stories/

  • 对于 Storybook v6 的新版本,使用这样的导出 const 装饰器 = [&lt;ThemeProvider theme={muiTheme}&gt;{story()}&lt;/ThemeProvider&gt;] (2认同)

Yod*_*ese 13

对于 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>
  ),
];

Run Code Online (Sandbox Code Playgroud)

有关如何装饰故事的更多详细信息,请访问: https ://storybook.js.org/docs/react/writing-stories/decorators

并在此处为 Material UI 创建主题: https ://material-ui.com/customization/theming/