Components Overlays
Tooltip
StableA short text label that appears on hover and keyboard focus.
Tooltips name icon-only controls and add brief, non-essential hints. They appear after a short delay on hover and immediately on keyboard focus, stay open while hovered, and close on Escape. Tooltip text must not be the only place important information lives, and it cannot contain links or buttons; use Popover or HoverCard for interactive content.
Overview
import { Button, Icon, Tooltip } from '@bindshq/stance-react';
export function Basic() {
return (
<Tooltip content="Copy signature HTML">
<Button variant="outline" size="sm" aria-label="Copy signature HTML">
<Icon name="copy" />
</Button>
</Tooltip>
);
}Light, dark and high contrast
Every Stance component is designed and tested in all three appearance modes.
Import
import { Tooltip, TooltipProvider } from '@bindshq/stance-react';Platforms
Tooltip has native counterparts. They share Stance tokens and intent, and use each platform’s own controls and conventions. The live previews on this page are the web implementation.
import { Tooltip, TooltipProvider } from '@bindshq/stance-react';Examples
import { Button, Tooltip } from '@bindshq/stance-react';
export function Placement() {
return (
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 12 }}>
{(['top', 'right', 'bottom', 'left'] as const).map((side) => (
<Tooltip key={side} content={`Shown on the ${side}`} side={side}>
<Button variant="secondary" size="sm">
{side}
</Button>
</Tooltip>
))}
</div>
);
}API reference
Tooltip
| Prop | Type | Default | Description |
|---|---|---|---|
content* required | ReactNode | None | Tooltip text. Keep it under ~80 characters. |
children* required | ReactElement | None | A single focusable element. Wrap disabled buttons in a focusable span if they need a tooltip. |
side | 'top' | 'right' | 'bottom' | 'left' | 'top' | Preferred side; flips near edges. |
align | 'start' | 'center' | 'end' | 'center' | Alignment along the side. |
sideOffset | number | 6 | Gap from the trigger in px. |
delay | number | 500 | Hover delay in ms (falls back to the provider). |
closeDelay | number | 100 | Grace period so the pointer can move onto the tooltip. |
open / defaultOpen / onOpenChange | boolean / boolean / (open: boolean) => void | None | Controlled or uncontrolled state. |
disabled | boolean | false | Never show the tooltip. |
className | string | None | Class for the tooltip bubble. |
TooltipProvider
| Prop | Type | Default | Description |
|---|---|---|---|
delay | number | 500 | Default hover delay for descendants. |
skipDelay | number | 300 | Window after a tooltip closes in which the next opens instantly. |
Accessibility
- The bubble has role="tooltip" and is referenced from the trigger with aria-describedby while visible (existing descriptions are preserved).
- Opens on keyboard focus without a delay; opening by click focus is suppressed to avoid flicker.
- Hoverable and dismissible without moving the pointer, meeting WCAG 1.4.13 Content on Hover or Focus.
- Touch input never opens tooltips; do not rely on them for essential information.
Keyboard
| Keys | Action |
|---|---|
| Tab | Focusing the trigger shows the tooltip. |
| Esc | Hides the tooltip. |
Usage guidelines
Do
- Use to name icon-only buttons (in addition to their aria-label).
- Keep text short and sentence-case.
Don’t
- Put links, buttons or form fields in a tooltip.
- Repeat the visible label of the trigger.