import { useState, useRef, useEffect, type ReactNode } from "react"; import { createPortal } from "react-dom"; interface HintProps { hint: ReactNode; children: ReactNode; } export function Hint({ hint, children }: HintProps) { const [open, setOpen] = useState(false); const [pos, setPos] = useState({ top: 0, left: 0 }); const wrapperRef = useRef(null); const tooltipRef = useRef(null); const updatePos = () => { if (!wrapperRef.current?.children[0]) return; const rect = wrapperRef.current.children[0].getBoundingClientRect(); setPos({ top: rect.bottom, left: rect.left + rect.width / 2, }); }; useEffect(() => { if (!open || !tooltipRef.current) return; const tip = tooltipRef.current.getBoundingClientRect(); const margin = 8; setPos((prev) => ({ top: tip.top, left: Math.min(Math.max(prev.left, tip.width / 2 + margin), window.innerWidth - tip.width / 2 - margin), })); }, [open]); return (
{ updatePos(); setOpen(true); }} onMouseLeave={() => setOpen(false)} > {children} {open && createPortal(
{hint}
, document.body, )}
); }