Tooltip
Tooltip displays a floating label on hover or focus to provide brief
contextual information. It wraps the Spar headless Tooltip primitive and adds
Takeoff visual vocabulary — variant, header, description, and arrow slots.
Usage
import { Tooltip } from '@takeoff-ui/react-spar';
<Tooltip>
<Tooltip.Trigger />
<Tooltip.Content>
<Tooltip.Header />
<Tooltip.Description />
<Tooltip.Arrow />
</Tooltip.Content>
</Tooltip>
To share delay configuration across a group of tooltips, wrap them in
Tooltip.Provider:
<Tooltip.Provider delayDuration={300} skipDelayDuration={150}>
{/* multiple <Tooltip /> instances */}
</Tooltip.Provider>
Playground
Variants
Placement
Header & Description
Arrow
Provider
Wrap a group of tooltips in Tooltip.Provider to share delayDuration and a
skipDelayDuration window — once one tooltip in the group has opened, moving to
a sibling within the skip window opens it instantly. Recommended for
toolbar-style clusters (WCAG 1.4.13).
Controlled
Accessibility & Keyboard
- Trigger uses
aria-describedbypointing to the content element. - Content has
role="tooltip". - Tooltip respects
WCAG 1.4.13— hoverable content remains visible while the pointer is over it. - Escape key dismisses the tooltip and returns focus to the trigger.
| Key | Behavior |
|---|---|
| Escape | Dismiss the tooltip. |
| Tab | Focus trigger shows tooltip; blur hides it. |
API Reference
Tooltip
See Spar Tooltip docs for primitive behavior.
Props
| Name | Type | Default | Description |
|---|---|---|---|
| children | React.React.ReactNode | - | Tooltip trigger and content components |
| id | string | - | Custom base ID for ARIA relationships. If not provided, one will be generated automatically. Sub-element IDs are derived as ${id}-trigger and ${id}-content. |
| disabled | boolean | false | Whether tooltip is disabled |
| open | boolean | - | Controlled state for tooltip visibility |
| defaultOpen | boolean | false | Default open state for uncontrolled tooltip |
| delay | number | - | Override provider delay for this tooltip |
| hideDelay | number | 0 | Override provider hide delay for this tooltip |
Events
| Name | Type | Default | Description |
|---|---|---|---|
| onOpenChange | (open: boolean) => void | - | Callback when tooltip open state changes |
Tooltip.Content
Props
| Name | Type | Default | Description |
|---|---|---|---|
| children | React.React.ReactNode | - | |
| variant | TooltipVariant | 'white' | Color variant. |
| classNames | Partial<Record<"root", string>> | - | Per-slot extra classes. |
| slotProps | Partial<Record<"root", React.HTMLAttributes<HTMLElement>>> | - | Per-slot HTML-attribute overrides. |
| container | HTMLElement | null | document.body | Portal container element. Content is portaled to document.body by default. |
| side | Side | 'top' | Preferred placement relative to trigger |
| align | Align | 'center' | Alignment relative to trigger |
| className | string | - |
Events
| Name | Type | Default | Description |
|---|---|---|---|
| onOpenAutoFocus | (event: Event) => void | - | Called when auto-focusing on open |
| onCloseAutoFocus | (event: Event) => void | - | Called when auto-focusing on close |
| onEscapeKeyDown | (event: KeyboardEvent) => void | - | Escape key handler |
| onPointerDownOutside | (event: PointerEvent) => void | - | Outside pointer down handler |
Data attributes
| Attribute | Applied when | Purpose |
|---|---|---|
| data-slot="root" | Always | Stable selector for wrapper styling on the root slot. |
| data-variant | Always | Reflects the resolved variant for theme recipe scoping. |
Tooltip.Header
Data attributes
| Attribute | Applied when | Purpose |
|---|---|---|
| data-slot="root" | Always | Stable selector for the header. |
Tooltip.Description
Data attributes
| Attribute | Applied when | Purpose |
|---|---|---|
| data-slot="root" | Always | Stable selector for the description. |
Tooltip.Trigger
Tooltip.Arrow
Type Definitions
| Name | Definition |
|---|---|
| TooltipVariant | 'white' | 'dark' | 'info' | 'success' | 'warning' | 'danger' | 'neutral' |
| Side | 'top' | 'right' | 'bottom' | 'left' |
| Align | 'start' | 'center' | 'end' |
| TooltipTriggerRenderProps | { isOpen: boolean; disabled: boolean; show: () => void; hide: () => void } |