diff --git a/packages/core/onClickOutside/demo.vue b/packages/core/onClickOutside/demo.vue index 797eeaca40f1..82a3f7f2c6d8 100644 --- a/packages/core/onClickOutside/demo.vue +++ b/packages/core/onClickOutside/demo.vue @@ -29,11 +29,15 @@ onClickOutside( -
+
- diff --git a/packages/core/onClickOutside/index.ts b/packages/core/onClickOutside/index.ts index a44f276b6bd4..02ad4b8936fa 100644 --- a/packages/core/onClickOutside/index.ts +++ b/packages/core/onClickOutside/index.ts @@ -5,6 +5,13 @@ import { useEventListener } from '../useEventListener' import type { ConfigurableWindow } from '../_configurable' import { defaultWindow } from '../_configurable' +export interface OnClickOutsideOptions extends ConfigurableWindow { + /** + * List of elements that should not trigger the event. + */ + ignore?: MaybeElementRef[] +} + /** * Listen for clicks outside of an element. * @@ -16,9 +23,9 @@ import { defaultWindow } from '../_configurable' export function onClickOutside( target: MaybeElementRef, handler: (evt: PointerEvent) => void, - options: ConfigurableWindow = {}, + options: OnClickOutsideOptions = {}, ) { - const { window = defaultWindow } = options + const { window = defaultWindow, ignore } = options if (!window) return @@ -27,10 +34,19 @@ export function onClickOutside( const listener = (event: PointerEvent) => { const el = unrefElement(target) + const composedPath = event.composedPath() - if (!el || el === event.target || event.composedPath().includes(el) || !shouldListen.value) + if (!el || el === event.target || composedPath.includes(el) || !shouldListen.value) return + if (ignore && ignore.length > 0) { + if (ignore.some((target) => { + const el = unrefElement(target) + return el && (event.target === el || composedPath.includes(el)) + })) + return + } + handler(event) }