import { SyntheticEvent , cloneElement , isValidElement , useCallback , useState , createElement } from 'react' ; import { Menu , PopoverOrigin } from '@mui/material' ; import type { MenuListProps , PaperProps } from '@mui/material' ; import { ShadowRootMenu } from '../shadow-root/ShadowRootComponents' ; import { useUpdate } from 'react-use' ; interface MenuProps { paperProps ? : PaperProps ; menuListProps ? : MenuListProps ; anchorOrigin ? : PopoverOrigin ; transformOrigin ? : PopoverOrigin ; } param menus export function useMenu ( elements , anchorSibling = false , props ? , useShadowRoot = true ) { const [ open , setOpen ] = useState ( false ) ; const [ anchorEl , setAnchorEl ] = useState < HTMLElement | null > ( null ) ; const close = ( ) => { setOpen ( false ) ; setAnchorEl ( null ) ; } ; const update = useUpdate ( ) ; return [ createElement ( useShadowRoot ? ShadowRootMenu : Menu , { PaperProps : props ?. paperProps , MenuListProps : props ?. menuListProps , open , anchorEl , onClose : close , onClick : close , anchorOrigin : props ?. anchorOrigin , transformOrigin : props ?. transformOrigin , } , elements ?. map ( ( element , key ) => isValidElement < object > ( element ) ? cloneElement ( element , { ... element . props , key } ) : element ) ) , useCallback ( ( anchorElOrEvent ) => { let element ; if ( anchorElOrEvent instanceof HTMLElement ) { element = anchorElOrEvent ; } else { element = anchorElOrEvent . currentTarget ; } const finalAnchor = anchorSibling ? ( element . nextElementSibling as HTMLElement ) ?? undefined : element ; setAnchorEl ( finalAnchor ) ; setOpen ( true ) ; window . requestAnimationFrame ( update ) ; } , [ ] ) , ] as const ; }