Browse Source

feat: refactor context menu to capture native events

prevent context-menu to show in html input fields
pull/7858/head
mew 5 months ago
committed by GitHub
parent
commit
ea1b38f66b
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 84
      packages/@core/ui-kit/shadcn-ui/src/components/context-menu/context-menu.vue

84
packages/@core/ui-kit/shadcn-ui/src/components/context-menu/context-menu.vue

@ -35,6 +35,14 @@ const props = defineProps<
const emits = defineEmits<ContextMenuRootEmits>(); const emits = defineEmits<ContextMenuRootEmits>();
const NATIVE_CONTEXT_SELECTORS = [
'input',
'textarea',
'select',
'[contenteditable="true"]',
'.allow-native-context',
].join(', ');
const delegatedProps = computed(() => { const delegatedProps = computed(() => {
const { const {
class: _cls, class: _cls,
@ -59,40 +67,50 @@ function handleClick(menu: IContextMenuItem) {
} }
menu?.handler?.(props.handlerData); menu?.handler?.(props.handlerData);
} }
function handleContextMenuCapture(e: MouseEvent) {
const target = e.target as HTMLElement;
if (target.closest(NATIVE_CONTEXT_SELECTORS)) {
e.stopPropagation();
}
}
</script> </script>
<template> <template>
<ContextMenu v-bind="forwarded"> <div @contextmenu.capture="handleContextMenuCapture">
<ContextMenuTrigger as-child> <ContextMenu v-bind="forwarded">
<slot></slot> <ContextMenuTrigger as-child>
</ContextMenuTrigger> <slot></slot>
<ContextMenuContent </ContextMenuTrigger>
:class="contentClass" <ContextMenuContent
v-bind="contentProps" :class="contentClass"
class="side-content z-popup" v-bind="contentProps"
> class="side-content z-popup"
<template v-for="menu in menusView" :key="menu.key"> >
<ContextMenuItem <template v-for="menu in menusView" :key="menu.key">
v-if="!menu.hidden" <ContextMenuItem
:class="itemClass" v-if="!menu.hidden"
:disabled="menu.disabled" :class="itemClass"
:inset="menu.inset || !menu.icon" :disabled="menu.disabled"
class="cursor-pointer" :inset="menu.inset || !menu.icon"
@click="handleClick(menu)" class="cursor-pointer"
> @click="handleClick(menu)"
<component >
:is="menu.icon" <component
v-if="menu.icon" :is="menu.icon"
class="mr-2 size-4 text-lg" v-if="menu.icon"
/> class="mr-2 size-4 text-lg"
/>
{{ menu.text }}
<ContextMenuShortcut v-if="menu.shortcut"> {{ menu.text }}
{{ menu.shortcut }} <ContextMenuShortcut v-if="menu.shortcut">
</ContextMenuShortcut> {{ menu.shortcut }}
</ContextMenuItem> </ContextMenuShortcut>
<ContextMenuSeparator v-if="menu.separator" /> </ContextMenuItem>
</template> <ContextMenuSeparator v-if="menu.separator" />
</ContextMenuContent> </template>
</ContextMenu> </ContextMenuContent>
</ContextMenu>
<div>
</template> </template>

Loading…
Cancel
Save