useTooltip
Region-scoped coordination plugin for tooltip open/close delays. Holds shared openDelay / closeDelay / skipDelay defaults plus a registry of currently-open tooltip tickets so neighboring <Tooltip.Root> instances can skip their open delay during the warmup window.
Usage
import { createTooltipPlugin, useTooltip } from '@vuetify/v0'
// App-wide defaults
app.use(
createTooltipPlugin({
openDelay: 500,
closeDelay: 150,
skipDelay: 300,
})
)
// Inside a component
const region = useTooltip()
region.openDelay.value // 500
region.isAnyOpen.value // false
region.shouldSkipOpenDelay() // false until a tooltip opens<Tooltip.Root> reads from useTooltip() automatically; you do not call this composable yourself unless you’re building a non-component consumer.
Adapters
Adapters let you swap the tooltip positioning engine without changing your application code. Tooltips reuse the PopoverAdapter contract from usePopover.
| Adapter | Import | Description |
|---|---|---|
V0PopoverAdapter | @vuetify/v0 | CSS anchor positioning (default, zero runtime dependency) |
FloatingUIPopoverAdapter | @vuetify/v0/popover/adapters/floating-ui | Floating UI↗︎ JS measurement — flip() covers overflow |
Pass adapter on createTooltipPlugin to set a tooltip-only engine. It does not leak into Popover, Select, or Combobox. createPopoverPlugin({ adapter }) is the app-wide default those other surfaces — and tooltips, when the tooltip plugin has no adapter — read. A per-instance adapter on Tooltip.Root still wins.
import { createTooltipPlugin } from '@vuetify/v0'
import { FloatingUIPopoverAdapter } from '@vuetify/v0/popover/adapters/floating-ui'
app.use(createTooltipPlugin({ adapter: new FloatingUIPopoverAdapter() }))Architecture
Reactivity
| Property | Type | Description |
|---|---|---|
openDelay | Readonly<Ref<number>> | Default open delay in ms (700) |
closeDelay | Readonly<Ref<number>> | Default close delay in ms (150) |
skipDelay | Readonly<Ref<number>> | Skip-window after last close in ms (300) |
disabled | Readonly<Ref<boolean>> | Region-wide disabled flag |
isAnyOpen | Readonly<Ref<boolean>> | True when any registered tooltip is currently open |
shouldSkipOpenDelay | () => boolean | Whether the next open should bypass the delay |
register | (input?: Partial<RegistryTicketInput>) => RegistryTicket | Track a newly-opened tooltip |
unregister | (id: ID) => void | Untrack a closed tooltip |
adapter | PopoverAdapter | undefined | Tooltip-only positioning engine. Per-instance adapter on Tooltip.Root wins; Popover / Select / Combobox never see this value |
Examples
Bold
Strong emphasis · Ctrl+B
Italic
Emphasis · Ctrl+I
Link
Insert link · Ctrl+K
Quote
Block quote
Code
Inline code · Ctrl+E
Region settings
idleOpen delay
Wait before the first tooltip appears
Close delay
Wait before a tooltip hides
Skip window
Idle grace period for instant reopen
Every change feeds the shared region, so the resolved delays the toolbar reads are 700ms open / 150ms close, with a 300ms skip window.
Hover the first button and wait out the open delay. Move to a neighbor while it is still open and the next tooltip appears instantly, tinted to mark the skip-window reveal. Leave the toolbar idle past the skip window and the next hover pays the full delay again.
FAQ
Skip-window coordination is most useful when neighbors across UI regions cooperate. An installed plugin shares one registry, so tooltips that inject it share the skip window. useTooltip() without the plugin gets a fresh registry on each call, and those tooltips do not coordinate with each other.
Yes. The plugin is just a small shared state object — register and unregister tickets manually if you’re building a custom tooltip surface and want it to coordinate with Vuetify0 tooltips on the page.
useTooltip() returns synthesized fallback defaults (700 / 150 / 300) so <Tooltip.Root> works without an app.use(createTooltipPlugin()) call.