Tooltip

A positioned descriptive surface shown on hover or focus. The trigger keeps focus and the tooltip is exposed via aria-describedby.

Features

  • Hover and focus open
  • Delayed close with hover bridge
  • Escape to dismiss
  • Portalled tooltip content
  • Placement-aware state hooks
  • Optional arrow

Installation

npm install @ariaui/tooltip

Examples

Two playgrounds from the legacy doc: uncontrolled hover/focus and controlled open state. Shared layout classes live in tooltipExampleTokens.ts next to these demos.

Content uses role="tooltip" and stays non-interactive — use Popover or HoverCard when users need to act inside the panel.

Uncontrolled

Default open-on-hover/focus behavior with placement and offset; no React state required.

Preview

No preview output yet.

live.tsxReady

Controlled

Drive visibility with open and onOpenChange, useful when coordinating with other UI or analytics.

Preview

No preview output yet.

live.tsxReady

Framer Motion

Keep the tooltip mounted through close and let Framer Motion animate the surface.

Preview

No preview output yet.

live.tsxReady

Anatomy

tsx
import * as Tooltip from "@ariaui/tooltip";

export default function Example() {
  return (
    <Tooltip.Root>
      <Tooltip.Trigger />
      <Tooltip.Content />
    </Tooltip.Root>
  );
}

API Reference

Root

Context provider and state owner for the tooltip. Does not render a DOM element.

PropTypeDefault
open
boolean
defaultOpen
booleanfalse
onOpenChange
(open: boolean) => void
placement
string'top'
offset
number

Trigger

Element that opens and closes the tooltip. Renders a `<button>` by default; use `asChild` to slot trigger props onto another element. Hover and focus open the tooltip. Mouse leave and blur close it, while moving the cursor from the trigger to the tooltip content keeps it open.

PropTypeDefault
asChild
booleanfalse
hover
booleantrue
focus
booleantrue
AttributeValues
aria-describedbyID of the `Content` element when open; absent when closed

Content

Portalled tooltip panel. Renders nothing when closed. Hovering over the content cancels the close timer; leaving restarts it. Renders a `<div>`.

PropTypeDefault
asChild
booleanfalse
arrow
booleanfalse
AttributeValues
role'tooltip'
data-state'delayed-open' when visible
data-sideactive placement side — 'top', 'bottom', 'left', or 'right'

Keyboard

ShortcutAction
EscImmediately closes the tooltip when the trigger has focus.
TabMoves focus away from the trigger, closing the tooltip.
Shift+TabMoves focus away from the trigger, closing the tooltip.

Accessibility

Tooltip follows the WAI-ARIA APG Tooltip pattern — a descriptive surface that supplements, but never replaces, the trigger's accessible name:

  • The Content element receives role="tooltip" and an auto-generated id that the Trigger exposes via aria-describedby while open. Focus stays on the trigger — tooltip content is never a focus target.
  • The trigger must be keyboard-focusable. Use a native <button> (the default) or pass as with an interactive element; wrapping a non-focusable element requires tabIndex={0} so keyboard users can reveal the tooltip.
  • Escape closes an open tooltip immediately without moving focus, so keyboard users can dismiss a tooltip that overlaps other content.
  • Never put essential information only in a tooltip. Touch-only users and some assistive-tech users cannot hover — duplicate critical content in a visible label, description, or help text.
  • Keep tooltip content short and non-interactive. Interactive controls inside a tooltip violate the pattern; use a Popover or HoverCard when users must click or tab into the content.
  • data-side reflects the active placement so you can style the arrow and transitions per-edge without additional JS.
Previous
Toggle Group