Tooltip
Contextual hints on hover or focus, with directional placement including leading and trailing sides.
Installation
The components are exported from @by/experience-system. Add the package with your package manager:
pnpm add @by/experience-systemIn this monorepo, depend on the workspace package (for example via workspace:* or your catalog) so imports resolve to packages/experience-system.
Composition
Wrap tooltips in TooltipProvider, then compose Tooltip, TooltipTrigger, and TooltipContent:
TooltipProvider
└── Tooltip
├── TooltipTrigger
└── TooltipContent
└── TooltipArrow (rendered by Experience System Content)Use TooltipTrigger asChild so the trigger stays a real Button or focusable control. Content is portaled to the ThemeProvider container when configured. See Radix Tooltip.
Usage
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
Button,
} from '@by/experience-system';TooltipProvider, Tooltip, TooltipTrigger, and TooltipContent are client components ('use client'). Use them inside a Client Component or a dynamic import when using the Next.js App Router.
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<Button variant="outline">Save</Button>
</TooltipTrigger>
<TooltipContent side="top">Save your changes</TooltipContent>
</Tooltip>
</TooltipProvider>Examples
Overview
Placements top, bottom, leading, and trailing around a frame (leading / trailing follow ThemeProvider direction).
Ellipsis with tooltip
Single-line, multi-line, and non-truncated cases using the registry TooltipEllipsisRecipe (wrapped in TooltipProvider).
Single-line truncation
Multi-line truncation
No tooltip when text fits
API Reference
TooltipProvider, Tooltip, TooltipTrigger, and TooltipContent map to Radix Tooltip parts. The tables for Provider, Root, Trigger, Portal, Content, and Arrow follow Radix Tooltip. TooltipContent extends side with leading and trailing, resolved via ThemeProvider direction. The Experience System TooltipProvider sets delayDuration={300} and skipDelayDuration={100} before ...props, so callers can override.
TooltipProvider
| Prop | Type | Default |
|---|---|---|
delayDuration | number | 300 (then Radix / caller override via ...props) |
skipDelayDuration | number | 100 |
disableHoverableContent | boolean | — |
Tooltip
| Prop | Type | Default |
|---|---|---|
defaultOpen | boolean | — |
open | boolean | — |
onOpenChange | (open: boolean) => void | — |
delayDuration | number | — |
disableHoverableContent | boolean | — |
| Data attribute | Values |
|---|---|
data-slot | tooltip |
TooltipTrigger
| Prop | Type | Default |
|---|---|---|
asChild | boolean | false |
| Data attribute | Values |
|---|---|
data-slot | tooltip-trigger |
data-state | closed | delayed-open | instant-open |
TooltipContent
| Prop | Type | Default |
|---|---|---|
asChild | boolean | false |
side | top | right | bottom | left | leading | trailing | top |
align | start | center | end | center |
sideOffset | number | 4 |
alignOffset | number | 0 |
aria-label | string | — |
onEscapeKeyDown | (event: KeyboardEvent) => void | — |
onPointerDownOutside | (event: PointerDownOutsideEvent) => void | — |
forceMount | boolean | — |
avoidCollisions | boolean | true |
collisionBoundary | Boundary | [] |
collisionPadding | number | Padding | 0 |
arrowPadding | number | 0 |
sticky | partial | always | partial |
hideWhenDetached | boolean | false |
| Data attribute | Values |
|---|---|
data-slot | tooltip-content |
data-state | closed | delayed-open | instant-open |
data-side | left | right | bottom | top |
data-align | start | end | center |
| CSS variable | Description |
|---|---|
--radix-tooltip-content-transform-origin | Computed transform origin for content and arrow |
--radix-tooltip-content-available-width | Remaining width between trigger and boundary |
--radix-tooltip-content-available-height | Remaining height between trigger and boundary |
--radix-tooltip-trigger-width | Trigger width |
--radix-tooltip-trigger-height | Trigger height |
Accessibility
Keep tooltip text short; avoid essential information only in a tooltip. Prefer visible labels and aria-describedby for critical help. TooltipTrigger asChild preserves the child control’s role and focus behavior. See Radix Tooltip — accessibility.
Keyboard interactions
| Key | Description |
|---|---|
Tab | Opens or closes the tooltip without delay when moving focus. |
Space | If open, closes the tooltip without delay. |
Enter | If open, closes the tooltip without delay. |
Escape | If open, closes the tooltip. |
Source in the repo: packages/experience-system/src/components/Tooltip/Tooltip.tsx. Agent-oriented contracts: packages/experience-system/src/components/Tooltip/Tooltip.instructions.md.
Registry examples
This @by-es item is a registry-only composite — live preview, installation steps, and source live on the dedicated page. See Registry for components.json setup and REGISTRY_TOKEN.
Ellipsis with tooltip
Truncated text with an overflow-only tooltip using Tooltip from @by/experience-system.