Tooltip

canon

One-line label for a control, on hover and on keyboard focus.

AD 14 September 2026 (OV-3): Popover and Tooltip stay two separate elements — they differ in how they open (click vs hover/focus), layer (101 vs 120), role and keyboard (arrows only in Popover); merging would rewrite both for no saving.

Used in 25 files · 8 areas · 46× — components/AppShell, components/mail, components/meetings, components/notes, components/sales-reports, components/segment …

Keyboard

  • The bubble opens on focus and closes on blur (capture handlers on the wrapper), so a keyboard user gets the same information as a mouse user — this is the part most tooltip implementations miss and this one has.
  • The bubble itself is never focusable and never traps focus (pointer-events: none).
  • Escape does not dismiss it; moving focus away does.
  • The 80 ms delay applies to focus as well as hover.

ARIA

  • The bubble carries role="tooltip" and gets an id; the single child trigger is cloned with aria-describedby pointing at it, so the text is announced as the control's description, after its name.
  • content={null} renders nothing at all — no empty bubble, no dangling aria-describedby.
  • The tooltip is a description, never the name: an icon-only control still needs its own aria-label.
  • A disabled <button> is not focusable in most browsers, so the explanation on a disabled action is reachable by pointer but not by Tab — a real limit of the pattern, not of this component.

Focus

  • No focus style of its own; the trigger keeps whatever ring it has (foundation ring from ds.css).
  • The bubble does not move focus and cannot steal it.

Contrast

Computed from packages/ui/src/tokens/tokens.css:

  • White text on --ink-900 = 17.59:1 light, 14.53:1 dark (the bubble keeps its own inverted surface in both themes).
  • The bubble has no border; separation comes from the fill and --shadow-pop.
  • Text is var(--small) at weight 500 — small, but far above the AA minimum thanks to the inverted surface.

Known limits

  • A disabled control cannot take keyboard focus, so its tooltip is pointer-only.
  • No touch equivalent: on a phone there is no hover, and the bubble is not tappable.
  • Only above/below placement; a trigger at the very top or bottom edge gets the flipped position, never a side one.
  • The hide is immediate, so the bubble cannot be "reached" — deliberate, but it means the text must be short enough to read at a glance.

Source: docs/popover/tooltip.a11y.md · GitLab