如何在React MUI组件中使用自定义Theme的marginAutoItem属性?
如何将自定义主题属性应用到MUI的CircularProgress组件?
我想要居中CircularProgress元素,为了样式复用,已经创建了theme.d.ts扩展MUI主题:
import { Theme, ThemeOptions } from '@mui/material/styles' declare module '@mui/material/styles' { interface CustomTheme extends Theme { marginAutoItem: { margin: string; }; } // allow configuration using `createTheme` interface CustomThemeOptions extends ThemeOptions { marginAutoItem: { margin?: string; }; } export function createTheme(options?: CustomThemeOptions): CustomTheme; }
接着创建了自定义主题并配置参数:
const theme = responsiveFontSizes(createTheme({ palette: { primary: { main: "#626262", }, secondary: { main: "#DFDFDF", }, }, typography: { fontFamily: [ 'Arial Regular', 'sans' ].join(','), }, marginAutoItem: { margin: 'auto' } })); const container = document.getElementById('root'); const root = createRoot(container as Element); root.render( <React.StrictMode> <StyledEngineProvider injectFirst> <ThemeProvider theme={theme}> <App /> </ThemeProvider> </StyledEngineProvider> </React.StrictMode> );
现在希望实现<CircularProgress marginAutoItem />这样的用法,把自定义主题里的marginAutoItem属性应用到组件上,请问该怎么做?
实现方法
要实现你想要的<CircularProgress marginAutoItem />用法,得做两件事:先让TypeScript识别这个自定义属性,再把主题里的样式绑定到组件上。
1. 给CircularProgress扩展Props类型
在你已有的theme.d.ts里,加一段代码扩展CircularProgress的属性,这样TypeScript不会报错:
import { CircularProgressProps } from '@mui/material/CircularProgress'; declare module '@mui/material/CircularProgress' { interface CircularProgressProps { marginAutoItem?: boolean; } }
2. 两种绑定样式的方式
方式一:封装自定义组件(灵活可控)
写一个简单的自定义组件,判断marginAutoItem属性是否存在,存在就套用主题里的样式:
import { CircularProgress, useTheme } from '@mui/material'; const CustomCircularProgress = ({ marginAutoItem, ...props }) => { const theme = useTheme(); // 当开启marginAutoItem时,合并主题样式和传入的sx const mergedSx = marginAutoItem ? { margin: theme.marginAutoItem.margin, ...props.sx } : props.sx; return <CircularProgress sx={mergedSx} {...props} />; }; // 用的时候直接用这个自定义组件 <CustomCircularProgress marginAutoItem />
方式二:全局配置主题(不用额外封装组件)
如果你不想单独写组件,也可以在创建主题时直接配置CircularProgress的样式规则,通过props来触发:
const theme = responsiveFontSizes(createTheme({ // 你的原有主题配置... marginAutoItem: { margin: 'auto' }, components: { MuiCircularProgress: { styleOverrides: { root: ({ ownerState, theme }) => { // 当组件props里有marginAutoItem时,应用主题样式 if (ownerState.marginAutoItem) { return { margin: theme.marginAutoItem.margin }; } return {}; } } } } }));
这样配置完,直接用<CircularProgress marginAutoItem />就能让组件自动居中,完全符合你的预期用法。
内容的提问来源于stack exchange,提问作者Taavi Ansper
相关产品推荐
相关产品推荐

