Tooltip
A hover/focus hint on Ark UI's Tooltip — ARIA-wired (role="tooltip" + aria-describedby), portaled and animated. Drops into running text or wraps any element.
Tooltip is the kit's lightweight hint — the hover/focus counterpart to Popover's clickable panel. It's a styled layer over Ark UI's Tooltip: Ark owns the open/close state, the open/close delays, positioning, and the accessibility wiring — role="tooltip" on the bubble, aria-describedby on the trigger, Esc to dismiss, and no focus trap. The kit adds the portaled, animated, inverted bubble.
It opens on pointer hover and keyboard focus, so it's accessible by default.
import { Tooltip } from '@42/ui-react/tooltip';
// Inline in text — children become a focusable trigger
<p>Validate the <Tooltip label="A graded project.">Norm</Tooltip> first.</p>
// Wrap an element — asChild makes the child the trigger
<Tooltip label="Delete" asChild>
<ActionIcon aria-label="Delete"><Trash2 /></ActionIcon>
</Tooltip>On a button
The common case: wrap any interactive element with asChild. The tooltip names or expands on the control.
Code
<Tooltip label="Saved automatically every few seconds" asChild><Button variant="default">Hover or focus me</Button></Tooltip>On an icon-only control
Pair it with an ActionIcon. Keep the aria-label on the icon — that's the accessible name; the tooltip is the visible echo for sighted users.
Code
<Tooltip label="Delete" asChild><ActionIcon aria-label="Delete" variant="subtle" color="gray"> <Trash2 /></ActionIcon></Tooltip>Inline in text
Without asChild, the children are wrapped in a focusable inline <span> trigger that inherits the surrounding font — so a tooltip drops straight into a <p>, and the term stays selectable, copyable prose (a <button> would be excluded from text selection). Use variant="text" for a dotted-underline glossary look, or the default variant="inline" to leave the text unstyled; classNames.trigger overrides either. To attach a hint to an element you already have (a link, an icon button), use asChild so that element becomes the trigger.
Every cadet must validate the Norm before moving on to the next milestone.
Code
<p>Every cadet must validate the{" "}<Tooltip label="A graded project in the 42 curriculum." variant="text"> Norm</Tooltip>{" "}before moving on to the next milestone.</p>Positioning
position sets the placement and offset the gap; the bubble flips and shifts to stay in view (Ark / Floating UI). Prefer the logical, RTL-aware sides start / end — they resolve to left / right based on the active direction, so the tooltip mirrors automatically under dir="rtl". (Physical left / right and Ark's aligned variants like top-start still work.)
Code
<Tooltip label="Placed start" position="start" asChild><Button variant="default">start</Button></Tooltip><Tooltip label="Placed top" position="top" asChild><Button variant="default">top</Button></Tooltip><Tooltip label="Placed bottom" position="bottom" asChild><Button variant="default">bottom</Button></Tooltip><Tooltip label="Placed end" position="end" asChild><Button variant="default">end</Button></Tooltip>With an arrow
Pass withArrow to grow a small arrow that points back at the trigger — a clearer visual tie when the bubble sits away from its anchor. It inherits the inverted surface, flips with the placement, and tucks behind the bubble so only the tip shows. In the compound form, compose a Tooltip.Arrow inside Tooltip.Content instead; restyle it with classNames.arrow (or the part's own className).
Code
<Tooltip label="Points back at the trigger" withArrow asChild><Button variant="default">Hover or focus me</Button></Tooltip>Playground
Tooltip
Dir
Presets
Props
Code
<Tooltip label="Saved automatically" position="top" variant="inline" openDelay={400} closeDelay={150}/>Anatomy
Tooltip— the convenience form: alabelplus a single child trigger.Tooltip.Root— wraps Ark'sTooltip.Root; owns open state, delays, and positioning.Tooltip.Trigger— the trigger; useasChildto wrap your own element.Tooltip.Content— the portaled, animated bubble (role="tooltip").Tooltip.Arrow— an optional arrow pointing at the trigger; place it insideTooltip.Content.
<Tooltip.Root position="end">
<Tooltip.Trigger asChild>
<Button>Hover</Button>
</Tooltip.Trigger>
<Tooltip.Content>
<Tooltip.Arrow />
Rich <strong>content</strong>
</Tooltip.Content>
</Tooltip.Root>API
Tooltip props (the convenience form; Tooltip.Root takes the same props minus label / asChild / withArrow / classNames):
Prop
Type