Tooltip
Shows a short hint about a control while it has hover or keyboard focus.
Installation
pnpm dlx shadcn@latest add @wisty/tooltip
The CLI installs the Radix or Base UI file to match your project.
If your project doesn't have Wisty UI's theme yet, add it once with npx shadcn@latest add @wisty/cosmos. Until then, components keep shadcn's default look. Installation has the details.
When to use
Use it
- A control needs a short hint in plain text, like what an icon button does or what a field expects.
- Field-level help: an info button beside a label, as Salesforce shows on record forms.
Don't use it
- The content has links, buttons or fields, or more than a sentence or two. Use Popover, or Hover Card for a preview.
- The information is needed to finish the task. Put it on the page, in the label or in a description below the field.
- The control has no name of its own. Give it a visible label or an
aria-labelfirst. A tooltip isn't a name. - On touch screens, where there's no hover. Don't hide anything people need behind a tooltip.
Usage
TooltipProvider
└── Tooltip
├── TooltipTrigger
└── TooltipContentPut one TooltipProvider near the root of the app, around every Tooltip. In Radix projects a tooltip throws without it. In Base UI projects it works without one, but waits its own delay before opening.
import { buttonVariants } from "@/components/ui/button"
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from "@/components/ui/tooltip"<Tooltip>
<TooltipTrigger className={buttonVariants({ variant: "outline" })}>
Freeze column
</TooltipTrigger>
<TooltipContent>Keeps this column in view as you scroll.</TooltipContent>
</Tooltip>Examples
On an icon button
Icon buttons carry their name in `aria-label`, and the tooltip shows the same words to people who can see the icon.
Sides
Tooltips on each side of their buttons, set with `side` on `TooltipContent`.
API reference
TooltipProvider
| Prop | Type | Default | Description |
|---|---|---|---|
delayDuration | number | 0 | The duration from when the pointer enters the trigger until the tooltip gets opened. |
TooltipContent
| Prop | Type | Default |
|---|---|---|
sideOffset | number | 0 |
SLDS mapping
TooltipContentisslds-popover slds-popover_tooltipand itsslds-popover__bodyin one element.- Its arrow is SLDS's nubbin (
slds-nubbin_*), centered on the edge that faces the trigger. TooltipTriggerhas no SLDS class of its own.
Known gaps:
- No corner nubbins (
slds-nubbin_bottom-leftand others), and no error or warning tooltips. - The nubbin's shadow is SLDS's bottom-nubbin shadow, turned to point outward on every side. SLDS's own shadows for the other sides differ slightly.
Accessibility
- Give every trigger a name of its own: its text, or an
aria-labelon an icon button, as the On an icon button example does. In Base UI projects nothing links the trigger to its tooltip, so screen readers don't read the tooltip at all. - Don't put anything in a tooltip that people can't get another way.
- When the tooltip repeats an icon button's
aria-label, some screen readers read it twice, once as the name and once as the description.
Motion
- The tooltip fades over 0.1s in every theme. In Base UI projects it fades out too; in Radix projects it disappears at once. The fade only changes opacity, so it stays on with reduced motion.
Rules
- Never nest a Button inside
TooltipTrigger. That's a button in a button; style the trigger withbuttonVariants()instead. - Keep tooltip text short and plain: no links, buttons or headings.
- Don't style
TooltipContent's colors, padding or nubbin. They come from the theme.