Tooltip
A short text label that appears when the pointer rests on, or focus reaches, a control.
<Tooltip>
<TooltipTrigger
render={
<Button variant="outline" size="icon" aria-label="Refresh alerts" />
}
>
<RefreshCwIcon />
</TooltipTrigger>
<TooltipContent>Refresh alerts</TooltipContent>
</Tooltip>Usage
import { RefreshCwIcon } from "lucide-react"
import { Button } from "@zenoxai/ui/components/button"
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from "@zenoxai/ui/components/tooltip"
<Tooltip>
<TooltipTrigger
render={
<Button variant="outline" size="icon" aria-label="Refresh alerts" />
}
>
<RefreshCwIcon />
</TooltipTrigger>
<TooltipContent>Refresh alerts</TooltipContent>
</Tooltip>
Use a tooltip to name an icon button or to add a few words about a control: the action of an icon in a toolbar, a keyboard shortcut, the full text of a truncated label. Keep it to one short line. The user must be able to work without ever seeing it: tooltips do not open on touch screens.
- For an explanation the user opens on purpose (an info icon next to a figure), use
Popover with
openOnHover, or the Help Tooltip pattern for the standard info icon. - For a preview of a linked record (an asset, a user), use Hover Card.
- For a message after an action (“Copied”), raise a toast.
Render the trigger through render so the tooltip attaches to the real button. A tooltip on a
disabled button never opens, because a disabled button receives no pointer or focus events;
make it reachable with focusableWhenDisabled on the Button.
Examples
With a keyboard shortcut
Put a Kbd after the label. The tooltip restyles it to read on its inverted background: dark in
the light theme, light in the dark theme.
<Tooltip>
<TooltipTrigger
render={
<Button variant="outline" size="icon" aria-label="Mute alert" />
}
>
<BellOffIcon />
</TooltipTrigger>
<TooltipContent>
Mute alert <Kbd>M</Kbd>
</TooltipContent>
</Tooltip>Side
side is top by default; align moves it along that side. The tooltip flips when there is
no room.
<>
{(["top", "right", "bottom", "left"] as const).map((side) => (
<Tooltip key={side}>
<TooltipTrigger render={<Button variant="outline" />}>
{side}
</TooltipTrigger>
<TooltipContent side={side}>Opens on the {side}</TooltipContent>
</Tooltip>
))}
</>Group with a provider
A tooltip opens 600ms after the pointer arrives. Inside TooltipProvider, tooltips open
without delay, and moving from one trigger to the next swaps them at once, which suits toolbars.
Wrap a toolbar, or the whole app, in one provider; pass delay to it to set a different value.
<TooltipProvider>
<div className="flex gap-1">
<Tooltip>
<TooltipTrigger
render={
<Button
variant="ghost"
size="icon"
aria-label="Download report"
/>
}
>
<DownloadIcon />
</TooltipTrigger>
<TooltipContent>Download report</TooltipContent>
</Tooltip>
<Tooltip>
<TooltipTrigger
render={
<Button variant="ghost" size="icon" aria-label="Share report" />
}
>
<ShareIcon />
</TooltipTrigger>
<TooltipContent>Share report</TooltipContent>
</Tooltip>
<Tooltip>
<TooltipTrigger
render={
<Button variant="ghost" size="icon" aria-label="Delete report" />
}
>
<Trash2Icon />
</TooltipTrigger>
<TooltipContent>Delete report</TooltipContent>
</Tooltip>
</div>
</TooltipProvider>Accessibility
- A tooltip is a visual label for pointer and keyboard users. It is not the accessible name of
its trigger: give every icon-only trigger an
aria-labelwith the same words. - The tooltip opens on hover and on keyboard focus, and closes on Escape, on blur and when the trigger is clicked.
- Never put links, buttons or anything the user must read to complete a task inside a tooltip.
API reference
Generated from the TypeScript source. className, style and children are accepted everywhere and omitted below.
Tooltip
Tooltip shows a short text label for a control on hover and keyboard focus, most often the name of an icon button. For an explanation beside a title or a figure use the HelpTooltip pattern; for rich or interactive content, Popover or HoverCard.
| Prop | Type | Default |
|---|---|---|
actionsRef | RefObject<TooltipRootActions | null>A ref to imperative actions. - `unmount`: Ends the closing phase of the tooltip after an externally controlled closing animation finishes. Call `preventUnmountOnClose()` in `onOpenChange` first, otherwise the tooltip completes closing on its own. Whether it leaves the DOM is decided by `keepMounted` on the portal. - `close`: Closes the tooltip imperatively when called. | - |
defaultOpen | booleanWhether the tooltip is initially open. | false |
defaultTriggerId | string | nullID of the trigger that the tooltip is associated with. This is useful in conjunction with the `defaultOpen` prop to create an initially open tooltip. | - |
disabled | booleanWhether the tooltip is disabled. | false |
disableHoverablePopup | booleanWhether the tooltip contents can be hovered without closing the tooltip. | false |
handle | TooltipHandle<unknown>A handle to associate the tooltip with a trigger. If specified, allows external triggers to control the tooltip's open state. Can be created with the Tooltip.createHandle() method. | - |
onOpenChange | ((open: boolean, eventDetails: TooltipRootChangeEventDetails) => void)Event handler called when the tooltip is opened or closed. | - |
onOpenChangeComplete | ((open: boolean) => void)Event handler called after any animations complete when the tooltip is opened or closed. | - |
open | booleanWhether the tooltip is currently open. | - |
trackCursorAxis | "none" | "both" | "x" | "y"Determines which axis the tooltip should track the cursor on. | 'none' |
triggerId | string | nullID of the trigger that the tooltip is associated with. This is useful in conjunction with the `open` prop to create a controlled tooltip. There's no need to specify this prop when the tooltip is uncontrolled (that is, when the `open` prop is not set). | - |
TooltipTrigger
| Prop | Type | Default |
|---|---|---|
closeDelay | numberHow long to wait before closing the tooltip. Specified in milliseconds. | 0 |
closeOnClick | booleanWhether the tooltip should close when this trigger is clicked. | true |
delay | numberHow long to wait before opening the tooltip on hover. Specified in milliseconds. | 600 |
disabled | booleanIf `true`, the tooltip will not open when interacting with this trigger. Note that this doesn't apply the `disabled` attribute to the trigger element. If you want to disable the trigger element itself, you can pass the `disabled` prop to the trigger element via the `render` prop. | false |
handle | TooltipHandle<unknown>A handle to associate the trigger with a tooltip. | - |
payload | unknownA payload to pass to the tooltip when it is opened. | - |
render | ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, TooltipTriggerState>Allows you to replace the component's HTML element with a different tag, or compose it with another component. | - |
TooltipContent
TooltipContent is the bubble with an arrow, in a portal above the trigger. Its colors invert the page: a dark bubble with light text in the light theme, a light bubble with dark text in the dark theme.
| Prop | Type | Default |
|---|---|---|
align | "center" | "start" | "end"How to align the popup relative to the specified side. | start |
alignOffset | number | OffsetFunctionAdditional offset along the alignment axis in pixels. Also accepts a function that returns the offset to read the dimensions of the anchor and positioner elements, along with its side and alignment. | 0 |
render | ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, TooltipPopupState>Allows you to replace the component's HTML element with a different tag, or compose it with another component. | - |
side | "left" | "right" | "top" | "bottom" | "inline-end" | "inline-start"Which side of the anchor element to align the popup against. May automatically change to avoid collisions. | top |
sideOffset | number | OffsetFunctionDistance between the anchor and the popup in pixels. Also accepts a function that returns the distance to read the dimensions of the anchor and positioner elements, along with its side and alignment. | 0 |
TooltipProvider
TooltipProvider shares the open delay of the tooltips inside it, so moving from one trigger to the next shows the next tooltip at once. Mount one near the root; its `delay` defaults to 0 here.
| Prop | Type | Default |
|---|---|---|
closeDelay | numberHow long to wait before closing a tooltip. Specified in milliseconds. | - |
delay | numberHow long to wait before opening the tooltip on hover. Specified in milliseconds. | 0 |
timeout | numberAnother tooltip will open instantly if the previous tooltip is closed within this timeout. Specified in milliseconds. | 400 |