Skip to content
UI

Tooltip

A short text label that appears when the pointer rests on, or focus reaches, a control.

@zenoxai/ui/components/tooltipBase UI Markdown
<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-label with 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.

PropTypeDefault
actionsRefRefObject<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.

-
defaultOpenboolean

Whether the tooltip is initially open.

false
defaultTriggerIdstring | null

ID of the trigger that the tooltip is associated with. This is useful in conjunction with the `defaultOpen` prop to create an initially open tooltip.

-
disabledboolean

Whether the tooltip is disabled.

false
disableHoverablePopupboolean

Whether the tooltip contents can be hovered without closing the tooltip.

false
handleTooltipHandle<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.

-
openboolean

Whether the tooltip is currently open.

-
trackCursorAxis"none" | "both" | "x" | "y"

Determines which axis the tooltip should track the cursor on.

'none'
triggerIdstring | null

ID 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

PropTypeDefault
closeDelaynumber

How long to wait before closing the tooltip. Specified in milliseconds.

0
closeOnClickboolean

Whether the tooltip should close when this trigger is clicked.

true
delaynumber

How long to wait before opening the tooltip on hover. Specified in milliseconds.

600
disabledboolean

If `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
handleTooltipHandle<unknown>

A handle to associate the trigger with a tooltip.

-
payloadunknown

A payload to pass to the tooltip when it is opened.

-
renderReactElement<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.

PropTypeDefault
align"center" | "start" | "end"

How to align the popup relative to the specified side.

start
alignOffsetnumber | OffsetFunction

Additional 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
renderReactElement<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
sideOffsetnumber | OffsetFunction

Distance 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.

PropTypeDefault
closeDelaynumber

How long to wait before closing a tooltip. Specified in milliseconds.

-
delaynumber

How long to wait before opening the tooltip on hover. Specified in milliseconds.

0
timeoutnumber

Another tooltip will open instantly if the previous tooltip is closed within this timeout. Specified in milliseconds.

400