V2 componentsUpdated Nov 9, 2026
Tooltip
A short label that names a control on hover or keyboard focus, after a 300ms delay. Use it for icon-only buttons and to show its hotkey. Dark in both themes, like Toast, so it reads as chrome rather than part of the page. Never put anything interactive or essential in it: touch users never see it. For rich or clickable content use Preview Card or Popover.
Source: packages/ui/src/components/tooltip
import { Tooltip } from '@highlight/ui'Change the props; the preview and the snippet update together.
<Tooltip> <Tooltip.Trigger render={<Button>Share</Button>} /> <Tooltip.Content> Share summary </Tooltip.Content></Tooltip>Pass the control through render so the trigger is a single element. Keep its aria-label.
import { Button, Tooltip } from '@highlight/ui'import { Copy } from 'lucide-react' export default function TooltipBasic() { return ( <Tooltip> <Tooltip.Trigger render={ <Button aria-label="Copy link" shape="square" variant="ghost"> <Copy /> </Button> } /> <Tooltip.Content>Copy link</Tooltip.Content> </Tooltip> )}Takes the same "cmd+k" string as Button's hotkey prop and renders the same keycap chips.
import { Button, Tooltip } from '@highlight/ui'import { Search } from 'lucide-react' export default function TooltipHotkey() { return ( <Tooltip> <Tooltip.Trigger render={ <Button aria-label="Search" shape="square" variant="ghost"> <Search /> </Button> } /> <Tooltip.Content> Search <Tooltip.Hotkey hotkey="cmd+k" /> </Tooltip.Content> </Tooltip> )}Wrap neighbours in Provider: once one opens, the next opens without the delay. Each keeps its own popup, so use Group for a tight row.
import { Button, Tooltip } from '@highlight/ui' const SIDES = ['top', 'right', 'bottom', 'left'] as const export default function TooltipSides() { return ( <Tooltip.Provider> <div className="flex flex-wrap items-center justify-center gap-3"> {SIDES.map((side) => ( <Tooltip key={side}> <Tooltip.Trigger render={ <Button size="sm" variant="outline" className="capitalize"> {side} </Button> } /> <Tooltip.Content side={side}>Opens on the {side}</Tooltip.Content> </Tooltip> ))} </div> </Tooltip.Provider> )}Wrap a row of icon buttons in Group, e.g. message actions or a toolbar. The tooltips share one popup that moves between triggers and swaps its text, so sliding along the row never closes and reopens it. Tooltips inside keep their usual markup, even in child components.
import { Button, Tooltip } from '@highlight/ui'import { Copy, Link2, RotateCcw, ThumbsDown, ThumbsUp, Volume2 } from 'lucide-react' const ACTIONS = [ { label: 'Copy message', Icon: Copy }, { label: 'Read aloud', Icon: Volume2 }, { label: 'Retry', Icon: RotateCcw }, { label: 'Copy link', Icon: Link2 }, { label: 'Good response', Icon: ThumbsUp }, { label: 'Bad response', Icon: ThumbsDown },] export default function TooltipGroup() { return ( <Tooltip.Group> <div className="flex items-center gap-1.5"> {ACTIONS.map(({ label, Icon }) => ( <Tooltip key={label}> <Tooltip.Trigger render={ <Button aria-label={label} size="sm" shape="square" variant="ghost"> <Icon /> </Button> } /> <Tooltip.Content>{label}</Tooltip.Content> </Tooltip> ))} </div> </Tooltip.Group> )}Wraps at 240px. If it needs more than two lines, it belongs on the page.
import { Button, Tooltip } from '@highlight/ui' export default function TooltipLong() { return ( <Tooltip> <Tooltip.Trigger render={<Button variant="outline">Auto-join</Button>} /> <Tooltip.Content> Highlight joins every meeting on your calendar that has a video link, and leaves when the last person does. </Tooltip.Content> </Tooltip> )}The root, then any compound sub-components. Every part accepts className and forwards the rest of its props to the element or Base UI part beneath it.
Tooltip- Base UI Tooltip.Root. Owns the open state; holds the trigger and the content.
Tooltip.Provider- Shares the delay across neighbouring tooltips, so the next opens without it. closeDelay defaults to 100ms to bridge gaps.
Tooltip.Group- A Provider whose tooltips share one popup (Base UI multiple triggers). Root props on a Tooltip inside it, like open, are ignored.
Tooltip.Trigger- Unstyled trigger; use render to supply a Button. delay defaults to 300.
Tooltip.Content- side (default top), sideOffset (8), align, alignOffset, collisionAvoidance.
Tooltip.Hotkey- Kbd: hotkey="cmd+k" as keycap chips after the label, the same chips as Button.
Tooltip.Portal / Positioner / Popup- Low-level parts.