Tooltip#

A short label that appears on hover or focus and describes its trigger. The popup is a role="tooltip" on popover="manual" — the top layer without light dismiss, because a tooltip closes when the pointer or focus leaves, never because the user clicked elsewhere — and the trigger references it through aria-describedby while it is open.

Import#

TSX
import { Tooltip } from '@sigx/zero/tooltip';

Tooltip is a compound: Tooltip.Root, Tooltip.Trigger, Tooltip.Popup. It is also re-exported from the @sigx/zero root, together with tooltipAnatomy and useTooltipContext.

Usage#

TSX
import { component } from 'sigx';
import { Tooltip } from '@sigx/zero/tooltip';

const SaveButton = component(({ signal }) => {
    const state = signal({ hint: false });

    return () => (
        <Tooltip.Root model={() => state.hint} placement="top">
            <Tooltip.Trigger asChild>
                {(p) => <button type="button" {...p} onClick={save}>Save</button>}
            </Tooltip.Trigger>
            <Tooltip.Popup>Save the document</Tooltip.Popup>
        </Tooltip.Root>
    );
});

model={() => state.hint} binds the open state both ways; the usual composition leaves it off and lets hover and focus drive the tooltip, with openChange reporting each change. There is no defaultOpen — a tooltip starts closed. See Models.

Tooltip.Root renders no element of its own — it only provides context. The tooltip opens immediately on focus and after openDelay on hover; it closes on blur or pointer-leave after closeDelay. Moving the pointer onto the popup itself keeps it open.

Delays#

TSX
<Tooltip.Root openDelay={300} closeDelay={100}>

openDelay is the hover intent — focus opens at once regardless. A non-zero closeDelay lets the pointer cross the gap between trigger and popup without the tooltip flickering.

Placement#

TSX
<Tooltip.Root placement="bottom-start" offset={8}>

placement accepts the fourteen placement names; the position behavior flips when there is no room and stamps the resolved value as data-placement on the popup. offset is the gap in px, and positionStrategy swaps the positioning implementation. See Positioning.

The trigger is the described element#

Tooltip.Trigger renders a real <button> so that keyboard users can reach the description. It is a plain hover / focus surface: it carries the open / closed state and the disabled flag, and no press feedback and no focus-visible flag — a tooltip describes the element it wraps rather than acting. The common composition is therefore asChild around your actual control, as above, so the anatomy lands on the element that already has its own press states.

Anatomy#

PartElementStatesFlagsNotes
triggerbuttonopen | closeddisabledaria-describedby → the popup while open. The anchor. Carries the variant axes. asChild.
popupdivopen | closedpopover="manual", role="tooltip", data-placement (resolved).

Tooltip's Root renders a fragment, so there is no root part. The trigger is the carrier part: the variant axes live on Tooltip.Trigger, and a design system's axis rules for the scope anchor there. Because the trigger declares only disabled, a design system author should reuse their overlay-trigger shape for it — not the pressed / press-animating states of their button recipe, which will never match here. See The anatomy contract.

Props#

Tooltip.Root#

PropTypeDefaultDescription
modelbooleanTwo-way binding of the open state.
openChangeevent (open: boolean)Fires whenever the open state changes.
openDelaynumber600Hover intent before opening, in ms; focus opens immediately.
closeDelaynumber0Delay before closing after pointer-leave or blur, in ms.
placementPlacement'top'Preferred side and alignment; the resolved value renders as data-placement on the popup.
offsetnumber6Gap between the trigger and the popup, in px.
positionStrategyPositionStrategyfixed-coordinatesReplaces the positioning implementation.

Tooltip.Trigger#

PropTypeDefaultDescription
disabledbooleanfalseRenders data-disabled and the native disabled attribute.
color / size / variant / axes / modsdesign-system vocabularyThe variant axes for the scope, rendered on the trigger.
asChildbooleanfalseRender through the default slot, which receives the part bag.
classstringExtra classes.

Tooltip.Popup#

Only class.

Keyboard and dismissal#

InteractionAction
Focus the triggerOpens immediately.
Blur the triggerCloses after closeDelay.
EscapeCloses wherever focus is — a document-level listener covers hover-opened tooltips too — and clears any pending hover-open so it cannot reappear.
Click outsideNot a dismissal; the tooltip is popover="manual".

Escape never moves focus; the tooltip closes and the user stays where they were.

In the shipped design systems#

@sigx/zero-basic and @sigx/zero-daisyui both wire color (the eight recommended roles) and size (xsxl) on the tooltip trigger. Neither wires a variant or any mods on the scope. The popup is styled by every shipped design system, including the open / closed transition and a placement-keyed arrow.

Popover when the surface holds interactive content · Kbd for showing the shortcut a tooltip describes.