MUI自定义主题颜色未在Storybook按钮组件下拉选项中显示
MUI自定义颜色未显示在Storybook按钮color下拉列表的解决思路
我使用React 18、TypeScript、MUI 5和Storybook 6.5,尝试为MUI主题添加自定义颜色myCustomColor,MaterialButton硬编码使用该颜色时功能正常,但该选项未出现在Storybook按钮组件的color属性下拉列表中。已按MUI文档完成模块扩展,以下是相关代码及解决思路:
相关代码文件
src/styles/theme.ts
import { createTheme } from "@mui/material"; export const theme = createTheme({ palette: { myCustomColor: { main: '#ff5555', contrastText: '#fff', }, }, });
src/styles/expanded-theme.ts
import '@mui/material/styles'; import '@mui/material/Button'; declare module '@mui/material/styles/createPalette' { interface Palette { myCustomColor: Palette['primary']; } interface PaletteOptions { myCustomColor?: PaletteOptions['primary']; } } declare module '@mui/material/Button/Button' { interface ButtonPropsColorOverrides { myCustomColor: true; } }
src/components/Button.tsx
import React from "react"; import { Button as MaterialButton } from "@mui/material"; import type { ButtonProps as MuiButtonProps } from "@mui/material"; export interface ButtonProps extends MuiButtonProps { label: string; onClick: React.MouseEventHandler<HTMLButtonElement>; } export const Button = (props: ButtonProps) => { const { label } = props; return <MaterialButton {...props}>{label}</MaterialButton>; };
.storybook/preview.js
import { CssBaseline, ThemeProvider } from "@mui/material"; import { Story } from "@storybook/react"; import { theme } from "../src/styles/theme"; export const parameters = { actions: { argTypesRegex: "^on[A-Z].*" }, controls: { expanded: true, // Adds the description and default columns matchers: { color: /(background|color)$/i, date: /Date$/, }, }, }; export const withMuiTheme = (Story) => { return ( <ThemeProvider theme={theme}> <CssBaseline /> <Story /> </ThemeProvider> ); }; export const decorators = [withMuiTheme];
.storybook/main.js
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", core: { builder: "@storybook/builder-webpack5", }, typescript: { check: false, checkOptions: {}, reactDocgen: "react-docgen-typescript", reactDocgenTypescriptOptions: { allowSyntheticDefaultImports: false, // speeds up storybook build time esModuleInterop: false, // speeds up storybook build time shouldExtractLiteralValuesFromEnum: true, // makes union prop types like variant and size appear as select controls shouldRemoveUndefinedFromOptional: true, // makes string and boolean types that can be undefined appear as inputs and switches savePropValueAsString: true, propFilter: (prop) => (prop.parent ? !/node_modules/.test(prop.parent.fileName) : true), }, }, };
解决思路
1. 确保类型扩展文件被组件导入
React-docgen-typescript无法自动识别未被引用的类型扩展文件,需在Button.tsx顶部导入expanded-theme.ts,让TypeScript将扩展类型纳入组件的类型定义:
import '../styles/expanded-theme';
2. 调整react-docgen-typescript的propFilter配置
当前配置的propFilter排除了所有node_modules文件,导致MUI的扩展类型未被识别。修改配置,保留MUI相关文件的类型解析:
reactDocgenTypescriptOptions: { // ... 其他配置 propFilter: (prop) => (prop.parent ? !/node_modules\/(?!@mui)/.test(prop.parent.fileName) : true) }
该配置会排除除@mui外的其他node_modules文件,确保自定义的ButtonPropsColorOverrides被识别。
3. 手动在Story中指定color选项
若上述方法无效,可在按钮的Story文件中手动定义color属性的可选值:
import { Button } from './Button'; export default { title: 'Components/Button', component: Button, argTypes: { color: { options: ['primary', 'secondary', 'error', 'myCustomColor'], control: { type: 'select' }, }, }, }; // 模板示例 const Template = (args) => <Button {...args} />; export const Default = Template.bind({}); Default.args = { label: 'Default Button', color: 'primary', };
4. 检查依赖版本与React-docgen模式
确保react-docgen-typescript为最新版本,若问题仍存在,可尝试将Storybook的reactDocgen切换为react-docgen(需注意可能丢失部分TypeScript特性)。
内容的提问来源于stack exchange,提问作者prismus
相关产品推荐
相关产品推荐

