import React, { useEffect, useRef } from "react"; import { useDispatch, useSelector } from "react-redux"; import { closePopup, openPopup, togglePopup, } from "../../slices/localVariablesSlice"; /** * align: "auto" | "left" | "right" * boundaryRef: optional ref to the drawer/container element to use as boundary */ const HoverPopup = ({ id, title, content, children, className = "", Mode = "hover", align = "auto", boundaryRef = null, }) => { const dispatch = useDispatch(); const visible = useSelector((s) => s.localVariables.popups[id] || false); const triggerRef = useRef(null); const popupRef = useRef(null); const handleMouseEnter = () => { if (Mode === "hover") dispatch(openPopup(id)); }; const handleMouseLeave = () => { if (Mode === "hover") dispatch(closePopup(id)); }; const handleClick = (e) => { if (Mode === "click") { e.stopPropagation(); dispatch(togglePopup(id)); } }; // Close on outside click when using click mode useEffect(() => { if (Mode !== "click" || !visible) return; const handler = (e) => { if ( popupRef.current && !popupRef.current.contains(e.target) && triggerRef.current && !triggerRef.current.contains(e.target) ) { dispatch(closePopup(id)); } }; document.addEventListener("click", handler); return () => document.removeEventListener("click", handler); }, [Mode, visible, dispatch, id]); useEffect(() => { if (!visible || !popupRef.current || !triggerRef.current) return; requestAnimationFrame(() => { const popup = popupRef.current; const boundaryEl = (boundaryRef && boundaryRef.current) || popup.parentElement; if (!boundaryEl) return; const boundaryRect = boundaryEl.getBoundingClientRect(); const triggerRect = triggerRef.current.getBoundingClientRect(); popup.style.left = ""; popup.style.right = ""; popup.style.transform = ""; popup.style.top = ""; const popupRect = popup.getBoundingClientRect(); const triggerCenterX = triggerRect.left + triggerRect.width / 2 - boundaryRect.left; let left = triggerCenterX - popupRect.width / 2; // Clamp to boundaries left = Math.max(0, Math.min(left, boundaryRect.width - popupRect.width)); popup.style.left = `${left}px`; }); }, [visible, align, boundaryRef]); return (