mirror of
https://gitee.com/dapppp/ruoyi-plus-vben5.git
synced 2026-03-19 07:58:50 +08:00
Merge branch 'main' of https://github.com/vbenjs/vue-vben-admin into antdv-next
This commit is contained in:
@@ -29,6 +29,7 @@ export {
|
||||
FoldHorizontal,
|
||||
Fullscreen,
|
||||
Github,
|
||||
Grid,
|
||||
Grip,
|
||||
GripVertical,
|
||||
Menu as IconDefault,
|
||||
@@ -36,6 +37,7 @@ export {
|
||||
Info,
|
||||
InspectionPanel,
|
||||
Languages,
|
||||
LayoutGrid,
|
||||
LoaderCircle,
|
||||
LockKeyhole,
|
||||
LogOut,
|
||||
|
||||
34
packages/@core/base/typings/src/helper.d.ts
vendored
34
packages/@core/base/typings/src/helper.d.ts
vendored
@@ -1,20 +1,38 @@
|
||||
import type { ComputedRef, MaybeRef } from 'vue';
|
||||
|
||||
/**
|
||||
* 类型级递归中增加深度计数
|
||||
*/
|
||||
type Increment<A extends unknown[]> = [...A, unknown];
|
||||
/**
|
||||
* 深层递归所有属性为可选
|
||||
*/
|
||||
type DeepPartial<T> = T extends object
|
||||
? {
|
||||
[P in keyof T]?: DeepPartial<T[P]>;
|
||||
}
|
||||
: T;
|
||||
type DeepPartial<
|
||||
T,
|
||||
D extends number = 10,
|
||||
C extends unknown[] = [],
|
||||
> = C['length'] extends D
|
||||
? T
|
||||
: T extends object
|
||||
? {
|
||||
[P in keyof T]?: DeepPartial<T[P], D, Increment<C>>;
|
||||
}
|
||||
: T;
|
||||
|
||||
/**
|
||||
* 深层递归所有属性为只读
|
||||
*/
|
||||
type DeepReadonly<T> = {
|
||||
readonly [P in keyof T]: T[P] extends object ? DeepReadonly<T[P]> : T[P];
|
||||
};
|
||||
type DeepReadonly<
|
||||
T,
|
||||
D extends number = 10,
|
||||
C extends unknown[] = [],
|
||||
> = C['length'] extends D
|
||||
? T
|
||||
: T extends object
|
||||
? {
|
||||
readonly [P in keyof T]: DeepReadonly<T[P], D, Increment<C>>;
|
||||
}
|
||||
: T;
|
||||
|
||||
/**
|
||||
* 任意类型的异步函数
|
||||
|
||||
@@ -104,6 +104,7 @@ exports[`defaultPreferences immutability test > should not modify the config obj
|
||||
"showIcon": true,
|
||||
"showMaximize": true,
|
||||
"showMore": true,
|
||||
"showRefresh": true,
|
||||
"styleType": "chrome",
|
||||
"visitHistory": true,
|
||||
"wheelable": true,
|
||||
@@ -119,6 +120,7 @@ exports[`defaultPreferences immutability test > should not modify the config obj
|
||||
"radius": "0.5",
|
||||
"semiDarkHeader": false,
|
||||
"semiDarkSidebar": false,
|
||||
"semiDarkSidebarSub": false,
|
||||
},
|
||||
"transition": {
|
||||
"enable": true,
|
||||
|
||||
@@ -105,6 +105,7 @@ const defaultPreferences: Preferences = {
|
||||
showIcon: true,
|
||||
showMaximize: true,
|
||||
showMore: true,
|
||||
showRefresh: true,
|
||||
styleType: 'chrome',
|
||||
visitHistory: true,
|
||||
wheelable: true,
|
||||
@@ -121,6 +122,7 @@ const defaultPreferences: Preferences = {
|
||||
fontSize: 16,
|
||||
semiDarkHeader: false,
|
||||
semiDarkSidebar: false,
|
||||
semiDarkSidebarSub: false,
|
||||
},
|
||||
transition: {
|
||||
enable: true,
|
||||
|
||||
@@ -38,12 +38,10 @@ const BUILT_IN_THEME_PRESETS: BuiltinThemePreset[] = [
|
||||
primaryColor: 'hsl(240 5.9% 10%)',
|
||||
type: 'zinc',
|
||||
},
|
||||
|
||||
{
|
||||
color: 'hsl(181 84% 32%)',
|
||||
type: 'deep-green',
|
||||
},
|
||||
|
||||
{
|
||||
color: 'hsl(211 91% 39%)',
|
||||
type: 'deep-blue',
|
||||
@@ -56,7 +54,6 @@ const BUILT_IN_THEME_PRESETS: BuiltinThemePreset[] = [
|
||||
color: 'hsl(0 75% 42%)',
|
||||
type: 'rose',
|
||||
},
|
||||
|
||||
{
|
||||
color: 'hsl(0 0% 25%)',
|
||||
darkPrimaryColor: 'hsl(0 0% 98%)',
|
||||
|
||||
@@ -222,6 +222,8 @@ interface TabbarPreferences {
|
||||
showMaximize: boolean;
|
||||
/** 显示更多按钮 */
|
||||
showMore: boolean;
|
||||
/** 显示刷新按钮 */
|
||||
showRefresh: boolean;
|
||||
/** 标签页风格 */
|
||||
styleType: TabsStyleType;
|
||||
/** 是否开启访问历史记录 */
|
||||
@@ -253,6 +255,8 @@ interface ThemePreferences {
|
||||
semiDarkHeader: boolean;
|
||||
/** 是否开启半深色菜单(只在theme='light'时生效) */
|
||||
semiDarkSidebar: boolean;
|
||||
/** 是否开启半深色子菜单(只在theme='light'时生效) */
|
||||
semiDarkSidebarSub: boolean;
|
||||
}
|
||||
|
||||
interface TransitionPreferences {
|
||||
|
||||
@@ -382,10 +382,10 @@ onUnmounted(() => {
|
||||
<div v-if="suffix" class="ml-1">
|
||||
<VbenRenderContent :content="suffix" />
|
||||
</div>
|
||||
<FormDescription v-if="description" class="ml-1">
|
||||
<VbenRenderContent :content="description" />
|
||||
</FormDescription>
|
||||
</div>
|
||||
<FormDescription v-if="description" class="text-xs">
|
||||
<VbenRenderContent :content="description" />
|
||||
</FormDescription>
|
||||
|
||||
<Transition name="slide-up" v-if="!compact">
|
||||
<FormMessage class="absolute bottom-[-4px]" />
|
||||
|
||||
@@ -77,7 +77,10 @@ interface Props {
|
||||
* 主题
|
||||
*/
|
||||
theme: string;
|
||||
|
||||
/**
|
||||
* 子主题
|
||||
*/
|
||||
themeSub: string;
|
||||
/**
|
||||
* 宽度
|
||||
*/
|
||||
@@ -261,40 +264,48 @@ function handleMouseleave() {
|
||||
class="h-full transition-all duration-150"
|
||||
></div>
|
||||
<aside
|
||||
:class="[
|
||||
theme,
|
||||
{
|
||||
'bg-sidebar-deep': isSidebarMixed,
|
||||
'border-r border-border bg-sidebar': !isSidebarMixed,
|
||||
},
|
||||
]"
|
||||
:style="style"
|
||||
class="fixed left-0 top-0 h-full transition-all duration-150"
|
||||
@mouseenter="handleMouseenter"
|
||||
@mouseleave="handleMouseleave"
|
||||
>
|
||||
<SidebarFixedButton
|
||||
v-if="!collapse && !isSidebarMixed && showFixedButton"
|
||||
v-model:expand-on-hover="expandOnHover"
|
||||
/>
|
||||
<div v-if="slots.logo" :style="headerStyle">
|
||||
<slot name="logo"></slot>
|
||||
</div>
|
||||
<VbenScrollbar :style="contentStyle" shadow shadow-border>
|
||||
<slot></slot>
|
||||
</VbenScrollbar>
|
||||
<div
|
||||
class="h-full"
|
||||
:class="[
|
||||
theme,
|
||||
{
|
||||
'bg-sidebar-deep': isSidebarMixed,
|
||||
'border-r border-border bg-sidebar': !isSidebarMixed,
|
||||
},
|
||||
]"
|
||||
:style="{ width: `${width}px` }"
|
||||
>
|
||||
<SidebarFixedButton
|
||||
v-if="!collapse && !isSidebarMixed && showFixedButton"
|
||||
v-model:expand-on-hover="expandOnHover"
|
||||
/>
|
||||
<div v-if="slots.logo" :style="headerStyle">
|
||||
<slot name="logo"></slot>
|
||||
</div>
|
||||
<VbenScrollbar :style="contentStyle" shadow shadow-border>
|
||||
<slot></slot>
|
||||
</VbenScrollbar>
|
||||
|
||||
<div :style="collapseStyle"></div>
|
||||
<SidebarCollapseButton
|
||||
v-if="showCollapseButton && !isSidebarMixed"
|
||||
v-model:collapsed="collapse"
|
||||
/>
|
||||
<div :style="collapseStyle"></div>
|
||||
<SidebarCollapseButton
|
||||
v-if="showCollapseButton && !isSidebarMixed"
|
||||
v-model:collapsed="collapse"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
v-if="isSidebarMixed"
|
||||
ref="asideRef"
|
||||
:class="{
|
||||
'border-l': extraVisible,
|
||||
}"
|
||||
:class="[
|
||||
themeSub,
|
||||
{
|
||||
'border-l': extraVisible,
|
||||
},
|
||||
]"
|
||||
:style="extraStyle"
|
||||
class="fixed top-0 h-full overflow-hidden border-r border-border bg-sidebar transition-all duration-200"
|
||||
>
|
||||
|
||||
@@ -146,6 +146,11 @@ interface VbenLayoutProps {
|
||||
* @default dark
|
||||
*/
|
||||
sidebarTheme?: ThemeModeType;
|
||||
/**
|
||||
* 侧边栏子栏
|
||||
* @default dark
|
||||
*/
|
||||
sidebarThemeSub?: ThemeModeType;
|
||||
/**
|
||||
* 侧边栏宽度
|
||||
* @default 210
|
||||
|
||||
@@ -56,6 +56,7 @@ const props = withDefaults(defineProps<Props>(), {
|
||||
sidebarHidden: false,
|
||||
sidebarMixedWidth: 80,
|
||||
sidebarTheme: 'dark',
|
||||
sidebarThemeSub: 'dark',
|
||||
sidebarWidth: 180,
|
||||
sideCollapseWidth: 60,
|
||||
tabbarEnable: true,
|
||||
@@ -502,6 +503,7 @@ const idMainContent = ELEMENT_ID_MAIN_CONTENT;
|
||||
:mixed-width="sidebarMixedWidth"
|
||||
:show="showSidebar"
|
||||
:theme="sidebarTheme"
|
||||
:theme-sub="sidebarThemeSub"
|
||||
:width="getSidebarWidth"
|
||||
:z-index="sidebarZIndex"
|
||||
@leave="() => emit('sideMouseLeave')"
|
||||
|
||||
@@ -463,33 +463,33 @@ $namespace: vben;
|
||||
&.is-dark {
|
||||
--menu-background-color: hsl(var(--menu));
|
||||
// --menu-submenu-opened-background-color: hsl(var(--menu-opened-dark));
|
||||
--menu-item-background-color: var(--menu-background-color);
|
||||
--menu-item-color: hsl(var(--foreground) / 80%);
|
||||
--menu-item-background-color: var(--menu-background-color);
|
||||
--menu-item-hover-color: hsl(var(--accent-foreground));
|
||||
--menu-item-hover-background-color: hsl(var(--accent));
|
||||
--menu-item-active-color: hsl(var(--accent-foreground));
|
||||
--menu-item-active-background-color: hsl(var(--accent));
|
||||
--menu-submenu-hover-color: hsl(var(--foreground));
|
||||
--menu-submenu-hover-background-color: hsl(var(--accent));
|
||||
--menu-submenu-active-color: hsl(var(--foreground));
|
||||
--menu-submenu-active-background-color: transparent;
|
||||
--menu-submenu-background-color: var(--menu-background-color);
|
||||
--menu-submenu-hover-color: hsl(var(--accent-foreground));
|
||||
--menu-submenu-hover-background-color: hsl(var(--accent));
|
||||
--menu-submenu-active-color: hsl(var(--accent-foreground));
|
||||
--menu-submenu-active-background-color: transparent;
|
||||
}
|
||||
|
||||
&.is-light {
|
||||
--menu-background-color: hsl(var(--menu));
|
||||
// --menu-submenu-opened-background-color: hsl(var(--menu-opened));
|
||||
--menu-item-color: hsl(var(--accent-foreground));
|
||||
--menu-item-background-color: var(--menu-background-color);
|
||||
--menu-item-color: hsl(var(--foreground));
|
||||
--menu-item-hover-color: var(--menu-item-color);
|
||||
--menu-item-hover-background-color: hsl(var(--accent));
|
||||
--menu-item-active-color: hsl(var(--primary));
|
||||
--menu-item-active-background-color: hsl(var(--primary) / 15%);
|
||||
--menu-submenu-background-color: var(--menu-background-color);
|
||||
--menu-submenu-hover-color: hsl(var(--primary));
|
||||
--menu-submenu-hover-background-color: hsl(var(--accent));
|
||||
--menu-submenu-active-color: hsl(var(--primary));
|
||||
--menu-submenu-active-background-color: transparent;
|
||||
--menu-submenu-background-color: var(--menu-background-color);
|
||||
}
|
||||
|
||||
&.is-rounded {
|
||||
@@ -518,25 +518,33 @@ $namespace: vben;
|
||||
--menu-background-color: transparent;
|
||||
|
||||
&.is-dark {
|
||||
--menu-background-color: hsl(var(--menu));
|
||||
--menu-item-color: hsl(var(--foreground) / 80%);
|
||||
--menu-item-background-color: var(--menu-background-color);
|
||||
--menu-item-hover-color: hsl(var(--accent-foreground));
|
||||
--menu-item-hover-background-color: hsl(var(--accent));
|
||||
--menu-item-active-color: hsl(var(--accent-foreground));
|
||||
--menu-item-active-background-color: hsl(var(--accent));
|
||||
--menu-submenu-active-color: hsl(var(--foreground));
|
||||
--menu-submenu-active-background-color: hsl(var(--accent));
|
||||
--menu-submenu-background-color: var(--menu-background-color);
|
||||
--menu-submenu-hover-color: hsl(var(--accent-foreground));
|
||||
--menu-submenu-hover-background-color: hsl(var(--accent));
|
||||
--menu-submenu-active-color: hsl(var(--accent-foreground));
|
||||
--menu-submenu-active-background-color: hsl(var(--accent));
|
||||
}
|
||||
|
||||
&.is-light {
|
||||
--menu-background-color: hsl(var(--menu));
|
||||
--menu-item-color: hsl(var(--accent-foreground));
|
||||
--menu-item-background-color: var(--menu-background-color);
|
||||
--menu-item-hover-color: var(--menu-item-color);
|
||||
--menu-item-hover-background-color: hsl(var(--accent));
|
||||
--menu-item-active-color: hsl(var(--primary));
|
||||
--menu-item-active-background-color: hsl(var(--primary) / 15%);
|
||||
--menu-item-hover-background-color: hsl(var(--accent));
|
||||
--menu-item-hover-color: hsl(var(--primary));
|
||||
--menu-submenu-active-color: hsl(var(--primary));
|
||||
--menu-submenu-active-background-color: hsl(var(--primary) / 15%);
|
||||
--menu-submenu-background-color: var(--menu-background-color);
|
||||
--menu-submenu-hover-color: hsl(var(--primary));
|
||||
--menu-submenu-hover-background-color: hsl(var(--accent));
|
||||
--menu-submenu-active-color: hsl(var(--primary));
|
||||
--menu-submenu-active-background-color: hsl(var(--primary) / 15%);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -862,9 +870,8 @@ $namespace: vben;
|
||||
padding-right: 12px !important;
|
||||
}
|
||||
|
||||
// &:not(.is-active):hover {
|
||||
&:hover {
|
||||
color: var(--menu-submenu-hover-color);
|
||||
&:not(.is-active):hover {
|
||||
//color: var(--menu-submenu-hover-color);
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
background: var(--menu-submenu-hover-background-color) !important;
|
||||
|
||||
@@ -151,10 +151,12 @@ $namespace: vben;
|
||||
}
|
||||
|
||||
&__name {
|
||||
width: 100%;
|
||||
margin-top: 8px;
|
||||
margin-bottom: 0;
|
||||
font-size: calc(var(--font-size-base, 16px) * 0.75);
|
||||
font-weight: 400;
|
||||
text-align: center;
|
||||
transition: all 0.25s ease;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,6 +210,7 @@ onBeforeUnmount(() => {
|
||||
opened ? '' : 'hidden',
|
||||
'overflow-auto',
|
||||
'max-h-[calc(var(--reka-hover-card-content-available-height)-20px)]',
|
||||
mode === 'horizontal' ? 'is-horizontal' : '',
|
||||
]"
|
||||
:content-props="contentProps"
|
||||
:open="true"
|
||||
|
||||
@@ -158,7 +158,7 @@ function onMouseDown(e: MouseEvent, tab: TabConfig) {
|
||||
<VbenIcon
|
||||
v-if="showIcon"
|
||||
:icon="tab.icon"
|
||||
class="mr-1 flex size-4 items-center overflow-hidden"
|
||||
class="mr-1 flex size-4 items-center overflow-hidden group-hover:animate-[shrink_0.3s_ease-in-out]"
|
||||
/>
|
||||
<span class="flex-1 overflow-hidden whitespace-nowrap text-sm">
|
||||
{{ tab.title }}
|
||||
|
||||
@@ -132,7 +132,7 @@ function onMouseDown(e: MouseEvent, tab: TabConfig) {
|
||||
<VbenIcon
|
||||
v-if="showIcon"
|
||||
:icon="tab.icon"
|
||||
class="mr-2 flex size-4 items-center overflow-hidden"
|
||||
class="mr-2 flex size-4 items-center overflow-hidden group-hover:animate-[shrink_0.3s_ease-in-out]"
|
||||
fallback
|
||||
/>
|
||||
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script lang="ts" setup>
|
||||
import type { DropdownMenuProps } from '@vben-core/shadcn-ui';
|
||||
|
||||
import { ChevronDown } from '@vben-core/icons';
|
||||
import { LayoutGrid } from '@vben-core/icons';
|
||||
import { VbenDropdownMenu } from '@vben-core/shadcn-ui';
|
||||
|
||||
defineProps<DropdownMenuProps>();
|
||||
@@ -12,7 +12,7 @@ defineProps<DropdownMenuProps>();
|
||||
<div
|
||||
class="flex-center h-full cursor-pointer border-l border-border px-2 text-lg font-semibold text-muted-foreground hover:bg-muted hover:text-foreground"
|
||||
>
|
||||
<ChevronDown class="size-4" />
|
||||
<LayoutGrid class="size-4" />
|
||||
</div>
|
||||
</VbenDropdownMenu>
|
||||
</template>
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
<script lang="ts" setup>
|
||||
import { RotateCw } from '@vben-core/icons';
|
||||
|
||||
const emit = defineEmits(['refresh']);
|
||||
|
||||
const handleRefresh = () => {
|
||||
emit('refresh');
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="flex-center h-full cursor-pointer border-l border-border px-2 text-lg font-semibold text-muted-foreground hover:bg-muted hover:text-foreground"
|
||||
@click="handleRefresh"
|
||||
>
|
||||
<RotateCw class="size-4" />
|
||||
</div>
|
||||
</template>
|
||||
@@ -2,7 +2,7 @@
|
||||
import type { TabsEmits, TabsProps } from './types';
|
||||
|
||||
import { useForwardPropsEmits } from '@vben-core/composables';
|
||||
import { ChevronLeft, ChevronRight } from '@vben-core/icons';
|
||||
import { ChevronsLeft, ChevronsRight } from '@vben-core/icons';
|
||||
import { VbenScrollbar } from '@vben-core/shadcn-ui';
|
||||
|
||||
import { Tabs, TabsChrome } from './components';
|
||||
@@ -60,7 +60,7 @@ useTabsDrag(props, emit);
|
||||
class="border-r px-2"
|
||||
@click="scrollDirection('left')"
|
||||
>
|
||||
<ChevronLeft class="size-4 h-full" />
|
||||
<ChevronsLeft class="size-4 h-full" />
|
||||
</span>
|
||||
|
||||
<div
|
||||
@@ -101,7 +101,7 @@ useTabsDrag(props, emit);
|
||||
class="cursor-pointer border-l px-2 text-muted-foreground hover:bg-muted"
|
||||
@click="scrollDirection('right')"
|
||||
>
|
||||
<ChevronRight class="size-4 h-full" />
|
||||
<ChevronsRight class="size-4 h-full" />
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user