MUI v5 + Storybook 自定义主题及font family配置不生效问题
核心原因
主要是2个常见配置问题导致:
- MUI v5默认使用Emotion作为样式引擎,你的项目中同时使用了styled-components,两个样式引擎的样式注入顺序混乱,Storybook自身的样式、styled-components生成的样式优先级高于MUI主题样式,导致自定义主题配置被覆盖。
- MUI默认会把样式插入到页面head的最顶部,而Storybook加载的全局样式、组件样式都会插入到head靠后的位置,按照CSS优先级规则,后加载的同名样式会覆盖先加载的MUI主题样式。
解决方案
第一步:统一样式引擎,如果你要继续用styled-components,先安装对应的MUI适配包,并且配置别名避免同时加载两个样式引擎:
如果你用yarn,在package.json中添加resolutions配置:{ "resolutions": { "@mui/styled-engine": "npm:@mui/styled-engine-sc@latest" } }如果你用npm,添加overrides配置:
{ "overrides": { "@mui/styled-engine": "npm:@mui/styled-engine-sc@latest" } }配置完后重新安装依赖。
第二步:调整MUI样式注入顺序,自定义MUI的缓存配置,让MUI样式插入到head末尾,提升优先级。你可以修改组件代码,用CacheProvider包裹ThemeProvider:
import React from "react"; import styled from "styled-components"; import { createTheme, ThemeProvider } from "@mui/material/styles"; import { CacheProvider } from "@emotion/react"; import createCache from "@emotion/cache"; import MuiTextField from "@mui/material/TextField"; // 自定义缓存,设置prepend为false,样式插入到head末尾 const cache = createCache({ key: "mui-custom", prepend: false, }); const StyledTextField = styled(MuiTextField)` width: 288px; `; const theme = createTheme({ typography: { allVariants: { fontFamily: "serif", fontSize: "12px", }, }, }); const ThemeProviderMine = () => ( <CacheProvider value={cache}> <ThemeProvider theme={theme}> <StyledTextField placeholder="Foobar" label={"Select a foobar"} /> </ThemeProvider> </CacheProvider> ); export default ThemeProviderMine;第三步(可选):如果你所有组件都需要用到这个MUI主题,直接把主题配置加到Storybook全局装饰器里,不用每个组件单独包ThemeProvider。在
.storybook/preview.js中添加以下配置:import { ThemeProvider, createTheme } from '@mui/material/styles'; import { CacheProvider } from "@emotion/react"; import createCache from "@emotion/cache"; const cache = createCache({ key: "mui-custom", prepend: false, }); const theme = createTheme({ typography: { allVariants: { fontFamily: "serif", fontSize: "12px", }, }, }); export const decorators = [ (Story) => ( <CacheProvider value={cache}> <ThemeProvider theme={theme}> <Story /> </ThemeProvider> </CacheProvider> ), ];
补充说明
如果以上配置完成还不生效,检查是否安装了MUI相关的Storybook插件,插件自带的ThemeProvider优先级更高,会覆盖你自定义的主题配置,修改插件配置使用你的自定义主题即可。
内容的提问来源于stack exchange,提问作者bigpotato
相关产品推荐
相关产品推荐

