Overlays

Tooltip

A description that appears on hover and on focus.

Client componentSource

Import

import { Tooltip } from '@the_viveksingh/vivek-ui'

On hover and on focus

Focus matters as much as hover: a tooltip only reachable with a mouse is invisible to keyboard users. The trigger gets aria-describedby, so the text is announced rather than merely drawn.

<Tooltip content="Copied to your clipboard on click">
  <Button>Hover or focus me</Button>
</Tooltip>

<Tooltip content="Billed per active seat, per month">
  <IconButton variant="ghost" aria-label="About seat pricing">
    <InfoIcon />
  </IconButton>
</Tooltip>

Sides

side is a preference. If the tooltip would leave the viewport it flips, so it never renders off-screen.

<Tooltip content="Above" side="top"><Button variant="outline">Top</Button></Tooltip>
<Tooltip content="To the right" side="right"><Button variant="outline">Right</Button></Tooltip>
<Tooltip content="Below" side="bottom"><Button variant="outline">Bottom</Button></Tooltip>
<Tooltip content="To the left" side="left"><Button variant="outline">Left</Button></Tooltip>

Props

Generated from the package's own type declarations, so this table cannot drift from the code.

Props for Tooltip
PropTypeDefaultDescription
children requiredReactElement<TooltipTriggerProps>The trigger. Exactly one element, and it must spread the props it is given - `aria-describedby` has to land on the real interactive element for a screen reader to read the tip, and a wrapper `<span>` cannot stand in for it. A ref is attached to it (composed with any ref it already had) to measure against, with the first pointer or focus event as a fallback - so a child that swallows refs still positions correctly on hover.
content requiredReactNodeThe tip. Keep it short and non-interactive: a tooltip is never focusable.
sideSidePreferred side. Flipped to its opposite when there is no room. Default `'top'`.
alignAlignCross-axis alignment. Default `'center'`.
offsetnumberGap between trigger and tip, px. Default `8`.
paddingnumberMinimum distance kept from the viewport edges, px. Default `8`.
openbooleanControlled open state.
defaultOpenbooleanInitial open state while uncontrolled. Default `false`.
onOpenChange(open: boolean) => void
openDelaynumberDelay before a hover opens the tip, ms. Default `200`. Keyboard focus deliberately ignores this and opens immediately: a delay on hover stops tips flickering as the pointer crosses a toolbar, but a keyboard user has already committed by pressing Tab, and making them wait is just lag.
closeDelaynumberDelay before the tip closes after the pointer leaves, ms. Default `150`. Must stay above zero: it is the window in which the pointer can cross the gap from the trigger onto the tip itself without the tip disappearing underneath it.
disabledbooleanNever open. For a trigger whose tip is temporarily meaningless.
containerPortalContainerWhere to portal the tip. Defaults to `document.body`.

Every remaining prop is spread onto the root element, so all standard HTML and ARIA attributes work. className and style are merged with the library's own, never replaced, and the ref forwards to the root DOM node.

Rendering