UNPKG

orchetera

Version:

Welcome to **Orchetera** — your orchestration tool to kickstart Firebase-ready projects with ease!

177 lines (161 loc) 4.45 kB
import { useEffect, useState } from "react"; import { List, ListItem, ListItemButton, ListItemIcon, ListItemText, Collapse, Paper, Popper, Divider, } from "@mui/material"; import { useTheme } from "@mui/material/styles"; import { ExpandLess, ExpandMore } from "@mui/icons-material"; const MultiLevelMenu = ({ menuData, open }) => { return ( <List component="nav" sx={{ width: 250 }}> {menuData.map((menuItem, index) => ( <MenuItem sidebarOpen={open} key={index} item={menuItem} level={1} /> ))} </List> ); }; const MenuItem = ({ item, level, sidebarOpen }) => { const theme = useTheme(); const [open, setOpen] = useState(false); const [anchorEl, setAnchorEl] = useState(null); const [popoverOpen, setPopoverOpen] = useState(false); const [popoverHovered, setPopoverHovered] = useState(true); const hasChildren = item.children && item.children.length > 0; const isPopoverLevel = level >= 3; const handleClick = () => { console.log("sidebarOpen", sidebarOpen); if (!sidebarOpen) return; if (isPopoverLevel) return; setOpen(!open); }; const handleMouseEnter = (event) => { if (!sidebarOpen) return; if (isPopoverLevel) { setAnchorEl(event.currentTarget); setPopoverOpen(true); } }; const handleMouseLeave = () => { if (!sidebarOpen) return; if (isPopoverLevel && !popoverHovered) { setPopoverOpen(false); } }; const handlePopoverEnter = () => { if (!sidebarOpen) return; setPopoverHovered(true); }; const handlePopoverLeave = () => { if (!sidebarOpen) return; setPopoverHovered(false); setPopoverOpen(false); }; useEffect(() => { if (!sidebarOpen) { setOpen(false); setPopoverHovered(false); setPopoverOpen(false); } console.log("sidebarUseeffect", sidebarOpen); }, [sidebarOpen]); return ( <> <ListItem disablePadding onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave} sx={{ display: "block" }} > <ListItemButton onClick={handleClick} sx={{ // pl: level * 2, minHeight: 48, justifyContent: "initial", px: 2.5, "&:hover": { backgroundColor: "action.hover", }, }} // selected={true} > {item.icon && ( <ListItemIcon sx={{ color: theme.palette.primary.contrastText, minWidth: 0, mr: 3, justifyContent: "center", }} > {item.icon} </ListItemIcon> )} <ListItemText primary={item.name} sx={{ opacity: 1 }} /> {hasChildren && !isPopoverLevel && (open ? <ExpandLess /> : <ExpandMore />)} </ListItemButton> </ListItem> {hasChildren && !isPopoverLevel && ( <Collapse in={open} timeout="auto" unmountOnExit> <List component="div" disablePadding> {item.children.map((child, idx) => ( <MenuItem sidebarOpen={open} key={idx} item={child} level={level + 1} /> ))} </List> </Collapse> )} {hasChildren && isPopoverLevel && ( <Popper open={popoverOpen} onMouseEnter={handlePopoverEnter} onMouseLeave={handlePopoverLeave} anchorEl={anchorEl} placement={level % 2 === 0 ? "right-start" : "right-end"} modifiers={[ { name: "offset", options: { offset: [0, 0], }, }, ]} sx={{ zIndex: 1300, marginLeft: "-10px !important", "&.MuiPopper-root": { marginLeft: "-10px !important", }, }} > <Paper elevation={3} sx={{ minWidth: 200 }}> <List> {item.children.map((child, idx) => ( <MenuItem sidebarOpen={open} key={idx} item={child} level={level + 1} /> ))} </List> </Paper> </Popper> )} </> ); }; export default MultiLevelMenu;