Skip to content

Commit

Permalink
feat(onClickOutside): add ignore option (vitest-dev#1205)
Browse files Browse the repository at this point in the history
Co-authored-by: Anthony Fu <anthonyfu117@hotmail.com>
  • Loading branch information
okxiaoliang4 and antfu committed Feb 8, 2022
1 parent a2b2b0d commit c275a2e
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 5 deletions.
8 changes: 6 additions & 2 deletions packages/core/onClickOutside/demo.vue
Expand Up @@ -29,11 +29,15 @@ onClickOutside(
<button @click="modal = true">
Open Modal
</button>
<div class="relative inline-block ml-2">
<div class="ml-2 relative inline-block">
<button @click="dropdown = true">
Open Dropdown
</button>
<div v-if="dropdown" ref="dropdownRef" class="dropdown-inner">
<div
v-if="dropdown"
ref="dropdownRef"
class="dropdown-inner"
>
Click outside of the dropdown to close it.
</div>
</div>
Expand Down
22 changes: 19 additions & 3 deletions packages/core/onClickOutside/index.ts
Expand Up @@ -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.
*
Expand All @@ -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
Expand All @@ -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)
}

Expand Down

0 comments on commit c275a2e

Please sign in to comment.