Skip to content

useHover

A composable that enables hover-based interactions for floating elements with support for delays, rest detection, and safe polygon traversal.

Signature

ts
function useHover(
  context: FloatingContext | TreeNode<FloatingContext>,
  options?: UseHoverOptions
): void

Parameters

ParameterTypeRequiredDescription
contextFloatingContext | TreeNode<FloatingContext>YesContext from useFloating or tree node
optionsUseHoverOptionsNoConfiguration options

Options

ts
interface UseHoverOptions {
  enabled?: MaybeRef<boolean>
  delay?: MaybeRef<number | { open?: number; close?: number }>
  restMs?: MaybeRef<number>
  mouseOnly?: MaybeRef<boolean>
  safePolygon?: MaybeRef<boolean | SafePolygonOptions>
}

interface SafePolygonOptions {
  buffer?: number
  blockPointerEvents?: boolean
}
OptionTypeDefaultDescription
enabledMaybeRef<boolean>trueEnable/disable hover listeners
delayMaybeRef<number | object>0Delay before showing/hiding (ms)
restMsMaybeRef<number>0Time pointer must rest before opening (ms)
mouseOnlyMaybeRef<boolean>falseOnly trigger for mouse-like pointers
safePolygonMaybeRef<boolean | SafePolygonOptions>falseEnable safe polygon traversal

Examples

Basic Usage

vue
<script setup>
import { ref } from 'vue'
import { useFloating, useHover } from 'v-float'

const anchorEl = ref(null)
const floatingEl = ref(null)

const context = useFloating(anchorEl, floatingEl)
useHover(context)
</script>

<template>
  <button ref="anchorEl">Hover me</button>
  <div v-if="context.open.value" ref="floatingEl" :style="context.floatingStyles">
    Tooltip
  </div>
</template>

With Delay

vue
<script setup>
import { useFloating, useHover } from 'v-float'

const context = useFloating(anchorEl, floatingEl)

useHover(context, {
  delay: 300
})
</script>

Different Open/Close Delays

vue
<script setup>
import { useFloating, useHover } from 'v-float'

const context = useFloating(anchorEl, floatingEl)

useHover(context, {
  delay: {
    open: 500,
    close: 150
  }
})
</script>

With Safe Polygon

vue
<script setup>
import { useFloating, useHover } from 'v-float'

const context = useFloating(anchorEl, floatingEl, {
  placement: 'right-start'
})

useHover(context, {
  safePolygon: true
})
</script>

Mouse Only

vue
<script setup>
import { useFloating, useHover } from 'v-float'

const context = useFloating(anchorEl, floatingEl)

useHover(context, {
  mouseOnly: true
})
</script>

Tree-Aware (Nested Menus)

vue
<script setup>
import { useFloating, useFloatingTree, useHover } from 'v-float'

const tree = useFloatingTree()

const parentContext = useFloating(parentRef, parentFloatingRef)
const parentNode = tree.addNode(parentRef, parentFloatingRef)

const childContext = useFloating(childRef, childFloatingRef)
const childNode = tree.addNode(childRef, childFloatingRef, { parentId: parentNode?.id })

useHover(parentNode, {
  delay: { open: 100, close: 300 },
  safePolygon: true
})

useHover(childNode, {
  delay: { open: 200, close: 300 }
})
</script>

With Rest Detection

vue
<script setup>
import { useFloating, useHover } from 'v-float'

const context = useFloating(anchorEl, floatingEl)

useHover(context, {
  restMs: 100
})
</script>

Reactive Options

vue
<script setup>
import { ref } from 'vue'
import { useFloating, useHover } from 'v-float'

const enabled = ref(true)
const delay = ref(300)

const context = useFloating(anchorEl, floatingEl)

useHover(context, {
  enabled,
  delay
})
</script>

See Also

Released under the MIT License.