Interactions

useClick

Opens and closes floating content on click, tap, or keyboard activation.

useClick toggles or opens a floating surface in response to pointer clicks, touchscreen taps, and keyboard activation on the anchor element.

It attaches listeners directly to the anchor element (or context element for virtual anchors) and updates node.open.value. Pair it with useOutsideClick and useEscapeKey when the surface should close on outside clicks or Escape key presses.

Type

function useClick(node: FloatingNode, options?: UseClickOptions): void;

type UseClickContext = FloatingNode;

interface UseClickOptions {
  enabled?: MaybeRefOrGetter<boolean>;
  event?: MaybeRefOrGetter<"click" | "mousedown">;
  toggle?: MaybeRefOrGetter<boolean>;
  ignoreMouse?: MaybeRefOrGetter<boolean>;
  ignoreKeyboard?: MaybeRefOrGetter<boolean>;
  ignoreTouch?: MaybeRefOrGetter<boolean>;
}

Options

NameTypeDefaultNotes
enabledMaybeRefOrGetter<boolean>trueReactive toggle. Setting to false disables interaction and removes all DOM event listeners from the anchor element.
eventMaybeRefOrGetter<"click" | "mousedown">"click"Which pointer DOM event triggers opening or toggling. "mousedown" fires immediately on press for mouse and pen devices, while touch input still safely uses the trailing click.
toggleMaybeRefOrGetter<boolean>trueWhether subsequent clicks toggle the open state. When false, clicking opens the surface if closed, but never closes it if already open.
ignoreMouseMaybeRefOrGetter<boolean>falseWhen true, ignores mouse and mouse-like pointer interactions. Touch and pen devices continue to trigger normally.
ignoreKeyboardMaybeRefOrGetter<boolean>falseWhen true, disables Enter and Space keyboard activation and ignores synthetic clicks generated by keyboard events.
ignoreTouchMaybeRefOrGetter<boolean>falseWhen true, ignores touch tap gestures. Mouse and pen devices continue to trigger normally.

Returns

useClick returns void. It manages event listeners directly on node.refs.anchorEl (or the underlying contextElement for virtual anchors) and automatically synchronizes when reactive options or elements change.

Details

Pointer and Touch Handling

  • Primary Button Only: Only primary clicks (e.button === 0) trigger activation. Auxiliary clicks (middle mouse button) and secondary clicks (context menu right-click) are ignored.
  • Modality Tracking: useClick tracks the input device modality ("mouse", "touch", "pen") via pointerdown.
  • Cancellation Safety: If a touch gesture is cancelled before release (e.g. when the user starts scrolling or dragging away, firing pointercancel), useClick resets its internal interaction state so subsequent gestures are not blocked.

click vs mousedown Activation

  • event: "click" (default): Opening or toggling occurs on the standard DOM click event.
  • event: "mousedown": Triggers immediately on press for mouse and pen devices, skipping the latency of waiting for mouse release. This is ideal for fast-response interfaces such as menus, toolbars, and contextual popovers.
  • Touch Safety with mousedown: When event: "mousedown" is used, touch devices do not trigger prematurely on touch-emulated mousedown events; useClick waits for the trailing click event to ensure natural touch scrolling.
  • Deduplication: When event: "mousedown" handles the press event, useClick automatically swallows the trailing click event from the same gesture to prevent double-toggling.

Keyboard Activation Semantics

When ignoreKeyboard is false (the default):

  • Native Buttons: Elements that natively dispatch synthetic click events upon pressing Space or Enter (<button>, <input type="button">, <input type="submit">, <input type="reset">, <input type="image">, <summary>) are detected automatically. useClick avoids duplicating actions on keydown and allows the native click emission to handle toggling.
  • Native Links: Links with an href attribute (<a href="...">) natively activate on Enter. useClick permits standard link navigation on Enter without double-toggling, while still supporting Space key activation.
  • Custom / ARIA Buttons: Custom trigger elements (such as <div role="button" tabindex="0"> or <a> without href) are fully supported. Pressing Enter triggers immediately on keydown, while pressing Space triggers on keyup (faithfully matching native browser button semantics).
  • Typeable Elements: If the anchor is a form control that accepts text entry (<input type="text">, <textarea>, <select>), Space and Enter are passed through without toggling the floating node.
  • Synthetic Keyboard Clicks: When ignoreKeyboard: true, synthetic click events dispatched by keyboard activation (where e.detail === 0 and no pointer gesture occurred) are ignored.

Virtual Anchors

useClick supports VirtualElement anchors. If the virtual anchor provides a contextElement property, useClick automatically resolves and binds DOM event listeners to that element.

Example

<script setup lang="ts">
import { ref } from "vue";
import { useClick, useEscapeKey, useFloatingNode, useOutsideClick, usePosition } from "v-float";

const anchorEl = ref<HTMLElement | null>(null);
const floatingEl = ref<HTMLElement | null>(null);

const node = useFloatingNode({ anchorEl, floatingEl });
usePosition(node, {
  placement: "bottom-start",
  middlewares: {
    offset: 8,
    flip: true,
    shift: { padding: 8 },
  },
});

useClick(node);
useOutsideClick(node);
useEscapeKey(node);
</script>

<template>
  <button ref="anchorEl" type="button">Toggle Menu</button>

  <div v-if="node.open.value" ref="floatingEl" class="dropdown">
    <button type="button" @click="node.open.value = false">Profile</button>
    <button type="button" @click="node.open.value = false">Settings</button>
    <button type="button" @click="node.open.value = false">Logout</button>
  </div>
</template>

See Also

Released under the MIT License. Copyright © 2026