import Tooltip from '@cronocode/react-box/components/tooltip';<Tooltip content="Deletes the row for good">
{(trigger) => <Button {...trigger}>Delete</Button>}
</Tooltip>aria-describedby on the element the user lands on — the control itself, not a wrapper around it. Cloning a child would mean guessing where that attribute goes, and this library has two answers: Box takes DOM attributes in a props bag, a plain <button> takes them at the top level. So the trigger is handed to you instead, and you say where it belongs. It carries a ref too — the bubble is positioned against the trigger's own box, which is what keeps it under the control and out of the layout.// A Box component — ref and props are both top-level Box props, so one spread does it.
<Tooltip content="Save the draft">{(trigger) => <Button {...trigger}>Save</Button>}</Tooltip>
// A plain element — the same two pieces, named.
<Tooltip content="Save the draft">{(trigger) => <button ref={trigger.ref} {...trigger.props}>Save</button>}</Tooltip>| Input | Result |
|---|---|
Pointer rests on the trigger | Shows under the trigger after openDelay (300 ms by default). |
Pointer leaves the trigger | Hides after closeDelay (150 ms) — unless it lands on the tooltip. |
Pointer moves onto the tooltip | Stays open for as long as it is there. |
Tab to the trigger | Shows immediately: focus ignores openDelay. |
Tab away | Hides, unless the pointer is still on the trigger. |
Escape | Hides. Focus stays on the trigger, and it does not come back until the pointer leaves and returns. |
Tab, again | Reaches the next control — the tooltip is never in the tab order. |
closeDelay (150 ms) rather than closing, so the pointer can travel onto the tooltip — to read a long description, or to select text in it. Once it is on the tooltip, the tooltip keeps it open.—const [open, setOpen] = useState(false);
<Tooltip
content="Deletes the row for good"
open={open}
onOpenChange={(next, { reason }) => {
setOpen(next);
console.log(reason); // 'hover' | 'focus' | 'pointer-leave' | 'blur' | 'escape'
}}
>
{(trigger) => <Button {...trigger}>Delete</Button>}
</Tooltip><Tooltip> styles the bubble, on top of the built-in tooltip component style (inverted against the page, so it reads as an overlay in either theme). adjustTranslateX and adjustTranslateY nudge where it lands.<Tooltip content="On brand" bgColor="indigo-600" color="white" borderRadius={2} adjustTranslateY="4px">
{(trigger) => <Button {...trigger}>Delete</Button>}
</Tooltip>overflow: hidden is not. The portal-and-position half of this component ships on its own as Overlay — no ARIA, no open state, no dismissal — and that is what to reach for when the thing being rendered is not a description of a control. Before A3 this component was that primitive, so code that used it to escape an overflow becomes Overlay, unchanged.import Overlay from '@cronocode/react-box/components/overlay';
<Overlay p={3} bgColor="slate-800">anything, anywhere</Overlay>