mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-21 23:34:31 +00:00
fix(assets): dismiss context menu on scroll and outside click (#8952)
This commit is contained in:
@@ -199,7 +199,8 @@ import {
|
||||
useDebounceFn,
|
||||
useElementHover,
|
||||
useResizeObserver,
|
||||
useStorage
|
||||
useStorage,
|
||||
useTimeoutFn
|
||||
} from '@vueuse/core'
|
||||
import Divider from 'primevue/divider'
|
||||
import { useToast } from 'primevue/usetoast'
|
||||
@@ -483,7 +484,16 @@ function handleAssetSelect(asset: AssetItem, assets?: AssetItem[]) {
|
||||
handleAssetClick(asset, index, assetList)
|
||||
}
|
||||
|
||||
const { start: scheduleCleanup, stop: cancelCleanup } = useTimeoutFn(
|
||||
() => {
|
||||
contextMenuAsset.value = null
|
||||
},
|
||||
0,
|
||||
{ immediate: false }
|
||||
)
|
||||
|
||||
function handleAssetContextMenu(event: MouseEvent, asset: AssetItem) {
|
||||
cancelCleanup()
|
||||
contextMenuAsset.value = asset
|
||||
void nextTick(() => {
|
||||
contextMenuRef.value?.show(event)
|
||||
@@ -491,10 +501,7 @@ function handleAssetContextMenu(event: MouseEvent, asset: AssetItem) {
|
||||
}
|
||||
|
||||
function handleContextMenuHide() {
|
||||
// Delay clearing to allow command callbacks to emit before component unmounts
|
||||
requestAnimationFrame(() => {
|
||||
contextMenuAsset.value = null
|
||||
})
|
||||
scheduleCleanup()
|
||||
}
|
||||
|
||||
const handleBulkDownload = (assets: AssetItem[]) => {
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
)
|
||||
}
|
||||
}"
|
||||
@hide="emit('hide')"
|
||||
@hide="onMenuHide"
|
||||
>
|
||||
<template #item="{ item, props }">
|
||||
<Button
|
||||
@@ -29,7 +29,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onClickOutside } from '@vueuse/core'
|
||||
import { useEventListener } from '@vueuse/core'
|
||||
import ContextMenu from 'primevue/contextmenu'
|
||||
import type { MenuItem } from 'primevue/menuitem'
|
||||
import type { ComponentPublicInstance } from 'vue'
|
||||
@@ -76,19 +76,32 @@ const emit = defineEmits<{
|
||||
type ContextMenuInstance = ComponentPublicInstance & {
|
||||
show: (event: MouseEvent) => void
|
||||
hide: () => void
|
||||
container?: HTMLElement
|
||||
$el?: HTMLElement
|
||||
}
|
||||
|
||||
const contextMenu = ref<ContextMenuInstance | null>(null)
|
||||
const isVisible = ref(false)
|
||||
const actions = useMediaAssetActions()
|
||||
const { t } = useI18n()
|
||||
|
||||
// Close context menu when clicking outside
|
||||
onClickOutside(
|
||||
computed(() => contextMenu.value?.$el),
|
||||
() => {
|
||||
hide()
|
||||
}
|
||||
)
|
||||
function getOverlayEl(): HTMLElement | null {
|
||||
return contextMenu.value?.container ?? contextMenu.value?.$el ?? null
|
||||
}
|
||||
|
||||
function dismissIfOutside(event: Event) {
|
||||
if (!isVisible.value) return
|
||||
const overlay = getOverlayEl()
|
||||
if (!overlay) return
|
||||
if (overlay.contains(event.target as Node)) return
|
||||
hide()
|
||||
}
|
||||
|
||||
useEventListener(window, 'pointerdown', dismissIfOutside, { capture: true })
|
||||
useEventListener(window, 'scroll', dismissIfOutside, {
|
||||
capture: true,
|
||||
passive: true
|
||||
})
|
||||
|
||||
const showAddToWorkflow = computed(() => {
|
||||
// Output assets can always be added
|
||||
@@ -265,11 +278,18 @@ const contextMenuItems = computed<MenuItem[]>(() => {
|
||||
return items
|
||||
})
|
||||
|
||||
const show = (event: MouseEvent) => {
|
||||
function onMenuHide() {
|
||||
isVisible.value = false
|
||||
emit('hide')
|
||||
}
|
||||
|
||||
function show(event: MouseEvent) {
|
||||
isVisible.value = true
|
||||
contextMenu.value?.show(event)
|
||||
}
|
||||
|
||||
const hide = () => {
|
||||
function hide() {
|
||||
isVisible.value = false
|
||||
contextMenu.value?.hide()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user