Tooltip
View as MarkdownA popup that appears when an element is hovered or focused, showing a hint for sighted users.
<ui:tooltip.root>
<ui:tooltip.trigger asChild="{true}">
<ui:button>Hover me</ui:button>
</ui:tooltip.trigger>
<ui:tooltip.content>This is the tooltip content.</ui:tooltip.content>
</ui:tooltip.root>
import { mountAll } from 'fluid-primitives';
import { Tooltip } from 'fluid-primitives/tooltip';
mountAll('tooltip', ({ props }) => {
const tooltip = new Tooltip(props);
tooltip.init();
return tooltip;
});
Features
- Opens on hover and focus
- Closes on pointer down or Escape key press
- Supports custom open and close delays
- Supports custom positioning with placement options
- Automatically adjusts position to stay in viewport
Installation
typo3 ui:add tooltip
Please copy the files manually from GitHub into your project.
Read more about installing Components and Primitives.
Examples
Custom Positioning
Control where the tooltip appears relative to the trigger.
<ui:tooltip.root positioning="{placement: 'right'}">
<ui:tooltip.trigger asChild="{true}">
<ui:button>Hover for right tooltip</ui:button>
</ui:tooltip.trigger>
<ui:tooltip.content>I appear on the right!</ui:tooltip.content>
</ui:tooltip.root>
Open Delay
Set a custom delay before the tooltip opens.
<ui:tooltip.root openDelay="1000">
<ui:tooltip.trigger asChild="{true}">
<ui:button>Slow tooltip (1000ms)</ui:button>
</ui:tooltip.trigger>
<ui:tooltip.content>I took 1000ms to appear.</ui:tooltip.content>
</ui:tooltip.root>
Close Delay
Set a custom delay before the tooltip closes after the pointer leaves.
<ui:tooltip.root closeDelay="500">
<ui:tooltip.trigger asChild="{true}">
<ui:button>Lingers for 500ms</ui:button>
</ui:tooltip.trigger>
<ui:tooltip.content>I stay visible for 500ms after you leave.</ui:tooltip.content>
</ui:tooltip.root>
Disabled Interaction
Prevent the tooltip from opening on hover.
<ui:tooltip.root disabled="{true}">
<ui:tooltip.trigger asChild="{true}">
<ui:button>No tooltip here</ui:button>
</ui:tooltip.trigger>
<ui:tooltip.content>You won't see this.</ui:tooltip.content>
</ui:tooltip.root>
On Icon Buttons
Common pattern for icon-only buttons that need accessible labels.
<ui:tooltip.root>
<ui:tooltip.trigger asChild="{true}">
<ui:button variant="ghost" size="icon">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4">
<path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z"></path>
<circle cx="12" cy="12" r="3"></circle>
</svg>
<span class="sr-only">Settings</span>
</ui:button>
</ui:tooltip.trigger>
<ui:tooltip.content>Settings</ui:tooltip.content>
</ui:tooltip.root>
API Reference
The following tables cover the available props of the Fluid Primitives. For a full list of available client side props and methods, see the Zag.js Machine API.
tooltip.root
Provides tooltip state and context for the composed parts. Renders no wrapper element.
| Name | Description | Required | Default |
|---|---|---|---|
defaultOpen | booleanThe initial open state of the tooltip when rendered. Use when you don't need to control the open state of the tooltip. | No | false |
disabled | booleanWhether the tooltip is disabled. | No | false |
openDelay | integerThe open delay of the tooltip. | No | 400 |
closeDelay | integerThe close delay of the tooltip. | No | 150 |
closeOnPointerDown | booleanWhether to close the tooltip on pointerdown. | No | true |
closeOnEscape | booleanWhether to close the tooltip when the Escape key is pressed. | No | true |
closeOnScroll | booleanWhether the tooltip should close on scroll. | No | true |
closeOnClick | booleanWhether the tooltip should close on click. | No | true |
interactive | booleanWhether the tooltip's content is interactive and remains open when hovered. | No | false |
positioning | arrayThe user provided options used to position the popover content. | No | - |
rootId | stringThe root ID of the component, used for hydration and identification. | No | - |
ids | arrayThe IDs of of the component parts for composition. | No | [] |
controlled | booleanIf true, the component is meant to be initialized manually inside another component | No | false |
tooltip.trigger
Acts as the anchor that opens the tooltip. Renders a <button> element.
| Name | Description | Required | Default |
|---|---|---|---|
value | string | No | - |
asChild | booleanIf true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. | No | - |
class | stringThe CSS class(es) to be applied to the component. | No | - |
attributes | arrayAdditional attributes that should be rendered on the component where ui:attributes is used. | No | [] |
Rendered data attributes
| Attribute | Description |
|---|---|
data-scope | tooltip |
data-part | trigger |
data-value | The value of the item |
data-current | Present when current |
data-expanded | Present when expanded |
data-state | "open" | "closed" |
tooltip.positioner
Positions the tooltip content relative to the trigger. Renders a <div> element.
| Name | Description | Required | Default |
|---|---|---|---|
asChild | booleanIf true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. | No | - |
class | stringThe CSS class(es) to be applied to the component. | No | - |
attributes | arrayAdditional attributes that should be rendered on the component where ui:attributes is used. | No | [] |
tooltip.content
Displays the tooltip bubble content. Renders a <div> element.
| Name | Description | Required | Default |
|---|---|---|---|
asChild | booleanIf true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. | No | - |
class | stringThe CSS class(es) to be applied to the component. | No | - |
attributes | arrayAdditional attributes that should be rendered on the component where ui:attributes is used. | No | [] |
Rendered data attributes
| Attribute | Description |
|---|---|
data-scope | tooltip |
data-part | content |
data-state | "open" | "closed" |
data-instant | |
data-placement | The placement of the content |
data-side | The side of the trigger that the content is positioned on |
tooltip.arrow
Displays a decorative tooltip arrow. Renders a <div> element.
| Name | Description | Required | Default |
|---|---|---|---|
asChild | booleanIf true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. | No | - |
class | stringThe CSS class(es) to be applied to the component. | No | - |
attributes | arrayAdditional attributes that should be rendered on the component where ui:attributes is used. | No | [] |
Machine JavaScript API
| Name | Type | Description |
|---|---|---|
open | boolean | Whether the tooltip is open. |
setOpen | (open: boolean) => void | Function to open the tooltip. |
triggerValue | string | null | The trigger value |
setTriggerValue | (value: string | null) => void | Function to set the trigger value |
reposition | (options?: Partial<PositioningOptions>) => void | Function to reposition the popover |
Accessibility
| Key | Description |
|---|---|
Tab | Opens/closes the tooltip without delay. |
Escape | If open, closes the tooltip without delay. |
Anatomy
<primitives:tooltip.root>
<primitives:tooltip.trigger />
<primitives:tooltip.positioner>
<primitives:tooltip.content>
<primitives:tooltip.arrow />
</primitives:tooltip.content>
</primitives:tooltip.positioner>
</primitives:tooltip.root>