Components
Tooltip
A floating label that surfaces a short hint when the user hovers or focuses an element — built on Radix UI with a directional arrow and smooth enter/exit animation.
Basic usage
Wrap a trigger with asChild and pair it with TooltipContent. Hover or tab to the button to reveal the hint. There is no provider to mount first — every Tooltip carries its own.
Placement
Use side to set the preferred direction. The tooltip automatically flips to stay in view when space is tight.
On icon buttons
Tooltips shine on icon-only controls, giving each glyph a discoverable text label without cluttering the toolbar.
Open delay
Tooltip mounts its own TooltipProvider with delayDuration={0} so a single tooltip works with no setup. Change the timing by passing delayDuration straight to the Tooltip.
Trap: an outer provider cannot change the delay
Radix resolves the innermost provider, and the one built into Tooltip is always innermost. Wrapping a region in TooltipProvider therefore has no effect on these tooltips — including the delayDuration={200} provider that ShellProvider mounts in @comitor/ui/shell. To share timing across a screen, pass the same delayDuration to each Tooltip, or keep a constant next to your other layout values.
Props
Every part forwards the full Radix prop set and exports its own prop type — TooltipProps, TooltipTriggerProps, TooltipContentProps and TooltipProviderProps.
Tooltip — the root, which also carries the timing.
| Prop | Type | Default | Description |
|---|---|---|---|
delayDuration | number | 0 | Hover delay in ms before the tooltip opens. This is the only place the delay can be set — a surrounding TooltipProvider has no effect. |
open | boolean | — | Controlled open state. Pair with onOpenChange. |
defaultOpen | boolean | false | Open state when initially rendered (uncontrolled). |
onOpenChange | (open: boolean) => void | — | Called when the open state changes. |
disableHoverableContent | boolean | false | Closes as soon as the pointer leaves the trigger, instead of letting the pointer travel into the tooltip. |
TooltipContent — the floating label, portaled to the body. A TooltipPrimitive.Arrow is always rendered inside it; there is no prop to turn it off.
| Prop | Type | Default | Description |
|---|---|---|---|
childrenrequired | React.ReactNode | — | Tooltip content. Keep it to a short, plain-text label. |
side | 'top' | 'right' | 'bottom' | 'left' | 'top' | Preferred side of the trigger the content renders against. |
sideOffset | number | 0 | Distance in pixels between the trigger and the content. The built-in arrow already supplies the visual gap. |
align | 'start' | 'center' | 'end' | 'center' | Alignment of the content against the trigger. |
alignOffset | number | 0 | Offset in pixels along the alignment axis. |
avoidCollisions | boolean | true | Flips and shifts the tooltip to keep it inside the viewport. |
className | string | — | Additional Tailwind classes merged onto TooltipContent. The surface is w-fit on bg-foreground / text-background. |
TooltipProvider — exported for API parity with shadcn. You rarely need it: see the trap above.
| Prop | Type | Default | Description |
|---|---|---|---|
delayDuration | number | 0 | Shared hover delay. Kept for shadcn API compatibility — it only reaches Radix Tooltip roots you mount yourself, never a Tooltip from this package. |
skipDelayDuration | number | 300 | Window in ms during which moving to another trigger skips the delay. Same caveat: it does not reach this package's Tooltip. |
disableHoverableContent | boolean | false | Provider-level default. Resolved against the nearest provider exactly like delayDuration, so it does not reach this package's Tooltip either — set it on the Tooltip. |
TooltipTrigger takes asChild (default false) plus every native button prop.
Accessibility
- Opens on hover and keyboard focus, so the hint is reachable without a pointer, and dismisses on Esc.
- The content is wired to the trigger via
aria-describedby, so screen readers announce it alongside the trigger's name. - Always give an icon-only trigger its own
aria-label— a tooltip is a supplemental hint, not a replacement for an accessible name. - Reserve tooltips for non-essential hints; never hide content required to complete a task behind a hover-only tooltip.
- The surface inverts the page —
bg-foregroundwithtext-background— so contrast holds in both the default and high-contrast palettes. Restyle it with role tokens if you must, never with a raw scale.