Tooltip
A popup that displays additional information when hovering over an element. Supports four placement directions and customizable delay.
Installation
bash
npx polyui add tooltipTooltipProvider required
Tooltip relies on context from TooltipProvider. Wrap your app root (e.g. layout.tsx or App.tsx) once — you do not need a separate provider for each Tooltip.
tsx
// layout.tsx (Next.js) or App.tsx
import { TooltipProvider } from "@polyui/react";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html>
<body>
<TooltipProvider>
{children}
</TooltipProvider>
</body>
</html>
);
}Default
tsx
import { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } from "@polyui/react/tooltip"
import { Button } from "@polyui/react/button"
export function TooltipDefault() {
return (
<TooltipProvider>
<Tooltip>
<TooltipTrigger render={<Button variant="outline" size="sm" />}>Hover me</TooltipTrigger>
<TooltipContent>
<p>This is a tooltip</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
)
}Error
tsx
import { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } from "@polyui/react/tooltip"
import { Button } from "@polyui/react/button"
export function TooltipError() {
return (
<TooltipProvider>
<Tooltip>
<TooltipTrigger render={<Button variant="outline" size="sm" />}>Error tooltip</TooltipTrigger>
<TooltipContent className="bg-destructive [&_svg]:bg-destructive [&_svg]:fill-destructive text-white">
<p>Something went wrong</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
)
}With Icon
tsx
import { InfoIcon } from "lucide-react"
import { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } from "@polyui/react/tooltip"
import { Button } from "@polyui/react/button"
export function TooltipWithIcon() {
return (
<TooltipProvider>
<Tooltip>
<TooltipTrigger render={<Button variant="outline" size="sm" />}>With icon</TooltipTrigger>
<TooltipContent className="max-w-64 text-pretty">
<div className="flex items-center gap-1.5">
<InfoIcon className="size-4" />
<p>Helpful information with an icon</p>
</div>
</TooltipContent>
</Tooltip>
</TooltipProvider>
)
}Rich Content
tsx
import { InfoIcon } from "lucide-react"
import { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } from "@polyui/react/tooltip"
import { Button } from "@polyui/react/button"
export function TooltipRichContent() {
return (
<TooltipProvider>
<Tooltip>
<TooltipTrigger render={<Button variant="outline" size="sm" />}>Rich content</TooltipTrigger>
<TooltipContent className="max-w-64 py-3 text-pretty">
<div className="space-y-1">
<div className="flex items-center gap-2">
<InfoIcon className="size-4" />
<p className="text-sm font-medium">Rich Tooltip Title</p>
</div>
<p className="text-background/80">Additional details and context can go here.</p>
</div>
</TooltipContent>
</Tooltip>
</TooltipProvider>
)
}Directions
tsx
import { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } from "@polyui/react/tooltip"
import { Button } from "@polyui/react/button"
export function TooltipDirections() {
return (
<TooltipProvider>
<div className="flex flex-wrap gap-2">
{(["left", "top", "bottom", "right"] as const).map((side) => (
<Tooltip key={side}>
<TooltipTrigger render={<Button variant="outline" size="sm" />}>
{side.charAt(0).toUpperCase() + side.slice(1)}
</TooltipTrigger>
<TooltipContent side={side}>Tooltip on {side}</TooltipContent>
</Tooltip>
))}
</div>
</TooltipProvider>
)
}Rounded
tsx
import { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } from "@polyui/react/tooltip"
import { Button } from "@polyui/react/button"
export function TooltipRounded() {
return (
<TooltipProvider>
<Tooltip>
<TooltipTrigger render={<Button variant="outline" size="sm" />}>Rounded tooltip</TooltipTrigger>
<TooltipContent className="rounded-full">
<p>Rounded tooltip style</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
)
}With Avatar
tsx
import { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } from "@polyui/react/tooltip"
import { Button } from "@polyui/react/button"
import { Avatar, AvatarFallback, AvatarImage } from "@polyui/react/avatar"
export function TooltipWithAvatar() {
return (
<TooltipProvider>
<Tooltip>
<TooltipTrigger render={<Button variant="outline" size="sm" />}>With avatar</TooltipTrigger>
<TooltipContent>
<div className="flex items-center gap-1.5">
<Avatar className="size-5">
<AvatarImage src="https://cdn.shadcnstudio.com/ss-assets/avatar/avatar-5.png" alt="User avatar" />
<AvatarFallback className="text-xs">HR</AvatarFallback>
</Avatar>
<p className="font-medium">Hannah Rose</p>
</div>
</TooltipContent>
</Tooltip>
</TooltipProvider>
)
}With Badge
tsx
import { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } from "@polyui/react/tooltip"
import { Button } from "@polyui/react/button"
import { Badge } from "@polyui/react/badge"
export function TooltipWithBadge() {
return (
<TooltipProvider>
<Tooltip>
<TooltipTrigger render={<Button variant="outline" size="sm" />}>With badge</TooltipTrigger>
<TooltipContent>
<div className="flex items-center gap-2">
<p>Status</p>
<Badge variant="secondary" className="px-1.5 py-px">
New
</Badge>
</div>
</TooltipContent>
</Tooltip>
</TooltipProvider>
)
}Props — Tooltip
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
delayDuration | number | 700 | Milliseconds of hover time before the tooltip opens. |
Props — TooltipContent
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
side | "top" | "right" | "bottom" | "left" | "top" | Preferred side of the trigger to render the tooltip against. |
sideOffset | number | 4 | Distance in pixels between the tooltip and the trigger element. |
Props — TooltipProvider
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
delayDuration | number | 700 | Global default hover delay in milliseconds, overridable per Tooltip via delayDuration. |
skipDelayDuration | number | 300 | Maximum time window (ms) in which moving between tooltips skips the delay. |