我是 React 新手。我有一个自定义 MUI 菜单组件,它有两种类型的菜单;
'menuitem-group' and 'menugroup-section'
在菜单标题中,会有一些类型为“menugroup-section”的菜单。
有没有办法让菜单项分为 4 列,类型为“menugroup-section”,即
<MenuGroupSection>
?
这是菜单代码;
export const Menu = ({ id, label, menuVariant, sections, popoutProps }: MenuProps) => {
const [anchorEl, setAnchorEl] = useState(null);
const isOpen = Boolean(anchorEl);
const handleClick = (event: any) => {
// Ensure previous menu closes when we click on sibling menus
(document.querySelector('.MuiModal-backdrop') as HTMLElement)?.click();
if (anchorEl === event.currentTarget) {
setAnchorEl(null);
} else {
setAnchorEl(event.currentTarget);
}
};
const handleClose = () => {
setAnchorEl(null);
};
function handleItemClick(i: MenuItemNode) {
if (i.onClick) {
i.onClick(i);
}
if (i.url) {
window.location.href = i.url;
}
handleClose();
}
let backgroundColor: string = 'none';
switch (menuVariant) {
case 'primary':
backgroundColor = 'grey';
break;
case 'secondary-color':
backgroundColor = 'grey';
break;
case 'tertiary':
backgroundColor = 'none';
break;
case 'secondary-white':
default:
backgroundColor = 'white';
break;
}
return (
<Box sx={{ display: 'flex', backgroundColor: backgroundColor }} className={isOpen ? 'raisedMenu' : ''}>
<MenuButton
id={id}
isOpen={isOpen}
aria-controls={`${id}-menu`}
aria-haspopup="true"
menuVariant={menuVariant}
onClick={handleClick}
>
<Typography variant="body3">{label}</Typography>
</MenuButton>
<Menu
PaperProps={{ sx: { maxHeight: '70%' } }}
id={`${id}-menu`}
anchorEl={anchorEl}
open={isOpen}
onClose={handleClose}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'left',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'left',
}}
elevation={5}
sx={{
marginTop: '1px',
paddingTop: '8px',
paddingLeft: '8px',
paddingRight: '8px',
paddingBottom: '12px',
'& .MuiList-root': { flexWrap: 'wrap', display:'grid' , gridTemplateColumns : 'auto auto auto auto', gap: '32px'},
...popoutProps,
}}
marginThreshold={5}
>
{sections &&
sections.map((section, index) => {
if (section.type === 'menugroup-section') {
return (
<MenuGroupSection
key={index}
label={section.label}
groups={section.items as MenuSectionNode[]}
menuVariant={menuVariant}
onItemClick={(i) => handleItemClick(i)}
></MenuGroupSection>
);
} else if (section.type === 'menuitem-group') {
return (
<MenuItemGroup
key={index}
label={section.label}
items={section.items as MenuItemNode[]}
menuVariant={menuVariant}
onItemClick={(i) => handleItemClick(i)}
></MenuItemGroup>
);
} else {
return (
<MenuItemGroup
key={index}
label={section.label}
items={section.items as MenuItemNode[]}
onItemClick={handleClose}
menuVariant={menuVariant}
></MenuItemGroup>
);
}
})}
</Menu>
</Box>
);
};
要在“menugroup-section”类型的四列中显示菜单项,您可以修改 MenuGroupSection 组件内部的渲染逻辑。您将需要计算每列的项目数并相应地呈现它们。以下是实现这一目标的方法:
import React from 'react';
import { Grid } from '@mui/material';
import MenuItemNode from './MenuItemNode'; // Import your MenuItemNode type
const MenuGroupSection = ({ label, groups, menuVariant, onItemClick }: any) => {
// Calculate number of items per column
const itemsPerColumn = Math.ceil(groups.length / 4);
return (
<>
<div style={{ marginBottom: '8px' }}>
<Typography variant="subtitle1">{label}</Typography>
</div>
<Grid container spacing={2}>
{/* Render menu items in four columns */}
{Array.from({ length: 4 }).map((_, columnIndex) => (
<Grid item xs={3} key={columnIndex}>
<div>
{groups.slice(columnIndex * itemsPerColumn, (columnIndex + 1) * itemsPerColumn).map((item: MenuItemNode, index: number) => (
<div key={index}>
<MenuItem
onClick={() => onItemClick(item)}
>
{item.label}
</MenuItem>
</div>
))}
</div>
</Grid>
))}
</Grid>
</>
);
};
export default MenuGroupSection;
此修改后的 MenuGroupSection 组件将在四列中呈现菜单项。根据您的布局要求调整 Grid 组件的 xs 值。这假设 MenuItemNode 类型包含必要的属性,例如 label 和 onClick。