Based on the Tooltip Radix component.
Component Structure
Tooltip.Provider
Root-level provider to avoid regressions and enable consistent behavior across the app.
Place it near the top of your component tree.
Tooltip
Parent wrapper for Trigger and Content.
Handles positioning, accessibility, and visibility state.
Tooltip.Trigger
Element that, when hovered or focused, shows the tooltip.
Requires a React component child (or asChild prop) that accepts a ref to allow event bindings and accessibility props to be cloned.
Example: buttons, icons, links.
Tooltip.Content
The tooltip box itself.
Holds the text or elements you want displayed.
Handles positioning relative to the Trigger.
<Tooltip.Provider>
<Tooltip>
<Tooltip.Trigger>
<Text>Hover on me</Text>
</Tooltip.Trigger>
<Tooltip.Content>This is the tooltip content, hello</Tooltip.Content>
</Tooltip>
</Tooltip.Provider>
Default to open state
<Tooltip.Provider>
<Tooltip defaultOpen>
<Tooltip.Trigger>
<Text>Hover on me</Text>
</Tooltip.Trigger>
<Tooltip.Content>This is the tooltip content, hello</Tooltip.Content>
</Tooltip>
</Tooltip.Provider>
Custom delay on hover
<Tooltip.Provider>
<Tooltip delayDuration={1500}>
<Tooltip.Trigger>
<Text>Hover on me</Text>
</Tooltip.Trigger>
<Tooltip.Content>This is the tooltip content, hello</Tooltip.Content>
</Tooltip>
</Tooltip.Provider>
Prevent the user from being able to hover and potentially select content from Tooltip.Content
<Tooltip.Provider>
<Tooltip disableHoverableContent>
<Tooltip.Trigger>
<Text>Hover on me</Text>
</Tooltip.Trigger>
<Tooltip.Content>This is the tooltip content, hello</Tooltip.Content>
</Tooltip>
</Tooltip.Provider>
Custom Trigger
Use asChild on the Trigger component
Note: this is not standard behaviour, so check the usage tab, and make sure the designers are aware if you need to use this.
<Tooltip.Provider>
<Tooltip>
<Tooltip.Trigger asChild>
<Button>
<Text>Custom trigger</Text>
</Button>
</Tooltip.Trigger>
<Tooltip.Content>This is the tooltip content, hello</Tooltip.Content>
</Tooltip>
</Tooltip.Provider>
size
Controls the max width of the content box.
<Tooltip.Provider>
<Tooltip>
<Tooltip.Trigger>
<Text>Custom trigger</Text>
</Tooltip.Trigger>
<Tooltip.Content size='sm'>This is the tooltip content, hello. It should have limited width, so the text spans on many, many lines.</Tooltip.Content>
</Tooltip>
</Tooltip.Provider>
sticky
The sticky behavior on the align axis. "partial" will keep the content in the boundary as long as the trigger is at least partially in the boundary whilst "always" will keep the content in the boundary regardless.
<Tooltip.Provider>
<Tooltip>
<Tooltip.Trigger>
<Text>Custom trigger</Text>
</Tooltip.Trigger>
<Tooltip.Content sticky="always">This is the tooltip content, hello</Tooltip.Content>
</Tooltip>
</Tooltip.Provider>
side
The preferred side of the trigger to render against when open. Will be reversed when collisions occur and avoidCollisions is enabled.
<Tooltip.Provider>
<Tooltip>
<Tooltip.Trigger>
<Text>Custom trigger</Text>
</Tooltip.Trigger>
<Tooltip.Content side="left">This is the tooltip content, hello</Tooltip.Content>
</Tooltip>
</Tooltip.Provider>
sideOffset
The distance in pixels from the trigger.
<Tooltip.Provider>
<Tooltip>
<Tooltip.Trigger>
<Text>Custom trigger</Text>
</Tooltip.Trigger>
<Tooltip.Content side="left" sideOffset={10}>This is the tooltip content, hello</Tooltip.Content>
</Tooltip>
</Tooltip.Provider>
align
The preferred alignment against the trigger. May change when collisions occur.
<Tooltip.Provider>
<Tooltip>
<Tooltip.Trigger>
<Text>Custom trigger</Text>
</Tooltip.Trigger>
<Tooltip.Content side="left" align="start">This is the tooltip content, hello</Tooltip.Content>
</Tooltip>
</Tooltip.Provider>
alignOffset
An offset in pixels from the "start" or "end" alignment options.
<Tooltip.Provider>
<Tooltip>
<Tooltip.Trigger>
<Text>Custom trigger</Text>
</Tooltip.Trigger>
<Tooltip.Content side="left" align="start" alignOffset={25}>This is the tooltip content, hello</Tooltip.Content>
</Tooltip>
</Tooltip.Provider>
arrowPadding
The padding between the arrow and the edges of the content. If your content has border-radius, this will prevent it from overflowing the corners.
<Tooltip.Provider>
<Tooltip>
<Tooltip.Trigger>
<Text>Custom trigger</Text>
</Tooltip.Trigger>
<Tooltip.Content side="left" align="start" alignOffset={25} arrowPadding={12}>This is the tooltip content, hello</Tooltip.Content>
</Tooltip>
</Tooltip.Provider>
avoidCollisions
When true, overrides the side and align preferences to prevent collisions with boundary edges.
<Tooltip.Provider>
<Tooltip>
<Tooltip.Trigger>
<Text>Custom trigger</Text>
</Tooltip.Trigger>
<Tooltip.Content avoidCollisions side="left" align="start" alignOffset={25} arrowPadding={12}>This is the tooltip content, hello</Tooltip.Content>
</Tooltip>
</Tooltip.Provider>
collisionBoundary
The element used as the collision boundary. By default this is the viewport, though you can provide additional element(s) to be included in this check.
<div
id="tooltip-boundary"
className="w-[500px] h-[200px] border-2 border-dashed border-red-500 p-5 overflow-hidden relative"
>
<Tooltip.Provider>
<Tooltip>
<Tooltip.Trigger asChild>
<Button className="absolute bottom-2.5 right-12">
Hover me
</Button>
</Tooltip.Trigger>
<Tooltip.Content
side="right"
align="center"
avoidCollisions
collisionBoundary={document.getElementById("tooltip-boundary")}
>
Tooltip text
</Tooltip.Content>
</Tooltip>
</Tooltip.Provider>
</div>
collisionPadding
The distance in pixels from the boundary edges where collision detection should occur. Accepts a number (same for all sides), or a partial padding object, for example: { top: 20, left: 20 }.
<div
id="tooltip-boundary"
className="w-[500px] h-[200px] border-2 border-dashed border-red-500 p-5 overflow-hidden relative"
>
<Tooltip.Provider>
<Tooltip>
<Tooltip.Trigger asChild>
<Button className="absolute bottom-2.5 right-12">
Hover me
</Button>
</Tooltip.Trigger>
<Tooltip.Content
side="right"
align="center"
collisionBoundary={document.getElementById("tooltip-boundary")}
collisionPadding={20}
avoidCollisions
>
Tooltip text
</Tooltip.Content>
</Tooltip>
</Tooltip.Provider>
</div>
hideWhenDetached
Whether to hide the content when the trigger becomes fully occluded.
<Tooltip.Provider>
<Tooltip>
<Tooltip.Trigger id='trigger' onClick={() => document.getElementById('trigger').style.display = 'none'}>
Hover me
</Tooltip.Trigger>
<Tooltip.Content hideWhenDetached>
Tooltip text
</Tooltip.Content>
</Tooltip>
</Tooltip.Provider>
onEscapeKeyDown
Event handler called when the Escape key is pressed while the tooltip is open.
<Tooltip.Provider>
<Tooltip>
<Tooltip.Trigger id='trigger'>
Hover me
</Tooltip.Trigger>
<Tooltip.Content onEscapeKeyDown={() => alert("Pressed Escape")}>
Tooltip text
</Tooltip.Content>
</Tooltip>
</Tooltip.Provider>
onPointerDownOutside
Event handler called when a pointer event occurs outside the bounds of the component. It can be prevented by calling event.preventDefault.
<Tooltip.Provider>
<Tooltip>
<Tooltip.Trigger id='trigger'>
Hover me
</Tooltip.Trigger>
<Tooltip.Content onPointerDownOutside={(e) => {alert("Clicked outside"); e.preventDefault()} }>
Tooltip text
</Tooltip.Content>
</Tooltip>
</Tooltip.Provider>