Tooltip
Contextual, accessible help text for controls and interface elements.
Tooltip displays short contextual information when a trigger is hovered, focused, or activated. It supports edge placement, alignment, delay control, interactive content, keyboard dismissal, arrows, variants, sizes, and controlled visibility.
Basic usage
import { Tooltip } from '@mosmox/ui';
<Tooltip content="Save the current changes.">
<button type="button">Save</button>
</Tooltip>By default, the tooltip opens on pointer hover and keyboard focus, uses the top placement, the dark variant, the default size, an 8px offset, and a 160ms opening delay. It closes after an 80ms delay.
Tooltips should explain an unfamiliar control briefly. For essential instructions, validation, or interactive content, use visible supporting text or a dialog instead.
Placement and alignment
placement supports twelve positions: top, top-start, top-end, right, right-start, right-end, bottom, bottom-start, bottom-end, left, left-start, and left-end.
<Tooltip placement="top" content="Centered above"><Button>Top</Button></Tooltip>
<Tooltip placement="right-start" content="Aligned to the top"><Button>Right start</Button></Tooltip>
<Tooltip placement="bottom-end" content="Aligned to the end"><Button>Bottom end</Button></Tooltip>
<Tooltip placement="left" content="Centered on the left"><Button>Left</Button></Tooltip>offset controls the gap between the trigger and tooltip in pixels and defaults to 8. maxWidth accepts any CSS max-width value, including a number of pixels, a percentage, rem, or none.
Variants and sizes
The dark, light, and primary variants use shared theme tokens. Sizes are sm, default, and lg.
<Tooltip variant="dark" size="sm" content="Compact dark tooltip"><Button>Small</Button></Tooltip>
<Tooltip variant="light" size="default" content="Light tooltip"><Button>Light</Button></Tooltip>
<Tooltip variant="primary" size="lg" content="Large primary tooltip"><Button>Primary</Button></Tooltip>Set arrow={false} to hide the directional arrow.
Hover, focus, click, and interactive content
The trigger wrapper opens on hover and focus. Press Enter or Space on the trigger to toggle the tooltip, and press Escape to close it. interactive allows the pointer to move from the trigger into the tooltip content without closing it.
<Tooltip
interactive
content={<span>Read the <a href="/learn-more">full explanation</a>.</span>}
>
<button type="button">Learn more</button>
</Tooltip>Interactive content should be used sparingly. For a menu or a larger interactive surface, use a dedicated popover or menu component.
Delays and width
openDelay and closeDelay are measured in milliseconds. maxWidth accepts a CSS width value and defaults to 280px; long content wraps within that width.
<Tooltip
openDelay={500}
closeDelay={200}
maxWidth={360}
content="This tooltip waits before opening and remains visible briefly while the pointer leaves."
>
<Button>Delayed help</Button>
</Tooltip>Controlled visibility
Use open and onOpenChange when the parent owns the visibility. Use defaultOpen for an initially open uncontrolled tooltip. In controlled mode, the parent must update open in response to onOpenChange; the component reports requested state changes but does not own the state. disabled prevents all opening and hides the tooltip.
const [open, setOpen] = useState(false);
<Tooltip
open={open}
onOpenChange={setOpen}
content="Controlled tooltip"
>
<button type="button">Toggle help</button>
</Tooltip>onOpenChange receives the requested visibility state from hover, focus, keyboard, click, Escape, and outside-pointer behavior. Enter or Space toggles an uncontrolled tooltip. Escape closes it when closeOnEscape is enabled. Outside pointer interaction closes an open tooltip. With interactive, the tooltip content accepts pointer interaction; otherwise the content is pointer-transparent and leaving the trigger schedules a close.
Accessibility
When visible, the tooltip content has role="tooltip" and is connected to the trigger wrapper with aria-describedby. The wrapper handles keyboard focus interactions and Escape dismissal. The tooltip is not opened for disabled triggers. Tooltip content has no transition animation, so there is no motion to suppress for reduced-motion users.
Always provide meaningful content. If the trigger has no accessible name of its own, use a visible label or an accessible label on the trigger control; aria-label on Tooltip labels the tooltip content itself, not the trigger.
API Reference
| Property | Type | Default | Description |
|---|---|---|---|
children | ReactNode | — | Trigger content. |
content | ReactNode | — | Tooltip content. |
placement | TooltipPlacement | 'top' | Position and alignment relative to the trigger. |
variant | 'dark' | 'light' | 'primary' | 'dark' | Visual surface variant. |
size | 'sm' | 'default' | 'lg' | 'default' | Tooltip typography and padding size. |
arrow | boolean | true | Show the directional arrow. |
offset | number | 8 | Gap from the trigger in pixels. |
maxWidth | CSSProperties['maxWidth'] | 280 | Maximum tooltip width. |
open | boolean | — | Controlled visibility. |
defaultOpen | boolean | false | Initial uncontrolled visibility. |
onOpenChange | (open: boolean) => void | — | Called when visibility changes. |
openDelay | number | 160 | Opening delay in milliseconds. |
closeDelay | number | 80 | Closing delay in milliseconds. |
interactive | boolean | false | Keep the tooltip open while its content is hovered. |
closeOnEscape | boolean | true | Close on Escape. |
disabled | boolean | false | Prevent opening and hide the tooltip. |
aria-label | string | — | Accessible label for the tooltip content. |
className | string | — | Additional class on the trigger wrapper. |
TooltipPlacement values
top, top-start, top-end, right, right-start, right-end, bottom, bottom-start, bottom-end, left, left-start, and left-end.
top, right, bottom, and left center the tooltip on the trigger edge. The -start and -end variants align it to the corresponding edge of that side.
Theme tokens
Tooltip visuals use shared theme tokens and can be overridden through ConfigProvider. Component-only positioning, arrow, and interaction rules live in Tooltip.css.
| Token | Purpose |
|---|---|
--mm-color-text | Dark tooltip background. |
--mm-color-surface | Light tooltip background. |
--mm-color-white | Dark and primary tooltip text. |
--mm-color-primary | Primary tooltip background. |
--mm-color-control-border | Light tooltip border. |
--mm-radius-control | Tooltip corner radius. |
--mm-font-family-sans | Tooltip typography. |
The component also derives --mm-tooltip-offset and --mm-tooltip-max-width from the offset and maxWidth props for placement and sizing.