first commit

This commit is contained in:
仲么了
2023-12-21 16:42:39 +08:00
commit 0f7b59f55b
79 changed files with 7638 additions and 0 deletions

View File

@@ -0,0 +1,108 @@
<template>
<transition name="el-zoom-in-center">
<div
class="el-popper is-pure is-light el-dropdown__popper ba-contextmenu"
:style="`top: ${state.axis.y + 5}px;left: ${state.axis.x - 14}px;width:${props.width}px`"
:key="Math.random()"
v-show="state.show"
aria-hidden="false"
data-popper-placement="bottom"
>
<ul class="el-dropdown-menu">
<template v-for="(item, idx) in props.items" :key="idx">
<li class="el-dropdown-menu__item" :class="item.disabled ? 'is-disabled' : ''" tabindex="-1" @click="onContextmenuItem(item)">
<Icon size="12" :name="item.icon" />
<span>{{ item.label }}</span>
</li>
</template>
</ul>
<span class="el-popper__arrow" :style="{ left: `${state.arrowAxis}px` }"></span>
</div>
</transition>
</template>
<script setup lang="ts">
import { onMounted, reactive, toRaw } from 'vue'
import type { Axis, ContextmenuItemClickEmitArg, Props } from './interface'
import type { RouteLocationNormalized } from 'vue-router'
import { useEventListener } from '@vueuse/core'
const props = withDefaults(defineProps<Props>(), {
width: 150,
items: () => [],
})
const emits = defineEmits<{
(e: 'contextmenuItemClick', item: ContextmenuItemClickEmitArg): void
}>()
const state: {
show: boolean
axis: {
x: number
y: number
}
menu: RouteLocationNormalized | undefined
arrowAxis: number
} = reactive({
show: false,
axis: {
x: 0,
y: 0,
},
menu: undefined,
arrowAxis: 10,
})
const onShowContextmenu = (menu: RouteLocationNormalized, axis: Axis) => {
state.menu = menu
state.axis = axis
state.show = true
}
const onContextmenuItem = (item: ContextmenuItemClickEmitArg) => {
if (item.disabled) return
item.menu = toRaw(state.menu)
emits('contextmenuItemClick', item)
}
const onHideContextmenu = () => {
state.show = false
}
defineExpose({
onShowContextmenu,
onHideContextmenu,
})
onMounted(() => {
useEventListener(document, 'click', onHideContextmenu)
})
</script>
<style scoped lang="scss">
.ba-contextmenu {
z-index: 9999;
}
.el-popper,
.el-popper.is-light .el-popper__arrow::before {
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
border: none;
}
.el-dropdown-menu__item {
padding: 8px 20px;
user-select: none;
}
.el-dropdown-menu__item .icon {
margin-right: 5px;
}
.el-dropdown-menu__item:not(.is-disabled) {
&:hover {
background-color: var(--el-dropdown-menuItem-hover-fill);
color: var(--el-dropdown-menuItem-hover-color);
.fa {
color: var(--el-dropdown-menuItem-hover-color) !important;
}
}
}
</style>

View File

@@ -0,0 +1,22 @@
import type { RouteLocationNormalized } from 'vue-router'
export interface Axis {
x: number
y: number
}
export interface ContextMenuItem {
name: string
label: string
icon?: string
disabled?: boolean
}
export interface ContextmenuItemClickEmitArg extends ContextMenuItem {
menu?: RouteLocationNormalized
}
export interface Props {
width?: number
items: ContextMenuItem[]
}