mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-05-04 21:22:07 +00:00
61 lines
1.3 KiB
TypeScript
61 lines
1.3 KiB
TypeScript
import { useEventListener } from '@vueuse/core'
|
|
|
|
import { toValue } from 'vue'
|
|
import type { MaybeRefOrGetter } from 'vue'
|
|
|
|
interface UseDismissableOverlayOptions {
|
|
isOpen: MaybeRefOrGetter<boolean>
|
|
getOverlayEl: () => HTMLElement | null
|
|
onDismiss: () => void
|
|
getTriggerEl?: () => HTMLElement | null
|
|
dismissOnScroll?: boolean
|
|
}
|
|
|
|
const isNode = (value: EventTarget | null | undefined): value is Node =>
|
|
value instanceof Node
|
|
|
|
const isInside = (target: Node, element: HTMLElement | null | undefined) =>
|
|
!!element?.contains(target)
|
|
|
|
export function useDismissableOverlay({
|
|
isOpen,
|
|
getOverlayEl,
|
|
onDismiss,
|
|
getTriggerEl,
|
|
dismissOnScroll = false
|
|
}: UseDismissableOverlayOptions) {
|
|
const dismissIfOutside = (event: Event) => {
|
|
if (!toValue(isOpen)) {
|
|
return
|
|
}
|
|
|
|
const overlay = getOverlayEl()
|
|
if (!overlay) {
|
|
return
|
|
}
|
|
|
|
if (!isNode(event.target)) {
|
|
onDismiss()
|
|
return
|
|
}
|
|
|
|
if (
|
|
isInside(event.target, overlay) ||
|
|
isInside(event.target, getTriggerEl?.())
|
|
) {
|
|
return
|
|
}
|
|
|
|
onDismiss()
|
|
}
|
|
|
|
useEventListener(window, 'pointerdown', dismissIfOutside, { capture: true })
|
|
|
|
if (dismissOnScroll) {
|
|
useEventListener(window, 'scroll', dismissIfOutside, {
|
|
capture: true,
|
|
passive: true
|
|
})
|
|
}
|
|
}
|