import cn from "@utils/classnames.ts"; import { type ReactNode, useRef, useState } from "react"; type TooltipPosition = "top" | "bottom" | "left" | "right"; type TextSize = "xs" | "sm" | "md" | "lg" | "xl"; export interface TooltipProps { children: ReactNode; text: ReactNode; position?: TooltipPosition; className?: string; textSize?: TextSize; } export default function Tooltip({ children, text, position = "top", className = "", textSize = "md", }: TooltipProps) { const [isVisible, setIsVisible] = useState(false); const timeoutRef = useRef(null); const positionClasses: Record = { top: "bottom-full left-1/2 -translate-x-1/2 mb-2", bottom: "top-full left-1/2 -translate-x-1/2 mt-2", left: "right-full top-1/2 -translate-y-1/2 mr-2", right: "left-full top-1/2 -translate-y-1/2 ml-2", }; const arrowClasses: Record = { top: "top-full left-1/2 -translate-x-1/2 border-l-transparent border-r-transparent border-b-transparent border-t-gray-900 dark:border-t-gray-100", bottom: "bottom-full left-1/2 -translate-x-1/2 border-l-transparent border-r-transparent border-t-transparent border-b-gray-900 dark:border-b-gray-100", left: "left-full top-1/2 -translate-y-1/2 border-t-transparent border-b-transparent border-r-transparent border-l-gray-900 dark:border-l-gray-100", right: "right-full top-1/2 -translate-y-1/2 border-t-transparent border-b-transparent border-l-transparent border-r-gray-900 dark:border-r-gray-100", }; const textSizeClass: Record = { xs: "text-xs", sm: "text-sm", md: "text-base", lg: "text-lg", xl: "text-xl", }; const showTooltip = () => { if (timeoutRef.current) { clearTimeout(timeoutRef.current); timeoutRef.current = null; } setIsVisible(true); }; const hideTooltip = () => { timeoutRef.current = window.setTimeout(() => { setIsVisible(false); }, 100); }; return (
{children} {isVisible && (
{text}
)}
); }