Skip to content
Glint UI

Tooltip

A hover-revealed bubble that displays a brief description or keyboard shortcut when a trigger receives pointer hover or keyboard focus.

Usage

import { Button } from "@glint/components/button.slint";
import { Tooltip, TooltipSide } from "@glint/components/tooltip.slint";
export component AppWindow inherits Window {
HorizontalLayout {
alignment: center;
Tooltip {
text: "Save document";
side: TooltipSide.top;
Button {
text: "Save";
}
}
}
}

A Tooltip wraps an interactive trigger control via its @children slot and reveals a concise contextual label after a brief hover delay.

Unlike standard toolkit tooltips, Glint’s Tooltip renders in a floating PopupWindow layer above other elements, sizes itself to its text using design tokens, and supports dual pointer/keyboard activation.

Examples

Sides

side sets which edge of the trigger the tooltip bubble anchors to: top (the default), right, bottom, or left.

Keyboard focus activation

active lets you trigger the tooltip from keyboard focus. By binding active to the wrapped control’s focus-held property, keyboard users navigating with Tab receive the same tooltip hints as pointer users.

Custom hover delays

open-delay (default 300ms) controls how long the pointer must rest on the trigger before the bubble opens, preventing visual noise during rapid pointer transit. close-delay (default 100ms) provides a brief grace period to absorb pointer jitter.

API Reference

Properties

PropertyTypeDefaultDescription
textin stringno defaultLabel rendered inside the bubble.
sidein TooltipSideTooltipSide.topWhich edge of the trigger to anchor to — top (default), right, bottom, left.
open-delayin duration300msHow long the pointer must rest on the trigger before the bubble opens, so incidental hovers never flash it. Radix's delayDuration is 700ms; Glint opens sooner, and matches HoverCard.open-delay — two surfaces that both appear on hover must not appear at different speeds, or the slower one reads as broken.
close-delayin duration100msHow long the bubble outlives a pointer leaving it. Short, because the delay is only there to absorb jitter at the zone edge — long enough and the bubble feels sticky. Published because HoverCard publishes it and the two were the same machine with one of them spelling this into a timer.
activein boolno defaultA second reason to show the bubble, ORed with the pointer's. shadcn's tooltip is defined as opening on keyboard focus *or* hover, so a keyboard user gets what a mouse user gets; bind this to the wrapped control's focus and it does: Tooltip { text: "Save and continue"; active: save.focus-held; save := Button { text: "Save"; } } focus-held rather than focus-visible, and the difference is the whole of why this property is hard: showing the bubble opens a PopupWindow, which takes the window's focus, which clears focus-visible on the control below — so a bubble gated on it closed itself the instant it appeared, the focus came back, and it opened again. Measured at 400ms a cycle, with the control's ring blinking in antiphase. focus-held is the same focus with the popup's borrowing discounted, so the bubble stops answering a question its own existence makes unanswerable. Tooltip cannot read it off the wrapped control itself: Slint reports focus only to the element that holds it, never to an ancestor, so a component that owns its trigger as @children still cannot see the trigger's focus. HoverCard.active is the same property for the same reason, and the two hover surfaces now agree. Which is why the controls that own a keyboard focus scope publish focus-visible themselves — Button, Toggle, Checkbox, Switch, Slider and Select. Wrapping one in a second FocusVisibleScope does not work and is not the shape to reach for: the wrapper reports its *own* focus, not the control's, and it adds a tab stop of its own that lands ahead of the control and answers nothing. One limit stays, and it is the pointer's limit on the keyboard's axis: an open PopupWindow takes the window's focus as well as its pointer events, so once the bubble is up the control below no longer holds the keyboard. The control answers Enter for the whole open-delay before that, and the bubble is a hint rather than a step in the task, so this is the same trade the zone below already documents. It has a second face now that focus-held keeps the bubble up: Tab cannot reach the control to report that the focus left, so a bubble the keyboard raised stays until the consumer clears active or a click dismisses the popup. That is the trade against a bubble that flashes twice a second, which is what gating on focus-visible costs.
is-openout boolno defaultWhether the bubble is currently shown; mirrors PopupWindow.is-open rather than being set by hand, so it cannot disagree with the popup.

Enums

EnumValues
TooltipSidetop, right, bottom, left

Accessibility

  • Dual activation. Tooltips support pointer hover and keyboard focus simultaneously when active is bound to the trigger’s focus-held property.
  • Hover zone & pointer routing. The popup creates a combined hover zone spanning both the trigger and the bubble, ensuring the bubble does not flicker. A click in that zone dismisses the tooltip and is consumed; the wrapped control responds to the next click.
  • Supported dismissal. A pointer-opened tooltip closes after the pointer leaves the trigger and hover zone, or immediately when that zone is clicked. Tooltip does not handle Escape itself.
  • Concise descriptions. Tooltip text should be reserved for brief hints or shortcuts; for rich or multi-line content, use HoverCard or Popover instead.