import * as React from "react"; import { useMousePosition } from "~/hooks/useMousePosition"; /** Component to cover the area between the mouse cursor and the sub-menu, to allow moving cursor to lower parts of sub-menu without the sub-menu disappearing. */ export function MouseSafeArea(props: { parentRef: React.RefObject }) { const { x = 0, y = 0, height: h = 0, width: w = 0 } = props.parentRef.current?.getBoundingClientRect() || {}; const [mouseX, mouseY] = useMousePosition(); const positions = { x, y, h, w, mouseX, mouseY }; return (
); } interface Positions { /* Sub-menu x */ x: number; /* Sub-menu y */ y: number; /* Sub-menu height */ h: number; /* Sub-menu width */ w: number; /* Mouse x */ mouseX: number; /* Mouse y */ mouseY: number; } const getLeft = ({ x, mouseX }: Positions) => (mouseX > x ? undefined : -Math.max(x - mouseX, 10) + "px"); const getRight = ({ x, w, mouseX }: Positions) => (mouseX > x ? -Math.max(mouseX - (x + w), 10) + "px" : undefined); const getWidth = ({ x, w, mouseX }: Positions) => mouseX > x ? Math.max(mouseX - (x + w), 10) + "px" : Math.max(x - mouseX, 10) + "px"; const getClipPath = ({ x, y, h, mouseX, mouseY }: Positions) => mouseX > x ? `polygon(0% 0%, 0% 100%, 100% ${(100 * (mouseY - y)) / h}%)` : `polygon(100% 0%, 0% ${(100 * (mouseY - y)) / h}%, 100% 100%)`;