import * as React from 'react'; import JoyMenu, { MenuActions } from '@mui/joy/Menu'; import MenuItem from '@mui/joy/MenuItem'; import { ListActionTypes } from '@mui/base/useList'; export default function Menu(props: { control: React.ReactElement; id: string; menus: Array<{ label: string } & { [k: string]: any }>; }) { const { control, menus, id } = props; const [buttonElement, setButtonElement] = React.useState( null, ); const [isOpen, setOpen] = React.useState(false); const buttonRef = React.useRef(null); const menuActions = React.useRef(null); const preventReopen = React.useRef(false); const updateAnchor = React.useCallback((node: HTMLButtonElement | null) => { setButtonElement(node); }, []); const handleButtonClick = (event: React.MouseEvent) => { if (preventReopen.current) { event.preventDefault(); preventReopen.current = false; return; } setOpen((open) => !open); }; const handleButtonKeyDown = (event: React.KeyboardEvent) => { if (event.key === 'ArrowDown' || event.key === 'ArrowUp') { event.preventDefault(); setOpen(true); if (event.key === 'ArrowUp') { menuActions.current?.dispatch({ type: ListActionTypes.keyDown, key: event.key, event, }); } } }; const close = () => { setOpen(false); buttonRef.current!.focus(); }; return ( {React.cloneElement(control, { type: 'button', onClick: handleButtonClick, onKeyDown: handleButtonKeyDown, ref: updateAnchor, 'aria-controls': isOpen ? id : undefined, 'aria-expanded': isOpen || undefined, 'aria-haspopup': 'menu', })} {menus.map(({ label, active, ...item }) => { const menuItem = ( {label} ); if (item.href) { return (
  • {React.cloneElement(menuItem, { component: 'a' })}
  • ); } return React.cloneElement(menuItem, { key: label }); })}
    ); }