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.
Overview
The Tooltip component in HeroUI v3 has been redesigned with a compound component pattern, requiring explicit structure with Tooltip.Trigger, Tooltip.Content, and Tooltip.Arrow components. The content prop has been removed.
Structure Changes
v2: Content Prop
In v2, Tooltip used a content prop:
import { Tooltip, Button } from "@heroui/react";
<Tooltip content="I am a tooltip">
<Button>Hover me</Button>
</Tooltip>v3: Compound Components
In v3, Tooltip requires compound components:
import { Tooltip, Button } from "@heroui/react";
<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 Prop | Notes |
|---|---|---|
content | - | Removed (use Tooltip.Content children) |
showArrow | showArrow (on Tooltip.Content) | Moved to Tooltip.Content |
placement | placement (on Tooltip.Content) | Moved to Tooltip.Content |
offset | offset (on Tooltip.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 |
motionProps | - | Removed (animations handled differently) |
trigger | trigger (on root) | Still exists, but simplified |
delay | delay (on root) | Still exists |
closeDelay | closeDelay (on root) | Still exists |
3. Removed Props
The following props are no longer available in v3:
content- UseTooltip.Contentchildren insteadcolor,size,radius,shadow- Use Tailwind CSS classesclassNames- UseclassNameprops on individual componentsmotionProps- Animations handled differentlyportalContainer- Not exposedupdatePositionDeps- Not exposedcontainerPadding,crossOffset- Not exposedshouldFlip- Handled automaticallytriggerScaleOnOpen- Not availableisKeyboardDismissDisabled- Not availableisDismissable- Not availableshouldCloseOnBlur- Not availableshouldCloseOnInteractOutside- Not availableonClose- UseonOpenChangeinstead
4. Props Moved to Tooltip.Content
showArrow- Now onTooltip.Contentplacement- Now onTooltip.Contentoffset- Now onTooltip.Content
Migration Examples
Basic Usage
import { Tooltip, Button } from "@heroui/react";
export default function App() {
return (
<Tooltip content="I am a tooltip">
<Button>Hover me</Button>
</Tooltip>
);
}import { Tooltip, Button } from "@heroui/react";
export default function App() {
return (
<Tooltip delay={0}>
<Tooltip.Trigger>
<Button>Hover me</Button>
</Tooltip.Trigger>
<Tooltip.Content>
<p>I am a tooltip</p>
</Tooltip.Content>
</Tooltip>
);
}With Arrow
<Tooltip content="I am a tooltip" showArrow>
<Button>Hover me</Button>
</Tooltip><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 content="Tooltip" placement="bottom">
<Button>Hover me</Button>
</Tooltip><Tooltip delay={0}>
<Tooltip.Trigger>
<Button>Hover me</Button>
</Tooltip.Trigger>
<Tooltip.Content placement="bottom">
<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>Custom Styling
<Tooltip
content="Tooltip"
color="primary"
size="lg"
classNames={{
base: "custom-base",
content: "custom-content"
}}
>
<Button>Hover me</Button>
</Tooltip><Tooltip delay={0}>
<Tooltip.Trigger>
<Button>Hover me</Button>
</Tooltip.Trigger>
<Tooltip.Content className="custom-content bg-accent text-accent-foreground">
<p>Tooltip</p>
</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>With Offset
<Tooltip content="Tooltip" offset={12}>
<Button>Hover me</Button>
</Tooltip><Tooltip delay={0}>
<Tooltip.Trigger>
<Button>Hover me</Button>
</Tooltip.Trigger>
<Tooltip.Content offset={12}>
<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]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)
Breaking Changes 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
Tips for Migration
- Update structure: Wrap trigger in
Tooltip.Triggerand content inTooltip.Content - Remove content prop: Move content to
Tooltip.Contentchildren - Add arrow: Use
showArrowonTooltip.Contentand includeTooltip.Arrowcomponent - Move placement: Move
placementprop toTooltip.Content - Move offset: Move
offsetprop toTooltip.Content - Update styling: Replace styling props with Tailwind CSS classes
- Update classNames: Replace
classNamesprop withclassNameprops on individual components - Set delay: If you need immediate tooltip (like v2 default), set
delay={0}
Need Help?
For v3 Tooltip features and API:
- See the API Reference
- Check interactive examples
For community support: