<script setup lang="ts">
|
import type { ClassType } from '@vben-core/typings';
|
import type {
|
ContextMenuContentProps,
|
ContextMenuRootEmits,
|
ContextMenuRootProps,
|
} from 'radix-vue';
|
|
import type { IContextMenuItem } from './interface';
|
|
import { computed } from 'vue';
|
|
import { useForwardPropsEmits } from 'radix-vue';
|
|
import {
|
ContextMenu,
|
ContextMenuContent,
|
ContextMenuItem,
|
ContextMenuSeparator,
|
ContextMenuShortcut,
|
ContextMenuTrigger,
|
} from '../../ui/context-menu';
|
|
const props = defineProps<
|
{
|
class?: ClassType;
|
contentClass?: ClassType;
|
contentProps?: ContextMenuContentProps;
|
handlerData?: Record<string, any>;
|
itemClass?: ClassType;
|
menus: (data: any) => IContextMenuItem[];
|
} & ContextMenuRootProps
|
>();
|
|
const emits = defineEmits<ContextMenuRootEmits>();
|
|
const delegatedProps = computed(() => {
|
const {
|
class: _cls,
|
contentClass: _,
|
contentProps: _cProps,
|
itemClass: _iCls,
|
...delegated
|
} = props;
|
|
return delegated;
|
});
|
|
const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
|
const menusView = computed(() => {
|
return props.menus?.(props.handlerData);
|
});
|
|
function handleClick(menu: IContextMenuItem) {
|
if (menu.disabled) {
|
return;
|
}
|
menu?.handler?.(props.handlerData);
|
}
|
</script>
|
|
<template>
|
<ContextMenu v-bind="forwarded">
|
<ContextMenuTrigger as-child>
|
<slot></slot>
|
</ContextMenuTrigger>
|
<ContextMenuContent
|
:class="contentClass"
|
v-bind="contentProps"
|
class="side-content z-[1000]"
|
>
|
<template v-for="menu in menusView" :key="menu.key">
|
<ContextMenuItem
|
:class="itemClass"
|
:disabled="menu.disabled"
|
:inset="menu.inset || !menu.icon"
|
class="cursor-pointer"
|
@click="handleClick(menu)"
|
>
|
<component
|
:is="menu.icon"
|
v-if="menu.icon"
|
class="mr-2 size-4 text-lg"
|
/>
|
|
{{ menu.text }}
|
<ContextMenuShortcut v-if="menu.shortcut">
|
{{ menu.shortcut }}
|
</ContextMenuShortcut>
|
</ContextMenuItem>
|
<ContextMenuSeparator v-if="menu.separator" />
|
</template>
|
</ContextMenuContent>
|
</ContextMenu>
|
</template>
|