Tooltip
Migration guide for Tooltip from HeroUI v2 to v3
Refer to the v3 Tooltip documentation for complete API reference, styling guide, and advanced examples. This guide only focuses on migrating from HeroUI v2.
Structure Changes
In v2, Tooltip used a content prop:
import { Tooltip, Button } from "@heroui/react";
export default function App() {
return (
<Tooltip content="I am a tooltip">
<Button>Hover me</Button>
</Tooltip>
);
}In v3, Tooltip requires compound components:
import { Tooltip, Button } from "@heroui/react";
export default function App() {
return (
<Tooltip>
<Tooltip.Trigger>
<Button>Hover me</Button>
</Tooltip.Trigger>
<Tooltip.Content>
I am a tooltip
</Tooltip.Content>
</Tooltip>
);
}Key Changes
1. Component Structure
v2: Simple Tooltip with content prop and children as trigger
v3: Compound components (Tooltip.Trigger, Tooltip.Content, Tooltip.Arrow)
2. Prop Changes
| v2 Prop | v3 Location | Notes |
|---|---|---|
content | — | Use Tooltip.Content children |
showArrow | showArrow (on Content) | Moved to Tooltip.Content |
placement | placement (on Content) | Moved to Tooltip.Content |
offset | offset (on Content) | Moved to Tooltip.Content |
color | — | Removed (use Tailwind CSS) |
size | — | Removed (use Tailwind CSS) |
radius | — | Removed (use Tailwind CSS) |
shadow | — | Removed (use Tailwind CSS) |
classNames | — | Use className props on individual components |
motionProps | — | Removed (animations handled differently) |
trigger | trigger (on root) | Still exists: "hover" | "focus" (default "hover") |
isDisabled | isDisabled (on root) | New in v3: disables the tooltip entirely |
delay | delay (on root) | Still exists (default changed from 0 to 700) |
closeDelay | closeDelay (on root) | Still exists (default 0) |
portalContainer | — | Not exposed |
updatePositionDeps | — | Not exposed |
containerPadding, crossOffset | — | Not exposed |
shouldFlip | — | Handled automatically |
triggerScaleOnOpen | — | Not available |
isKeyboardDismissDisabled | — | Not available |
isDismissable | — | Not available |
shouldCloseOnBlur | — | Not available |
shouldCloseOnInteractOutside | — | Not available |
onClose | — | Use onOpenChange instead |
3. Props Moved to Tooltip.Content
showArrow- Now onTooltip.Contentplacement- Now onTooltip.Contentoffset- Now onTooltip.Content
Migration Examples
Content Configuration
{/* With arrow */}
<Tooltip content="I am a tooltip" showArrow>
<Button>Hover me</Button>
</Tooltip>
{/* With placement */}
<Tooltip content="Tooltip" placement="bottom">
<Button>Hover me</Button>
</Tooltip>
{/* With offset */}
<Tooltip content="Tooltip" offset={12}>
<Button>Hover me</Button>
</Tooltip>{/* With arrow */}
<Tooltip delay={0}>
<Tooltip.Trigger>
<Button>Hover me</Button>
</Tooltip.Trigger>
<Tooltip.Content showArrow>
<Tooltip.Arrow />
<p>I am a tooltip</p>
</Tooltip.Content>
</Tooltip>
{/* With placement */}
<Tooltip delay={0}>
<Tooltip.Trigger>
<Button>Hover me</Button>
</Tooltip.Trigger>
<Tooltip.Content placement="bottom">
<p>Tooltip</p>
</Tooltip.Content>
</Tooltip>
{/* With offset */}
<Tooltip delay={0}>
<Tooltip.Trigger>
<Button>Hover me</Button>
</Tooltip.Trigger>
<Tooltip.Content offset={12}>
<p>Tooltip</p>
</Tooltip.Content>
</Tooltip>Controlled Tooltip
import { useState } from "react";
const [isOpen, setIsOpen] = useState(false);
<Tooltip
content="I am a tooltip"
isOpen={isOpen}
onOpenChange={setIsOpen}
>
<Button>Hover me</Button>
</Tooltip>import { useState } from "react";
const [isOpen, setIsOpen] = useState(false);
<Tooltip isOpen={isOpen} onOpenChange={setIsOpen} delay={0}>
<Tooltip.Trigger>
<Button>Hover me</Button>
</Tooltip.Trigger>
<Tooltip.Content>
<p>I am a tooltip</p>
</Tooltip.Content>
</Tooltip>With Delay
<Tooltip content="Tooltip" delay={500} closeDelay={200}>
<Button>Hover me</Button>
</Tooltip><Tooltip delay={500} closeDelay={200}>
<Tooltip.Trigger>
<Button>Hover me</Button>
</Tooltip.Trigger>
<Tooltip.Content>
<p>Tooltip</p>
</Tooltip.Content>
</Tooltip>Custom Content
<Tooltip
content={
<div>
<strong>Title</strong>
<p>Description</p>
</div>
}
>
<Button>Hover me</Button>
</Tooltip><Tooltip delay={0}>
<Tooltip.Trigger>
<Button>Hover me</Button>
</Tooltip.Trigger>
<Tooltip.Content>
<div>
<strong>Title</strong>
<p>Description</p>
</div>
</Tooltip.Content>
</Tooltip>With Custom Trigger
<Tooltip content="Tooltip">
<div className="custom-trigger">Custom trigger</div>
</Tooltip><Tooltip delay={0}>
<Tooltip.Trigger className="custom-trigger">
<div>Custom trigger</div>
</Tooltip.Trigger>
<Tooltip.Content>
<p>Tooltip</p>
</Tooltip.Content>
</Tooltip>Component Anatomy
The v3 Tooltip follows this structure:
Tooltip (Root)
├── Tooltip.Trigger
│ └── [Trigger element]
└── Tooltip.Content
├── Tooltip.Arrow (optional)
└── [Tooltip content]New Props in v3
isDisabled
The isDisabled prop allows you to completely disable the tooltip. When disabled, the tooltip will not appear on hover or focus:
<Tooltip isDisabled>
<Tooltip.Trigger>
<Button>No tooltip</Button>
</Tooltip.Trigger>
<Tooltip.Content>
<p>This will not show</p>
</Tooltip.Content>
</Tooltip>trigger
The trigger prop controls how the tooltip is activated. It accepts "hover" (default) or "focus":
{/* Show tooltip only on focus */}
<Tooltip trigger="focus">
<Tooltip.Trigger>
<Button>Focus me</Button>
</Tooltip.Trigger>
<Tooltip.Content>
<p>Shown on focus only</p>
</Tooltip.Content>
</Tooltip>Custom Render Function
Tooltip.Content and Tooltip.Arrow both support a render prop that allows you to override the default DOM element with a custom render function for advanced use cases.
Important Notes
Content Prop
- v2: Used
contentprop for tooltip text/content - v3: Content goes as children of
Tooltip.Contentcomponent
Arrow
- v2: Controlled by
showArrowprop on root - v3: Use
showArrowprop onTooltip.Contentand includeTooltip.Arrowcomponent
Placement and Offset
- v2:
placementandoffsetprops on root - v3:
placementandoffsetprops moved toTooltip.Content
Trigger Element
- v2: Children were automatically used as trigger
- v3: Must wrap trigger element in
Tooltip.Triggercomponent
Default Delay
- v2:
delaydefault was0 - v3:
delaydefault is700(note: examples usedelay={0}to match v2 behavior)
Summary
- Component Structure: Must use compound components (
Tooltip.Trigger,Tooltip.Content,Tooltip.Arrow) - Content Prop Removed:
contentprop removed - useTooltip.Contentchildren - Props Moved:
showArrow,placement,offsetmoved toTooltip.Content - Styling Props Removed:
color,size,radius,shadow- use Tailwind CSS - ClassNames Removed: Use
classNameprops on individual components - Motion Props Removed:
motionPropsremoved - animations handled differently - Advanced Props Removed: Many positioning and behavior props removed
- Default Delay Changed: Default delay changed from
0to700 - isDisabled Prop: New
isDisabledprop to completely disable the tooltip - trigger Prop: Accepts
"hover"(default) or"focus"to control activation method - Render Props:
Tooltip.ContentandTooltip.Arrowsupport arenderprop for custom DOM rendering