Pho Design System

Tooltip

A brief label that appears on hover or focus — most often naming an icon-only control. Built on Base UI Tooltip. Tooltips are supplementary and visual-only: never put essential or interactive content in one (use Popover for that).

Import

import { Tooltip } from "@photon-ai/pho-ui/components/tooltip";

Basic

Wrap your app (or a section) in a single Tooltip.Provider to share timing. The trigger must be focusable — hover it or tab to it. Because the tooltip is visual-only, give the trigger an aria-label that matches the popup text.

<Tooltip.Provider>
  <Tooltip.Root>
    <Tooltip.Trigger
      render={
        <Button svgOnly aria-label="Copy deployment URL">
          <Copy />
        </Button>
      }
    />
    <Tooltip.Portal>
      <Tooltip.Positioner>
        <Tooltip.Popup>Copy deployment URL</Tooltip.Popup>
      </Tooltip.Positioner>
    </Tooltip.Portal>
  </Tooltip.Root>
</Tooltip.Provider>

Placement

Tooltip.Positioner places the popup with side (top by default) and align (center). It flips to the opposite side to avoid collisions. The pho positioner sets a sideOffset of 6; override it or alignOffset for more gap.

<Tooltip.Positioner side="right">
  <Tooltip.Popup>Copy deployment URL</Tooltip.Popup>
</Tooltip.Positioner>

Grouping

Tooltips under one Tooltip.Provider share a delay. Once one opens, moving to an adjacent trigger within the provider’s timeout (400 ms) opens the next instantly — so a toolbar of icon buttons feels responsive rather than making you wait through the open delay each time.

<Tooltip.Provider delay={400}>
  {formats.map(({ label, icon: Icon }) => (
    <Tooltip.Root key={label}>
      <Tooltip.Trigger
        render={
          <Button svgOnly aria-label={label}>
            <Icon />
          </Button>
        }
      />
      <Tooltip.Portal>
        <Tooltip.Positioner>
          <Tooltip.Popup>{label}</Tooltip.Popup>
        </Tooltip.Positioner>
      </Tooltip.Portal>
    </Tooltip.Root>
  ))}
</Tooltip.Provider>

Anatomy

Props

Set on Tooltip.Provider:

Set on Tooltip.Root:

Set on Tooltip.Trigger:

Set on Tooltip.Positioner:

Accessibility

Tooltips serve sighted mouse and keyboard users; they are not exposed to touch or screen-reader users. Because of that, the tooltip text is not a substitute for labelling the trigger — the trigger must have its own aria-label (or visible text) that closely matches the popup, so screen-reader users get the same information. If the content is essential or interactive, use Popover with openOnHover instead.

The trigger renders a focusable <button> and gets data-popup-open while the tooltip is showing.

Behavior:

Best practices