From 99c38c93c8ccd0597d4fe994f906d44d3d3e6878 Mon Sep 17 00:00:00 2001 From: mew <88119911+doraemonxxx@users.noreply.github.com> Date: Tue, 28 Apr 2026 13:36:13 +0800 Subject: [PATCH] feat: refactor context menu to capture native events (#7858) * feat: refactor context menu to capture native events prevent context-menu to show in html input fields * fix: refactor context-menu.vue for improved structure * chore: fix format * chore: remove dead code * chore: fix lint * fix: update contenteditable selector in context menu proposed fixed by coderabitai --- .../components/context-menu/context-menu.vue | 34 +++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/packages/@core/ui-kit/shadcn-ui/src/components/context-menu/context-menu.vue b/packages/@core/ui-kit/shadcn-ui/src/components/context-menu/context-menu.vue index 009f267ef..f6de51ea8 100644 --- a/packages/@core/ui-kit/shadcn-ui/src/components/context-menu/context-menu.vue +++ b/packages/@core/ui-kit/shadcn-ui/src/components/context-menu/context-menu.vue @@ -9,7 +9,7 @@ import type { ClassType } from '@vben-core/typings'; import type { IContextMenuItem } from './interface'; -import { computed } from 'vue'; +import { computed, onMounted, onUnmounted, ref } from 'vue'; import { useForwardPropsEmits } from 'reka-ui'; @@ -35,6 +35,14 @@ const props = defineProps< const emits = defineEmits(); +const NATIVE_CONTEXT_SELECTORS = [ + 'input', + 'textarea', + 'select', + '[contenteditable]:not([contenteditable="false"])', + '.allow-native-context', +].join(', '); + const delegatedProps = computed(() => { const { class: _cls, @@ -59,12 +67,34 @@ function handleClick(menu: IContextMenuItem) { } menu?.handler?.(props.handlerData); } + +const triggerRef = ref(null); + +function onContextMenuCapture(e: MouseEvent) { + if ((e.target as HTMLElement).closest(NATIVE_CONTEXT_SELECTORS)) { + e.stopPropagation(); + } +} + +onMounted(() => { + triggerRef.value?.addEventListener('contextmenu', onContextMenuCapture, { + capture: true, + }); +}); + +onUnmounted(() => { + triggerRef.value?.removeEventListener('contextmenu', onContextMenuCapture, { + capture: true, + }); +});