Skip to content

HyTooltip ​

Usage examples on this page are written for Lit / plain HTML (<hy-tooltip>). The same component ships as HyTooltip in @whitespaceux/harmony-react (native React 19), with typed wrappers for Angular, Solid, Svelte, and Vue. The API reference below applies to all frameworks.

A lightweight tooltip component that displays contextual information when hovering or focusing on an element.

Trigger Patterns ​

Slotted trigger (preferred for client-side apps): The trigger element is passed via the trigger slot, ensuring ARIA relationships work correctly across shadow DOM boundaries.

for attribute (fallback for SSR frameworks): For SSR frameworks like Next.js, Nuxt, or SvelteKit, use the for attribute to reference a trigger element by ID. This avoids hydration timing issues with the slotchange event.

Key Features ​

  • Automatic positioning with Floating UI
  • Configurable show/hide delays
  • Hover, focus, or combined triggers
  • Dismissible, hoverable, and persistent
  • Full keyboard support (Escape to dismiss)
  • SSR-compatible via for attribute fallback

Accessibility: built in ​

  • Automatic aria-describedby on the trigger element
  • role="tooltip" for screen readers
  • Focus stays on trigger (tooltips never steal focus)

Accessibility: your part ​

  • Put a focusable control in the trigger slot, such as hy-icon-button, never a bare span; a hint on a disabled control needs a trigger that can still take focus.
  • Never let the tooltip be a control's only accessible name; give the control its own label or aria-label.

When to use

  • Naming an icon-only control.
  • A short hint about a control that people may want but do not need.

Do

  • Keep it to a few words or one short sentence.

When not to use

  • Text people must read to go on: show it inline on the page.
  • Content with links, buttons or fields, or longer than one short sentence: hy-popover.
  • A control whose visible label already says the same thing: no tooltip.
  • A problem with a field's value: the field's own error-message or warning-message.
  • Brief confirmation such as saved or copied: hy-toast.

Examples ​

Basic Usage (Slotted Trigger) ​

html
<hy-tooltip>
  <button slot="trigger">Save</button>
  Save your changes
</hy-tooltip>

SSR Framework Usage (for attribute) ​

html
<button id="save-btn">Save</button> <hy-tooltip for="save-btn">Save your changes</hy-tooltip>

With Placement ​

html
<hy-tooltip placement="bottom">
  <button slot="trigger">?</button>
  Click for help
</hy-tooltip>

Hover Only ​

html
<hy-tooltip trigger="hover">
  <span slot="trigger" tabindex="0">API</span>
  Application Programming Interface
</hy-tooltip>

Custom Delay ​

html
<hy-tooltip delay="500">
  <button slot="trigger">Delete</button>
  This cannot be undone
</hy-tooltip>

Note: show / hide are dispatched with bubbles: false. A tooltip's visibility is a purely local concern (no parent-coordination protocol like menubar↔menu-item), and a bubbling composed hide would collide with an ancestor overlay's same-named handler — e.g. a tooltip inside an hy-dialog would trip the dialog's onhide and close the modal. Listen directly on the <hy-tooltip> element (onshow / onhide) — target-phase delivery is unaffected. Matches the React mirror, whose onShow / onHide are callbacks that never bubble.

API ​

Properties ​

PropertyAttributeTypeDefaultDescription
placementplacement'top' | 'top-start' | 'top-end' | 'bottom' | 'bottom-start' | 'bottom-end' | 'left' | 'left-start' | 'left-end' | 'right' | 'right-start' | 'right-end''top'Where to place the tooltip relative to the trigger. Uses Floating UI with automatic fallback when there isn't enough space.
distancedistancenumber6Distance between the tooltip and its trigger element in pixels.
triggertrigger'hover' | 'focus' | 'hover focus''hover focus'How the tooltip is triggered. - 'hover': Show on mouseenter, hide on mouseleave - 'focus': Show on keyboard focus (:focus-visible), hide on blur — the focus a click gives the trigger, or focus handed back to it after a pointer pick in a menu, does not open it - 'hover focus': Show on either, requires both to be removed to hide
delaydelaynumber200Delay before showing the tooltip in milliseconds.
hideDelayhide-delaynumber100Delay before hiding the tooltip in milliseconds.
arrowarrowbooleantrueWhether to show the arrow indicator.
openopenbooleanfalseControls the open state of the tooltip.
disableddisabledbooleanfalseDisables the tooltip entirely. When disabled, the tooltip will not show on any trigger.
forforstring | undefined—ID of the trigger element. Use this as a fallback when the slotted trigger pattern isn't available (e.g., in SSR frameworks where slot forwarding may not work).

Events ​

EventDetailDescription
show—Fired after the tooltip opens (does NOT bubble). Detail: { source: 'hover' | 'focus' | 'programmatic' }
hide—Fired after the tooltip closes (does NOT bubble). Detail: { source: 'hover' | 'focus' | 'escape-key' | 'programmatic' }

Slots ​

SlotDescription
triggerThe element that triggers the tooltip (required)
defaultThe tooltip content

CSS Parts ​

PartDescription
bodyThe tooltip content wrapper
arrowThe arrow indicator element

CSS Custom Properties ​

The documented hooks. Every override hook the component reads — one per token it paints — is listed in @whitespaceux/harmony/theme-api.json, and @whitespaceux/harmony/component-bindings.json (the Harmony MCP get-bindings tool) says which part and state each one paints.

PropertyDefaultDescription
--hy-tooltip-background-surface-basevar(--hy-background-surface-base)Tooltip text color (inverted: uses surface-base)
--hy-tooltip-background-surface-inversevar(--hy-background-surface-inverse)Tooltip background color (inverted: uses surface-inverse)
--hy-tooltip-padding-overlay-floating-sm-blockvar(--hy-padding-overlay-floating-sm-block)Block padding
--hy-tooltip-padding-overlay-floating-sm-inlinevar(--hy-padding-overlay-floating-sm-inline)Inline padding
--hy-tooltip-radius-overlay-floating-smvar(--hy-radius-overlay-floating-sm)Border radius
--hy-tooltip-surface-width-smvar(--hy-surface-width-sm)Maximum width (default: surface-width-sm)
--hy-tooltip-ornament-bulletvar(--hy-ornament-bullet)Arrow indicator size
--hy-tooltip-safe-zone—Safe hover zone around tooltip, set dynamically via JS (default: 12px)
--hy-tooltip-shadow-elevation-2var(--hy-shadow-elevation-2)Box shadow for the tooltip
--hy-tooltip-body-sm-font-familyvar(--hy-body-sm-font-family)Font family override for tooltip text
--hy-tooltip-motion-transition-enter-durationvar(--hy-motion-transition-enter-duration)Transition duration for the show animation
--hy-tooltip-motion-transition-enter-easingvar(--hy-motion-transition-enter-easing)Transition easing for the show animation
--hy-tooltip-motion-transition-exit-durationvar(--hy-motion-transition-exit-duration)Transition duration for the hide animation
--hy-tooltip-motion-transition-exit-easingvar(--hy-motion-transition-exit-easing)Transition easing for the hide animation

Methods ​

show() ​

Shows the tooltip programmatically.

hide() ​

Hides the tooltip programmatically.

Built with Lit. Documented with VitePress.