如何在 MUI 菜单组件上应用自定义样式表 - React

问题描述 投票:0回答:1

我是 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>
  );
};
css reactjs material-ui styled-components
1个回答
0
投票

要在“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。

© www.soinside.com 2019 - 2024. All rights reserved.