UNPKG

@carbon/react

Version:

React components for the Carbon Design System

64 lines (59 loc) 1.59 kB
/** * Copyright IBM Corp. 2016, 2023 * * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. */ import { useState } from 'react'; /** * Array of two numbers either representing [left, right] or [top, bottom]. */ /** * This hook contains common code to be used when a menu should be visually attached to an anchor based on a click event. * * @param {Element|object} anchor The element or ref the menu should visually be attached to. * @returns {useAttachedMenuReturn} */ function useAttachedMenu(anchor) { const [open, setOpen] = useState(false); const [position, setPosition] = useState([[-1, -1], [-1, -1]]); function openMenu() { const anchorEl = anchor?.current || anchor; if (anchorEl) { const { left, top, right, bottom } = anchorEl.getBoundingClientRect(); setPosition([[left, right], [top, bottom]]); } setOpen(true); } function closeMenu() { setOpen(false); } function handleClick() { if (open) { closeMenu(); } else { openMenu(); } } function handleMousedown(e) { // prevent default for mousedown on trigger element to avoid // the "blur" event from firing on the menu as this would close // it and immediately re-open since "click" event is fired after // "blur" event. e.preventDefault(); } return { open, x: position[0], y: position[1], handleClick, handleMousedown, handleClose: closeMenu }; } export { useAttachedMenu };