mirror of
https://github.com/doocs/md.git
synced 2024-11-24 19:10:34 +08:00
feat: update trigger of dropdown (#349)
This commit is contained in:
parent
43c63f7c23
commit
3ebceb8370
@ -17,6 +17,11 @@ body,
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 抵消下拉菜单开启时带来的样式
|
||||||
|
body {
|
||||||
|
pointer-events: initial !important;
|
||||||
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar {
|
::-webkit-scrollbar {
|
||||||
width: 6px;
|
width: 6px;
|
||||||
height: 6px;
|
height: 6px;
|
||||||
@ -78,6 +83,4 @@ body,
|
|||||||
.el-icon.el-color-picker__icon.is-icon-arrow-down {
|
.el-icon.el-color-picker__icon.is-icon-arrow-down {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
@ -8,6 +8,8 @@ import {
|
|||||||
|
|
||||||
import { useStore } from '@/stores'
|
import { useStore } from '@/stores'
|
||||||
|
|
||||||
|
const props = defineProps([`isOpen`, `clickTrigger`, `openDropdown`, `updateOpen`])
|
||||||
|
|
||||||
const store = useStore()
|
const store = useStore()
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@ -17,14 +19,19 @@ const {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<DropdownMenu>
|
<DropdownMenu :open="props.isOpen" @update:open="props.updateOpen">
|
||||||
<DropdownMenuTrigger class="flex items-center">
|
<DropdownMenuTrigger
|
||||||
|
class="flex items-center p-2 px-4 hover:bg-gray-2 dark:hover:bg-stone-9"
|
||||||
|
:class="{
|
||||||
|
'bg-gray-2': props.isOpen,
|
||||||
|
'dark:bg-stone-9': props.isOpen,
|
||||||
|
}"
|
||||||
|
@click="props.clickTrigger()"
|
||||||
|
@mouseenter="props.openDropdown()"
|
||||||
|
>
|
||||||
编辑
|
编辑
|
||||||
<el-icon class="ml-2">
|
|
||||||
<ElIconArrowDown />
|
|
||||||
</el-icon>
|
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
<DropdownMenuContent>
|
<DropdownMenuContent align="start">
|
||||||
<DropdownMenuItem @click="toggleShowUploadImgDialog()">
|
<DropdownMenuItem @click="toggleShowUploadImgDialog()">
|
||||||
<el-icon class="mr-2 h-4 w-4">
|
<el-icon class="mr-2 h-4 w-4">
|
||||||
<ElIconUpload />
|
<ElIconUpload />
|
||||||
|
@ -11,6 +11,8 @@ import {
|
|||||||
|
|
||||||
import { useStore } from '@/stores'
|
import { useStore } from '@/stores'
|
||||||
|
|
||||||
|
const props = defineProps([`isOpen`, `clickTrigger`, `openDropdown`, `updateOpen`])
|
||||||
|
|
||||||
const store = useStore()
|
const store = useStore()
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@ -28,14 +30,19 @@ const {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<DropdownMenu>
|
<DropdownMenu :open="props.isOpen" @update:open="props.updateOpen">
|
||||||
<DropdownMenuTrigger class="flex items-center">
|
<DropdownMenuTrigger
|
||||||
|
class="flex items-center p-2 px-4 hover:bg-gray-2 dark:hover:bg-stone-9"
|
||||||
|
:class="{
|
||||||
|
'bg-gray-2': props.isOpen,
|
||||||
|
'dark:bg-stone-9': props.isOpen,
|
||||||
|
}"
|
||||||
|
@click="props.clickTrigger()"
|
||||||
|
@mouseenter="props.openDropdown()"
|
||||||
|
>
|
||||||
文件
|
文件
|
||||||
<el-icon class="ml-2">
|
|
||||||
<ElIconArrowDown />
|
|
||||||
</el-icon>
|
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
<DropdownMenuContent>
|
<DropdownMenuContent align="start">
|
||||||
<DropdownMenuItem @click="importMarkdownContent()">
|
<DropdownMenuItem @click="importMarkdownContent()">
|
||||||
<el-icon class="mr-2 h-4 w-4">
|
<el-icon class="mr-2 h-4 w-4">
|
||||||
<ElIconUpload />
|
<ElIconUpload />
|
||||||
|
@ -10,18 +10,25 @@ import {
|
|||||||
DropdownMenuTrigger,
|
DropdownMenuTrigger,
|
||||||
} from '@/components/ui/dropdown-menu'
|
} from '@/components/ui/dropdown-menu'
|
||||||
|
|
||||||
|
const props = defineProps([`isOpen`, `clickTrigger`, `openDropdown`, `updateOpen`])
|
||||||
|
|
||||||
const aboutDialogVisible = ref(false)
|
const aboutDialogVisible = ref(false)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<DropdownMenu>
|
<DropdownMenu :open="props.isOpen" @update:open="props.updateOpen">
|
||||||
<DropdownMenuTrigger class="flex items-center">
|
<DropdownMenuTrigger
|
||||||
|
class="flex items-center p-2 px-4 hover:bg-gray-2 dark:hover:bg-stone-9"
|
||||||
|
:class="{
|
||||||
|
'bg-gray-2': props.isOpen,
|
||||||
|
'dark:bg-stone-9': props.isOpen,
|
||||||
|
}"
|
||||||
|
@click="props.clickTrigger()"
|
||||||
|
@mouseenter="props.openDropdown()"
|
||||||
|
>
|
||||||
帮助
|
帮助
|
||||||
<el-icon class="ml-2">
|
|
||||||
<ElIconArrowDown />
|
|
||||||
</el-icon>
|
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
<DropdownMenuContent>
|
<DropdownMenuContent align="start">
|
||||||
<DropdownMenuItem @click="aboutDialogVisible = true">
|
<DropdownMenuItem @click="aboutDialogVisible = true">
|
||||||
<el-icon class="mr-2 h-4 w-4" />
|
<el-icon class="mr-2 h-4 w-4" />
|
||||||
<span>关于</span>
|
<span>关于</span>
|
||||||
|
@ -21,6 +21,8 @@ import {
|
|||||||
import { codeBlockThemeOptions, colorOptions, fontFamilyOptions, fontSizeOptions, legendOptions, themeOptions } from '@/config'
|
import { codeBlockThemeOptions, colorOptions, fontFamilyOptions, fontSizeOptions, legendOptions, themeOptions } from '@/config'
|
||||||
import { useStore } from '@/stores'
|
import { useStore } from '@/stores'
|
||||||
|
|
||||||
|
const props = defineProps([`isOpen`, `clickTrigger`, `openDropdown`, `updateOpen`])
|
||||||
|
|
||||||
const store = useStore()
|
const store = useStore()
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@ -67,14 +69,19 @@ function customStyle() {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<DropdownMenu>
|
<DropdownMenu :open="props.isOpen" @update:open="props.updateOpen">
|
||||||
<DropdownMenuTrigger class="flex items-center">
|
<DropdownMenuTrigger
|
||||||
|
class="flex items-center p-2 px-4 hover:bg-gray-2 dark:hover:bg-stone-9"
|
||||||
|
:class="{
|
||||||
|
'bg-gray-2': props.isOpen,
|
||||||
|
'dark:bg-stone-9': props.isOpen,
|
||||||
|
}"
|
||||||
|
@click="props.clickTrigger()"
|
||||||
|
@mouseenter="props.openDropdown()"
|
||||||
|
>
|
||||||
样式
|
样式
|
||||||
<el-icon class="ml-2">
|
|
||||||
<ElIconArrowDown />
|
|
||||||
</el-icon>
|
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
<DropdownMenuContent class="w-56">
|
<DropdownMenuContent class="w-56" align="start">
|
||||||
<StyleOptionMenu title="主题" :options="themeOptions" :current="theme" :change="themeChanged" />
|
<StyleOptionMenu title="主题" :options="themeOptions" :current="theme" :change="themeChanged" />
|
||||||
<DropdownMenuSeparator />
|
<DropdownMenuSeparator />
|
||||||
<StyleOptionMenu title="字体" :options="fontFamilyOptions" :current="fontFamily" :change="fontChanged" />
|
<StyleOptionMenu title="字体" :options="fontFamilyOptions" :current="fontFamily" :change="fontChanged" />
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { nextTick } from 'vue'
|
import { nextTick, reactive, ref } from 'vue'
|
||||||
import { storeToRefs } from 'pinia'
|
import { storeToRefs } from 'pinia'
|
||||||
import { ElNotification } from 'element-plus'
|
import { ElNotification } from 'element-plus'
|
||||||
import CodeMirror from 'codemirror'
|
import CodeMirror from 'codemirror'
|
||||||
|
import { Command } from 'lucide-vue-next'
|
||||||
|
|
||||||
import PostInfo from './PostInfo.vue'
|
import PostInfo from './PostInfo.vue'
|
||||||
import FileDropdown from './FileDropdown.vue'
|
import FileDropdown from './FileDropdown.vue'
|
||||||
@ -32,35 +33,38 @@ const defaultKeyMap = CodeMirror.keyMap.default
|
|||||||
const modPrefix
|
const modPrefix
|
||||||
= defaultKeyMap === CodeMirror.keyMap.macDefault ? `Cmd` : `Ctrl`
|
= defaultKeyMap === CodeMirror.keyMap.macDefault ? `Cmd` : `Ctrl`
|
||||||
|
|
||||||
|
const kbdIcon
|
||||||
|
= defaultKeyMap === CodeMirror.keyMap.macDefault ? `⌘` : `Ctrl`
|
||||||
|
|
||||||
const formatItems = [
|
const formatItems = [
|
||||||
{
|
{
|
||||||
label: `加粗`,
|
label: `加粗`,
|
||||||
kbd: `${modPrefix} + B`,
|
kbd: [kbdIcon, `B`],
|
||||||
emitArgs: [`addFormat`, `${modPrefix}-B`],
|
emitArgs: [`addFormat`, `${modPrefix}-B`],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: `斜体`,
|
label: `斜体`,
|
||||||
kbd: `${modPrefix} + I`,
|
kbd: [kbdIcon, `I`],
|
||||||
emitArgs: [`addFormat`, `${modPrefix}-I`],
|
emitArgs: [`addFormat`, `${modPrefix}-I`],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: `删除线`,
|
label: `删除线`,
|
||||||
kbd: `${modPrefix} + D`,
|
kbd: [kbdIcon, `D`],
|
||||||
emitArgs: [`addFormat`, `${modPrefix}-D`],
|
emitArgs: [`addFormat`, `${modPrefix}-D`],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: `超链接`,
|
label: `超链接`,
|
||||||
kbd: `${modPrefix} + K`,
|
kbd: [kbdIcon, `K`],
|
||||||
emitArgs: [`addFormat`, `${modPrefix}-K`],
|
emitArgs: [`addFormat`, `${modPrefix}-K`],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: `行内代码`,
|
label: `行内代码`,
|
||||||
kbd: `${modPrefix} + E`,
|
kbd: [kbdIcon, `E`],
|
||||||
emitArgs: [`addFormat`, `${modPrefix}-E`],
|
emitArgs: [`addFormat`, `${modPrefix}-E`],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: `格式化`,
|
label: `格式化`,
|
||||||
kbd: `${modPrefix} + F`,
|
kbd: [kbdIcon, `F`],
|
||||||
emitArgs: [`formatContent`],
|
emitArgs: [`formatContent`],
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
@ -153,29 +157,62 @@ function copy() {
|
|||||||
})
|
})
|
||||||
}, 350)
|
}, 350)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isClickTrigger = ref(false)
|
||||||
|
const isOpenList = reactive(Array.from({ length: 5 }).fill(false))
|
||||||
|
function clickTrigger() {
|
||||||
|
isClickTrigger.value = !isClickTrigger.value
|
||||||
|
}
|
||||||
|
|
||||||
|
function openDropdown(index) {
|
||||||
|
return () => {
|
||||||
|
isOpenList.fill(false)
|
||||||
|
isOpenList[index] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateOpen(isOpen) {
|
||||||
|
if (!isOpen) {
|
||||||
|
isOpenList.fill(false)
|
||||||
|
isClickTrigger.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="header-container">
|
<div class="header-container">
|
||||||
<el-space class="dropdowns flex-auto" size="large">
|
<div class="dropdowns flex flex-auto">
|
||||||
<FileDropdown />
|
<FileDropdown
|
||||||
<DropdownMenu>
|
:is-open="isClickTrigger && isOpenList[0]"
|
||||||
<DropdownMenuTrigger class="flex items-center">
|
:click-trigger="clickTrigger"
|
||||||
|
:open-dropdown="openDropdown(0)"
|
||||||
|
:update-open="updateOpen"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<DropdownMenu :open="isClickTrigger && isOpenList[1]" @update:open="updateOpen">
|
||||||
|
<DropdownMenuTrigger
|
||||||
|
class="flex items-center p-2 px-4 hover:bg-gray-2 dark:hover:bg-stone-9"
|
||||||
|
:class="{
|
||||||
|
'bg-gray-2': isOpenList[1],
|
||||||
|
'dark:bg-stone-9': isOpenList[1],
|
||||||
|
}"
|
||||||
|
@click="clickTrigger()"
|
||||||
|
@mouseenter="openDropdown(1)()"
|
||||||
|
>
|
||||||
格式
|
格式
|
||||||
<el-icon class="ml-2">
|
|
||||||
<ElIconArrowDown />
|
|
||||||
</el-icon>
|
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
<DropdownMenuContent class="w-60">
|
<DropdownMenuContent class="w-60" align="start">
|
||||||
<DropdownMenuItem v-for="{ label, kbd, emitArgs } in formatItems" :key="kbd" @click="$emit(...emitArgs)">
|
<DropdownMenuItem v-for="{ label, kbd, emitArgs } in formatItems" :key="kbd" @click="$emit(...emitArgs);">
|
||||||
<el-icon class="mr-2 h-4 w-4" />
|
<el-icon class="mr-2 h-4 w-4" />
|
||||||
{{ label }}
|
{{ label }}
|
||||||
<DropdownMenuShortcut>
|
<DropdownMenuShortcut>
|
||||||
{{ kbd }}
|
<kbd v-for="item in kbd" :key="item" class="mx-1 bg-gray-2 dark:bg-stone-9">
|
||||||
|
{{ item }}
|
||||||
|
</kbd>
|
||||||
</DropdownMenuShortcut>
|
</DropdownMenuShortcut>
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
<DropdownMenuSeparator />
|
<DropdownMenuSeparator />
|
||||||
<DropdownMenuItem @click="citeStatusChanged">
|
<DropdownMenuItem @click="citeStatusChanged()">
|
||||||
<el-icon class="mr-2 h-4 w-4" :class="{ 'opacity-0': !isCiteStatus }">
|
<el-icon class="mr-2 h-4 w-4" :class="{ 'opacity-0': !isCiteStatus }">
|
||||||
<ElIconCheck />
|
<ElIconCheck />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
@ -183,10 +220,26 @@ function copy() {
|
|||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
</DropdownMenuContent>
|
</DropdownMenuContent>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
<EditDropdown />
|
<EditDropdown
|
||||||
<StyleDropdown />
|
:is-open="isClickTrigger && isOpenList[2]"
|
||||||
<HelpDropdown />
|
:click-trigger="clickTrigger"
|
||||||
</el-space>
|
:open-dropdown="openDropdown(2)"
|
||||||
|
:update-open="updateOpen"
|
||||||
|
/>
|
||||||
|
<StyleDropdown
|
||||||
|
|
||||||
|
:is-open="isClickTrigger && isOpenList[3]"
|
||||||
|
:click-trigger="clickTrigger"
|
||||||
|
:open-dropdown="openDropdown(3)"
|
||||||
|
:update-open="updateOpen"
|
||||||
|
/>
|
||||||
|
<HelpDropdown
|
||||||
|
:is-open="isClickTrigger && isOpenList[4]"
|
||||||
|
:click-trigger="clickTrigger"
|
||||||
|
:open-dropdown="openDropdown(4)"
|
||||||
|
:update-open="updateOpen"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<el-button plain type="primary" @click="copy">
|
<el-button plain type="primary" @click="copy">
|
||||||
复制
|
复制
|
||||||
</el-button>
|
</el-button>
|
||||||
@ -202,4 +255,17 @@ function copy() {
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
padding: 0 20px;
|
padding: 0 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dropdowns {
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
kbd {
|
||||||
|
display: inline-flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
border: 1px solid #a8a8a8;
|
||||||
|
padding: 1px 4px;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
Loading…
Reference in New Issue
Block a user