FluxUI Pro is live - modern UI, powerful animations, zero hassle.
Components
Tooltip

Tooltip

Animated tooltip with customizable positioning, delay, and smooth transitions.

Installation

1

Install the packages

npm i motion clsx tailwind-merge
2

Add util file

lib/util.ts
import { ClassValue, clsx } from "clsx"; import { twMerge } from "tailwind-merge"; export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)); }
3

Copy and paste the following code into your project

tooltip.tsx
"use client"; import { cn } from "@/lib/utils"; import { motion, AnimatePresence } from "motion/react"; import React, { useState, useRef } from "react"; interface TooltipProps { content?: string; children?: React.ReactNode; position?: "top" | "bottom" | "left" | "right"; delay?: number; } const Tooltip: React.FC<TooltipProps> = ({ content = "This is a tooltip", children, position = "top", delay = 300 }) => { const [isVisible, setIsVisible] = useState(false); const [timeoutId, setTimeoutId] = useState<NodeJS.Timeout | null>(null); const tooltipRef = useRef<HTMLDivElement>(null); const handleMouseEnter = () => { const id = setTimeout(() => setIsVisible(true), delay); setTimeoutId(id); }; const handleMouseLeave = () => { if (timeoutId) { clearTimeout(timeoutId); setTimeoutId(null); } setIsVisible(false); }; const positionClasses = { top: "bottom-full left-1/2 transform -translate-x-1/2 mb-2", bottom: "top-full left-1/2 transform -translate-x-1/2 mt-2", left: "right-full top-1/2 transform -translate-y-1/2 mr-2", right: "left-full top-1/2 transform -translate-y-1/2 ml-2", }; const arrowClasses = { top: "top-full left-1/2 transform -translate-x-1/2 border-l-transparent border-r-transparent border-b-transparent", bottom: "bottom-full left-1/2 transform -translate-x-1/2 border-l-transparent border-r-transparent border-t-transparent", left: "left-full top-1/2 transform -translate-y-1/2 border-t-transparent border-b-transparent border-r-transparent", right: "right-full top-1/2 transform -translate-y-1/2 border-t-transparent border-b-transparent border-l-transparent", }; return ( <div ref={tooltipRef} className="relative inline-block" onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave} > {children || ( <button className="px-4 py-2 bg-cyan-500 text-white rounded-lg hover:bg-cyan-600 transition-colors"> Hover me </button> )} <AnimatePresence> {isVisible && ( <motion.div className={cn( "absolute z-50 px-3 py-2", "bg-neutral-900 dark:bg-neutral-700 text-white rounded-lg shadow-lg", "border border-neutral-700 dark:border-neutral-600", "max-w-xs text-sm text-center", positionClasses[position] )} initial={{ opacity: 0, scale: 0.8 }} animate={{ opacity: 1, scale: 1 }} exit={{ opacity: 0, scale: 0.8 }} transition={{ duration: 0.2, ease: "easeOut" }} > {content} {/* Arrow */} <div className={cn( "absolute w-0 h-0 border-4", arrowClasses[position] )} style={{ borderColor: position === "top" ? "transparent transparent #374151 transparent" : position === "bottom" ? "transparent transparent transparent #374151" : position === "left" ? "transparent #374151 transparent transparent" : "transparent transparent transparent #374151" }} /> </motion.div> )} </AnimatePresence> </div> ); }; export default Tooltip;
4

Update the import paths to match your project setup

Props

PropTypeDefaultDescription
contentstringThis is a tooltipThe text content of the tooltip.
childrenReactNodenullThe trigger element for the tooltip.
positionstringtopPosition of the tooltip (top, bottom, left, right).
delaynumber300Delay in milliseconds before showing the tooltip.