如何向MUI styled Menu传递props实现条件样式效果?
解决方案
MUI 的 styled 工具支持透传自定义属性到样式回调函数,你只需要显式声明要传入的自定义属性,就可以在样式定义中直接访问做条件判断,不需要把样式定义迁移到组件内部,具体修改如下:
- 给
StyledMenu扩展自定义属性声明,同时在样式回调中接收该属性用于条件判断 - 在
Expandable组件调用StyledMenu时,把当前的type值作为自定义属性传入 - 修正原有代码的语法错误和无效属性值
修改后的完整代码:
import { styled, alpha } from '@mui/material/styles'; import Menu, { MenuProps } from '@mui/material/Menu'; import Box from '@mui/material/Box'; import React, { useContext } from 'react'; // 给styled泛型扩展自定义menuType属性,避免TS类型报错,纯JS环境可删除泛型声明 const StyledMenu = styled((props: MenuProps & { menuType?: string }) => ( <Menu elevation={0} anchorOrigin={{ vertical: 'bottom', horizontal: 200, }} transformOrigin={{ vertical: 'top', horizontal: 'right', }} {...props} /> ))(({ theme, menuType }) => ({ // 修正原rgba无效值,颜色通道最大值为255 backgroundColor: 'rgba(255, 255, 255, 0.455)', backdropFilter: 'blur(1px)', '& .MuiPaper-root': { borderRadius: 3, // 直接在属性值位置做条件判断即可 minWidth: menuType === 'Type' ? 1360 : 250, marginTop: theme.spacing(1), color: theme.palette.mode === 'light' ? 'rgb(55, 65, 81)' : theme.palette.grey[300], boxShadow: 'rgb(255, 255, 255) 0px 0px 0px 0px, rgba(0, 0, 0, 0.05) 0px 0px 0px 1px, rgba(0, 0, 0, 0.1) 0px 10px 15px -3px, rgba(0, 0, 0, 0.05) 0px 4px 6px -2px', '& .MuiMenu-list': { padding: '4px 0', }, '& .MuiMenuItem-root': { '& .MuiSvgIcon-root': { fontSize: 18, color: theme.palette.text.secondary, marginRight: theme.spacing(1.5), }, '&:active': { backgroundColor: alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity), }, }, }, })); interface Props { source: any; type: string; date: string; icon: React.ReactNode; } // 请替换为你的实际上下文定义 const movementsContext = React.createContext<any>(null); export const Expandable: React.FC<Props> = ({ source, type, date, icon }) => { const context = useContext(movementsContext); const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null); const open = Boolean(anchorEl); const handleClick = (event: React.MouseEvent<HTMLElement>) => { setAnchorEl(event.currentTarget); }; const handleClose = () => { setAnchorEl(null); }; return ( <Box style={{ margin: 'auto', display: 'flex', justifyContent: 'center' }}> {/* 把当前type作为menuType属性传给StyledMenu */} <StyledMenu id='demo-customized-menu' menuType={type} MenuListProps={{ 'aria-labelledby': 'demo-customized-button', }} anchorEl={anchorEl} open={open} onClose={handleClose} > {/* 此处放置你的MenuItem子项 */} </StyledMenu> </Box> ); };
内容的提问来源于stack exchange,提问作者Richardson
相关产品推荐
相关产品推荐

