fix(assets): dismiss context menu on scroll and outside click (#8952)

This commit is contained in:
Jin Yi
2026-02-21 13:19:13 +09:00
committed by GitHub
parent 5fe902358c
commit c05644045f
2 changed files with 43 additions and 16 deletions

View File

@@ -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()
}