Tooltip

Atom
Small floating helper text on hover or focus.

Playground

Every control sets a real prop of TooltipProps. The JSX below updates as you go.
Props
label
string
Placement
pick one
iconTrigger
boolean
open
boolean
JSX · TooltipProps
<Tooltip label="Copy snippet" top iconTrigger open />

Variants

7 examples from src/atoms/tooltip/tooltip.md, each rendered live from its own JSX.
Right
<Tooltip label="Open settings" trigger="Settings" open right />
Bottom
<Column padLoose alignCenter>
<Tooltip label="Open settings" trigger="Settings" open bottom />
</Column>
Left
<Tooltip label="Open settings" trigger="Settings" open left />
Icon
<Column padLoose alignCenter>
<Tooltip label="Open settings" iconTrigger open />
</Column>
Text
<Column padLoose alignCenter>
<Tooltip textTrigger label="Open settings" trigger="hover this text" open />
</Column>
Element trigger
<Column padLoose alignCenter>
<Tooltip label="Open settings" open>
<Button ghost icon accessibilityLabel="Open settings" iconLeft={<Icon settings size={16} />} />
</Tooltip>
</Column>
On hover
<Tooltip label="Open settings" trigger="Hover me" />

Anatomy

1
Trigger
2
Bubble
3
Arrow
Dimmed parts appear only in some states or variants.

Props

13 props on TooltipProps, grouped as they are declared in source. Required props are marked *.
Prop
Type
Default
Description
Props
1 prop
children
ReactNode
–
An arbitrary element for the tip to hang off: an existing Button, Chip, or any other control that already owns its own press and accessible name. The highest-precedence trigger: children win over iconTrigger, textTrigger, and the default Button. The child renders as-is and stays the single interactive, labelled element; the root view Tooltip wraps it in takes no accessibility role and no tab stop, listens only for hover and focus, and never claims the press, so a Button child keeps its onPress and the tip does not toggle on tap.
The tip text shown in the bubble
5 props
label
string
–
The tip text shown in the bubble.
trigger
string
–
The element the tip describes. By default rendered as a text <Button outline small>; set iconTrigger for a ghost icon button, textTrigger to hang the tip off an inline pressable word, or pass children to wrap an element you already have. Ignored when children is passed.
iconTrigger
boolean
false
Render the trigger as a ghost icon button (a settings glyph) instead of the text Button. When set, trigger (the label string) is ignored. Ignored when children is passed, which takes precedence.
textTrigger
boolean
false
Render the trigger string as a pressable inline word (an underlined hover-text affordance) rather than the default text Button, so the tip can hang off a run of body copy. Orthogonal to placement (top/left/right/bottom). Ignored when children or iconTrigger is set, both of which take precedence.
open
boolean
false
Controlled visibility. Omit for uncontrolled: the tip shows while the trigger is hovered or focused, and a tap toggles it (the touch analogue of hover) on the built-in triggers. An element trigger (children) has no tap toggle (the child keeps its own press), and native platforms never fire hover, so open is the native and touch path for that trigger.
Fired when the bubble is shown/hidden
1 prop
onOpenChange
(open: boolean) => void
–
Fired when the bubble is shown/hidden.
Placement
pick one
6 props
top
boolean
false
bottom
boolean
false
left
boolean
false
right
boolean
false
testID
string
–
E2E hook forwarded to the root element.
style
LayoutStyle
–
Composition within a parent only, never a restyle hook and never a width: the parent layout container provides the bounds.

Accessibility and keyboard

Keyboard
Tab
Focus on the trigger shows the tip
Escape
Hides the tip without moving focus
Semantics
Roles
alert
button
States
expanded
ARIA on web
aria-expanded
aria-live
From the docs
Small floating helper text on hover or focus.
Hover and focus are pointer-and-keyboard affordances. Touch pointers are skipped, and iOS and Android never fire hover at all. On touch the built-in triggers toggle the tip on tap (tap again to close it; a tip is never modal, so a tap elsewhere goes to the page). A long press is not taken: it belongs to the platform and to the control. An element trigger has no tap toggle either, because that press belongs to the child, so on native and on touch the controlled open prop is the way to show its tip: drive it from w

Platform skins

The playground's props on each platform: same tree, native shapes, type and touch sizes.
Web
control 10 · field 10 · card 16 · Instrument Sans
iOS
capsule controls · field 8 · card 12 · SF Pro · 44 pt
Android
Material 3 stadium · field 4 · card 12 · Roboto · 48 dp

Usage

The examples pinned open leave room on the bubble's side, as a page would: the bubble floats and takes no room of its own.
<Column padLoose alignCenter>
<Tooltip label="Open settings" trigger="Settings" open />
</Column>
The bubble floats over the page: it is drawn in the overlay layer of the nearest OverlayProvider, placed against its trigger, and changes no layout, so a tip on a table row's action never grows the cell. It centers on the trigger at the side you pick, flips to the opposite side when the visible area has no room there, and slides to stay inside it. Moving the pointer from the trigger onto the bubble keeps it up. With no OverlayProvider mounted it still floats, on an absolute anchor beside the trigger, but an ancestor that clips its content can then cut it off.
The bubble inverts against the page (dark in the light scheme, light in the dark one) and sets its text in Dark Factory's label type; iOS, which has no tooltip, shows the same bubble, and Android keeps the Material 3 plain tooltip.
The trigger is a boolean axis of its own, resolved first match wins:

Tokens

Read from the playground render. Values follow the scheme and the ion hue.
--bg
--fd
--ft
--ln2
--sf2
--sh-md
--tx

Related components