diff --git a/packages/core/onClickOutside/demo.vue b/packages/core/onClickOutside/demo.vue index 7484fee69ca1..c58be7e102aa 100644 --- a/packages/core/onClickOutside/demo.vue +++ b/packages/core/onClickOutside/demo.vue @@ -22,7 +22,6 @@ onClickOutside( console.log(event) dropdown.value = false }, - { event: 'mousedown' }, ) diff --git a/packages/core/onClickOutside/directive.ts b/packages/core/onClickOutside/directive.ts index b7df0eda4604..240292fb61d9 100644 --- a/packages/core/onClickOutside/directive.ts +++ b/packages/core/onClickOutside/directive.ts @@ -1,9 +1,9 @@ import { FunctionDirective } from 'vue-demi' -import { onClickOutside, OnClickOutsideEvents } from '.' +import { onClickOutside } from '.' /** * TODO: Test that this actually works */ -export const VOnClickOutside: FunctionDirective void> = (el, binding) => { +export const VOnClickOutside: FunctionDirective void> = (el, binding) => { onClickOutside(el, binding.value) } diff --git a/packages/core/onClickOutside/index.ts b/packages/core/onClickOutside/index.ts index d93413c0cfe6..3f9cfa82475a 100644 --- a/packages/core/onClickOutside/index.ts +++ b/packages/core/onClickOutside/index.ts @@ -1,12 +1,8 @@ +import { ref } from 'vue-demi' import { MaybeElementRef, unrefElement } from '../unrefElement' import { useEventListener } from '../useEventListener' import { ConfigurableWindow, defaultWindow } from '../_configurable' -export type OnClickOutsideEvents = Pick -export interface OnClickOutsideOptions extends ConfigurableWindow { - event?: E -} - /** * Listen for clicks outside of an element. * @@ -15,26 +11,36 @@ export interface OnClickOutsideOptions ext * @param handler * @param options */ -export function onClickOutside( +export function onClickOutside( target: MaybeElementRef, - handler: (evt: OnClickOutsideEvents[E]) => void, - options: OnClickOutsideOptions = {}, + handler: (evt: PointerEvent) => void, + options: ConfigurableWindow = {}, ) { - const { window = defaultWindow, event = 'pointerdown' } = options + const { window = defaultWindow } = options if (!window) return - const listener = (event: OnClickOutsideEvents[E]) => { + const shouldListen = ref(true) + + const listener = (event: PointerEvent) => { const el = unrefElement(target) - if (!el) - return - if (el === event.target || event.composedPath().includes(el)) + if (!el || el === event.target || event.composedPath().includes(el) || !shouldListen.value) return handler(event) } - return useEventListener(window, event, listener, { passive: true }) + const cleanup = [ + useEventListener(window, 'click', listener, { passive: true, capture: true }), + useEventListener(window, 'pointerdown', (e) => { + const el = unrefElement(target) + shouldListen.value = !!el && !e.composedPath().includes(el) + }, { passive: true }), + ] + + const stop = () => cleanup.forEach(fn => fn()) + + return stop }