Skip to content

Tooltip

Open in GitHub

A small popup that appears when hovering over or focusing on an element.

Add to library

---
import { Button } from '@bejamas/ui/components/button';
import { Tooltip, TooltipContent, TooltipTrigger } from '@bejamas/ui/components/tooltip';
---
<Tooltip>
<TooltipTrigger asChild>
<Button variant="outline">Hover</Button>
</TooltipTrigger>
<TooltipContent>
<p>Add to library</p>
</TooltipContent>
</Tooltip>
Terminal window
bunx bejamas add tooltip
---
import { Tooltip, TooltipTrigger, TooltipContent } from '@bejamas/ui/components/tooltip';
import { Button } from '@bejamas/ui/components/button';
---
<Tooltip>
<TooltipTrigger asChild>
<Button variant="outline">Hover</Button>
</TooltipTrigger>
<TooltipContent>
<p>Add to library</p>
</TooltipContent>
</Tooltip>

This tooltip appears after 1000ms

---
import { Button } from '@bejamas/ui/components/button';
import { Tooltip, TooltipContent, TooltipTrigger } from '@bejamas/ui/components/tooltip';
---
<Tooltip delay={1000}>
<TooltipTrigger asChild>
<Button variant="outline">Hover with delay</Button>
</TooltipTrigger>
<TooltipContent>
<p>This tooltip appears after 1000ms</p>
</TooltipContent>
</Tooltip>

When a tooltip is shown, hovering over other tooltip triggers will show their tooltips immediately without delay. Try hovering over the first button, then quickly move to the others.

Bold (Ctrl+B)

Italic (Ctrl+I)

Underline (Ctrl+U)

---
import { Button } from '@bejamas/ui/components/button';
import { Tooltip, TooltipContent, TooltipTrigger } from '@bejamas/ui/components/tooltip';
---
<div class="flex gap-2">
<Tooltip delay={500}>
<TooltipTrigger asChild>
<Button variant="outline">Bold</Button>
</TooltipTrigger>
<TooltipContent>
<p>Bold (Ctrl+B)</p>
</TooltipContent>
</Tooltip>
<Tooltip delay={500}>
<TooltipTrigger asChild>
<Button variant="outline">Italic</Button>
</TooltipTrigger>
<TooltipContent>
<p>Italic (Ctrl+I)</p>
</TooltipContent>
</Tooltip>
<Tooltip delay={500}>
<TooltipTrigger asChild>
<Button variant="outline">Underline</Button>
</TooltipTrigger>
<TooltipContent>
<p>Underline (Ctrl+U)</p>
</TooltipContent>
</Tooltip>
</div>

Use the side prop to control which side the tooltip appears on.

Tooltip on left

Tooltip on top

Tooltip on bottom

Tooltip on right

---
import { Button } from '@bejamas/ui/components/button';
import { Tooltip, TooltipContent, TooltipTrigger } from '@bejamas/ui/components/tooltip';
---
<div class="flex gap-4 items-center justify-center py-8">
<Tooltip>
<TooltipTrigger asChild>
<Button variant="outline">Left</Button>
</TooltipTrigger>
<TooltipContent side="left">
<p>Tooltip on left</p>
</TooltipContent>
</Tooltip>
<Tooltip>
<TooltipTrigger asChild>
<Button variant="outline">Top</Button>
</TooltipTrigger>
<TooltipContent side="top">
<p>Tooltip on top</p>
</TooltipContent>
</Tooltip>
<Tooltip>
<TooltipTrigger asChild>
<Button variant="outline">Bottom</Button>
</TooltipTrigger>
<TooltipContent side="bottom">
<p>Tooltip on bottom</p>
</TooltipContent>
</Tooltip>
<Tooltip>
<TooltipTrigger asChild>
<Button variant="outline">Right</Button>
</TooltipTrigger>
<TooltipContent side="right">
<p>Tooltip on right</p>
</TooltipContent>
</Tooltip>
</div>

Use the align prop to control how the tooltip aligns relative to the trigger.

Aligned to start

Aligned to center

Aligned to end

Aligned to start

Aligned to center

Aligned to end

---
import { Button } from '@bejamas/ui/components/button';
import { Tooltip, TooltipContent, TooltipTrigger } from '@bejamas/ui/components/tooltip';
---
<div class="flex flex-col gap-4 items-center py-8">
<div class="flex gap-4">
<Tooltip>
<TooltipTrigger asChild>
<Button variant="outline">Top Start</Button>
</TooltipTrigger>
<TooltipContent side="top" align="start">
<p>Aligned to start</p>
</TooltipContent>
</Tooltip>
<Tooltip>
<TooltipTrigger asChild>
<Button variant="outline">Top Center</Button>
</TooltipTrigger>
<TooltipContent side="top" align="center">
<p>Aligned to center</p>
</TooltipContent>
</Tooltip>
<Tooltip>
<TooltipTrigger asChild>
<Button variant="outline">Top End</Button>
</TooltipTrigger>
<TooltipContent side="top" align="end">
<p>Aligned to end</p>
</TooltipContent>
</Tooltip>
</div>
<div class="flex gap-4">
<Tooltip>
<TooltipTrigger asChild>
<Button variant="outline">Bottom Start</Button>
</TooltipTrigger>
<TooltipContent side="bottom" align="start">
<p>Aligned to start</p>
</TooltipContent>
</Tooltip>
<Tooltip>
<TooltipTrigger asChild>
<Button variant="outline">Bottom Center</Button>
</TooltipTrigger>
<TooltipContent side="bottom" align="center">
<p>Aligned to center</p>
</TooltipContent>
</Tooltip>
<Tooltip>
<TooltipTrigger asChild>
<Button variant="outline">Bottom End</Button>
</TooltipTrigger>
<TooltipContent side="bottom" align="end">
<p>Aligned to end</p>
</TooltipContent>
</Tooltip>
</div>
</div>

This feature is currently unavailable

---
import { Button } from '@bejamas/ui/components/button';
import { Tooltip, TooltipContent, TooltipTrigger } from '@bejamas/ui/components/tooltip';
---
<Tooltip>
<TooltipTrigger asChild>
<Button variant="outline" disabled>Disabled</Button>
</TooltipTrigger>
<TooltipContent>
<p>This feature is currently unavailable</p>
</TooltipContent>
</Tooltip>

The tooltip emits custom events that you can listen to:

EventDetailDescription
tooltip:change{ open: boolean, trigger: HTMLElement, content: HTMLElement, reason: string }Fired when visibility changes
<Tooltip id="my-tooltip">
<TooltipTrigger asChild>
<Button variant="outline">Hover me</Button>
</TooltipTrigger>
<TooltipContent>
<p>Tooltip content</p>
</TooltipContent>
</Tooltip>
<script>
const tooltip = document.getElementById('my-tooltip');
tooltip.addEventListener('tooltip:change', (e) => {
console.log('Is open:', e.detail.open);
console.log('Reason:', e.detail.reason);
});
</script>

You can control the tooltip programmatically by dispatching a tooltip:set event:

const tooltip = document.getElementById('my-tooltip');
// Show the tooltip
tooltip.dispatchEvent(new CustomEvent('tooltip:set', {
detail: { open: true }
}));
// Hide the tooltip
tooltip.dispatchEvent(new CustomEvent('tooltip:set', {
detail: { open: false }
}));

The tooltip sets these data attributes that you can use for styling or querying state:

AttributeElementDescription
data-statetooltip, tooltip-contentCurrent state (open or closed)
data-sidetooltip-contentPosition relative to trigger (top, right, bottom, or left)
data-aligntooltip-contentAlignment (start, center, or end)