import * as React from "react"; import { PortalWrapper } from "../PortalWrapper"; import { PolymorphicWithRef } from "../types"; import { MenuOwnProps } from "./types"; import MenuBase from "./MenuBase"; import { MenuItem } from "../MenuItem"; import { useIsomorphicLayoutEffect, useOnClickOutside } from "../hooks"; import { usePopper } from "react-popper"; type ItemProps = { icon: React.ComponentProps; label: React.ComponentProps; }; type MenuProps = PolymorphicWithRef< T, MenuOwnProps & { children: (Item: typeof MenuItem, props: ItemProps) => React.ReactNode; } >; type MenuElement = ( props: MenuProps ) => React.ReactElement>; const Menu: MenuElement = React.forwardRef( >( props: MenuProps, innerRef: typeof props.ref ) => { // props const { component, anchorEl, open, onClose, placement = "bottom", children, ...rest } = props; const [menuRef, setMenuRef] = React.useState(null); const [container, setContainer] = React.useState(); React.useImperativeHandle(innerRef, () => Boolean(menuRef) && menuRef); const { styles, attributes } = usePopper(anchorEl, menuRef, { placement, modifiers: [ { name: "preventOverflow", options: { boundary: container, }, }, ], }); useOnClickOutside(menuRef, () => { if (open) { onClose && onClose(); } }); useIsomorphicLayoutEffect(() => { setContainer(document.querySelector("[data-container]") as HTMLElement); }, []); return ( {() => (
{children(MenuItem, { // Default configuration icon: { size: "medium" }, label: { variant: "body1", size: "large", component: "span" }, })}
)}
); } ); export default Menu;