Components
- Accordion
- Alert
- Alert Dialog
- Aspect Ratio
- Attachment
- Avatar
- Badge
- Breadcrumb
- Bubble
- Button
- Button Group
- Calendar
- Card
- Carousel
- Chart
- Checkbox
- Collapsible
- Combobox
- Command
- Context Menu
- Date Picker
- Dialog
- Drawer
- Dropdown Menu
- Empty
- Field
- Hover Card
- Input
- Input OTP
- Input Group
- Item
- Kbd
- Label
- Marker
- Menubar
- Message
- Message Scroller
- Native Select
- Navigation Menu
- Pagination
- Popover
- Progress
- Radio Group
- Resizable
- Scroll Area
- Select
- Separator
- Sheet
- Sidebar
- Skeleton
- Slider
- Sonner
- Spinner
- Switch
- Table
- Tabs
- Textarea
- Toggle
- Toggle Group
- Tooltip
- New Component
Elements
Charts
Icons
What is this?
import { InfoIcon, PlusIcon, SettingsIcon } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Kbd } from "@/components/ui/kbd";
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
export const TooltipDemo = () => (
<div className="flex flex-wrap items-center gap-6">
{/* Basic */}
<Tooltip>
<TooltipTrigger asChild><Button variant="outline">Hover me</Button></TooltipTrigger>
<TooltipContent>Helpful hint</TooltipContent>
</Tooltip>
{/* Icon button with tooltip */}
<Tooltip>
<TooltipTrigger asChild><Button variant="ghost" size="icon" aria-label="Settings"><SettingsIcon /></Button></TooltipTrigger>
<TooltipContent>Settings</TooltipContent>
</Tooltip>
{/* With keyboard shortcut */}
<Tooltip>
<TooltipTrigger asChild><Button variant="ghost" size="icon" aria-label="New item"><PlusIcon /></Button></TooltipTrigger>
<TooltipContent className="flex items-center gap-2">New item<Kbd>⌘K</Kbd></TooltipContent>
</Tooltip>
{/* Sides */}
{(["top", "right", "bottom", "left"] as const).map((side) => (
<Tooltip key={side}>
<TooltipTrigger asChild><Button variant="outline" size="sm" className="capitalize">{side}</Button></TooltipTrigger>
<TooltipContent side={side}>Tooltip on {side}</TooltipContent>
</Tooltip>
))}
{/* On a non-interactive element via span */}
<Tooltip>
<TooltipTrigger asChild><span className="inline-flex cursor-default items-center gap-1 text-sm underline decoration-dotted"><InfoIcon className="size-3.5" />What is this?</span></TooltipTrigger>
<TooltipContent className="max-w-48">Tooltips provide short contextual information about an element on hover or focus.</TooltipContent>
</Tooltip>
</div>
);With asChild
Wrap any element in TooltipTrigger asChild to attach the tooltip without an extra DOM node. Always use asChild on interactive elements like Button.
<Tooltip>
<TooltipTrigger asChild>
<Button variant="ghost" size="icon" aria-label="Settings">
<SettingsIcon />
</Button>
</TooltipTrigger>
<TooltipContent>Settings</TooltipContent>
</Tooltip>Side
<TooltipContent side="top" /> {/* default */}
<TooltipContent side="right" />
<TooltipContent side="bottom" />
<TooltipContent side="left" />With keyboard shortcut
Combine with Kbd inside TooltipContent for a shortcut hint.
<TooltipContent className="flex items-center gap-2">
New item
<Kbd>⌘K</Kbd>
</TooltipContent>Delay
The default delayDuration is 0. Wrap in TooltipProvider to set a custom delay for a group.
<TooltipProvider delayDuration={300}>
<Tooltip>…</Tooltip>
<Tooltip>…</Tooltip>
</TooltipProvider>Controlled
<Tooltip open={open} onOpenChange={setOpen}>
…
</Tooltip>Props
TooltipContent
| Prop | Type | Default | Description |
|---|---|---|---|
side | "top" | "right" | "bottom" | "left" | "top" | Preferred side |
sideOffset | number | 0 | Gap between trigger and tooltip |
align | "start" | "center" | "end" | "center" | Alignment along the side |
hidden | boolean | false | Hides the content while keeping mount |
Tooltip (Root)
| Prop | Type | Default | Description |
|---|---|---|---|
open | boolean | — | Controlled open state |
defaultOpen | boolean | false | Uncontrolled initial state |
onOpenChange | (open: boolean) => void | — | Callback on state change |
delayDuration | number | 0 | Override provider delay for this tooltip |
Usage
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from "@/components/ui/tooltip";
<Tooltip>
<TooltipTrigger asChild>
<Button variant="ghost" size="icon" aria-label="Add">
<PlusIcon />
</Button>
</TooltipTrigger>
<TooltipContent>Add item</TooltipContent>
</Tooltip>Specs
# Mint — Tooltip Specs
## Component
- name: tooltip
- file: registry/mint/tooltip.tsx
- installs to: components/ui/tooltip.tsx
- dependencies: radix-ui
- registryDependencies: none
## What is it
A floating label that appears on hover or focus to provide supplemental context
for an element. Use it to clarify icon-only buttons, truncated text, or
non-obvious controls. Do not use it to convey information required to complete
a task — that content belongs in the UI, not a tooltip.
## Visual identity
Solid medium-green fill (--primary) with white text gives a high-contrast,
unambiguous callout with a fresh Mint accent. Slightly rounded corners
(rounded-md) and compact padding (px-3 py-1.5) keep it dense and lightweight.
A small rotated square arrow anchors the tooltip to its trigger.
## Design tokens
--primary: oklch(0.5 0.14 155) / oklch(0.62 0.15 155) — tooltip background
--primary-foreground: oklch(1 0 0) / oklch(0.1 0 0) — tooltip text
## Sub-components
- TooltipProvider → Radix Provider; sets delayDuration (default 0) for a group
- Tooltip → wraps TooltipProvider + Radix Root; self-contained by default
- TooltipTrigger → Radix Trigger; use asChild for interactive elements
- TooltipContent → Radix Portal + Content; renders the floating label and arrow
## States
- open: animate-in fade-in-0 zoom-in-95 + directional slide-in-from-opposite-side-2
- closed: animate-out fade-out-0 zoom-out-95 + directional slide-out-to-opposite-side-2
## Conventions
- Each Tooltip auto-wraps in TooltipProvider (delayDuration=0); no manual provider needed for single tooltips
- Wrap multiple Tooltip instances in a shared TooltipProvider to set a common delayDuration or skipDelayDuration
- Always use TooltipTrigger asChild on interactive elements (Button, anchor) to avoid a nested focusable element
- Icon-only buttons must have an aria-label; the tooltip text may duplicate it for visual users
- Kbd inside TooltipContent adapts automatically via data-[slot=tooltip-content]: inverted colour classes
- Sub-components expose data-slot="tooltip-provider", "tooltip", "tooltip-trigger", "tooltip-content" for CSS targetingInstallation
$ npx shadcn add \https://gin-design.vercel.app/tooltip