import { useEffect, useRef, useState } from 'react'; import MenuItem from '../menu-item'; import StyledMenu from './styled-menu'; import { Positions } from '../../styles'; import * as React from 'react'; interface Props { anchorId: string; id: string; style?: React.CSSProperties; children?: React.ReactNode; show: boolean; toggleMenu: (value?: boolean) => void; parentRef?: any; useParentWidth?: boolean; position: Positions; items?: [ { id: string, name: string, value: React.ReactNode, } ] } const Menu = (props: Props) => { const [position, setPosition] = useState() const handleClickOutside = (e: any) => { if(props && props.show ){ const verifyId = e.target.id === props.id; const verifyParentId = e.target.offsetParent && e.target.offsetParent.id === props.id; if(!verifyId && !verifyParentId){ props.toggleMenu(); } } } const updatePosition = () => { const newPosition = getPosition(props.anchorId, props.position, props.id); setPosition(newPosition); } useEffect(() => { const newPosition = getPosition(props.anchorId, props.position, props.id); setPosition(newPosition); }, [props]) document.addEventListener('mousedown', handleClickOutside); window.addEventListener('resize', updatePosition); const myRef = useRef(null); return( {props.children} {props.items && props.items.map( item => ( {item.value} ))} ); }; Menu.defaultProps = { position: 'bottom', }; const getPosition = (id: string, position: Positions, myId: string) => { const element = document.getElementById(id); if(element){ const menu = document.getElementById(myId); const elementWidth = element.offsetWidth; const elementHeight = element.offsetHeight; const elementTop = element.offsetTop; const elementLeft = element.offsetLeft; const right = elementWidth + elementLeft + 10; const bottom = elementTop + elementHeight + 10; let top = elementTop - 10; let left = elementLeft - 10; if(menu){ top = top - menu.offsetHeight; left = left - menu.offsetWidth; } switch(position){ case 'top': return {top, left: elementLeft}; case 'right': return {left: right, top: elementTop}; case 'left': return {left, top: elementTop}; case 'bottom': return {top: bottom, left: elementLeft}; } } return {minWidth: 100}; }; export default Menu;