|
1 | 1 | import type { Fn, MaybeRefOrGetter } from '@vueuse/shared'
|
| 2 | +import type { ComponentPublicInstance, VNode } from 'vue-demi' |
2 | 3 | import type { ConfigurableWindow } from '../_configurable'
|
3 | 4 | import type { MaybeElementRef } from '../unrefElement'
|
4 | 5 | import { isIOS, noop, toValue } from '@vueuse/shared'
|
@@ -69,9 +70,35 @@ export function onClickOutside<T extends OnClickOutsideOptions>(
|
69 | 70 | })
|
70 | 71 | }
|
71 | 72 |
|
| 73 | + /** |
| 74 | + * Determines if the given target has multiple root elements. |
| 75 | + * Referenced from: https://github.com/vuejs/test-utils/blob/ccb460be55f9f6be05ab708500a41ec8adf6f4bc/src/vue-wrapper.ts#L21 |
| 76 | + */ |
| 77 | + function hasMultipleRoots(target: MaybeElementRef): boolean { |
| 78 | + const vm = toValue(target) as ComponentPublicInstance |
| 79 | + return vm && vm.$.subTree.shapeFlag === 16 |
| 80 | + } |
| 81 | + |
| 82 | + function checkMultipleRoots(target: MaybeElementRef, event: PointerEvent): boolean { |
| 83 | + const vm = toValue(target) as ComponentPublicInstance |
| 84 | + const children = vm.$.subTree && vm.$.subTree.children |
| 85 | + |
| 86 | + if (children == null || !Array.isArray(children)) |
| 87 | + return false |
| 88 | + |
| 89 | + // @ts-expect-error should be VNode |
| 90 | + return children.some((child: VNode) => child.el === event.target || event.composedPath().includes(child.el)) |
| 91 | + } |
| 92 | + |
72 | 93 | const listener = (event: PointerEvent) => {
|
73 | 94 | const el = unrefElement(target)
|
74 | 95 |
|
| 96 | + if (event.target == null) |
| 97 | + return |
| 98 | + |
| 99 | + if (!(el instanceof Element) && hasMultipleRoots(target) && checkMultipleRoots(target, event)) |
| 100 | + return |
| 101 | + |
75 | 102 | if (!el || el === event.target || event.composedPath().includes(el))
|
76 | 103 | return
|
77 | 104 |
|
|
0 commit comments