Tooltip
Lightweight hints and hierarchy
Usage
Hover Hint
Short hints with low intrusion.
Loading demo...
<template>
<TxTooltip content="Copied">
<TxButton variant="ghost">Copy</TxButton>
</TxTooltip>
</template>
Best Practices
- Keep tooltip text short and avoid multiline hints.
- Keep spacing light around the trigger element.
- Put visual complexity in
anchor, not in tooltip-specific props. - Do not place forms, long explanations, or bulk actions inside Tooltip; upgrade complex content to
TxPopover/TxDrawer.
Tooltip Button
Icon button with a hint.
Loading demo...
Anchor Presets
Show different looks and placement through anchor pass-through.
Loading demo...
API Reference
Props
| Prop | Type | Default | Description |
|---|---|---|---|
modelValue | boolean | undefined | Optional controlled open state for v-model. Unset uses internal state. |
content | string | '' | Fallback tooltip text when the content slot is not provided. |
disabled | boolean | false | Blocks opening and closes the tooltip when it becomes disabled. |
trigger | 'hover' | 'click' | 'focus' | 'hover' | Trigger strategy for the reference wrapper. |
openDelay | number | From the layer preset (200 for hint) | Delay before opening in hover or focus mode, clamped to at least 0. Left unset, the shared delay service supplies it from layer. |
closeDelay | number | From the layer preset (120 for hint) | Delay before closing in hover or focus mode, clamped to at least 0. Left unset, the shared delay service supplies it from layer. |
maxHeight | number | 320 | Panel max height in pixels. <= 0 disables the max height. Content slot defaults to no max height at 320. |
referenceFullWidth | boolean | false | Makes the reference wrapper take width: 100%. |
interactive | boolean | false | In hover mode, the pointer can move into the floating panel without closing it. Brings the hover bridge and the safe triangle; see Overview. |
keepAliveContent | boolean | false | Passes through to TxBaseAnchor to keep floating content mounted after close. |
closeOnClickOutside | boolean | trigger === 'click' | Overrides outside-click close behavior. Anchor config is used next, then click mode defaults to true. |
toggleOnReferenceClick | boolean | trigger === 'click' | Overrides reference click toggle behavior. Anchor config is used next, then click mode defaults to true. |
anchor | Partial<TooltipAnchorProps> | {} | Pass-through config for TxBaseAnchor; modelValue / disabled are owned by Tooltip (set them via v-model / the disabled prop, not anchor); tooltip supplies placement, panel, and animation defaults first; it draws no arrow unless you pass anchor.showArrow: true. |
Events
| Event | Payload | Description |
|---|---|---|
update:modelValue | (value: boolean) => void | Emitted whenever the resolved open state changes. |
open | () => void | Emitted after the tooltip changes from closed to open. |
close | () => void | Emitted after the tooltip changes from open to closed. |
Slots
| Slot | Props | Description |
|---|---|---|
default | - | Reference content wrapped by the tooltip trigger span. |
content | { side: string } | Custom tooltip body. Receives the resolved floating side from TxBaseAnchor. |
Anchor Passthrough
<template>
<TxTooltip
content="Bottom tooltip"
:anchor="{ placement: 'bottom', panelBackground: 'mask' }"
>
<TxButton variant="ghost">Bottom</TxButton>
</TxTooltip>
</template>
Click Toggle (close on outside click)
Loading demo...
Click Toggle (keep on outside click)
Loading demo...
Dashboard Feedback Center
In admin task panels, Tooltip should explain one action or metric without interrupting the flow. Use TxToastHost for persistent task results and TxLoadingOverlay when a panel needs to be blocked during refresh.
Dashboard task feedback center
A screenshot-verified composition of Tooltip with Toast / LoadingOverlay / Spinner.
Loading demo...
Overview
- Hover and focus triggers use
openDelay/closeDelay; click trigger delegates toggling and outside-click handling toTxBaseAnchor. disabled=trueclears pending timers and forces the resolved open state tofalse.interactive=trueonly affects hover mode. The hover zone is the whole floating layer: the panel box, card padding included, plus the hover bridge between the reference and the panel. Entering it clears the close timer (and any parent panel's); leaving the whole layer schedules the close again.- A pointer that leaves the reference towards the panel is in transit. While it stays inside the triangle from its exit point to the panel's facing edge (the safe triangle) and keeps moving, the panel does not close on
closeDelay, a parent panel does not close because the path crossed out of it, and no other hover trigger along the way opens. A stop longer than 100ms, or a step out of the triangle, gives the trip up: the panel closes on its usualcloseDelay, and the trigger the pointer stopped on opens. Leaving through the edge facing away from the panel is not a trip and closes on the delay as before. Plain hints (notinteractive) are unchanged. - Tooltip sets
role="tooltip"on the floating body and exposesdata-sidefor placement-aware styling. - The default anchor animation is
{ type: 'boom' }(a symmetric focus zoom in and out); ananchor.animationoverride replaces it entirely. - There is no arrow by default (
anchor.showArrowdefaults tofalse), as across the whole anchor family; once enabled it moves with the panel, and the gap to the trigger staysoffset(8px by default).
Technologies
- Open-state contract:
TxTooltipis controlled whenmodelValueis boolean, otherwise it ownsinternalOpen. Opening/closing emitsupdate:modelValueplusopenorclose, unlessdisabledprevents opening. - Anchor contract: Click trigger defaults
closeOnClickOutsideandtoggleOnReferenceClicktotrue; other triggers leave those behaviors off unless props oranchoroverride them. - Transit: geometry and transit state live in
packages/tuffex/packages/utils/hover-intent.ts, which listens topointermoveonly during a trip. Parent panels are held by the anchor-delay service'sholdChain/releaseChain: a close that comes due during the trip is deferred, runs at once if the pointer gives up, and is dropped if it arrives. - Rejected design: binding the panel's hover handlers to the content inside the card. The card's padding (8px in DropdownMenu) became a dead ring: reaching the first row meant crossing the
offsetplus the padding, about 18px, within 100ms, and resting on the panel's edge closed it. - Rejected design: forgiving the trip with a longer
closeDelay(FlatDropdown's 600ms default was hiding the problem). No delay stops a diagonal path: with a menu already open the menu layer'sopenDelayis 0, so the neighbouring trigger opens on the frame the pointer crosses it and preempts the panel. - Verified coverage:
tooltip.test.tscovers keep-alive defaults, the boom default and animation forwarding, content slotsidecontext, and click outside override behavior.tooltip-hover-intent.test.tsdrives the real Popover → Tooltip chain over faked layout: only interactive hover panels get a bridge; a pointer heading for the panel stays open pastcloseDelayand closes as usual once off course; a trigger crossed on the way does not open, and takes over only when the pointer stops on it; arriving at the panel cancels the close; leaving through the far edge closes as usual. - Component source:
packages/tuffex/packages/components/src/tooltip/src/TxTooltip.vue. - Types:
packages/tuffex/packages/components/src/tooltip/src/types.ts. - Coverage:
packages/tuffex/packages/components/src/tooltip/__tests__/tooltip.test.tsverifies keep-alive defaults, anchor animation forwarding, slot side context, and click outside behavior.
查看源码
packages/tuffex/packages/components/src/tooltip/index.ts