feat: Feature/pro docs (#70)

* chore: merge main

* feat: update docs

* feat: remove coze-assistant

* feat: add watermark plugin

* feat: update preferences

* feat: update docs

---------

Co-authored-by: vince <vince292007@gmail.com>
This commit is contained in:
Vben
2024-07-28 14:29:05 +08:00
committed by GitHub
parent 14538f7ed5
commit 376fd17a61
225 changed files with 7731 additions and 1784 deletions

View File

@@ -42,6 +42,6 @@
"@vben-core/shadcn-ui": "workspace:*",
"@vben-core/typings": "workspace:*",
"@vueuse/core": "^10.11.0",
"vue": "^3.4.33"
"vue": "^3.4.34"
}
}

View File

@@ -43,6 +43,6 @@
"@vben-core/toolkit": "workspace:*",
"@vben-core/typings": "workspace:*",
"@vueuse/core": "^10.11.0",
"vue": "^3.4.33"
"vue": "^3.4.34"
}
}

View File

@@ -26,6 +26,10 @@ const subMenu = useSubMenuContext();
const { parentMenu, parentPaths } = useMenu();
const active = computed(() => props.path === rootMenu?.activePath);
const menuIcon = computed(() =>
active.value ? props.activeIcon || props.icon : props.icon,
);
const isTopLevelMenuItem = computed(
() => parentMenu.value?.type.name === 'Menu',
);
@@ -94,7 +98,7 @@ onBeforeUnmount(() => {
>
<template #trigger>
<div :class="[nsMenu.be('tooltip', 'trigger')]">
<VbenIcon :class="nsMenu.e('icon')" :icon="icon" fallback />
<VbenIcon :class="nsMenu.e('icon')" :icon="menuIcon" fallback />
<slot></slot>
<span v-if="collapseShowTitle" :class="nsMenu.e('name')">
<slot name="title"></slot>
@@ -109,7 +113,7 @@ onBeforeUnmount(() => {
class="right-2"
v-bind="props"
/>
<VbenIcon :class="nsMenu.e('icon')" :icon="icon" fallback />
<VbenIcon :class="nsMenu.e('icon')" :icon="menuIcon" fallback />
<slot></slot>
<slot name="title"></slot>
</div>

View File

@@ -12,7 +12,7 @@ defineOptions({
name: 'NormalMenu',
});
withDefaults(defineProps<Props>(), {
const props = withDefaults(defineProps<Props>(), {
activePath: '',
collapse: false,
menus: () => [],
@@ -25,6 +25,12 @@ const emit = defineEmits<{
}>();
const { b, e, is } = useNamespace('normal-menu');
function menuIcon(menu: MenuRecordRaw) {
return props.activePath === menu.path
? menu.activeIcon || menu.icon
: menu.icon;
}
</script>
<template>
@@ -44,7 +50,8 @@ const { b, e, is } = useNamespace('normal-menu');
@click="() => emit('select', menu)"
@mouseenter="() => emit('enter', menu)"
>
<VbenIcon :class="e('icon')" :icon="menu.icon" fallback />
<VbenIcon :class="e('icon')" :icon="menuIcon(menu)" fallback />
<span :class="e('name')" class="truncate"> {{ menu.name }}</span>
</li>
</template>

View File

@@ -172,6 +172,10 @@ function handleMouseleave(deepDispatch = false) {
}
}
const menuIcon = computed(() =>
active.value ? props.activeIcon || props.icon : props.icon,
);
const item = reactive({
active,
parentPaths,
@@ -215,7 +219,7 @@ onBeforeUnmount(() => {
<template #trigger>
<SubMenuContent
:class="is('active', active)"
:icon="icon"
:icon="menuIcon"
:is-menu-more="isSubMenuMore"
:is-top-level-menu-submenu="isTopLevelMenuSubmenu"
:level="currentLevel"
@@ -246,7 +250,7 @@ onBeforeUnmount(() => {
<template v-else>
<SubMenuContent
:class="is('active', active)"
:icon="icon"
:icon="menuIcon"
:is-menu-more="isSubMenuMore"
:is-top-level-menu-submenu="isTopLevelMenuSubmenu"
:level="currentLevel"

View File

@@ -50,6 +50,10 @@ interface MenuProps {
}
interface SubMenuProps extends MenuRecordBadgeRaw {
/**
* @zh_CN 激活图标
*/
activeIcon?: string;
/**
* @zh_CN 是否禁用
*/
@@ -65,6 +69,10 @@ interface SubMenuProps extends MenuRecordBadgeRaw {
}
interface MenuItemProps extends MenuRecordBadgeRaw {
/**
* @zh_CN 图标
*/
activeIcon?: string;
/**
* @zh_CN 是否禁用
*/

View File

@@ -31,12 +31,19 @@ const hasChildren = computed(() => {
Reflect.has(menu, 'children') && !!menu.children && menu.children.length > 0
);
});
// function menuIcon(menu: MenuRecordRaw) {
// return props.activePath === menu.path
// ? menu.activeIcon || menu.icon
// : menu.icon;
// }
</script>
<template>
<MenuItem
v-if="!hasChildren"
:key="menu.path"
:active-icon="menu.activeIcon"
:badge="menu.badge"
:badge-type="menu.badgeType"
:badge-variants="menu.badgeVariants"
@@ -48,6 +55,7 @@ const hasChildren = computed(() => {
<SubMenuComp
v-else
:key="`${menu.path}_sub`"
:active-icon="menu.activeIcon"
:icon="menu.icon"
:path="menu.path"
>

View File

@@ -48,8 +48,8 @@
"@vben-core/typings": "workspace:*",
"@vueuse/core": "^10.11.0",
"class-variance-authority": "^0.7.0",
"lucide-vue-next": "^0.414.0",
"lucide-vue-next": "^0.416.0",
"radix-vue": "^1.9.2",
"vue": "^3.4.33"
"vue": "^3.4.34"
}
}

View File

@@ -32,14 +32,14 @@ function handleItemClick(menu: IDropdownMenuItem) {
</DropdownMenuTrigger>
<DropdownMenuContent align="start">
<DropdownMenuGroup>
<template v-for="menu in menus" :key="menu.key">
<template v-for="menu in menus" :key="menu.value">
<DropdownMenuItem
:disabled="menu.disabled"
class="data-[state=checked]:bg-accent data-[state=checked]:text-accent-foreground text-foreground/80 mb-1 cursor-pointer"
@click="handleItemClick(menu)"
>
<component :is="menu.icon" v-if="menu.icon" class="mr-2 size-4" />
{{ menu.text }}
{{ menu.label }}
</DropdownMenuItem>
<DropdownMenuSeparator v-if="menu.separator" class="bg-border" />
</template>

View File

@@ -30,18 +30,20 @@ function handleItemClick(value: string) {
<template v-for="menu in menus" :key="menu.key">
<DropdownMenuItem
:class="
menu.key === modelValue ? 'bg-accent text-accent-foreground' : ''
menu.value === modelValue
? 'bg-accent text-accent-foreground'
: ''
"
class="data-[state=checked]:bg-accent data-[state=checked]:text-accent-foreground text-foreground/80 mb-1 cursor-pointer"
@click="handleItemClick(menu.key)"
@click="handleItemClick(menu.value)"
>
<component :is="menu.icon" v-if="menu.icon" class="mr-2 size-4" />
<span
v-if="!menu.icon"
:class="menu.key === modelValue ? 'bg-foreground' : ''"
:class="menu.value === modelValue ? 'bg-foreground' : ''"
class="mr-2 size-1.5 rounded-full"
></span>
{{ menu.text }}
{{ menu.label }}
</DropdownMenuItem>
</template>
</DropdownMenuGroup>

View File

@@ -12,17 +12,17 @@ interface VbenDropdownMenuItem {
*/
icon?: Component;
/**
* @zh_CN 唯一标识
* @zh_CN 标题
*/
key: string;
label: string;
/**
* @zh_CN 是否是分割线
*/
separator?: boolean;
/**
* @zh_CN 标题
* @zh_CN 唯一标识
*/
text: string;
value: string;
}
interface DropdownMenuProps {

View File

@@ -41,6 +41,6 @@
"@vben-core/icons": "workspace:*",
"@vben-core/shadcn-ui": "workspace:*",
"@vben-core/typings": "workspace:*",
"vue": "^3.4.33"
"vue": "^3.4.34"
}
}

View File

@@ -1,2 +1,3 @@
export { default as TabsToolMore } from './tool-more.vue';
export { default as TabsToolRefresh } from './tool-refresh.vue';
export { default as TabsToolScreen } from './tool-screen.vue';

View File

@@ -0,0 +1,31 @@
<script lang="ts" setup>
import { ref } from 'vue';
import { RotateCw } from '@vben-core/icons';
const emit = defineEmits<{ refresh: [] }>();
const loading = ref(false);
function handleClick() {
loading.value = true;
setTimeout(() => {
loading.value = false;
}, 1000);
emit('refresh');
}
</script>
<template>
<div
class="flex-center hover:bg-muted hover:text-foreground text-muted-foreground border-border h-full cursor-pointer border-l px-[9px] text-lg font-semibold"
@click="handleClick"
>
<RotateCw
:class="{
'animate-spin duration-1000': loading,
}"
class="size-4"
/>
</div>
</template>