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, + }); +});