import { useState, useRef, useCallback, type ReactNode } from "react"; import { createPortal } from "react-dom"; interface TooltipProps { label: string; children: ReactNode; delay?: number; side?: "top" | "bottom"; } export function Tooltip({ label, children, delay = 400, side = "top" }: TooltipProps) { const [visible, setVisible] = useState(false); const [pos, setPos] = useState({ x: 0, y: 0 }); const timerRef = useRef | null>(null); const triggerRef = useRef(null); const show = useCallback(() => { timerRef.current = setTimeout(() => { const el = triggerRef.current; if (!el) return; const child = el.firstElementChild as HTMLElement | null; const rect = (child ?? el).getBoundingClientRect(); if (rect.width === 0 && rect.height === 0) return; setPos({ x: rect.left + rect.width / 2, y: side === "top" ? rect.top - 6 : rect.bottom + 6, }); setVisible(true); }, delay); }, [delay, side]); const hide = useCallback(() => { if (timerRef.current) { clearTimeout(timerRef.current); timerRef.current = null; } setVisible(false); }, []); return ( <> {children} {visible && createPortal(
{label}
, document.body, )} ); }