UNPKG

glass-app-manager

Version:

Informatica's Glass Framework CLI for bootstrapping

76 lines (62 loc) 2.39 kB
// @flow import * as React from "react"; import { openMenu, closeMenu, MenuOpener } from "./utils"; export type SubmenuProps = { /** * Children of the submenu. */ children: Node, /** * Label of the menu. */ label: string, }; export default function Submenu({ children, label, disabled }: SubmenuProps) { const [open, setOpen] = React.useState(false); const ref = React.useRef(null); // Close the submenu if the mouse moves to another sibling. const handleMouseMove = React.useCallback(e => { const parentRect = ref.current.parentNode.parentNode.getBoundingClientRect(); const inSameMenu = e.clientX >= parentRect.left && e.clientX <= parentRect.left + parentRect.width && e.clientY >= parentRect.top && e.clientY <= parentRect.top + parentRect.height; const rect = ref.current.getBoundingClientRect(); const inDiffItem = e.clientY < rect.top || e.clientY > rect.top + ref.current.clientHeight; if (inSameMenu && inDiffItem) { closeMenu(open, setOpen); } }); React.useEffect(() => { if (open) { window.addEventListener("mousemove", handleMouseMove); } return () => window.removeEventListener("mousemove", handleMouseMove); }, [open]); return ( <MenuOpener open={open} setOpen={setOpen} position={["right", "start"]} align="start" contentLocation={({ targetRect, popoverRect, position, align, nudgedLeft, nudgedTop }) => { const { scrollX: windowX, scrollY: windowY } = window; return { top: nudgedTop + windowY - 11, left: nudgedLeft - windowX }; }} onClickOutside={() => closeMenu(open, setOpen)} trigger={ <li ref={ref} className="menu__item menu__submenu" onClick={() => openMenu(open, setOpen)} onMouseEnter={() => openMenu(open, setOpen)}> {label} <i className="menu__submenu-icon" /> </li> }> {children} </MenuOpener> ); } Submenu.displayName = "Menu.Submenu";