import * as React from 'react';
import PropTypes from 'prop-types';
import Menu, { menuClasses } from '@mui/joy/Menu';
import MenuItem from '@mui/joy/MenuItem';
import IconButton from '@mui/joy/IconButton';
import List from '@mui/joy/List';
import ListItem from '@mui/joy/ListItem';
import Sheet from '@mui/joy/Sheet';
import Apps from '@mui/icons-material/Apps';
import Settings from '@mui/icons-material/Settings';
import Person from '@mui/icons-material/Person';
import Dropdown from '@mui/joy/Dropdown';
import MenuButton from '@mui/joy/MenuButton';
// The Menu is built on top of Popper v2, so it accepts `modifiers` prop that will be passed to the Popper.
// https://popper.js.org/docs/v2/modifiers/offset/
const modifiers = [
{
name: 'offset',
options: {
offset: ({ placement }) => {
if (placement.includes('end')) {
return [8, 20];
}
return [-8, 20];
},
},
},
];
function NavMenuButton({
children,
menu,
open,
onOpen,
onLeaveMenu,
label,
...props
}) {
const isOnButton = React.useRef(false);
const internalOpen = React.useRef(open);
const handleButtonKeyDown = (event) => {
internalOpen.current = open;
if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
event.preventDefault();
onOpen(event);
}
};
return (
{
if (isOpen) {
onOpen?.();
}
}}
>
{
internalOpen.current = open;
}}
onClick={() => {
if (!internalOpen.current) {
onOpen();
}
}}
onMouseEnter={() => {
onOpen();
isOnButton.current = true;
}}
onMouseLeave={() => {
isOnButton.current = false;
}}
onKeyDown={handleButtonKeyDown}
sx={[
{
'&:focus-visible': {
bgcolor: 'neutral.plainHoverBg',
},
},
open ? { bgcolor: 'neutral.plainHoverBg' } : { bgcolor: null },
]}
>
{children}
{React.cloneElement(menu, {
onMouseLeave: () => {
onLeaveMenu(() => isOnButton.current);
},
modifiers,
slotProps: {
listbox: {
id: `nav-example-menu-${label}`,
'aria-label': label,
},
},
placement: 'right-start',
sx: {
width: 288,
[`& .${menuClasses.listbox}`]: {
'--List-padding': 'var(--ListDivider-gap)',
},
},
})}
);
}
NavMenuButton.propTypes = {
children: PropTypes.node,
label: PropTypes.string.isRequired,
menu: PropTypes.element.isRequired,
onLeaveMenu: PropTypes.func.isRequired,
onOpen: PropTypes.func.isRequired,
open: PropTypes.bool.isRequired,
};
export default function MenuIconSideNavExample() {
const [menuIndex, setMenuIndex] = React.useState(null);
const itemProps = {
onClick: () => setMenuIndex(null),
};
const createHandleLeaveMenu = (index) => (getIsOnButton) => {
setTimeout(() => {
const isOnButton = getIsOnButton();
if (!isOnButton) {
setMenuIndex((latestIndex) => {
if (index === latestIndex) {
return null;
}
return latestIndex;
});
}
}, 200);
};
return (
setMenuIndex(0)}
onLeaveMenu={createHandleLeaveMenu(0)}
menu={
}
>
setMenuIndex(1)}
onLeaveMenu={createHandleLeaveMenu(1)}
menu={
}
>
setMenuIndex(2)}
onLeaveMenu={createHandleLeaveMenu(2)}
menu={
}
>
);
}