Tooltip
A popup that displays information related to an element on focus or hover.
Tooltip is a contextual hint that appears when the trigger is hovered or focused. Keep the content short (name of an icon button, keyboard shortcut, brief description). For rich content, use HoverCard.
PRISM pattern: the trigger and the content are siblings inside a Tooltip wrapper. The content is rendered with the hidden attribute; the ui.js island removes it when the pointer enters the wrapper or when focus moves inside it, and restores it on leave, on blur and on Escape.
Shorthand: <Tooltip trigger={…} content="…" /> builds the TooltipTrigger and TooltipContent for you.
Installation
$ bext ui add tooltip
Copy and paste the following into src/components/ui/tooltip.tsx.
This component is interactive. Make sure the shared island is loaded (see Islands). It reacts to data-ui="tooltip" hooks.
Usage
Anatomy
<Tooltip> ├── <TooltipTrigger> │ └── <Button>Hover me</Button> └── <TooltipContent>Add to library</TooltipContent>
API Reference
Tooltip
| Prop | Type | Default | Description |
|---|---|---|---|
| children | ReactNode | — | Composed form: a TooltipTrigger and a TooltipContent. |
| trigger | ReactNode | — | Shorthand: the trigger element. Used with content instead of children. |
| content | ReactNode | — | Shorthand: the tooltip text. |
| id | string | — | Shorthand: id given to the TooltipContent. |
| className | string | — | Extra classes on the wrapper, a with relative inline-flex. |
TooltipTrigger
| Prop | Type | Default | Description |
|---|---|---|---|
| children | ReactNode | — | Trigger element. Use a focusable one (button, link) so the tooltip also shows on keyboard focus. |
TooltipContent
| Prop | Type | Default | Description |
|---|---|---|---|
| id | string | — | Optional id. Without it the island generates one to build aria-describedby on the trigger. |
| children | ReactNode | — | Tooltip text. |
| className | string | — | Extra classes. Default: absolute, above the trigger and centered, bg-primary text-primary-foreground text-xs px-3 py-1.5 rounded-md, single line. |
Data Attributes
Attributes you can target in custom CSS to override the style for each state.
| Attribute | On | Values | Description |
|---|---|---|---|
| data-ui="tooltip" | Tooltip | — | The island listens for pointer and focus events on this wrapper. |
| data-ui="tooltip-trigger" | TooltipTrigger | — | Marks the trigger wrapper. The island sets aria-describedby on the focusable element inside it. |
| data-ui="tooltip-content" | TooltipContent | hidden attribute present or absent | The island shows it by removing hidden and hides it by restoring it. |
Keyboard
| Key | Action |
|---|---|
| Tab | Focusing the trigger shows the tooltip; moving focus away hides it. |
| Escape | Hides the tooltip. Focus stays on the trigger. |
Accessibility
TooltipContent has role="tooltip". The island gives it an id when it has none and sets aria-describedby on the focusable element inside TooltipTrigger, so the text is announced as the description of that element. A description is not a name: an icon-only button still needs its own aria-label.
The tooltip shows on hover and on keyboard focus, provided the trigger is focusable (a <button> or a link). It stays visible while the pointer is over it, and Escape hides it without moving focus.
Content must stay short (≤ 60 characters). For more, use HoverCard or Popover.
Examples
On an icon button
Edit this component live in the bext playground. The PRISM + signals version is the bext-native idiom: fine-grained reactivity, no virtual DOM.
On This Page