Files
f8e879cc-2b1e-45f6-bc11-9a3…/src/components/ui/Tooltip.tsx
2026-06-18 10:19:26 +00:00

54 lines
1.6 KiB
TypeScript

"use client";
import { useState } from "react";
import { motion, AnimatePresence } from "motion/react";
import { cls } from "@/lib/utils";
interface TooltipProps {
content: string;
position?: "top" | "bottom" | "left" | "right";
children: React.ReactNode;
className?: string;
}
const POSITIONS = {
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 Tooltip = ({ content, position = "top", children, className = "" }: TooltipProps) => {
const [isVisible, setIsVisible] = useState(false);
return (
<div
className="relative inline-block"
onMouseEnter={() => setIsVisible(true)}
onMouseLeave={() => setIsVisible(false)}
>
{children}
<AnimatePresence>
{isVisible && (
<motion.div
className={cls(
"absolute z-50 whitespace-nowrap rounded px-2 py-1 text-xs pointer-events-none",
"secondary-button text-secondary-cta-text",
POSITIONS[position],
className
)}
initial={{ opacity: 0, scale: 0.95, y: position === "bottom" ? -4 : position === "top" ? 4 : 0 }}
animate={{ opacity: 1, scale: 1, y: 0 }}
exit={{ opacity: 0, scale: 0.95 }}
transition={{ duration: 0.25, ease: [0.25, 0.46, 0.45, 0.94] }}
>
{content}
</motion.div>
)}
</AnimatePresence>
</div>
);
};
export default Tooltip;