Components
Back to catalog
Component detail entry
Overlay
@vean/ui
STooltip

Tooltip

Tooltip belongs to the Overlay category. Start with demos and usage, then use the API tables to finish integration and styling decisions.

Use the quick jump panel to reach overview, usage, demos, and API first, then continue through the full page.

Quick jump

Related components

If you are composing interactions in the same family, these components usually pair well together.

Tooltip

Overview

A popup that displays information related to an element when the element receives keyboard focus or the mouse hovers over it. STooltip combines the Aria TooltipRoot/TooltipTrigger/TooltipPositioner/TooltipPopup/TooltipArrow primitive family (built on the shared Popper) with the tooltipVariants style recipe (3 slots, 6 sizes).

Use a tooltip for a short, non-interactive hint. For rich hover content use hover-card; for click-triggered content use popover; for a confirmation use popconfirm.

Usage

Features

  • 🧩 Aria/styled split — TooltipCompact aggregates the popper trigger, positioner, popup and arrow; STooltip only injects styles and forwards slots/events
  • 🖱️ Hover + focus — opens on pointer hover or keyboard focus; dismisses on Escape or pointer leave
  • ⏱️ Delay tuning — delayDuration (open) and skipDelayDuration (between triggers), with global defaults via ConfigProvider
  • 🎯 Placement — full popper placement control with collision avoidance and side-aware slide animations
  • 🔽 Arrow — showArrow renders a positioned arrow; configurable via arrowProps
  • 🏷️ Content — content prop or the default slot
  • ♿ Behavior toggles — ignoreNonKeyboardFocus, disableHoverableContent, disableClosingTrigger, disabled
  • 📐 6 sizes — xs–2xl size; per-slot ui overrides
  • ♿ Accessible — role="tooltip" (visually-hidden text node), non-modal, axe-core zero violations open and closed

Component family

  • STooltip (styled) — the entry wrapper; tooltipVariants recipe with dynamic slot forwarding
  • TooltipRoot (Aria) — the state owner; open via useControllableState, delayDuration/skipDelayDuration/disabled/ignoreNonKeyboardFocus, merges the global ConfigProvider tooltip config
  • TooltipTrigger (Aria) — the anchor that opens the tooltip on hover/focus
  • TooltipPositioner / TooltipPositionerImpl (Aria) — the positioned surface (built on PopperPositioner)
  • TooltipPopup (Aria) — the popup body; exposes a visually-hidden role="tooltip" text node for screen readers
  • TooltipArrow (Aria) — the popper arrow
  • TooltipCompact (Aria) — the aggregated composite; composes trigger/positioner/popup/arrow and exposes the slots

Demos

Basic

API

Aria Layer

9

Tooltip

21 Props8 Emits2 Slots
Props
PropTypeDefaultDescription
class
ClassValue
—
class of popup
size
ThemeSize
—
Visual size of the component.
ui
Partial<TooltipUi>
—
Per-slot class overrides for the component.
content
string
—
Content.
placement
Placement
—
Placement.
showArrow
boolean
—
Whether to show an arrow.
triggerProps
PopperAnchorProps
—
Properties forwarded to the trigger element.
portalProps
TooltipPortalProps
—
Properties forwarded to the portal element.
positionerProps
TooltipPositionerProps
—
Properties forwarded to the positioner element.
popupProps
TooltipPopupProps
—
Properties forwarded to the popup element.
arrowProps
TooltipArrowProps
—
Properties forwarded to the arrow element.
defaultOpen
boolean
—
The open state of the tooltip when it is initially rendered. Use when you do not need to control its open state.
open
boolean
—
The controlled open state of the tooltip.
dir
Direction
—
—
modal
boolean
—
—
disabled
boolean
—
When `true`, disable tooltip
delayDuration
number
150
The duration from when the pointer enters the trigger until the tooltip gets opened.
skipDelayDuration
number
300
How much time a user has to enter another trigger without incurring a delay again.
disableHoverableContent
boolean
false
When `true`, trying to hover the content will result in the tooltip closing as the pointer leaves the trigger.
disableClosingTrigger
boolean
false
When `true`, clicking on trigger will not close the content.
ignoreNonKeyboardFocus
boolean
false
Prevent the tooltip from opening if the focus did not come from the keyboard by matching against the `:focus-visible` selector. This is useful if you want to avoid opening it when switching browser tabs or closing a dialog.
Emits
Emit NameParametersDescription
update:open
boolean, reason?: PopperOpenChangeReason | undefined
Event handler called when the open state of the tooltip changes.
escapeKeyDown
KeyboardEvent
Event handler called when the escape key is down. Can be prevented.
pointerDownOutside
PointerDownOutsideEvent
Event handler called when a `pointerdown` event happens outside of the `DismissableLayer`. Can be prevented.
focusOutside
FocusOutsideEvent
Event handler called when the focus moves outside of the `DismissableLayer`. Can be prevented.
interactOutside
PointerDownOutsideEvent | FocusOutsideEvent
Event handler called when an interaction happens outside the `DismissableLayer`. Specifically, when a `pointerdown` event happens outside or focus moves outside of it. Can be prevented.
openAutoFocus
Event
Event handler called when auto-focusing on open. Can be prevented.
closeAutoFocus
Event
Event handler called when auto-focusing on close. Can be prevented.
placed
—
—
Slots
Slot NameParametersDescription
default
—
Custom content for the default slot.
trigger
—
Custom content for the trigger slot.

TooltipArrow

TooltipCompact

18 Props8 Emits2 Slots
Props
PropTypeDefaultDescription
content
string
—
Content.
placement
Placement
—
Placement.
showArrow
boolean
—
Whether to show an arrow.
triggerProps
PopperAnchorProps
—
Properties forwarded to the trigger element.
portalProps
TooltipPortalProps
—
Properties forwarded to the portal element.
positionerProps
TooltipPositionerProps
—
Properties forwarded to the positioner element.
popupProps
TooltipPopupProps
—
Properties forwarded to the popup element.
arrowProps
TooltipArrowProps
—
Properties forwarded to the arrow element.
defaultOpen
boolean
—
The open state of the tooltip when it is initially rendered. Use when you do not need to control its open state.
open
boolean
—
The controlled open state of the tooltip.
dir
Direction
—
—
modal
boolean
—
—
disabled
boolean
—
When `true`, disable tooltip
delayDuration
number
150
The duration from when the pointer enters the trigger until the tooltip gets opened.
skipDelayDuration
number
300
How much time a user has to enter another trigger without incurring a delay again.
disableHoverableContent
boolean
false
When `true`, trying to hover the content will result in the tooltip closing as the pointer leaves the trigger.
disableClosingTrigger
boolean
false
When `true`, clicking on trigger will not close the content.
ignoreNonKeyboardFocus
boolean
false
Prevent the tooltip from opening if the focus did not come from the keyboard by matching against the `:focus-visible` selector. This is useful if you want to avoid opening it when switching browser tabs or closing a dialog.
Emits
Emit NameParametersDescription
update:open
boolean, reason?: PopperOpenChangeReason | undefined
Event handler called when the open state of the tooltip changes.
escapeKeyDown
KeyboardEvent
Event handler called when the escape key is down. Can be prevented.
pointerDownOutside
PointerDownOutsideEvent
Event handler called when a `pointerdown` event happens outside of the `DismissableLayer`. Can be prevented.
focusOutside
FocusOutsideEvent
Event handler called when the focus moves outside of the `DismissableLayer`. Can be prevented.
interactOutside
PointerDownOutsideEvent | FocusOutsideEvent
Event handler called when an interaction happens outside the `DismissableLayer`. Specifically, when a `pointerdown` event happens outside or focus moves outside of it. Can be prevented.
openAutoFocus
Event
Event handler called when auto-focusing on open. Can be prevented.
closeAutoFocus
Event
Event handler called when auto-focusing on close. Can be prevented.
placed
—
—
Slots
Slot NameParametersDescription
default
—
Custom content for the default slot.
trigger
—
Custom content for the trigger slot.

TooltipPopup

1 Props
Props
PropTypeDefaultDescription
ariaLabel
string
—
By default, screen readers will announce the content inside the component. If this is not descriptive enough, or you have content that cannot be announced, use `aria-label` as a more descriptive label.

TooltipPortal

TooltipPositioner

23 Props7 Emits
Props
PropTypeDefaultDescription
placement
Placement
undefined
The placement of the floating element. If used, it will override the `side` and `align` props.
side
Side
'bottom'
The preferred side of the trigger to render against when open. Will be reversed when collisions occur and avoidCollisions is enabled.
sideOffset
number
0
The distance in pixels from the trigger.
sideFlip
boolean
true
Flip to the opposite side when colliding with boundary.
align
Align
'center'
The preferred alignment against the trigger. May change when collisions occur.
alignOffset
number
0
An offset in pixels from the `start` or `end` alignment options.
alignFlip
boolean
true
Flip alignment when colliding with boundary. May only occur when `prioritizePosition` is true.
avoidCollisions
boolean
true
When `true`, overrides the side and align preferences to prevent collisions with boundary edges.
collisionBoundary
Element | (Element | null)[] | null
[ ]
The element used as the collision boundary. By default this is the viewport, though you can provide additional element(s) to be included in this check.
collisionPadding
Padding
0
The distance in pixels from the boundary edges where collision detection should occur. Accepts a number (same for all sides), or a partial padding object, for example: { top: 20, left: 20 }.
arrowPadding
number
0
The padding between the arrow and the edges of the content. If your content has border-radius, this will prevent it from overflowing the corners.
hideShiftedArrow
boolean
true
When `true`, hides the arrow when it cannot be centered to the reference element.
sticky
'partial' | 'always'
'partial'
The sticky behavior on the align axis. `partial` will keep the content in the boundary as long as the trigger is at least partially in the boundary whilst "always" will keep the content in the boundary regardless.
hideWhenDetached
boolean
false
Whether to hide the content when the trigger becomes fully occluded.
positionStrategy
'fixed' | 'absolute'
'fixed'
The type of CSS position property to use.
updatePositionStrategy
'always' | 'optimized'
'optimized'
Strategy to update the position of the floating element on every animation frame.
disableUpdateOnLayoutShift
boolean
false
Whether to disable the update position for the content when the layout shifted.
prioritizePosition
boolean
false
Force content to be position within the viewport. Might overlap the reference element, which may not be desired.
reference
ReferenceElement
—
The custom element or virtual element that will be set as the reference to position the floating element. If provided, it will replace the default anchor element.
trapFocus
boolean
modal
Whether focus is trapped inside the popup while open (Tab cycles within the layer and body scroll is locked for modal layers).
disableHoverableContent
boolean
false
When `true`, hovering the popup closes instead of keeping it open (the grace area is disabled, so leaving the trigger closes the layer immediately).
onGracePointerExit
(() => void)
—
Callback invoked when the pointer finally leaves the grace area. Lets an upper layer (e.g. Tooltip) run area-scoped close logic without registering its own second grace area.
forceMount
boolean
—
Used to force mounting when more control is needed. Useful when controlling animation with Vue animation libraries.
Emits
Emit NameParametersDescription
escapeKeyDown
KeyboardEvent
Event handler called when the escape key is down. Can be prevented.
pointerDownOutside
PointerDownOutsideEvent
Event handler called when a `pointerdown` event happens outside of the `DismissableLayer`. Can be prevented.
focusOutside
FocusOutsideEvent
Event handler called when the focus moves outside of the `DismissableLayer`. Can be prevented.
interactOutside
PointerDownOutsideEvent | FocusOutsideEvent
Event handler called when an interaction happens outside the `DismissableLayer`. Specifically, when a `pointerdown` event happens outside or focus moves outside of it. Can be prevented.
openAutoFocus
Event
Event handler called when auto-focusing on open. Can be prevented.
closeAutoFocus
Event
Event handler called when auto-focusing on close. Can be prevented.
placed
—
—

TooltipProvider

7 Props
Props
PropTypeDefaultDescription
delayDuration
number
150
The duration from when the pointer enters the trigger until the tooltip gets opened.
skipDelayDuration
number
300
How much time a user has to enter another trigger without incurring a delay again.
disableHoverableContent
boolean
false
When `true`, trying to hover the content will result in the tooltip closing as the pointer leaves the trigger.
disableClosingTrigger
boolean
false
When `true`, clicking on trigger will not close the content.
disabled
boolean
false
When `true`, disable tooltip
ignoreNonKeyboardFocus
boolean
false
Prevent the tooltip from opening if the focus did not come from the keyboard by matching against the `:focus-visible` selector. This is useful if you want to avoid opening it when switching browser tabs or closing a dialog.
positionerProps
TooltipPositionerProps
—
Props to be passed down to the positioner. Useful when you need to control the positioner, such as disabling it when the trigger is disabled.

TooltipRoot

11 Props1 Emits
Props
PropTypeDefaultDescription
defaultOpen
boolean
—
The open state of the tooltip when it is initially rendered. Use when you do not need to control its open state.
open
boolean
—
The controlled open state of the tooltip.
dir
Direction
—
—
modal
boolean
—
—
disabled
boolean
—
When `true`, disable tooltip
delayDuration
number
150
The duration from when the pointer enters the trigger until the tooltip gets opened.
skipDelayDuration
number
300
How much time a user has to enter another trigger without incurring a delay again.
disableHoverableContent
boolean
false
When `true`, trying to hover the content will result in the tooltip closing as the pointer leaves the trigger.
disableClosingTrigger
boolean
false
When `true`, clicking on trigger will not close the content.
ignoreNonKeyboardFocus
boolean
false
Prevent the tooltip from opening if the focus did not come from the keyboard by matching against the `:focus-visible` selector. This is useful if you want to avoid opening it when switching browser tabs or closing a dialog.
positionerProps
TooltipPositionerProps
—
Props to be passed down to the positioner. Useful when you need to control the positioner, such as disabling it when the trigger is disabled.
Emits
Emit NameParametersDescription
update:open
boolean, reason?: PopperOpenChangeReason | undefined
Event handler called when the open state of the tooltip changes.

TooltipTrigger

Notes

Architecture and benchmark differences

TooltipCompact owns the trigger/positioner/popup/arrow composition while every primitive stays style-free and only the UI wrapper injects the tooltipVariants classes. This mirrors radix-ui/shadcn-ui’s headless split, built on the shared Popper primitives. Ant Design, Element Plus, Mantine and Naive UI ship a single styled tooltip with title/placement props; VeanUI additionally exposes per-slot *Props, a size scale, an arrow toggle, a delayDuration/skipDelayDuration tuning model with ConfigProvider global defaults, and an accessible visually-hidden role="tooltip" node.

CapabilityVeanUIshadcn/uiAnt Design TooltipElement Plus TooltipMantine TooltipNaive UI Tooltip
Aria/styled split✅✅————
Popper placement (12)✅✅✅✅✅✅
Delay tuning✅✅—✅✅—
Arrow✅✅————
Sizes (6)✅—————
Focus trigger✅✅✅✅✅✅

— = unsupported or a different interaction model.

Cautions

  • The tooltip opens on hover and keyboard focus; tune delayDuration/skipDelayDuration (or the ConfigProvider tooltip defaults) to reduce accidental triggers.
  • ignoreNonKeyboardFocus (default) ignores non-keyboard focus (e.g. programmatic), matching native tooltip semantics.
  • The popup is rendered through a Portal (teleported to document.body); position it inside a relatively-positioned ancestor only with portalProps: { disabled: true }.
  • showArrow renders an arrow; arrowProps can override its position/classes.
  • The tooltip is non-modal and does not trap focus; it dismisses on Escape or pointer leave.

Roadmap

N/A — tooltip is feature-complete for the current parity set.

FAQ

How do I add a tooltip to an element?

Wrap the element in the trigger slot and set content:

<STooltip content="Delete this item">
  <template #trigger><SButton>Delete</SButton></template>
</STooltip>

How do I position the tooltip?

Use placement:

<STooltip placement="top" content="Copy">
  <template #trigger><SButton>Copy</SButton></template>
</STooltip>

How do I adjust the open timing?

Set delay-duration (ms), with skip-delay-duration between triggers:

<STooltip :delay-duration="150" :skip-delay-duration="50" content="Save">
  <template #trigger><SButton>Save</SButton></template>
</STooltip>

How do I hide the arrow?

Set show-arrow={false}:

<STooltip :show-arrow="false" content="Info">
  <template #trigger><SButton>?</SButton></template>
</STooltip>

Changelog

Version history is grouped by release so you can quickly see what changed for this component across published versions.

v0.20.0

2026-05-12

Compare release

Optimization

rename forwardedRootProps to forwardedProps for consistency

Scope: tooltipAuthors: soybeanjsView commitae39f

v0.19.0

2026-05-11

Compare release

Feature

add prioritizePosition prop for improved tooltip positioning

Scope: tooltipAuthors: soybeanfeView commit85b45

Feature

Implement TooltipCompact components

Scope: tooltipAuthors: soybeanjs, CopilotKit, soybeanfeView commitdbae3

v0.14.0

2026-04-03

Compare release

Feature

enhance positioner props and context integration

Scope: tooltipAuthors: soybeanjsView commit5ce78

v0.12.0

2026-03-07

Compare release

Optimization

add default prop for avoidCollisions in TooltipPositioner; bind triggerProps to TooltipTrigger

Scope: tooltipAuthors: soybeanjsView commite024c

v0.8.0

2026-02-10

Compare release

Refactor

simplify ariaLabel computation and remove unused slots

Scope: tooltipAuthors: soybeanjsView commit2fa29

v0.0.8

2026-01-01

Compare release

Optimization

remove TooltipPositioner context and update related components for improved clarity and functionality

Scope: tooltipAuthors: soybeanjsView commit4d8da

Refactor

remove TooltipContent, introduce TooltipPopup and TooltipPositioner components, and enhance context management for improved structure and functionality

Scope: tooltipAuthors: soybeanjsView commit41a2d

v0.0.2

2025-11-18

Compare release

Feature

add tooltip component with provider, trigger, and content implementations for enhanced UI interactions

Scope: tooltipAuthors: soybeanjsView commita132b

Feature

add scroll event handling to close tooltip on scroll and enhance cleanup management

Scope: tooltipAuthors: soybeanjsView commit9b6de

Feature

implement STooltip component with customizable positioning, arrow support, and enhanced theming

Scope: tooltipAuthors: soybeanjsView commit77bd5

Style

enhance element management by replacing setElement functions with callback handlers and introducing PopperContentWrapper for improved structure

Scope: tooltipAuthors: soybeanjsView commit13afb

Style

reduce delayDuration from 700 to 150 for improved tooltip responsiveness

Scope: tooltipAuthors: soybeanjsView commit51bbd

Style

replace TooltipProvider with TooltipOpenDelayed context and enhance tooltip configuration management

Scope: tooltipAuthors: soybeanjsView commit0eda5

Feature

add optional 'content' prop to tooltip component

Scope: tooltipAuthors: soybeanjsView commit9a5cc

Feature

add tooltip component with provider, trigger, and content implementations for enhanced UI interactions

Scope: tooltipAuthors: soybeanjsView commita132b

Feature

add scroll event handling to close tooltip on scroll and enhance cleanup management

Scope: tooltipAuthors: soybeanjsView commit9b6de

Feature

implement STooltip component with customizable positioning, arrow support, and enhanced theming

Scope: tooltipAuthors: soybeanjsView commit77bd5

Style

enhance element management by replacing setElement functions with callback handlers and introducing PopperContentWrapper for improved structure

Scope: tooltipAuthors: soybeanjsView commit13afb

Style

reduce delayDuration from 700 to 150 for improved tooltip responsiveness

Scope: tooltipAuthors: soybeanjsView commit51bbd

Style

replace TooltipProvider with TooltipOpenDelayed context and enhance tooltip configuration management

Scope: tooltipAuthors: soybeanjsView commit0eda5

Feature

add optional 'content' prop to tooltip component

Scope: tooltipAuthors: soybeanjsView commit9a5cc