Skip to main content

Design system components

Tooltip

Radix tooltip primitive set (Provider, Trigger, Content) for icon hints.

Status: beta. Group: overlay. Markdown version: /design-system/components/tooltip.md

When to use

Tooltip is the composed Radix primitive set for supplementary hints on focusable controls; most often icon-only buttons. Wrap a subtree in TooltipProvider (sets delayDuration, default 200ms), then per hint: Tooltip (open state) containing TooltipTrigger asChild around the real control and TooltipContent with the text and a side placement (top by default, flips when out of room). It opens on hover and keyboard focus, dismisses on Escape, and Radix links the content to the trigger via aria-describedby. The content is description, not a name: the trigger still needs its own accessible label.

When not to use

  • Do not put interactive content (links, buttons) inside a tooltip; it cannot be reached by keyboard or touch; use a Modal or disclosure instead.
  • Do not use a tooltip as the only label of a control; give the control a real accessible name and let the tooltip add detail.
  • Do not attach tooltips to non-focusable elements; hover-only hints exclude keyboard and touch users.

Look-alikes

  • Modal: Do not put interactive content (links, buttons) inside a tooltip; it cannot be reached by keyboard or touch; use a Modal or disclosure instead.

Props

Tooltip props
PropTypeDefaultDescriptionRequired
classNamestringnoneExtra class on the content bubble.No
side"left" | "right" | "top" | "bottom"nonePreferred placement relative to the trigger; flips when out of room.No
sideOffsetnumbernoneGap in px between the trigger and the bubble.No
childrenReactNodenoneHint content; a short phrase, never interactive.Yes
shortcutstring[]noneKeys held together for the trigger's action, one entry per key; rendered after the label as keycaps joined by plus signs. Modifier symbols (⌘ ⇧ ⌥ ⌃ ⌫ ↵) render as icons with a translated key name for assistive technology.No

Variants

  • Allowed side values: left, right, top, bottom.

Invalid combinations

The contract records no invalid combinations.

Keyboard

Tooltip keyboard behaviour
KeyBehaviour
TabMoves focus to the control and on to the next focusable element. (standard)
EscapeCloses or dismisses the open layer. (standard)

Rows marked (standard) name a key the contract lists without a description; the behaviour shown is the usual one for that key.

Rules

Every item under When not to use is a MUST NOT. MUST and SHOULD follow RFC 2119.

Tooltip rules
LevelRuleHow it is checked
MUSTARIA: Opens on hover AND keyboard focus of the trigger.Not yet verified: no evidence record. WCAG 4.1.2.
MUSTARIA: Escape dismisses without moving focus.Not yet verified: no evidence record. WCAG 4.1.2.
MUSTARIA: Content is linked to the trigger via aria-describedby (Radix)Not yet verified: no evidence record. WCAG 4.1.2.
MUSTARIA: Content must be supplementary; never put essential or interactive content in a tooltip.Not yet verified: no evidence record. WCAG 4.1.2.
MUSTRequired stories produce no axe violations at the configured severity.Automated by npm run test:stories:matrix:ci. WCAG 2.5.8.
MUSTThe accessibility tree (role, name, state) matches the committed snapshot for every required story.Automated by npm run test:stories:matrix:ci. WCAG 1.3.1, 4.1.2.
MUSTThe component remains legible and operable under a real browser forced-colors: active pass.Automated by npm run test:stories:hc.
MUSTEvery documented keyboard interaction works as specified.Not yet verified: no evidence record. WCAG 2.1.1, 2.1.2.
MUSTA human completed an end-to-end accessibility review of this component.Manual review, last on 2026-07-03.
SHOULDWrap the trigger with asChild so your real Button/IconButton receives the tooltip wiring instead of a nested extra button.Not stated in the contract.
SHOULDUse one TooltipProvider per surface (page or toolbar) so the open delay is shared and hopping between adjacent triggers feels instant.Not stated in the contract.
SHOULDKeep content to a short phrase; the tooltip supplements the control's accessible name (aria-describedby), it does not replace it.Not stated in the contract.
SHOULDPick side by surrounding space; Radix flips automatically when the preferred side runs out of room.Not stated in the contract.
SHOULDShow a keyboard shortcut with the shortcut prop, never hand-built Kbd children: it sizes the keycaps to the label, draws modifier symbols as icons and joins keys with plus signs. Pass platform words (Ctrl, Shift) on Windows.Not stated in the contract.
SHOULD NOTDo not put links, buttons, or anything interactive inside TooltipContent; it is unreachable by keyboard and touch.Not stated in the contract.
SHOULD NOTDo not rely on a tooltip as the only label of an icon-only control; give the control aria-label and use the tooltip for the visible hint.Not stated in the contract.

Install and import

  • Install: npm install @digitaltableteur/react (version 0.9.1, restricted access on npm).
  • Import: import { Tooltip } from "@digitaltableteur/react";
  • Entry point: @digitaltableteur/react/feedback exports it too.
  • Styles: import @digitaltableteur/react/style.css once at the app boundary.
  • Also available as the custom element <dt-tooltip>; see the custom elements manifest.