CatPtain's picture
Upload 339 files
89ce340 verified
raw
history blame
1.77 kB
<template>
<div
class="mask"
@contextmenu.prevent="removeContextmenu()"
@mousedown.left="removeContextmenu()"
></div>
<div
class="contextmenu"
:style="{
left: style.left + 'px',
top: style.top + 'px',
}"
@contextmenu.prevent
>
<MenuContent
:menus="menus"
:handleClickMenuItem="handleClickMenuItem"
/>
</div>
</template>
<script lang="ts" setup>
import { computed } from 'vue'
import type { ContextmenuItem, Axis } from './types'
import MenuContent from './MenuContent.vue'
const props = defineProps<{
axis: Axis
el: HTMLElement
menus: ContextmenuItem[]
removeContextmenu: () => void
}>()
const style = computed(() => {
const MENU_WIDTH = 180
const MENU_HEIGHT = 30
const DIVIDER_HEIGHT = 11
const PADDING = 5
const { x, y } = props.axis
const menuCount = props.menus.filter(menu => !(menu.divider || menu.hide)).length
const dividerCount = props.menus.filter(menu => menu.divider).length
const menuWidth = MENU_WIDTH
const menuHeight = menuCount * MENU_HEIGHT + dividerCount * DIVIDER_HEIGHT + PADDING * 2
const screenWidth = document.body.clientWidth
const screenHeight = document.body.clientHeight
return {
left: screenWidth <= x + menuWidth ? x - menuWidth : x,
top: screenHeight <= y + menuHeight ? y - menuHeight : y,
}
})
const handleClickMenuItem = (item: ContextmenuItem) => {
if (item.disable) return
if (item.children && !item.handler) return
if (item.handler) item.handler(props.el)
props.removeContextmenu()
}
</script>
<style lang="scss">
.mask {
position: fixed;
left: 0;
top: 0;
width: 100vw;
height: 100vh;
z-index: 9998;
}
.contextmenu {
position: fixed;
z-index: 9999;
user-select: none;
}
</style>