Appearance
useOutsideClick
useOutsideClick closes a floating context when a pointer event targets something outside its anchor, floating element, and linked child floating contexts.
Type
ts
function useOutsideClick(context: UseOutsideClickContext, options?: UseOutsideClickOptions): void;
interface UseOutsideClickContext extends Pick<FloatingContext, "refs" | "state"> {}
interface UseOutsideClickOptions {
enabled?: MaybeRefOrGetter<boolean>;
event?: MaybeRefOrGetter<"pointerdown" | "mousedown" | "click">;
capture?: MaybeRefOrGetter<boolean>;
ignoreClick?: OutsideClickPredicate;
onClick?: (event: MouseEvent) => void;
ignoreScrollbar?: MaybeRefOrGetter<boolean>;
ignoreDrag?: MaybeRefOrGetter<boolean>;
}
type OutsideClickPredicate = (event: MouseEvent, target: EventTarget | null) => boolean;Details
useOutsideClick attaches a document-level listener and closes with the "outside-pointer" reason when the context is open.
enableddefaults totrue. Set it tofalseto disable dismissal.eventdefaults to"pointerdown".capturedefaults totrue.ignoreClickskips selected outside clicks when it returnstrue.onClickreplaces the default close behavior when you need custom logic.ignoreScrollbardefaults totrueand prevents scrollbar interaction from closing the floating element.ignoreDragdefaults totrueand ignores click events that finish outside after a drag started inside the floating element.
Pair this composable with useClick, useHover, or application-owned open state whenever outside pointer input should dismiss the floating surface.
Example
This example opens the floating element manually and lets useOutsideClick own dismissal.
vue
<script setup lang="ts">
import { ref } from "vue";
import { useEscapeKey, useFloatingContext, useOutsideClick, usePosition } from "v-float";
const anchorEl = ref<HTMLElement | null>(null);
const floatingEl = ref<HTMLElement | null>(null);
const context = useFloatingContext({ refs: { anchorEl, floatingEl } });
const { styles } = usePosition(context);
useOutsideClick(context);
useEscapeKey(context);
</script>
<template>
<button ref="anchorEl" @click="context.state.setOpen(!context.state.open.value, 'anchor-click')">
Toggle
</button>
<div v-if="context.state.open.value" ref="floatingEl" :style="styles">Floating content</div>
</template>Ignore Specific Outside Targets
Use a predicate when some external UI should keep the floating element open.
vue
<script setup lang="ts">
import { ref } from "vue";
import { useFloatingContext, useOutsideClick, usePosition } from "v-float";
const anchorEl = ref<HTMLElement | null>(null);
const floatingEl = ref<HTMLElement | null>(null);
const toolbarEl = ref<HTMLElement | null>(null);
const context = useFloatingContext({ refs: { anchorEl, floatingEl } });
const { styles } = usePosition(context);
useOutsideClick(context, {
ignoreClick: (_event, target) => {
return target instanceof Node && !!toolbarEl.value?.contains(target);
},
});
</script>
<template>
<button ref="anchorEl" @click="context.state.setOpen(true, 'anchor-click')">Open</button>
<div v-if="context.state.open.value" ref="floatingEl" :style="styles">Floating content</div>
<div ref="toolbarEl">Toolbar content</div>
</template>