perf: improve overall theme color matching
parent
caf1fc4375
commit
f95d9aa609
|
@ -12,7 +12,7 @@ const routes: RouteRecordRaw[] = [
|
||||||
badgeType: 'dot',
|
badgeType: 'dot',
|
||||||
icon: VBEN_LOGO_URL,
|
icon: VBEN_LOGO_URL,
|
||||||
order: 9999,
|
order: 9999,
|
||||||
title: 'Vben Admin',
|
title: 'Vben',
|
||||||
},
|
},
|
||||||
name: 'AboutLayout',
|
name: 'AboutLayout',
|
||||||
path: '/vben-admin',
|
path: '/vben-admin',
|
||||||
|
|
|
@ -27,6 +27,8 @@ packages.forEach((pkg) => {
|
||||||
const shadcnUiColors = {
|
const shadcnUiColors = {
|
||||||
accent: {
|
accent: {
|
||||||
DEFAULT: 'hsl(var(--accent))',
|
DEFAULT: 'hsl(var(--accent))',
|
||||||
|
dark: 'hsl(var(--accent-dark))',
|
||||||
|
'dark-hover': 'hsl(var(--accent-dark-hover))',
|
||||||
foreground: 'hsl(var(--accent-foreground))',
|
foreground: 'hsl(var(--accent-foreground))',
|
||||||
hover: 'hsl(var(--accent-hover))',
|
hover: 'hsl(var(--accent-hover))',
|
||||||
},
|
},
|
||||||
|
@ -34,17 +36,23 @@ const shadcnUiColors = {
|
||||||
DEFAULT: 'hsl(var(--background))',
|
DEFAULT: 'hsl(var(--background))',
|
||||||
content: 'hsl(var(--background-content))',
|
content: 'hsl(var(--background-content))',
|
||||||
},
|
},
|
||||||
border: 'hsl(var(--border))',
|
border: {
|
||||||
|
DEFAULT: 'hsl(var(--border))',
|
||||||
|
dark: 'hsl(var(--border-dark))',
|
||||||
|
},
|
||||||
card: {
|
card: {
|
||||||
DEFAULT: 'hsl(var(--card))',
|
DEFAULT: 'hsl(var(--card))',
|
||||||
foreground: 'hsl(var(--card-foreground))',
|
foreground: 'hsl(var(--card-foreground))',
|
||||||
},
|
},
|
||||||
destructive: {
|
destructive: {
|
||||||
...createColorsPattern('destructive'),
|
...createColorsPalette('destructive'),
|
||||||
DEFAULT: 'hsl(var(--destructive))',
|
DEFAULT: 'hsl(var(--destructive))',
|
||||||
},
|
},
|
||||||
|
|
||||||
foreground: 'hsl(var(--foreground))',
|
foreground: {
|
||||||
|
DEFAULT: 'hsl(var(--foreground))',
|
||||||
|
dark: 'hsl(var(--foreground-dark))',
|
||||||
|
},
|
||||||
|
|
||||||
input: {
|
input: {
|
||||||
DEFAULT: 'hsl(var(--input))',
|
DEFAULT: 'hsl(var(--input))',
|
||||||
|
@ -59,7 +67,7 @@ const shadcnUiColors = {
|
||||||
foreground: 'hsl(var(--popover-foreground))',
|
foreground: 'hsl(var(--popover-foreground))',
|
||||||
},
|
},
|
||||||
primary: {
|
primary: {
|
||||||
...createColorsPattern('primary'),
|
...createColorsPalette('primary'),
|
||||||
DEFAULT: 'hsl(var(--primary))',
|
DEFAULT: 'hsl(var(--primary))',
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -76,7 +84,7 @@ const customColors = {
|
||||||
DEFAULT: 'hsl(var(--authentication))',
|
DEFAULT: 'hsl(var(--authentication))',
|
||||||
},
|
},
|
||||||
green: {
|
green: {
|
||||||
...createColorsPattern('green'),
|
...createColorsPalette('green'),
|
||||||
foreground: 'hsl(var(--success-foreground))',
|
foreground: 'hsl(var(--success-foreground))',
|
||||||
},
|
},
|
||||||
heavy: {
|
heavy: {
|
||||||
|
@ -88,19 +96,19 @@ const customColors = {
|
||||||
},
|
},
|
||||||
overlay: 'hsl(var(--overlay))',
|
overlay: 'hsl(var(--overlay))',
|
||||||
red: {
|
red: {
|
||||||
...createColorsPattern('red'),
|
...createColorsPalette('red'),
|
||||||
foreground: 'hsl(var(--destructive-foreground))',
|
foreground: 'hsl(var(--destructive-foreground))',
|
||||||
},
|
},
|
||||||
success: {
|
success: {
|
||||||
...createColorsPattern('success'),
|
...createColorsPalette('success'),
|
||||||
DEFAULT: 'hsl(var(--success))',
|
DEFAULT: 'hsl(var(--success))',
|
||||||
},
|
},
|
||||||
warning: {
|
warning: {
|
||||||
...createColorsPattern('warning'),
|
...createColorsPalette('warning'),
|
||||||
DEFAULT: 'hsl(var(--warning))',
|
DEFAULT: 'hsl(var(--warning))',
|
||||||
},
|
},
|
||||||
yellow: {
|
yellow: {
|
||||||
...createColorsPattern('yellow'),
|
...createColorsPalette('yellow'),
|
||||||
foreground: 'hsl(var(--warning-foreground))',
|
foreground: 'hsl(var(--warning-foreground))',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -189,7 +197,31 @@ export default {
|
||||||
},
|
},
|
||||||
} as Config;
|
} as Config;
|
||||||
|
|
||||||
function createColorsPattern(name: string) {
|
function createColorsPalette(name: string) {
|
||||||
|
// backgroundLightest: '#EFF6FF', // Tailwind CSS 默认的 `blue-50`
|
||||||
|
// backgroundLighter: '#DBEAFE', // Tailwind CSS 默认的 `blue-100`
|
||||||
|
// backgroundLight: '#BFDBFE', // Tailwind CSS 默认的 `blue-200`
|
||||||
|
// borderLight: '#93C5FD', // Tailwind CSS 默认的 `blue-300`
|
||||||
|
// border: '#60A5FA', // Tailwind CSS 默认的 `blue-400`
|
||||||
|
// main: '#3B82F6', // Tailwind CSS 默认的 `blue-500`
|
||||||
|
// hover: '#2563EB', // Tailwind CSS 默认的 `blue-600`
|
||||||
|
// active: '#1D4ED8', // Tailwind CSS 默认的 `blue-700`
|
||||||
|
// backgroundDark: '#1E40AF', // Tailwind CSS 默认的 `blue-800`
|
||||||
|
// backgroundDarker: '#1E3A8A', // Tailwind CSS 默认的 `blue-900`
|
||||||
|
// backgroundDarkest: '#172554', // Tailwind CSS 默认的 `blue-950`
|
||||||
|
|
||||||
|
// • backgroundLightest (#EFF6FF): 适用于最浅的背景色,可能用于非常轻微的阴影或卡片的背景。
|
||||||
|
// • backgroundLighter (#DBEAFE): 适用于略浅的背景色,通常用于次要背景或略浅的区域。
|
||||||
|
// • backgroundLight (#BFDBFE): 适用于浅色背景,可能用于输入框或表单区域的背景。
|
||||||
|
// • borderLight (#93C5FD): 适用于浅色边框,可能用于输入框或卡片的边框。
|
||||||
|
// • border (#60A5FA): 适用于普通边框,可能用于按钮或卡片的边框。
|
||||||
|
// • main (#3B82F6): 适用于主要的主题色,通常用于按钮、链接或主要的强调色。
|
||||||
|
// • hover (#2563EB): 适用于鼠标悬停状态下的颜色,例如按钮悬停时的背景色或边框色。
|
||||||
|
// • active (#1D4ED8): 适用于激活状态下的颜色,例如按钮按下时的背景色或边框色。
|
||||||
|
// • backgroundDark (#1E40AF): 适用于深色背景,可能用于主要按钮或深色卡片背景。
|
||||||
|
// • backgroundDarker (#1E3A8A): 适用于更深的背景,通常用于头部导航栏或页脚。
|
||||||
|
// • backgroundDarkest (#172554): 适用于最深的背景,可能用于非常深色的区域或极端对比色。
|
||||||
|
|
||||||
return {
|
return {
|
||||||
50: `hsl(var(--${name}-50))`,
|
50: `hsl(var(--${name}-50))`,
|
||||||
100: `hsl(var(--${name}-100))`,
|
100: `hsl(var(--${name}-100))`,
|
||||||
|
@ -199,18 +231,29 @@ function createColorsPattern(name: string) {
|
||||||
500: `hsl(var(--${name}-500))`,
|
500: `hsl(var(--${name}-500))`,
|
||||||
600: `hsl(var(--${name}-600))`,
|
600: `hsl(var(--${name}-600))`,
|
||||||
700: `hsl(var(--${name}-700))`,
|
700: `hsl(var(--${name}-700))`,
|
||||||
800: `hsl(var(--${name}-800))`,
|
// 800: `hsl(var(--${name}-800))`,
|
||||||
900: `hsl(var(--${name}-900))`,
|
// 900: `hsl(var(--${name}-900))`,
|
||||||
950: `hsl(var(--${name}-950))`,
|
// 950: `hsl(var(--${name}-950))`,
|
||||||
active: `hsl(var(--${name}-600))`,
|
// 激活状态下的颜色,适用于按钮按下时的背景色或边框色。
|
||||||
background: `hsl(var(--${name}-50))`,
|
active: `hsl(var(--${name}-700))`,
|
||||||
'background-hover': `hsl(var(--${name}-100))`,
|
// 浅色背景,适用于输入框或表单区域的背景。
|
||||||
border: `hsl(var(--${name}-200))`,
|
'background-light': `hsl(var(--${name}-200))`,
|
||||||
'border-hover': `hsl(var(--${name}-300))`,
|
// 适用于略浅的背景色,通常用于次要背景或略浅的区域。
|
||||||
|
'background-lighter': `hsl(var(--${name}-100))`,
|
||||||
|
// 最浅的背景色,适用于非常轻微的阴影或卡片的背景。
|
||||||
|
'background-lightest': `hsl(var(--${name}-50))`,
|
||||||
|
// 适用于普通边框,可能用于按钮或卡片的边框。
|
||||||
|
border: `hsl(var(--${name}-400))`,
|
||||||
|
// 浅色边框,适用于输入框或卡片的边框。
|
||||||
|
'border-light': `hsl(var(--${name}-300))`,
|
||||||
foreground: `hsl(var(--${name}-foreground))`,
|
foreground: `hsl(var(--${name}-foreground))`,
|
||||||
hover: `hsl(var(--${name}-400))`,
|
// 鼠标悬停状态下的颜色,适用于按钮悬停时的背景色或边框色。
|
||||||
text: `hsl(var(--${name}-800))`,
|
hover: `hsl(var(--${name}-600))`,
|
||||||
'text-active': `hsl(var(--${name}-900))`,
|
// 主色文本
|
||||||
'text-hover': `hsl(var(--${name}-700))`,
|
text: `hsl(var(--${name}-500))`,
|
||||||
|
// 主色文本激活态
|
||||||
|
'text-active': `hsl(var(--${name}-700))`,
|
||||||
|
// 主色文本悬浮态
|
||||||
|
'text-hover': `hsl(var(--${name}-600))`,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -174,18 +174,18 @@ class PreferenceManager {
|
||||||
if (colorPrimary) {
|
if (colorPrimary) {
|
||||||
document.documentElement.style.setProperty(
|
document.documentElement.style.setProperty(
|
||||||
'--primary',
|
'--primary',
|
||||||
colorVariables['--primary-600'],
|
colorVariables['--primary-500'],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (colorVariables['--green-600']) {
|
if (colorVariables['--green-500']) {
|
||||||
colorVariables['--success'] = colorVariables['--green-600'];
|
colorVariables['--success'] = colorVariables['--green-500'];
|
||||||
}
|
}
|
||||||
if (colorVariables['--yellow-600']) {
|
if (colorVariables['--yellow-500']) {
|
||||||
colorVariables['--warning'] = colorVariables['--yellow-600'];
|
colorVariables['--warning'] = colorVariables['--yellow-500'];
|
||||||
}
|
}
|
||||||
if (colorVariables['--red-600']) {
|
if (colorVariables['--red-500']) {
|
||||||
colorVariables['--destructive'] = colorVariables['--red-600'];
|
colorVariables['--destructive'] = colorVariables['--red-500'];
|
||||||
}
|
}
|
||||||
updateCSSVariables(colorVariables);
|
updateCSSVariables(colorVariables);
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,8 +36,12 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@vben-core/constants": "workspace:*",
|
||||||
|
"@vben-core/toolkit": "workspace:*",
|
||||||
|
"@vueuse/core": "^10.11.0",
|
||||||
"radix-vue": "^1.9.1",
|
"radix-vue": "^1.9.1",
|
||||||
"sortablejs": "^1.15.2"
|
"sortablejs": "^1.15.2",
|
||||||
|
"vue": "^3.4.31"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/sortablejs": "^1.15.8"
|
"@types/sortablejs": "^1.15.8"
|
|
@ -1,3 +1,4 @@
|
||||||
|
export * from './use-content-height';
|
||||||
export * from './use-namespace';
|
export * from './use-namespace';
|
||||||
export * from './use-sortable';
|
export * from './use-sortable';
|
||||||
export {
|
export {
|
|
@ -0,0 +1,45 @@
|
||||||
|
import { computed, onMounted, ref, watch } from 'vue';
|
||||||
|
|
||||||
|
import { CSS_VARIABLE_LAYOUT_CONTENT_HEIGHT } from '@vben-core/constants';
|
||||||
|
import { getElementVisibleHeight } from '@vben-core/toolkit';
|
||||||
|
|
||||||
|
import { useCssVar, useDebounceFn, useWindowSize } from '@vueuse/core';
|
||||||
|
/**
|
||||||
|
* @zh_CN 获取内容高度(可视区域,不包含滚动条)
|
||||||
|
*/
|
||||||
|
function useContentHeight() {
|
||||||
|
const contentHeight = useCssVar(CSS_VARIABLE_LAYOUT_CONTENT_HEIGHT);
|
||||||
|
|
||||||
|
const contentStyles = computed(() => {
|
||||||
|
return {
|
||||||
|
height: `var(${CSS_VARIABLE_LAYOUT_CONTENT_HEIGHT})`,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return { contentHeight, contentStyles };
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @zh_CN 创建内容高度监听
|
||||||
|
*/
|
||||||
|
function useContentHeightListener() {
|
||||||
|
const contentElement = ref<HTMLDivElement | null>(null);
|
||||||
|
|
||||||
|
const { height, width } = useWindowSize();
|
||||||
|
const contentHeight = useCssVar(CSS_VARIABLE_LAYOUT_CONTENT_HEIGHT);
|
||||||
|
const debouncedCalcHeight = useDebounceFn(() => {
|
||||||
|
contentHeight.value = `${getElementVisibleHeight(contentElement.value)}px`;
|
||||||
|
}, 200);
|
||||||
|
|
||||||
|
watch([height, width], () => {
|
||||||
|
debouncedCalcHeight();
|
||||||
|
});
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
debouncedCalcHeight();
|
||||||
|
});
|
||||||
|
|
||||||
|
return { contentElement };
|
||||||
|
}
|
||||||
|
|
||||||
|
export { useContentHeight, useContentHeightListener };
|
|
@ -0,0 +1,15 @@
|
||||||
|
// --vben-content-client-height
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @zh_CN CSS 变量前缀
|
||||||
|
* @en_US CSS variable prefix
|
||||||
|
*/
|
||||||
|
const CSS_VARIABLE_PREFIX = '--vben';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @zh_CN 布局内容高度 css变量
|
||||||
|
* @en_US Layout content height
|
||||||
|
*/
|
||||||
|
const CSS_VARIABLE_LAYOUT_CONTENT_HEIGHT = `${CSS_VARIABLE_PREFIX}-content-height`;
|
||||||
|
|
||||||
|
export { CSS_VARIABLE_LAYOUT_CONTENT_HEIGHT, CSS_VARIABLE_PREFIX };
|
|
@ -1,22 +1,2 @@
|
||||||
/**
|
export * from './global';
|
||||||
* @zh_CN GITHUB 仓库地址
|
export * from './vben';
|
||||||
*/
|
|
||||||
const VBEN_GITHUB_URL = 'https://github.com/vbenjs/vue-vben-admin';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @zh_CN 文档地址
|
|
||||||
*/
|
|
||||||
const VBEN_DOC_URL = 'https://doc.vben.pro';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @zh_CN Vben Logo
|
|
||||||
*/
|
|
||||||
const VBEN_LOGO_URL =
|
|
||||||
'https://cdn.jsdelivr.net/npm/@vbenjs/static-source@0.1.3/source/logo-v1.webp';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @zh_CN Vben Admin 首页地址
|
|
||||||
*/
|
|
||||||
const VBEN_PREVIEW_URL = 'https://vben.pro';
|
|
||||||
|
|
||||||
export { VBEN_DOC_URL, VBEN_GITHUB_URL, VBEN_LOGO_URL, VBEN_PREVIEW_URL };
|
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
/**
|
||||||
|
* @zh_CN GITHUB 仓库地址
|
||||||
|
*/
|
||||||
|
const VBEN_GITHUB_URL = 'https://github.com/vbenjs/vue-vben-admin';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @zh_CN 文档地址
|
||||||
|
*/
|
||||||
|
const VBEN_DOC_URL = 'https://doc.vben.pro';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @zh_CN Vben Logo
|
||||||
|
*/
|
||||||
|
const VBEN_LOGO_URL =
|
||||||
|
'https://cdn.jsdelivr.net/npm/@vbenjs/static-source@0.1.3/source/logo-v1.webp';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @zh_CN Vben Admin 首页地址
|
||||||
|
*/
|
||||||
|
const VBEN_PREVIEW_URL = 'https://vben.pro';
|
||||||
|
|
||||||
|
export { VBEN_DOC_URL, VBEN_GITHUB_URL, VBEN_LOGO_URL, VBEN_PREVIEW_URL };
|
|
@ -56,7 +56,7 @@
|
||||||
--heavy-foreground: var(--accent-foreground);
|
--heavy-foreground: var(--accent-foreground);
|
||||||
|
|
||||||
/* Default border color */
|
/* Default border color */
|
||||||
--border: 215 27.9% 16.9%;
|
--border: 240 3.7% 15.9%;
|
||||||
|
|
||||||
/* Border color for inputs such as <Input />, <Select />, <Textarea /> */
|
/* Border color for inputs such as <Input />, <Select />, <Textarea /> */
|
||||||
--input: 0deg 0% 100% / 10%;
|
--input: 0deg 0% 100% / 10%;
|
||||||
|
@ -90,6 +90,7 @@
|
||||||
|
|
||||||
:root.dark[data-theme='violet'] {
|
:root.dark[data-theme='violet'] {
|
||||||
--background: 224 71.4% 4.1%;
|
--background: 224 71.4% 4.1%;
|
||||||
|
--background-content: var(--background);
|
||||||
--foreground: 210 20% 98%;
|
--foreground: 210 20% 98%;
|
||||||
--card: 224 71.4% 4.1%;
|
--card: 224 71.4% 4.1%;
|
||||||
--card-foreground: 210 20% 98%;
|
--card-foreground: 210 20% 98%;
|
||||||
|
@ -111,6 +112,7 @@
|
||||||
|
|
||||||
:root.dark[data-theme='pink'] {
|
:root.dark[data-theme='pink'] {
|
||||||
--background: 20 14.3% 4.1%;
|
--background: 20 14.3% 4.1%;
|
||||||
|
--background-content: var(--background);
|
||||||
--foreground: 0 0% 95%;
|
--foreground: 0 0% 95%;
|
||||||
--card: 24 9.8% 10%;
|
--card: 24 9.8% 10%;
|
||||||
--card-foreground: 0 0% 95%;
|
--card-foreground: 0 0% 95%;
|
||||||
|
@ -132,6 +134,7 @@
|
||||||
|
|
||||||
:root.dark[data-theme='rose'] {
|
:root.dark[data-theme='rose'] {
|
||||||
--background: 0 0% 3.9%;
|
--background: 0 0% 3.9%;
|
||||||
|
--background-content: var(--background);
|
||||||
--foreground: 0 0% 98%;
|
--foreground: 0 0% 98%;
|
||||||
--card: 0 0% 3.9%;
|
--card: 0 0% 3.9%;
|
||||||
--card-foreground: 0 0% 98%;
|
--card-foreground: 0 0% 98%;
|
||||||
|
@ -153,6 +156,7 @@
|
||||||
|
|
||||||
:root.dark[data-theme='sky-blue'] {
|
:root.dark[data-theme='sky-blue'] {
|
||||||
--background: 222.2 84% 4.9%;
|
--background: 222.2 84% 4.9%;
|
||||||
|
--background-content: var(--background);
|
||||||
--foreground: 210 40% 98%;
|
--foreground: 210 40% 98%;
|
||||||
--card: 222.2 84% 4.9%;
|
--card: 222.2 84% 4.9%;
|
||||||
--card-foreground: 210 40% 98%;
|
--card-foreground: 210 40% 98%;
|
||||||
|
@ -174,6 +178,7 @@
|
||||||
|
|
||||||
:root.dark[data-theme='deep-blue'] {
|
:root.dark[data-theme='deep-blue'] {
|
||||||
--background: 222.2 84% 4.9%;
|
--background: 222.2 84% 4.9%;
|
||||||
|
--background-content: var(--background);
|
||||||
--foreground: 210 40% 98%;
|
--foreground: 210 40% 98%;
|
||||||
--card: 222.2 84% 4.9%;
|
--card: 222.2 84% 4.9%;
|
||||||
--card-foreground: 210 40% 98%;
|
--card-foreground: 210 40% 98%;
|
||||||
|
@ -195,6 +200,7 @@
|
||||||
|
|
||||||
:root.dark[data-theme='green'] {
|
:root.dark[data-theme='green'] {
|
||||||
--background: 20 14.3% 4.1%;
|
--background: 20 14.3% 4.1%;
|
||||||
|
--background-content: var(--background);
|
||||||
--foreground: 0 0% 95%;
|
--foreground: 0 0% 95%;
|
||||||
--card: 24 9.8% 10%;
|
--card: 24 9.8% 10%;
|
||||||
--card-foreground: 0 0% 95%;
|
--card-foreground: 0 0% 95%;
|
||||||
|
@ -216,6 +222,7 @@
|
||||||
|
|
||||||
:root.dark[data-theme='deep-green'] {
|
:root.dark[data-theme='deep-green'] {
|
||||||
--background: 20 14.3% 4.1%;
|
--background: 20 14.3% 4.1%;
|
||||||
|
--background-content: var(--background);
|
||||||
--foreground: 0 0% 95%;
|
--foreground: 0 0% 95%;
|
||||||
--card: 24 9.8% 10%;
|
--card: 24 9.8% 10%;
|
||||||
--card-foreground: 0 0% 95%;
|
--card-foreground: 0 0% 95%;
|
||||||
|
@ -237,6 +244,7 @@
|
||||||
|
|
||||||
:root.dark[data-theme='orange'] {
|
:root.dark[data-theme='orange'] {
|
||||||
--background: 20 14.3% 4.1%;
|
--background: 20 14.3% 4.1%;
|
||||||
|
--background-content: var(--background);
|
||||||
--foreground: 60 9.1% 97.8%;
|
--foreground: 60 9.1% 97.8%;
|
||||||
--card: 20 14.3% 4.1%;
|
--card: 20 14.3% 4.1%;
|
||||||
--card-foreground: 60 9.1% 97.8%;
|
--card-foreground: 60 9.1% 97.8%;
|
||||||
|
@ -258,6 +266,7 @@
|
||||||
|
|
||||||
:root.dark[data-theme='yellow'] {
|
:root.dark[data-theme='yellow'] {
|
||||||
--background: 20 14.3% 4.1%;
|
--background: 20 14.3% 4.1%;
|
||||||
|
--background-content: var(--background);
|
||||||
--foreground: 60 9.1% 97.8%;
|
--foreground: 60 9.1% 97.8%;
|
||||||
--card: 20 14.3% 4.1%;
|
--card: 20 14.3% 4.1%;
|
||||||
--card-foreground: 60 9.1% 97.8%;
|
--card-foreground: 60 9.1% 97.8%;
|
||||||
|
@ -279,6 +288,7 @@
|
||||||
|
|
||||||
:root.dark[data-theme='zinc'] {
|
:root.dark[data-theme='zinc'] {
|
||||||
--background: 240 10% 3.9%;
|
--background: 240 10% 3.9%;
|
||||||
|
--background-content: var(--background);
|
||||||
--foreground: 0 0% 98%;
|
--foreground: 0 0% 98%;
|
||||||
--card: 240 10% 3.9%;
|
--card: 240 10% 3.9%;
|
||||||
--card-foreground: 0 0% 98%;
|
--card-foreground: 0 0% 98%;
|
||||||
|
@ -300,6 +310,7 @@
|
||||||
|
|
||||||
:root.dark[data-theme='neutral'] {
|
:root.dark[data-theme='neutral'] {
|
||||||
--background: 0 0% 3.9%;
|
--background: 0 0% 3.9%;
|
||||||
|
--background-content: var(--background);
|
||||||
--foreground: 0 0% 98%;
|
--foreground: 0 0% 98%;
|
||||||
--card: 0 0% 3.9%;
|
--card: 0 0% 3.9%;
|
||||||
--card-foreground: 0 0% 98%;
|
--card-foreground: 0 0% 98%;
|
||||||
|
@ -321,6 +332,7 @@
|
||||||
|
|
||||||
:root.dark[data-theme='slate'] {
|
:root.dark[data-theme='slate'] {
|
||||||
--background: 222.2 84% 4.9%;
|
--background: 222.2 84% 4.9%;
|
||||||
|
--background-content: var(--background);
|
||||||
--foreground: 210 40% 98%;
|
--foreground: 210 40% 98%;
|
||||||
--card: 222.2 84% 4.9%;
|
--card: 222.2 84% 4.9%;
|
||||||
--card-foreground: 210 40% 98%;
|
--card-foreground: 210 40% 98%;
|
||||||
|
@ -342,6 +354,7 @@
|
||||||
|
|
||||||
:root.dark[data-theme='gray'] {
|
:root.dark[data-theme='gray'] {
|
||||||
--background: 224 71.4% 4.1%;
|
--background: 224 71.4% 4.1%;
|
||||||
|
--background-content: var(--background);
|
||||||
--foreground: 210 20% 98%;
|
--foreground: 210 20% 98%;
|
||||||
--card: 224 71.4% 4.1%;
|
--card: 224 71.4% 4.1%;
|
||||||
--card-foreground: 210 20% 98%;
|
--card-foreground: 210 20% 98%;
|
||||||
|
|
|
@ -86,20 +86,20 @@
|
||||||
--authentication: 231deg 61% 44%;
|
--authentication: 231deg 61% 44%;
|
||||||
|
|
||||||
/* 用于浅色主题下一些暗色主题的颜色 */
|
/* 用于浅色主题下一些暗色主题的颜色 */
|
||||||
--dark-foreground: 220 13% 91%;
|
--accent-dark-hover: 0deg 0% 100% / 12%;
|
||||||
--dark-border: 0deg 0% 100% / 10%;
|
--foreground-dark: 220 13% 91%;
|
||||||
--dark-accent: 0deg 0% 100% / 8%;
|
--accent-dark: 0deg 0% 100% / 8%;
|
||||||
--dark-accent-hover: 0deg 0% 100% / 12%;
|
--border-dark: 240 3.7% 15.9%;
|
||||||
|
|
||||||
/* =============component & UI============= */
|
/* =============component & UI============= */
|
||||||
|
|
||||||
/* menu */
|
/* menu */
|
||||||
--menu: 0deg 0% 100%;
|
--menu: 0deg 0% 100%;
|
||||||
--menu-deep: 0deg 0% 95%;
|
--menu-deep: 210 11.11% 96.47%;
|
||||||
|
|
||||||
/* menu-dark */
|
/* menu-dark */
|
||||||
--menu-dark: 222.34deg 10.43% 12.27%;
|
--menu-dark: 222.34deg 10.43% 12.27%;
|
||||||
--menu-dark-deep: 223deg 11% 10%;
|
--menu-dark-deep: 220deg 13.06% 9%;
|
||||||
|
|
||||||
accent-color: var(--primary);
|
accent-color: var(--primary);
|
||||||
color-scheme: light;
|
color-scheme: light;
|
||||||
|
@ -124,6 +124,12 @@
|
||||||
--border: 220 13% 91%;
|
--border: 220 13% 91%;
|
||||||
--input: 220 13% 91%;
|
--input: 220 13% 91%;
|
||||||
--ring: 262.1 83.3% 57.8%;
|
--ring: 262.1 83.3% 57.8%;
|
||||||
|
|
||||||
|
/* menu-dark */
|
||||||
|
--menu-dark: 224 71.4% 4.1%;
|
||||||
|
--menu-dark-deep: 224 71.4% 4.1%;
|
||||||
|
--border-dark: 215 27.9% 16.9%;
|
||||||
|
--foreground-dark: 210 20% 98%;
|
||||||
}
|
}
|
||||||
|
|
||||||
:root[data-theme='pink'] {
|
:root[data-theme='pink'] {
|
||||||
|
@ -145,6 +151,12 @@
|
||||||
--border: 240 5.9% 90%;
|
--border: 240 5.9% 90%;
|
||||||
--input: 240 5.9% 90%;
|
--input: 240 5.9% 90%;
|
||||||
--ring: 346.8 77.2% 49.8%;
|
--ring: 346.8 77.2% 49.8%;
|
||||||
|
|
||||||
|
/* menu-dark */
|
||||||
|
--menu-dark: 20 14.3% 4.1%;
|
||||||
|
--menu-dark-deep: 20 14.3% 4.1%;
|
||||||
|
--border-dark: 240 3.7% 15.9%;
|
||||||
|
--foreground-dark: 0 0% 95%;
|
||||||
}
|
}
|
||||||
|
|
||||||
:root[data-theme='rose'] {
|
:root[data-theme='rose'] {
|
||||||
|
@ -166,6 +178,12 @@
|
||||||
--border: 240 5.9% 90%;
|
--border: 240 5.9% 90%;
|
||||||
--input: 240 5.9% 90%;
|
--input: 240 5.9% 90%;
|
||||||
--ring: 346.8 77.2% 49.8%;
|
--ring: 346.8 77.2% 49.8%;
|
||||||
|
|
||||||
|
/* menu-dark */
|
||||||
|
--menu-dark: 0 0% 3.9%;
|
||||||
|
--menu-dark-deep: 0 0% 3.9%;
|
||||||
|
--border-dark: 0 0% 14.9%;
|
||||||
|
--foreground-dark: 0 0% 98%;
|
||||||
}
|
}
|
||||||
|
|
||||||
:root[data-theme='sky-blue'] {
|
:root[data-theme='sky-blue'] {
|
||||||
|
@ -187,6 +205,12 @@
|
||||||
--border: 214.3 31.8% 91.4%;
|
--border: 214.3 31.8% 91.4%;
|
||||||
--input: 214.3 31.8% 91.4%;
|
--input: 214.3 31.8% 91.4%;
|
||||||
--ring: 221.2 83.2% 53.3%;
|
--ring: 221.2 83.2% 53.3%;
|
||||||
|
|
||||||
|
/* menu-dark */
|
||||||
|
--menu-dark: 222.2 84% 4.9%;
|
||||||
|
--menu-dark-deep: 222.2 84% 4.9%;
|
||||||
|
--border-dark: 217.2 32.6% 17.5%;
|
||||||
|
--foreground-dark: 210 40% 98%;
|
||||||
}
|
}
|
||||||
|
|
||||||
:root[data-theme='deep-blue'] {
|
:root[data-theme='deep-blue'] {
|
||||||
|
@ -208,6 +232,12 @@
|
||||||
--border: 214.3 31.8% 91.4%;
|
--border: 214.3 31.8% 91.4%;
|
||||||
--input: 214.3 31.8% 91.4%;
|
--input: 214.3 31.8% 91.4%;
|
||||||
--ring: 221.2 83.2% 53.3%;
|
--ring: 221.2 83.2% 53.3%;
|
||||||
|
|
||||||
|
/* menu-dark */
|
||||||
|
--menu-dark: 222.2 84% 4.9%;
|
||||||
|
--menu-dark-deep: 222.2 84% 4.9%;
|
||||||
|
--border-dark: 217.2 32.6% 17.5%;
|
||||||
|
--foreground-dark: 210 40% 98%;
|
||||||
}
|
}
|
||||||
|
|
||||||
:root[data-theme='green'] {
|
:root[data-theme='green'] {
|
||||||
|
@ -229,6 +259,12 @@
|
||||||
--border: 240 5.9% 90%;
|
--border: 240 5.9% 90%;
|
||||||
--input: 240 5.9% 90%;
|
--input: 240 5.9% 90%;
|
||||||
--ring: 142.1 76.2% 36.3%;
|
--ring: 142.1 76.2% 36.3%;
|
||||||
|
|
||||||
|
/* menu-dark */
|
||||||
|
--menu-dark: 20 14.3% 4.1%;
|
||||||
|
--menu-dark-deep: 20 14.3% 4.1%;
|
||||||
|
--border-dark: 240 3.7% 15.9%;
|
||||||
|
--foreground-dark: 0 0% 95%;
|
||||||
}
|
}
|
||||||
|
|
||||||
:root[data-theme='deep-green'] {
|
:root[data-theme='deep-green'] {
|
||||||
|
@ -250,6 +286,12 @@
|
||||||
--border: 240 5.9% 90%;
|
--border: 240 5.9% 90%;
|
||||||
--input: 240 5.9% 90%;
|
--input: 240 5.9% 90%;
|
||||||
--ring: 142.1 76.2% 36.3%;
|
--ring: 142.1 76.2% 36.3%;
|
||||||
|
|
||||||
|
/* menu-dark */
|
||||||
|
--menu-dark: 20 14.3% 4.1%;
|
||||||
|
--menu-dark-deep: 20 14.3% 4.1%;
|
||||||
|
--border-dark: 240 3.7% 15.9%;
|
||||||
|
--foreground-dark: 0 0% 95%;
|
||||||
}
|
}
|
||||||
|
|
||||||
:root[data-theme='orange'] {
|
:root[data-theme='orange'] {
|
||||||
|
@ -271,6 +313,12 @@
|
||||||
--border: 20 5.9% 90%;
|
--border: 20 5.9% 90%;
|
||||||
--input: 20 5.9% 90%;
|
--input: 20 5.9% 90%;
|
||||||
--ring: 24.6 95% 53.1%;
|
--ring: 24.6 95% 53.1%;
|
||||||
|
|
||||||
|
/* menu-dark */
|
||||||
|
--menu-dark: 20 14.3% 4.1%;
|
||||||
|
--menu-dark-deep: 20 14.3% 4.1%;
|
||||||
|
--border-dark: 12 6.5% 15.1%;
|
||||||
|
--foreground-dark: 60 9.1% 97.8%;
|
||||||
}
|
}
|
||||||
|
|
||||||
:root[data-theme='yellow'] {
|
:root[data-theme='yellow'] {
|
||||||
|
@ -292,6 +340,12 @@
|
||||||
--border: 20 5.9% 90%;
|
--border: 20 5.9% 90%;
|
||||||
--input: 20 5.9% 90%;
|
--input: 20 5.9% 90%;
|
||||||
--ring: 20 14.3% 4.1%;
|
--ring: 20 14.3% 4.1%;
|
||||||
|
|
||||||
|
/* menu-dark */
|
||||||
|
--menu-dark: 20 14.3% 4.1%;
|
||||||
|
--menu-dark-deep: 20 14.3% 4.1%;
|
||||||
|
--border-dark: 12 6.5% 15.1%;
|
||||||
|
--foreground-dark: 60 9.1% 97.8%;
|
||||||
}
|
}
|
||||||
|
|
||||||
:root[data-theme='zinc'] {
|
:root[data-theme='zinc'] {
|
||||||
|
@ -313,6 +367,12 @@
|
||||||
--border: 240 5.9% 90%;
|
--border: 240 5.9% 90%;
|
||||||
--input: 240 5.9% 90%;
|
--input: 240 5.9% 90%;
|
||||||
--ring: 240 5.9% 10%;
|
--ring: 240 5.9% 10%;
|
||||||
|
|
||||||
|
/* menu-dark */
|
||||||
|
--menu-dark: 240 10% 3.9%;
|
||||||
|
--menu-dark-deep: 240 10% 3.9%;
|
||||||
|
--border-dark: 240 3.7% 15.9%;
|
||||||
|
--foreground-dark: 0 0% 98%;
|
||||||
}
|
}
|
||||||
|
|
||||||
:root[data-theme='neutral'] {
|
:root[data-theme='neutral'] {
|
||||||
|
@ -334,6 +394,12 @@
|
||||||
--border: 0 0% 89.8%;
|
--border: 0 0% 89.8%;
|
||||||
--input: 0 0% 89.8%;
|
--input: 0 0% 89.8%;
|
||||||
--ring: 0 0% 3.9%;
|
--ring: 0 0% 3.9%;
|
||||||
|
|
||||||
|
/* menu-dark */
|
||||||
|
--menu-dark: 0 0% 3.9%;
|
||||||
|
--menu-dark-deep: 0 0% 3.9%;
|
||||||
|
--border-dark: 0 0% 14.9%;
|
||||||
|
--foreground-dark: 0 0% 98%;
|
||||||
}
|
}
|
||||||
|
|
||||||
:root[data-theme='slate'] {
|
:root[data-theme='slate'] {
|
||||||
|
@ -355,6 +421,12 @@
|
||||||
--border: 214.3 31.8% 91.4%;
|
--border: 214.3 31.8% 91.4%;
|
||||||
--input: 214.3 31.8% 91.4%;
|
--input: 214.3 31.8% 91.4%;
|
||||||
--ring: 222.2 84% 4.9%;
|
--ring: 222.2 84% 4.9%;
|
||||||
|
|
||||||
|
/* menu-dark */
|
||||||
|
--menu-dark: 222.2 84% 4.9%;
|
||||||
|
--menu-dark-deep: 222.2 84% 4.9%;
|
||||||
|
--border-dark: 217.2 32.6% 17.5%;
|
||||||
|
--foreground-dark: 210 40% 98%;
|
||||||
}
|
}
|
||||||
|
|
||||||
:root[data-theme='gray'] {
|
:root[data-theme='gray'] {
|
||||||
|
@ -376,4 +448,10 @@
|
||||||
--border: 220 13% 91%;
|
--border: 220 13% 91%;
|
||||||
--input: 220 13% 91%;
|
--input: 220 13% 91%;
|
||||||
--ring: 224 71.4% 4.1%;
|
--ring: 224 71.4% 4.1%;
|
||||||
|
|
||||||
|
/* menu-dark */
|
||||||
|
--menu-dark: 224 71.4% 4.1%;
|
||||||
|
--menu-dark-deep: 224 71.4% 4.1%;
|
||||||
|
--border-dark: 215 27.9% 16.9%;
|
||||||
|
--foreground-dark: 210 20% 98%;
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@vben-core/hooks": "workspace:*",
|
||||||
"@vben-core/icons": "workspace:*",
|
"@vben-core/icons": "workspace:*",
|
||||||
"@vben-core/shadcn-ui": "workspace:*",
|
"@vben-core/shadcn-ui": "workspace:*",
|
||||||
"@vben-core/toolkit": "workspace:*",
|
"@vben-core/toolkit": "workspace:*",
|
||||||
|
|
|
@ -2,11 +2,9 @@
|
||||||
import type { ContentCompactType } from '@vben-core/typings';
|
import type { ContentCompactType } from '@vben-core/typings';
|
||||||
|
|
||||||
import type { CSSProperties } from 'vue';
|
import type { CSSProperties } from 'vue';
|
||||||
import { computed, onMounted, ref, watch } from 'vue';
|
import { computed } from 'vue';
|
||||||
|
|
||||||
import { getElementVisibleHeight } from '@vben-core/toolkit';
|
import { useContentHeightListener } from '@vben-core/hooks';
|
||||||
|
|
||||||
import { useCssVar, useDebounceFn, useWindowSize } from '@vueuse/core';
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
/**
|
/**
|
||||||
|
@ -56,13 +54,7 @@ const props = withDefaults(defineProps<Props>(), {
|
||||||
paddingTop: 16,
|
paddingTop: 16,
|
||||||
});
|
});
|
||||||
|
|
||||||
const contentElement = ref<HTMLDivElement | null>();
|
const { contentElement } = useContentHeightListener();
|
||||||
|
|
||||||
const { height, width } = useWindowSize();
|
|
||||||
const contentClientHeight = useCssVar('--vben-content-client-height');
|
|
||||||
const debouncedCalcHeight = useDebounceFn(() => {
|
|
||||||
contentClientHeight.value = `${getElementVisibleHeight(contentElement.value)}px`;
|
|
||||||
}, 200);
|
|
||||||
|
|
||||||
const style = computed((): CSSProperties => {
|
const style = computed((): CSSProperties => {
|
||||||
const {
|
const {
|
||||||
|
@ -88,14 +80,6 @@ const style = computed((): CSSProperties => {
|
||||||
paddingTop: `${paddingTop}px`,
|
paddingTop: `${paddingTop}px`,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
watch([height, width], () => {
|
|
||||||
debouncedCalcHeight();
|
|
||||||
});
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
debouncedCalcHeight();
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
|
@ -7,10 +7,6 @@ import { VbenScrollbar } from '@vben-core/shadcn-ui';
|
||||||
import { SidebarCollapseButton, SidebarFixedButton } from './widgets';
|
import { SidebarCollapseButton, SidebarFixedButton } from './widgets';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
/**
|
|
||||||
* 背景颜色
|
|
||||||
*/
|
|
||||||
backgroundColor: string;
|
|
||||||
/**
|
/**
|
||||||
* 折叠区域高度
|
* 折叠区域高度
|
||||||
* @default 32
|
* @default 32
|
||||||
|
@ -26,10 +22,6 @@ interface Props {
|
||||||
* @default true
|
* @default true
|
||||||
*/
|
*/
|
||||||
domVisible?: boolean;
|
domVisible?: boolean;
|
||||||
/**
|
|
||||||
* 扩展区域背景颜色
|
|
||||||
*/
|
|
||||||
extraBackgroundColor: string;
|
|
||||||
/**
|
/**
|
||||||
* 扩展区域宽度
|
* 扩展区域宽度
|
||||||
* @default 180
|
* @default 180
|
||||||
|
@ -113,15 +105,15 @@ const slots = useSlots();
|
||||||
|
|
||||||
const asideRef = shallowRef<HTMLDivElement | null>();
|
const asideRef = shallowRef<HTMLDivElement | null>();
|
||||||
|
|
||||||
const hiddenSideStyle = computed((): CSSProperties => {
|
const hiddenSideStyle = computed((): CSSProperties => calcMenuWidthStyle(true));
|
||||||
return calcMenuWidthStyle(true);
|
|
||||||
});
|
const isDark = computed(() => props.theme === 'dark');
|
||||||
|
|
||||||
const style = computed((): CSSProperties => {
|
const style = computed((): CSSProperties => {
|
||||||
const { isSidebarMixed, paddingTop, theme, zIndex } = props;
|
const { isSidebarMixed, paddingTop, zIndex } = props;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'--scroll-shadow': theme === 'dark' ? 'var(--menu-dark)' : 'var(--menu)',
|
'--scroll-shadow': isDark.value ? 'var(--menu-dark)' : 'var(--menu)',
|
||||||
...calcMenuWidthStyle(false),
|
...calcMenuWidthStyle(false),
|
||||||
paddingTop: `${paddingTop}px`,
|
paddingTop: `${paddingTop}px`,
|
||||||
zIndex,
|
zIndex,
|
||||||
|
@ -130,9 +122,14 @@ const style = computed((): CSSProperties => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const extraStyle = computed((): CSSProperties => {
|
const extraStyle = computed((): CSSProperties => {
|
||||||
const { extraBackgroundColor, extraWidth, show, width, zIndex } = props;
|
const { extraWidth, show, width, zIndex } = props;
|
||||||
|
|
||||||
|
const backgroundColor = isDark.value
|
||||||
|
? 'hsl(var(--menu-dark))'
|
||||||
|
: 'hsl(var(--menu))';
|
||||||
|
|
||||||
return {
|
return {
|
||||||
backgroundColor: extraBackgroundColor,
|
backgroundColor,
|
||||||
left: `${width}px`,
|
left: `${width}px`,
|
||||||
width: extraVisible.value && show ? `${extraWidth}px` : 0,
|
width: extraVisible.value && show ? `${extraWidth}px` : 0,
|
||||||
zIndex,
|
zIndex,
|
||||||
|
@ -196,14 +193,7 @@ watchEffect(() => {
|
||||||
});
|
});
|
||||||
|
|
||||||
function calcMenuWidthStyle(isHiddenDom: boolean): CSSProperties {
|
function calcMenuWidthStyle(isHiddenDom: boolean): CSSProperties {
|
||||||
const {
|
const { extraWidth, fixedExtra, isSidebarMixed, show, width } = props;
|
||||||
backgroundColor,
|
|
||||||
extraWidth,
|
|
||||||
fixedExtra,
|
|
||||||
isSidebarMixed,
|
|
||||||
show,
|
|
||||||
width,
|
|
||||||
} = props;
|
|
||||||
|
|
||||||
let widthValue = `${width + (isSidebarMixed && fixedExtra && extraVisible.value ? extraWidth : 0)}px`;
|
let widthValue = `${width + (isSidebarMixed && fixedExtra && extraVisible.value ? extraWidth : 0)}px`;
|
||||||
|
|
||||||
|
@ -213,6 +203,18 @@ function calcMenuWidthStyle(isHiddenDom: boolean): CSSProperties {
|
||||||
widthValue = `${collapseWidth}px`;
|
widthValue = `${collapseWidth}px`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let backgroundColor = '';
|
||||||
|
|
||||||
|
if (isDark.value) {
|
||||||
|
backgroundColor = isSidebarMixed
|
||||||
|
? 'hsl(var(--menu-dark-deep))'
|
||||||
|
: 'hsl(var(--menu-dark))';
|
||||||
|
} else {
|
||||||
|
backgroundColor = isSidebarMixed
|
||||||
|
? 'hsl(var(--menu-deep))'
|
||||||
|
: 'hsl(var(--menu))';
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...(widthValue === '0px' ? { overflow: 'hidden' } : {}),
|
...(widthValue === '0px' ? { overflow: 'hidden' } : {}),
|
||||||
backgroundColor,
|
backgroundColor,
|
||||||
|
@ -254,8 +256,9 @@ function handleMouseleave() {
|
||||||
class="h-full transition-all duration-200"
|
class="h-full transition-all duration-200"
|
||||||
></div>
|
></div>
|
||||||
<aside
|
<aside
|
||||||
|
:data-theme="theme"
|
||||||
:style="style"
|
:style="style"
|
||||||
class="border-border fixed left-0 top-0 h-full border-r transition-all duration-200"
|
class="data-[theme=dark]:border-border-dark border-border fixed left-0 top-0 h-full border-r transition-all duration-200"
|
||||||
@mouseenter="handleMouseenter"
|
@mouseenter="handleMouseenter"
|
||||||
@mouseleave="handleMouseleave"
|
@mouseleave="handleMouseleave"
|
||||||
>
|
>
|
||||||
|
@ -280,8 +283,9 @@ function handleMouseleave() {
|
||||||
<div
|
<div
|
||||||
v-if="isSidebarMixed"
|
v-if="isSidebarMixed"
|
||||||
ref="asideRef"
|
ref="asideRef"
|
||||||
|
:data-theme="theme"
|
||||||
:style="extraStyle"
|
:style="extraStyle"
|
||||||
class="fixed top-0 h-full overflow-hidden transition-all duration-200"
|
class="data-[theme=dark]:border-border-dark border-border fixed top-0 h-full overflow-hidden border-x transition-all duration-200"
|
||||||
>
|
>
|
||||||
<SidebarCollapseButton
|
<SidebarCollapseButton
|
||||||
v-if="isSidebarMixed && expandOnHover"
|
v-if="isSidebarMixed && expandOnHover"
|
||||||
|
@ -294,10 +298,15 @@ function handleMouseleave() {
|
||||||
v-model:expand-on-hover="expandOnHover"
|
v-model:expand-on-hover="expandOnHover"
|
||||||
:theme="theme"
|
:theme="theme"
|
||||||
/>
|
/>
|
||||||
<div v-if="!extraCollapse" :style="extraTitleStyle">
|
<div v-if="!extraCollapse" :style="extraTitleStyle" class="pl-2">
|
||||||
<slot name="extra-title"></slot>
|
<slot name="extra-title"></slot>
|
||||||
</div>
|
</div>
|
||||||
<VbenScrollbar :style="extraContentStyle" class="py-4" shadow>
|
<VbenScrollbar
|
||||||
|
:data-theme="theme"
|
||||||
|
:style="extraContentStyle"
|
||||||
|
class="data-[theme=dark]:border-border-dark border-border border-t py-2"
|
||||||
|
shadow
|
||||||
|
>
|
||||||
<slot name="extra"></slot>
|
<slot name="extra"></slot>
|
||||||
</VbenScrollbar>
|
</VbenScrollbar>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -5,7 +5,7 @@ interface Props {
|
||||||
theme: string;
|
theme: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
withDefaults(defineProps<Props>(), {});
|
defineProps<Props>();
|
||||||
|
|
||||||
const collapsed = defineModel<boolean>('collapsed');
|
const collapsed = defineModel<boolean>('collapsed');
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ function handleCollapsed() {
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
:data-theme="theme"
|
:data-theme="theme"
|
||||||
class="flex-center hover:text-foreground text-foreground/60 hover:bg-accent-hover bg-accent absolute bottom-2 left-3 z-10 cursor-pointer rounded-sm p-1 transition-all duration-300 data-[theme=dark]:bg-[hsl(var(--dark-accent))] data-[theme=dark]:text-[hsl(var(--dark-foreground)/60%)] data-[theme=dark]:hover:bg-[hsl(var(--dark-accent-hover))] data-[theme=dark]:hover:text-[hsl(var(--dark-foreground))]"
|
class="flex-center hover:text-foreground text-foreground/60 hover:bg-accent-hover bg-accent data-[theme=dark]:hover:bg-accent-dark-hover data-[theme=dark]:bg-accent-dark data-[theme=dark]:text-foreground-dark/60 data-[theme=dark]:hover:text-foreground-dark absolute bottom-2 left-3 z-10 cursor-pointer rounded-sm p-1 transition-all duration-300"
|
||||||
@click.stop="handleCollapsed"
|
@click.stop="handleCollapsed"
|
||||||
>
|
>
|
||||||
<MdiMenuClose v-if="collapsed" />
|
<MdiMenuClose v-if="collapsed" />
|
||||||
|
|
|
@ -5,7 +5,7 @@ interface Props {
|
||||||
theme: string;
|
theme: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
withDefaults(defineProps<Props>(), {});
|
defineProps<Props>();
|
||||||
|
|
||||||
const expandOnHover = defineModel<boolean>('expandOnHover');
|
const expandOnHover = defineModel<boolean>('expandOnHover');
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ function toggleFixed() {
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
:data-theme="theme"
|
:data-theme="theme"
|
||||||
class="flex-center hover:text-foreground text-foreground/60 hover:bg-accent-hover bg-accent absolute bottom-2 right-3 z-10 cursor-pointer rounded-sm p-1 transition-all duration-300 data-[theme=dark]:bg-[hsl(var(--dark-accent))] data-[theme=dark]:text-[hsl(var(--dark-foreground)/60%)] data-[theme=dark]:hover:bg-[hsl(var(--dark-accent-hover))] data-[theme=dark]:hover:text-[hsl(var(--dark-foreground))]"
|
class="flex-center hover:text-foreground text-foreground/60 hover:bg-accent-hover bg-accent data-[theme=dark]:hover:bg-accent-dark-hover data-[theme=dark]:bg-accent-dark data-[theme=dark]:text-foreground-dark/60 data-[theme=dark]:hover:text-foreground-dark absolute bottom-2 right-3 z-10 cursor-pointer rounded-sm p-1 transition-all duration-300"
|
||||||
@click="toggleFixed"
|
@click="toggleFixed"
|
||||||
>
|
>
|
||||||
<MdiPinOff v-if="!expandOnHover" />
|
<MdiPinOff v-if="!expandOnHover" />
|
||||||
|
|
|
@ -41,11 +41,6 @@ interface VbenLayoutProps {
|
||||||
* @default 16
|
* @default 16
|
||||||
*/
|
*/
|
||||||
contentPaddingTop?: number;
|
contentPaddingTop?: number;
|
||||||
/**
|
|
||||||
* footer背景颜色
|
|
||||||
* @default #fff
|
|
||||||
*/
|
|
||||||
footerBackgroundColor?: string;
|
|
||||||
/**
|
/**
|
||||||
* footer 是否可见
|
* footer 是否可见
|
||||||
* @default false
|
* @default false
|
||||||
|
@ -61,11 +56,7 @@ interface VbenLayoutProps {
|
||||||
* @default 32
|
* @default 32
|
||||||
*/
|
*/
|
||||||
footerHeight?: number;
|
footerHeight?: number;
|
||||||
/**
|
|
||||||
* 背景颜色
|
|
||||||
* @default #fff
|
|
||||||
*/
|
|
||||||
headerBackgroundColor?: string;
|
|
||||||
/**
|
/**
|
||||||
* header高度
|
* header高度
|
||||||
* @default 48
|
* @default 48
|
||||||
|
@ -157,11 +148,6 @@ interface VbenLayoutProps {
|
||||||
* @default 210
|
* @default 210
|
||||||
*/
|
*/
|
||||||
sidebarWidth?: number;
|
sidebarWidth?: number;
|
||||||
/**
|
|
||||||
* footer背景颜色
|
|
||||||
* @default #fff
|
|
||||||
*/
|
|
||||||
tabbarBackgroundColor?: string;
|
|
||||||
/**
|
/**
|
||||||
* tab是否可见
|
* tab是否可见
|
||||||
* @default true
|
* @default true
|
||||||
|
|
|
@ -205,25 +205,7 @@ const showSidebar = computed(() => {
|
||||||
const sidebarFace = computed(() => {
|
const sidebarFace = computed(() => {
|
||||||
const { sidebarSemiDark, sidebarTheme } = props;
|
const { sidebarSemiDark, sidebarTheme } = props;
|
||||||
const isDark = sidebarTheme === 'dark' || sidebarSemiDark;
|
const isDark = sidebarTheme === 'dark' || sidebarSemiDark;
|
||||||
|
|
||||||
let backgroundColor = '';
|
|
||||||
let extraBackgroundColor = '';
|
|
||||||
|
|
||||||
if (isDark) {
|
|
||||||
backgroundColor = isSidebarMixedNav.value
|
|
||||||
? 'hsl(var(--menu-dark-deep))'
|
|
||||||
: 'hsl(var(--menu-dark))';
|
|
||||||
} else {
|
|
||||||
backgroundColor = isSidebarMixedNav.value
|
|
||||||
? 'hsl(var(--menu-deep))'
|
|
||||||
: 'hsl(var(--menu))';
|
|
||||||
}
|
|
||||||
|
|
||||||
extraBackgroundColor = isDark ? 'hsl(var(--menu-dark))' : 'hsl(var(--menu))';
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
backgroundColor,
|
|
||||||
extraBackgroundColor,
|
|
||||||
theme: isDark ? 'dark' : 'light',
|
theme: isDark ? 'dark' : 'light',
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
@ -476,9 +458,9 @@ function handleOpenMenu() {
|
||||||
:mixed-width="sidebarMixedWidth"
|
:mixed-width="sidebarMixedWidth"
|
||||||
:padding-top="sidePaddingTop"
|
:padding-top="sidePaddingTop"
|
||||||
:show="showSidebar"
|
:show="showSidebar"
|
||||||
|
:theme="sidebarFace.theme"
|
||||||
:width="getSidebarWidth"
|
:width="getSidebarWidth"
|
||||||
:z-index="sidebarZIndex"
|
:z-index="sidebarZIndex"
|
||||||
v-bind="sidebarFace"
|
|
||||||
@leave="() => emit('sideMouseLeave')"
|
@leave="() => emit('sideMouseLeave')"
|
||||||
>
|
>
|
||||||
<template v-if="isSideMode && !isMixedNav" #logo>
|
<template v-if="isSideMode && !isMixedNav" #logo>
|
||||||
|
|
|
@ -423,9 +423,9 @@ $namespace: vben;
|
||||||
--menu-title-width: 140px;
|
--menu-title-width: 140px;
|
||||||
--menu-item-icon-width: 20px;
|
--menu-item-icon-width: 20px;
|
||||||
--menu-item-height: 38px;
|
--menu-item-height: 38px;
|
||||||
--menu-item-padding-y: 26px;
|
--menu-item-padding-y: 22px;
|
||||||
--menu-item-padding-x: 12px;
|
--menu-item-padding-x: 12px;
|
||||||
--menu-item-popup-padding-y: 22px;
|
--menu-item-popup-padding-y: 20px;
|
||||||
--menu-item-popup-padding-x: 12px;
|
--menu-item-popup-padding-x: 12px;
|
||||||
--menu-item-margin-y: 4px;
|
--menu-item-margin-y: 4px;
|
||||||
--menu-item-margin-x: 0px;
|
--menu-item-margin-x: 0px;
|
||||||
|
@ -443,14 +443,14 @@ $namespace: vben;
|
||||||
--menu-background-color: hsl(var(--menu-dark));
|
--menu-background-color: hsl(var(--menu-dark));
|
||||||
// --menu-submenu-opened-background-color: hsl(var(--menu-opened-dark));
|
// --menu-submenu-opened-background-color: hsl(var(--menu-opened-dark));
|
||||||
--menu-item-background-color: var(--menu-background-color);
|
--menu-item-background-color: var(--menu-background-color);
|
||||||
--menu-item-color: hsl(var(--dark-foreground) / 80%);
|
--menu-item-color: hsl(var(--foreground-dark) / 80%);
|
||||||
--menu-item-hover-color: hsl(var(--primary-foreground));
|
--menu-item-hover-color: hsl(var(--primary-foreground));
|
||||||
--menu-item-hover-background-color: hsl(var(--menu-dark-background));
|
--menu-item-hover-background-color: hsl(var(--menu-dark-background));
|
||||||
--menu-item-active-color: hsl(var(--primary-foreground));
|
--menu-item-active-color: hsl(var(--foreground-dark));
|
||||||
--menu-item-active-background-color: hsl(var(--primary));
|
--menu-item-active-background-color: hsl(var(--menu-dark-background));
|
||||||
--menu-submenu-hover-color: hsl(var(--dark-foreground));
|
--menu-submenu-hover-color: hsl(var(--foreground-dark));
|
||||||
--menu-submenu-hover-background-color: hsl(var(--menu-dark-background));
|
--menu-submenu-hover-background-color: hsl(var(--menu-dark-background));
|
||||||
--menu-submenu-active-color: hsl(var(--dark-foreground));
|
--menu-submenu-active-color: hsl(var(--foreground-dark));
|
||||||
--menu-submenu-active-background-color: transparent;
|
--menu-submenu-active-background-color: transparent;
|
||||||
--menu-submenu-background-color: var(--menu-background-color);
|
--menu-submenu-background-color: var(--menu-background-color);
|
||||||
}
|
}
|
||||||
|
@ -462,8 +462,8 @@ $namespace: vben;
|
||||||
--menu-item-color: hsl(var(--foreground));
|
--menu-item-color: hsl(var(--foreground));
|
||||||
--menu-item-hover-color: var(--menu-item-color);
|
--menu-item-hover-color: var(--menu-item-color);
|
||||||
--menu-item-hover-background-color: hsl(var(--menu-light-background));
|
--menu-item-hover-background-color: hsl(var(--menu-light-background));
|
||||||
--menu-item-active-color: hsl(var(--primary-foreground));
|
--menu-item-active-color: hsl(var(--primary));
|
||||||
--menu-item-active-background-color: hsl(var(--primary));
|
--menu-item-active-background-color: hsl(var(--primary) / 15%);
|
||||||
--menu-submenu-hover-color: hsl(var(--primary));
|
--menu-submenu-hover-color: hsl(var(--primary));
|
||||||
--menu-submenu-hover-background-color: hsl(var(--menu-light-background));
|
--menu-submenu-hover-background-color: hsl(var(--menu-light-background));
|
||||||
--menu-submenu-active-color: hsl(var(--primary));
|
--menu-submenu-active-color: hsl(var(--primary));
|
||||||
|
@ -512,10 +512,10 @@ $namespace: vben;
|
||||||
--menu-item-active-background-color: hsl(var(--menu-light-background));
|
--menu-item-active-background-color: hsl(var(--menu-light-background));
|
||||||
--menu-item-hover-background-color: hsl(var(--menu-light-background));
|
--menu-item-hover-background-color: hsl(var(--menu-light-background));
|
||||||
--menu-item-hover-color: hsl(var(--primary));
|
--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-hover-color: hsl(var(--primary));
|
--menu-submenu-hover-color: hsl(var(--primary));
|
||||||
--menu-submenu-hover-background-color: hsl(var(--menu-light-background));
|
--menu-submenu-hover-background-color: hsl(var(--menu-light-background));
|
||||||
--menu-submenu-active-color: hsl(var(--foreground));
|
|
||||||
--menu-submenu-active-background-color: hsl(var(--menu-light-background));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -666,7 +666,7 @@ $namespace: vben;
|
||||||
.#{$namespace}-sub-menu-content,
|
.#{$namespace}-sub-menu-content,
|
||||||
.#{$namespace}-menu-item {
|
.#{$namespace}-menu-item {
|
||||||
&.is-active {
|
&.is-active {
|
||||||
color: hsl(var(--primary-foreground)) !important;
|
// color: hsl(var(--primary-foreground)) !important;
|
||||||
background: var(--menu-item-active-background-color) !important;
|
background: var(--menu-item-active-background-color) !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -788,6 +788,7 @@ $namespace: vben;
|
||||||
&.is-active {
|
&.is-active {
|
||||||
div[data-state='open'] > .#{$namespace}-sub-menu-content,
|
div[data-state='open'] > .#{$namespace}-sub-menu-content,
|
||||||
> .#{$namespace}-sub-menu-content {
|
> .#{$namespace}-sub-menu-content {
|
||||||
|
font-weight: 500;
|
||||||
color: var(--menu-submenu-active-color);
|
color: var(--menu-submenu-active-color);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
@ -806,7 +807,7 @@ $namespace: vben;
|
||||||
&__icon-arrow {
|
&__icon-arrow {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
right: 6px;
|
right: 10px;
|
||||||
width: inherit;
|
width: inherit;
|
||||||
margin-top: -8px;
|
margin-top: -8px;
|
||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
|
|
|
@ -63,7 +63,7 @@ $namespace: vben;
|
||||||
.#{$namespace}-normal-menu {
|
.#{$namespace}-normal-menu {
|
||||||
--menu-item-margin-y: 4px;
|
--menu-item-margin-y: 4px;
|
||||||
--menu-item-margin-x: 0px;
|
--menu-item-margin-x: 0px;
|
||||||
--menu-item-padding-y: 11px;
|
--menu-item-padding-y: 8px;
|
||||||
--menu-item-padding-x: 0px;
|
--menu-item-padding-x: 0px;
|
||||||
--menu-item-radius: 0px;
|
--menu-item-radius: 0px;
|
||||||
--menu-dark-background: 0deg 0% 100% / 10%;
|
--menu-dark-background: 0deg 0% 100% / 10%;
|
||||||
|
@ -77,12 +77,21 @@ $namespace: vben;
|
||||||
|
|
||||||
&.is-dark {
|
&.is-dark {
|
||||||
.#{$namespace}-normal-menu__item {
|
.#{$namespace}-normal-menu__item {
|
||||||
color: hsl(var(--dark-foreground) / 80%);
|
color: hsl(var(--foreground-dark) / 80%);
|
||||||
|
|
||||||
&:not(.is-active):hover {
|
&:not(.is-active):hover {
|
||||||
color: hsl(var(--primary-foreground));
|
color: hsl(var(--primary-foreground));
|
||||||
background-color: hsl(var(--menu-dark-background));
|
background-color: hsl(var(--menu-dark-background));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.is-active {
|
||||||
|
background-color: hsl(var(--menu-dark-background));
|
||||||
|
|
||||||
|
.#{$namespace}-normal-menu__name,
|
||||||
|
.#{$namespace}-normal-menu__icon {
|
||||||
|
color: hsl(var(--primary-foreground));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,26 +124,21 @@ $namespace: vben;
|
||||||
border-radius: var(--menu-item-radius);
|
border-radius: var(--menu-item-radius);
|
||||||
transition:
|
transition:
|
||||||
background 0.15s ease,
|
background 0.15s ease,
|
||||||
// color 0.15s ease,
|
|
||||||
padding 0.15s ease,
|
padding 0.15s ease,
|
||||||
border-color 0.15s ease;
|
border-color 0.15s ease;
|
||||||
|
|
||||||
&.is-active {
|
&.is-active {
|
||||||
font-weight: 700;
|
@apply text-primary bg-primary/20;
|
||||||
color: hsl(var(--primary-foreground));
|
|
||||||
background-color: hsl(var(--primary));
|
|
||||||
|
|
||||||
.#{$namespace}-normal-menu__name {
|
|
||||||
color: hsl(var(--primary-foreground));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
.#{$namespace}-normal-menu__name,
|
||||||
.#{$namespace}-normal-menu__icon {
|
.#{$namespace}-normal-menu__icon {
|
||||||
color: hsl(var(--primary-foreground));
|
@apply text-primary font-semibold;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&:not(.is-active):hover {
|
&:not(.is-active):hover {
|
||||||
color: hsl(var(--foreground));
|
@apply text-foreground;
|
||||||
|
|
||||||
background-color: hsl(var(--menu-dark-background));
|
background-color: hsl(var(--menu-dark-background));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,506 +0,0 @@
|
||||||
$namespace: vben;
|
|
||||||
|
|
||||||
.#{$namespace}-menu__popup-container,
|
|
||||||
.#{$namespace}-menu {
|
|
||||||
--menu-title-width: 140px;
|
|
||||||
--menu-item-icon-width: 20px;
|
|
||||||
--menu-item-height: 38px;
|
|
||||||
--menu-item-padding-y: 26px;
|
|
||||||
--menu-item-padding-x: 12px;
|
|
||||||
--menu-item-popup-padding-y: 22px;
|
|
||||||
--menu-item-popup-padding-x: 12px;
|
|
||||||
--menu-item-margin-y: 4px;
|
|
||||||
--menu-item-margin-x: 0px;
|
|
||||||
--menu-item-collapse-padding-y: 25px;
|
|
||||||
--menu-item-collapse-padding-x: 0px;
|
|
||||||
--menu-item-collapse-margin-y: 4px;
|
|
||||||
--menu-item-collapse-margin-x: 0px;
|
|
||||||
--menu-item-radius: 0px;
|
|
||||||
--menu-item-indent: 16px;
|
|
||||||
--menu-font-size: 14px;
|
|
||||||
--menu-dark-background: 0deg 0% 100% / 10%;
|
|
||||||
--menu-light-background: 192deg 1% 93%;
|
|
||||||
|
|
||||||
&.is-dark {
|
|
||||||
--menu-background-color: hsl(var(--menu-dark));
|
|
||||||
// --menu-submenu-opened-background-color: hsl(var(--menu-opened-dark));
|
|
||||||
--menu-item-background-color: var(--menu-background-color);
|
|
||||||
--menu-item-color: hsl(var(--dark-foreground) / 80%);
|
|
||||||
--menu-item-hover-color: hsl(var(--primary-foreground));
|
|
||||||
--menu-item-hover-background-color: hsl(var(--menu-dark-background));
|
|
||||||
--menu-item-active-color: hsl(var(--primary-foreground));
|
|
||||||
--menu-item-active-background-color: hsl(var(--primary));
|
|
||||||
--menu-submenu-hover-color: hsl(var(--dark-foreground));
|
|
||||||
--menu-submenu-hover-background-color: hsl(var(--menu-dark-background));
|
|
||||||
--menu-submenu-active-color: hsl(var(--dark-foreground));
|
|
||||||
--menu-submenu-active-background-color: transparent;
|
|
||||||
--menu-submenu-background-color: var(--menu-background-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.is-light {
|
|
||||||
--menu-background-color: hsl(var(--menu));
|
|
||||||
// --menu-submenu-opened-background-color: hsl(var(--menu-opened));
|
|
||||||
--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(--menu-light-background));
|
|
||||||
--menu-item-active-color: hsl(var(--primary-foreground));
|
|
||||||
--menu-item-active-background-color: hsl(var(--primary));
|
|
||||||
--menu-submenu-hover-color: hsl(var(--primary));
|
|
||||||
--menu-submenu-hover-background-color: hsl(var(--menu-light-background));
|
|
||||||
--menu-submenu-active-color: hsl(var(--primary));
|
|
||||||
--menu-submenu-active-background-color: transparent;
|
|
||||||
--menu-submenu-background-color: var(--menu-background-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.is-rounded {
|
|
||||||
--menu-item-margin-x: 8px;
|
|
||||||
--menu-item-collapse-margin-x: 6px;
|
|
||||||
--menu-item-radius: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.is-horizontal:not(.is-rounded) {
|
|
||||||
--menu-item-height: 60px;
|
|
||||||
--menu-item-radius: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.is-horizontal.is-rounded {
|
|
||||||
--menu-item-height: 40px;
|
|
||||||
--menu-item-radius: 6px;
|
|
||||||
--menu-item-padding-x: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
// .vben-menu__popup,
|
|
||||||
&.is-horizontal {
|
|
||||||
--menu-item-padding-y: 0px;
|
|
||||||
--menu-item-padding-x: 10px;
|
|
||||||
--menu-item-margin-y: 0px;
|
|
||||||
--menu-item-margin-x: 1px;
|
|
||||||
--menu-background-color: transparent;
|
|
||||||
|
|
||||||
&.is-dark {
|
|
||||||
--menu-item-hover-color: var(--foreground);
|
|
||||||
--menu-item-hover-background-color: hsl(var(--menu-dark-background));
|
|
||||||
--menu-item-active-color: hsl(var(--foreground));
|
|
||||||
--menu-item-active-background-color: hsl(var(--menu-dark-background));
|
|
||||||
--menu-submenu-active-color: hsl(var(--foreground));
|
|
||||||
--menu-submenu-active-background-color: hsl(var(--menu-dark-background));
|
|
||||||
--menu-submenu-hover-color: hsl(var(--foreground));
|
|
||||||
--menu-submenu-hover-background-color: hsl(var(--menu-dark-background));
|
|
||||||
}
|
|
||||||
|
|
||||||
&.is-light {
|
|
||||||
--menu-item-active-color: hsl(var(--foreground));
|
|
||||||
--menu-item-active-background-color: hsl(var(--menu-light-background));
|
|
||||||
--menu-item-hover-background-color: hsl(var(--menu-light-background));
|
|
||||||
--menu-item-hover-color: hsl(var(--primary));
|
|
||||||
--menu-submenu-hover-color: hsl(var(--primary));
|
|
||||||
--menu-submenu-hover-background-color: hsl(var(--menu-light-background));
|
|
||||||
--menu-submenu-active-color: hsl(var(--foreground));
|
|
||||||
--menu-submenu-active-background-color: hsl(var(--menu-light-background));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@mixin menu-item-active {
|
|
||||||
color: var(--menu-item-active-color);
|
|
||||||
text-decoration: none;
|
|
||||||
cursor: pointer;
|
|
||||||
background: var(--menu-item-active-background-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
@mixin menu-item {
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
// gap: 12px;
|
|
||||||
align-items: center;
|
|
||||||
height: var(--menu-item-height);
|
|
||||||
padding: var(--menu-item-padding-y) var(--menu-item-padding-x);
|
|
||||||
margin: 0 var(--menu-item-margin-x) var(--menu-item-margin-y)
|
|
||||||
var(--menu-item-margin-x);
|
|
||||||
font-size: var(--menu-font-size);
|
|
||||||
color: var(--menu-item-color);
|
|
||||||
text-decoration: none;
|
|
||||||
white-space: nowrap;
|
|
||||||
list-style: none;
|
|
||||||
cursor: pointer;
|
|
||||||
background: var(--menu-item-background-color);
|
|
||||||
border: none;
|
|
||||||
border-radius: var(--menu-item-radius);
|
|
||||||
transition:
|
|
||||||
background 0.15s ease,
|
|
||||||
color 0.15s ease,
|
|
||||||
padding 0.15s ease,
|
|
||||||
border-color 0.15s ease;
|
|
||||||
|
|
||||||
&.is-disabled {
|
|
||||||
cursor: not-allowed;
|
|
||||||
background: none !important;
|
|
||||||
opacity: 0.25;
|
|
||||||
}
|
|
||||||
|
|
||||||
.#{$namespace}-menu__icon {
|
|
||||||
transition: transform 0.25s;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
.#{$namespace}-menu__icon {
|
|
||||||
transform: scale(1.3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover,
|
|
||||||
&:focus {
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
* {
|
|
||||||
vertical-align: bottom;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@mixin menu-title {
|
|
||||||
max-width: var(--menu-title-width);
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.#{$namespace}-menu {
|
|
||||||
position: relative;
|
|
||||||
box-sizing: border-box;
|
|
||||||
padding-left: 0;
|
|
||||||
margin: 0;
|
|
||||||
list-style: none;
|
|
||||||
background: hsl(var(--menu-background-color));
|
|
||||||
|
|
||||||
// 垂直菜单
|
|
||||||
&.is-vertical {
|
|
||||||
&:not(.#{$namespace}-menu.is-collapse) {
|
|
||||||
& .#{$namespace}-menu-item,
|
|
||||||
& .#{$namespace}-sub-menu-content,
|
|
||||||
& .#{$namespace}-menu-item-group__title {
|
|
||||||
padding-left: calc(
|
|
||||||
var(--menu-item-indent) + var(--menu-level) * var(--menu-item-indent)
|
|
||||||
);
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
& > .#{$namespace}-sub-menu {
|
|
||||||
// .#{$namespace}-menu {
|
|
||||||
// background: var(--menu-submenu-opened-background-color);
|
|
||||||
|
|
||||||
// .#{$namespace}-sub-menu,
|
|
||||||
// .#{$namespace}-menu-item:not(.is-active),
|
|
||||||
// .#{$namespace}-sub-menu-content:not(.is-active) {
|
|
||||||
// background: var(--menu-submenu-opened-background-color);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
& > .#{$namespace}-menu {
|
|
||||||
& > .#{$namespace}-menu-item {
|
|
||||||
padding-left: calc(
|
|
||||||
0px + var(--menu-item-indent) + var(--menu-level) *
|
|
||||||
var(--menu-item-indent)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
& > .#{$namespace}-sub-menu-content {
|
|
||||||
padding-left: calc(var(--menu-item-indent) - 8px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
& > .#{$namespace}-menu-item {
|
|
||||||
padding-left: calc(var(--menu-item-indent) - 8px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.is-horizontal {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: nowrap;
|
|
||||||
max-width: 100%;
|
|
||||||
height: var(--height-horizontal-height);
|
|
||||||
border-right: none;
|
|
||||||
|
|
||||||
.#{$namespace}-menu-item {
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
height: var(--menu-item-height);
|
|
||||||
padding-right: calc(var(--menu-item-padding-x) + 6px);
|
|
||||||
margin: 0;
|
|
||||||
margin-right: 2px;
|
|
||||||
// border-bottom: 2px solid transparent;
|
|
||||||
border-radius: var(--menu-item-radius);
|
|
||||||
}
|
|
||||||
|
|
||||||
& > .#{$namespace}-sub-menu {
|
|
||||||
height: var(--menu-item-height);
|
|
||||||
margin-right: 2px;
|
|
||||||
|
|
||||||
&:focus,
|
|
||||||
&:hover {
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
& .#{$namespace}-sub-menu-content {
|
|
||||||
height: 100%;
|
|
||||||
padding-right: 40px;
|
|
||||||
// border-bottom: 2px solid transparent;
|
|
||||||
border-radius: var(--menu-item-radius);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
& .#{$namespace}-menu-item:not(.is-disabled):hover,
|
|
||||||
& .#{$namespace}-menu-item:not(.is-disabled):focus {
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
& > .#{$namespace}-menu-item.is-active {
|
|
||||||
color: var(--menu-item-active-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
// &.is-light {
|
|
||||||
// & > .#{$namespace}-sub-menu {
|
|
||||||
// &.is-active {
|
|
||||||
// border-bottom: 2px solid var(--menu-item-active-color);
|
|
||||||
// }
|
|
||||||
// &:not(.is-active) .#{$namespace}-sub-menu-content {
|
|
||||||
// &:hover {
|
|
||||||
// border-bottom: 2px solid var(--menu-item-active-color);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// & > .#{$namespace}-menu-item.is-active {
|
|
||||||
// border-bottom: 2px solid var(--menu-item-active-color);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// & .#{$namespace}-menu-item:not(.is-disabled):hover,
|
|
||||||
// & .#{$namespace}-menu-item:not(.is-disabled):focus {
|
|
||||||
// border-bottom: 2px solid var(--menu-item-active-color);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
// 折叠菜单
|
|
||||||
|
|
||||||
&.is-collapse {
|
|
||||||
.#{$namespace}-menu__icon {
|
|
||||||
margin-right: 0;
|
|
||||||
}
|
|
||||||
.#{$namespace}-sub-menu__icon-arrow {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.#{$namespace}-sub-menu-content,
|
|
||||||
.#{$namespace}-menu-item {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
padding: var(--menu-item-collapse-padding-y)
|
|
||||||
var(--menu-item-collapse-padding-x);
|
|
||||||
margin: var(--menu-item-collapse-margin-y)
|
|
||||||
var(--menu-item-collapse-margin-x);
|
|
||||||
transition: all 0.3s;
|
|
||||||
|
|
||||||
&.is-active {
|
|
||||||
background: var(--menu-item-active-background-color) !important;
|
|
||||||
border-radius: var(--menu-item-radius);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.is-light {
|
|
||||||
.#{$namespace}-sub-menu-content,
|
|
||||||
.#{$namespace}-menu-item {
|
|
||||||
&.is-active {
|
|
||||||
color: hsl(var(--primary-foreground)) !important;
|
|
||||||
background: var(--menu-item-active-background-color) !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.is-rounded {
|
|
||||||
.#{$namespace}-sub-menu-content,
|
|
||||||
.#{$namespace}-menu-item {
|
|
||||||
&.is-collapse-show-title {
|
|
||||||
// padding: 32px 0 !important;
|
|
||||||
margin: 4px 8px !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__popup-container {
|
|
||||||
max-width: 240px;
|
|
||||||
height: unset;
|
|
||||||
padding: 0;
|
|
||||||
background: var(--menu-background-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
&__popup {
|
|
||||||
padding: 4px 0;
|
|
||||||
border-radius: var(--menu-item-radius);
|
|
||||||
|
|
||||||
.#{$namespace}-sub-menu-content,
|
|
||||||
.#{$namespace}-menu-item {
|
|
||||||
padding: var(--menu-item-popup-padding-y) var(--menu-item-popup-padding-x);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__icon {
|
|
||||||
flex-shrink: 0;
|
|
||||||
// width: var(--menu-item-icon-width);
|
|
||||||
max-height: var(--menu-item-icon-width);
|
|
||||||
margin-right: 12px;
|
|
||||||
font-size: 20px;
|
|
||||||
text-align: center;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.#{$namespace}-menu-item {
|
|
||||||
fill: var(--menu-item-color);
|
|
||||||
stroke: var(--menu-item-color);
|
|
||||||
|
|
||||||
@include menu-item;
|
|
||||||
|
|
||||||
&.is-active {
|
|
||||||
fill: var(--menu-item-active-color);
|
|
||||||
stroke: var(--menu-item-active-color);
|
|
||||||
|
|
||||||
@include menu-item-active;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__content {
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
width: 100%;
|
|
||||||
height: var(--menu-item-height);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.is-collapse-show-title {
|
|
||||||
padding: 32px 0 !important;
|
|
||||||
// margin: 4px 8px !important;
|
|
||||||
.#{$namespace}-menu-tooltip__trigger {
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
.#{$namespace}-menu__icon {
|
|
||||||
display: block;
|
|
||||||
font-size: 20px !important;
|
|
||||||
transition: all 0.25s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.#{$namespace}-menu__name {
|
|
||||||
display: inline-flex;
|
|
||||||
margin-top: 8px;
|
|
||||||
margin-bottom: 0;
|
|
||||||
font-size: 12px;
|
|
||||||
font-weight: 400;
|
|
||||||
line-height: normal;
|
|
||||||
transition: all 0.25s ease;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:not(.is-active):hover {
|
|
||||||
color: var(--menu-item-hover-color);
|
|
||||||
text-decoration: none;
|
|
||||||
cursor: pointer;
|
|
||||||
background: var(--menu-item-hover-background-color) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.#{$namespace}-menu-tooltip__trigger {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
box-sizing: border-box;
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
padding: 0 var(--menu-item-padding-x);
|
|
||||||
font-size: var(--menu-font-size);
|
|
||||||
line-height: var(--menu-item-height);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.#{$namespace}-sub-menu {
|
|
||||||
padding-left: 0;
|
|
||||||
margin: 0;
|
|
||||||
list-style: none;
|
|
||||||
background: var(--menu-submenu-background-color);
|
|
||||||
fill: var(--menu-item-color);
|
|
||||||
stroke: var(--menu-item-color);
|
|
||||||
|
|
||||||
&.is-active {
|
|
||||||
div[data-state='open'] > .#{$namespace}-sub-menu-content,
|
|
||||||
> .#{$namespace}-sub-menu-content {
|
|
||||||
color: var(--menu-submenu-active-color);
|
|
||||||
text-decoration: none;
|
|
||||||
cursor: pointer;
|
|
||||||
background: var(--menu-submenu-active-background-color);
|
|
||||||
fill: var(--menu-submenu-active-color);
|
|
||||||
stroke: var(--menu-submenu-active-color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.#{$namespace}-sub-menu-content {
|
|
||||||
height: var(--menu-item-height);
|
|
||||||
|
|
||||||
@include menu-item;
|
|
||||||
|
|
||||||
&__icon-arrow {
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
right: 6px;
|
|
||||||
width: inherit;
|
|
||||||
margin-top: -8px;
|
|
||||||
margin-right: 0;
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: normal;
|
|
||||||
opacity: 1;
|
|
||||||
transition: transform 0.25s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__title {
|
|
||||||
@include menu-title;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.is-collapse-show-title {
|
|
||||||
flex-direction: column;
|
|
||||||
padding: 32px 0 !important;
|
|
||||||
// margin: 4px 8px !important;
|
|
||||||
.#{$namespace}-menu__icon {
|
|
||||||
display: block;
|
|
||||||
font-size: 20px !important;
|
|
||||||
transition: all 0.25s ease;
|
|
||||||
}
|
|
||||||
.#{$namespace}-sub-menu-content__title {
|
|
||||||
display: inline-flex;
|
|
||||||
flex-shrink: 0;
|
|
||||||
margin-top: 8px;
|
|
||||||
margin-bottom: 0;
|
|
||||||
font-size: 12px;
|
|
||||||
font-weight: 400;
|
|
||||||
line-height: normal;
|
|
||||||
transition: all 0.25s ease;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.is-more {
|
|
||||||
padding-right: 12px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
// &:not(.is-active):hover {
|
|
||||||
&:hover {
|
|
||||||
color: var(--menu-submenu-hover-color);
|
|
||||||
text-decoration: none;
|
|
||||||
cursor: pointer;
|
|
||||||
background: var(--menu-submenu-hover-background-color) !important;
|
|
||||||
|
|
||||||
svg {
|
|
||||||
fill: var(--menu-submenu-hover-color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -66,10 +66,9 @@ const logoClass = computed(() => {
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
v-if="!collapse"
|
v-if="!collapse"
|
||||||
class="text-primary truncate text-nowrap group-[.dark]:text-[hsl(var(--dark-foreground))]"
|
class="text-primary group-[.dark]:text-foreground-dark truncate text-nowrap"
|
||||||
>
|
>
|
||||||
{{ text }}
|
{{ text }}
|
||||||
<!-- <span class="text-primary ml-1 align-super text-[smaller]">Pro</span> -->
|
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -43,7 +43,7 @@ const badgeStyle = computed(() => {
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<span v-if="isDot || badge" :class="$attrs.class" class="absolute right-5">
|
<span v-if="isDot || badge" :class="$attrs.class" class="absolute right-6">
|
||||||
<BadgeDot v-if="isDot" :dot-class="badgeClass" :dot-style="badgeStyle" />
|
<BadgeDot v-if="isDot" :dot-class="badgeClass" :dot-style="badgeStyle" />
|
||||||
<div
|
<div
|
||||||
v-else
|
v-else
|
||||||
|
|
|
@ -6,7 +6,7 @@ import type { TabConfig, TabsProps } from '../../types';
|
||||||
import { computed, nextTick, onMounted, ref, watch } from 'vue';
|
import { computed, nextTick, onMounted, ref, watch } from 'vue';
|
||||||
|
|
||||||
import { IcRoundClose, MdiPin } from '@vben-core/icons';
|
import { IcRoundClose, MdiPin } from '@vben-core/icons';
|
||||||
import { VbenContextMenu, VbenIcon } from '@vben-core/shadcn-ui';
|
import { VbenContextMenu, VbenIcon, VbenScrollbar } from '@vben-core/shadcn-ui';
|
||||||
|
|
||||||
interface Props extends TabsProps {}
|
interface Props extends TabsProps {}
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ const props = withDefaults(defineProps<Props>(), {
|
||||||
contextMenus: () => [],
|
contextMenus: () => [],
|
||||||
gap: 7,
|
gap: 7,
|
||||||
maxWidth: 150,
|
maxWidth: 150,
|
||||||
minWidth: 40,
|
minWidth: 80,
|
||||||
tabs: () => [],
|
tabs: () => [],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -40,20 +40,20 @@ const style = computed(() => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const layout = () => {
|
const layout = () => {
|
||||||
const { gap, maxWidth, minWidth, tabs } = props;
|
const { maxWidth, minWidth } = props;
|
||||||
if (!contentRef.value) {
|
if (!contentRef.value) {
|
||||||
return Math.max(maxWidth, minWidth);
|
return Math.max(maxWidth, minWidth);
|
||||||
}
|
}
|
||||||
const contentWidth = contentRef.value.clientWidth - gap * 3;
|
// const contentWidth = contentRef.value.clientWidth - gap * 3;
|
||||||
let width = contentWidth / tabs.length;
|
// let width = contentWidth / tabs.length;
|
||||||
width += gap * 2;
|
// width += gap * 2;
|
||||||
if (width > maxWidth) {
|
// if (width > maxWidth) {
|
||||||
width = maxWidth;
|
// width = maxWidth;
|
||||||
}
|
// }
|
||||||
if (width < minWidth) {
|
// if (width < minWidth) {
|
||||||
width = minWidth;
|
// width = minWidth;
|
||||||
}
|
// }
|
||||||
tabWidth.value = width;
|
tabWidth.value = maxWidth;
|
||||||
};
|
};
|
||||||
|
|
||||||
const tabsView = computed((): TabConfig[] => {
|
const tabsView = computed((): TabConfig[] => {
|
||||||
|
@ -95,121 +95,115 @@ function handleUnpinTab(tab: TabConfig) {
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div :style="style" class="tabs-chrome size-full flex-1 overflow-hidden pt-1">
|
<div :style="style" class="tabs-chrome size-full flex-1 overflow-hidden pt-1">
|
||||||
<!-- footer -> 4px -->
|
<VbenScrollbar class="h-full" horizontal>
|
||||||
<div
|
<!-- footer -> 4px -->
|
||||||
ref="contentRef"
|
<div
|
||||||
:class="contentClass"
|
ref="contentRef"
|
||||||
class="relative h-full overflow-hidden"
|
:class="contentClass"
|
||||||
>
|
class="relative !flex h-full w-max"
|
||||||
<TransitionGroup name="slide-down">
|
>
|
||||||
<div
|
<TransitionGroup name="slide-down">
|
||||||
v-for="(tab, i) in tabsView"
|
<div
|
||||||
:key="tab.key"
|
v-for="(tab, i) in tabsView"
|
||||||
ref="tabRef"
|
:key="tab.key"
|
||||||
:class="[
|
ref="tabRef"
|
||||||
{ 'is-active': tab.key === active, dragable: !tab.affixTab },
|
:class="[
|
||||||
]"
|
{ 'is-active': tab.key === active, dragable: !tab.affixTab },
|
||||||
:data-index="i"
|
]"
|
||||||
:style="{
|
:data-index="i"
|
||||||
width: `${tabWidth}px`,
|
:style="{
|
||||||
left: `${(tabWidth - gap * 2) * i}px`,
|
width: `${tabWidth}px`,
|
||||||
}"
|
left: `${(tabWidth - gap * 2) * i}px`,
|
||||||
class="tabs-chrome__item group absolute flex h-full select-none items-center transition-all"
|
}"
|
||||||
@click="active = tab.key"
|
class="tabs-chrome__item group absolute flex h-full select-none items-center transition-all"
|
||||||
>
|
@click="active = tab.key"
|
||||||
<VbenContextMenu
|
|
||||||
:handler-data="tab"
|
|
||||||
:menus="contextMenus"
|
|
||||||
:modal="false"
|
|
||||||
item-class="pr-6"
|
|
||||||
>
|
>
|
||||||
<div class="size-full">
|
<VbenContextMenu
|
||||||
<!-- divider -->
|
:handler-data="tab"
|
||||||
<div
|
:menus="contextMenus"
|
||||||
v-if="i !== 0"
|
:modal="false"
|
||||||
class="tabs-chrome__divider bg-foreground/80 absolute left-[var(--gap)] top-1/2 z-0 h-4 w-[1px] translate-y-[-50%] transition-all"
|
item-class="pr-6"
|
||||||
></div>
|
>
|
||||||
<!-- background -->
|
<div class="size-full">
|
||||||
<div
|
<!-- divider -->
|
||||||
class="tabs-chrome__background absolute z-[1] size-full px-[calc(var(--gap)-1px)] py-0 transition-opacity duration-150"
|
|
||||||
>
|
|
||||||
<div
|
<div
|
||||||
class="tabs-chrome__background-content h-full rounded-tl-[var(--gap)] rounded-tr-[var(--gap)] duration-150"
|
v-if="i !== 0 && tab.key !== active"
|
||||||
|
class="tabs-chrome__divider bg-foreground/80 absolute left-[var(--gap)] top-1/2 z-0 h-4 w-[1px] translate-y-[-50%] transition-all"
|
||||||
></div>
|
></div>
|
||||||
<svg
|
<!-- background -->
|
||||||
class="tabs-chrome__background-before absolute bottom-[-1px] left-[-1px] fill-transparent transition-all duration-150"
|
<div
|
||||||
height="7"
|
class="tabs-chrome__background absolute z-[1] size-full px-[calc(var(--gap)-1px)] py-0 transition-opacity duration-150"
|
||||||
width="7"
|
|
||||||
>
|
>
|
||||||
<path d="M 0 7 A 7 7 0 0 0 7 0 L 7 7 Z" />
|
<div
|
||||||
</svg>
|
class="tabs-chrome__background-content h-full rounded-tl-[var(--gap)] rounded-tr-[var(--gap)] duration-150"
|
||||||
<svg
|
></div>
|
||||||
class="tabs-chrome__background-after absolute bottom-[-1px] right-[-1px] fill-transparent transition-all duration-150"
|
<svg
|
||||||
height="7"
|
class="tabs-chrome__background-before absolute bottom-[-1px] left-[-1px] fill-transparent transition-all duration-150"
|
||||||
width="7"
|
height="7"
|
||||||
>
|
width="7"
|
||||||
<path d="M 0 0 A 7 7 0 0 0 7 7 L 0 7 Z" />
|
>
|
||||||
</svg>
|
<path d="M 0 7 A 7 7 0 0 0 7 0 L 7 7 Z" />
|
||||||
</div>
|
</svg>
|
||||||
|
<svg
|
||||||
|
class="tabs-chrome__background-after absolute bottom-[-1px] right-[-1px] fill-transparent transition-all duration-150"
|
||||||
|
height="7"
|
||||||
|
width="7"
|
||||||
|
>
|
||||||
|
<path d="M 0 0 A 7 7 0 0 0 7 7 L 0 7 Z" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- extra -->
|
<!-- extra -->
|
||||||
<div
|
<div
|
||||||
class="tabs-chrome__extra absolute right-[calc(var(--gap)*2)] top-1/2 z-[3] size-4 translate-y-[-50%]"
|
class="tabs-chrome__extra absolute right-[calc(var(--gap)*1.5)] top-1/2 z-[3] size-4 translate-y-[-50%]"
|
||||||
>
|
>
|
||||||
<!-- <div
|
<!-- <div
|
||||||
class="tabs-chrome__extra absolute right-[calc(var(--gap)*2)] top-1/2 z-[3] size-4 translate-y-[-50%] opacity-0 transition-opacity group-hover:opacity-100"
|
class="tabs-chrome__extra absolute right-[calc(var(--gap)*2)] top-1/2 z-[3] size-4 translate-y-[-50%] opacity-0 transition-opacity group-hover:opacity-100"
|
||||||
> -->
|
> -->
|
||||||
<!-- close-icon -->
|
<!-- close-icon -->
|
||||||
<IcRoundClose
|
<IcRoundClose
|
||||||
v-show="!tab.affixTab && tabsView.length > 1 && tab.closable"
|
v-show="
|
||||||
class="hover:bg-accent stroke-accent-foreground/80 hover:stroke-accent-foreground group-[.is-active]:text-primary mt-[2px] size-3 cursor-pointer rounded-full transition-all"
|
!tab.affixTab && tabsView.length > 1 && tab.closable
|
||||||
@click.stop="handleClose(tab.key)"
|
"
|
||||||
/>
|
class="hover:bg-accent stroke-accent-foreground/80 hover:stroke-accent-foreground group-[.is-active]:text-primary mt-[2px] size-3 cursor-pointer rounded-full transition-all"
|
||||||
<MdiPin
|
@click.stop="handleClose(tab.key)"
|
||||||
v-show="tab.affixTab && tabsView.length > 1 && tab.closable"
|
/>
|
||||||
class="hover:bg-accent hover:stroke-accent-foreground group-[.is-active]:text-primary mt-[2px] size-3.5 cursor-pointer rounded-full transition-all"
|
<MdiPin
|
||||||
@click.stop="handleUnpinTab(tab)"
|
v-show="tab.affixTab && tabsView.length > 1 && tab.closable"
|
||||||
/>
|
class="hover:bg-accent hover:stroke-accent-foreground group-[.is-active]:text-primary mt-[2px] size-3.5 cursor-pointer rounded-full transition-all"
|
||||||
</div>
|
@click.stop="handleUnpinTab(tab)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- tab-item-main -->
|
<!-- tab-item-main -->
|
||||||
<div
|
<div
|
||||||
class="tabs-chrome__item-main group-[.is-active]:text-primary text-accent-foreground absolute left-0 right-0 z-[2] mx-[calc(var(--gap)*2)] my-0 flex h-full items-center overflow-hidden rounded-tl-[5px] rounded-tr-[5px] pr-4 duration-150 group-hover:pr-3 group-[.is-active]:font-semibold"
|
class="tabs-chrome__item-main group-[.is-active]:text-primary text-accent-foreground absolute left-0 right-0 z-[2] mx-[calc(var(--gap)*2)] my-0 flex h-full items-center overflow-hidden rounded-tl-[5px] rounded-tr-[5px] pr-4 duration-150 group-hover:pr-3"
|
||||||
>
|
|
||||||
<VbenIcon
|
|
||||||
v-if="showIcon"
|
|
||||||
:icon="tab.icon"
|
|
||||||
class="ml-[var(--gap)] flex size-4 items-center overflow-hidden"
|
|
||||||
fallback
|
|
||||||
/>
|
|
||||||
|
|
||||||
<span
|
|
||||||
class="tabs-chrome__label ml-[var(--gap)] flex-1 overflow-hidden whitespace-nowrap"
|
|
||||||
>
|
>
|
||||||
{{ tab.title }}
|
<VbenIcon
|
||||||
</span>
|
v-if="showIcon"
|
||||||
|
:icon="tab.icon"
|
||||||
|
class="ml-[var(--gap)] flex size-4 items-center overflow-hidden"
|
||||||
|
fallback
|
||||||
|
/>
|
||||||
|
|
||||||
|
<span
|
||||||
|
class="tabs-chrome__label ml-[var(--gap)] flex-1 overflow-hidden whitespace-nowrap"
|
||||||
|
>
|
||||||
|
{{ tab.title }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</VbenContextMenu>
|
||||||
</VbenContextMenu>
|
</div>
|
||||||
</div>
|
</TransitionGroup>
|
||||||
</TransitionGroup>
|
</div>
|
||||||
</div>
|
<!-- footer -->
|
||||||
<!-- footer -->
|
<div class="bg-background h-1"></div>
|
||||||
<div class="bg-background h-1"></div>
|
</VbenScrollbar>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
/* html.dark {
|
|
||||||
.tabs-chrome {
|
|
||||||
.is-active {
|
|
||||||
.tabs-chrome__item-main {
|
|
||||||
@apply text-accent-foreground;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} */
|
|
||||||
|
|
||||||
.tabs-chrome {
|
.tabs-chrome {
|
||||||
.dragging {
|
.dragging {
|
||||||
.tabs-chrome__item-main {
|
.tabs-chrome__item-main {
|
||||||
|
@ -222,7 +216,7 @@ function handleUnpinTab(tab: TabConfig) {
|
||||||
}
|
}
|
||||||
|
|
||||||
&__item {
|
&__item {
|
||||||
&:hover {
|
&:hover:not(.is-active) {
|
||||||
& + .tabs-chrome__item {
|
& + .tabs-chrome__item {
|
||||||
.tabs-chrome__divider {
|
.tabs-chrome__divider {
|
||||||
@apply opacity-0;
|
@apply opacity-0;
|
||||||
|
@ -235,12 +229,12 @@ function handleUnpinTab(tab: TabConfig) {
|
||||||
|
|
||||||
.tabs-chrome__background {
|
.tabs-chrome__background {
|
||||||
&-content {
|
&-content {
|
||||||
@apply bg-heavy;
|
@apply bg-primary/10 mx-1 rounded-md pb-2;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-before,
|
&-before,
|
||||||
&-after {
|
&-after {
|
||||||
@apply fill-heavy;
|
@apply fill-primary/0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -248,16 +242,22 @@ function handleUnpinTab(tab: TabConfig) {
|
||||||
&.is-active {
|
&.is-active {
|
||||||
@apply z-[2];
|
@apply z-[2];
|
||||||
|
|
||||||
|
& + .tabs-chrome__item {
|
||||||
|
.tabs-chrome__divider {
|
||||||
|
@apply opacity-0 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.tabs-chrome__background {
|
.tabs-chrome__background {
|
||||||
@apply opacity-100;
|
@apply opacity-100;
|
||||||
|
|
||||||
&-content {
|
&-content {
|
||||||
@apply bg-background-content;
|
@apply bg-primary/15;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-before,
|
&-before,
|
||||||
&-after {
|
&-after {
|
||||||
@apply fill-background-content;
|
@apply fill-primary/15;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,14 +26,14 @@ const active = defineModel<string>('active');
|
||||||
const typeWithClass = computed(() => {
|
const typeWithClass = computed(() => {
|
||||||
const typeClasses: Record<string, { content: string }> = {
|
const typeClasses: Record<string, { content: string }> = {
|
||||||
brisk: {
|
brisk: {
|
||||||
content: `h-full after:content-[''] after:absolute after:bottom-0 after:left-0 after:w-full after:h-[1.5px] after:bg-primary after:scale-x-0 after:transition-[transform] after:ease-out after:duration-300 hover:after:scale-x-100 after:origin-left [&.is-active]:after:scale-x-100`,
|
content: `h-full after:content-[''] after:absolute after:bottom-0 after:left-0 after:w-full after:h-[1.5px] after:bg-primary after:scale-x-0 after:transition-[transform] after:ease-out after:duration-300 hover:after:scale-x-100 after:origin-left [&.is-active]:after:scale-x-100 border-l border-border`,
|
||||||
},
|
},
|
||||||
card: {
|
card: {
|
||||||
content:
|
content:
|
||||||
'h-[calc(100%-6px)] rounded-md mr-2 border-border [&.is-active]:border-primary border transition-all',
|
'h-[calc(100%-6px)] rounded-md ml-2 border border-border transition-all',
|
||||||
},
|
},
|
||||||
plain: {
|
plain: {
|
||||||
content: 'h-full',
|
content: 'h-full border-l border-border',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ function handleUnpinTab(tab: TabConfig) {
|
||||||
:key="tab.key"
|
:key="tab.key"
|
||||||
:class="[
|
:class="[
|
||||||
{
|
{
|
||||||
'tabs-item is-active bg-background-content': tab.key === active,
|
'is-active bg-primary/15': tab.key === active,
|
||||||
dragable: !tab.affixTab,
|
dragable: !tab.affixTab,
|
||||||
},
|
},
|
||||||
typeWithClass.content,
|
typeWithClass.content,
|
||||||
|
@ -110,14 +110,14 @@ function handleUnpinTab(tab: TabConfig) {
|
||||||
/>
|
/>
|
||||||
<MdiPin
|
<MdiPin
|
||||||
v-show="tab.affixTab && tabsView.length > 1 && tab.closable"
|
v-show="tab.affixTab && tabsView.length > 1 && tab.closable"
|
||||||
class="hover:bg-accent hover:stroke-accent-foreground group-[.is-active]:text-primary mt-[2px] size-3.5 cursor-pointer rounded-full transition-all"
|
class="hover:bg-heavy hover:stroke-accent-foreground group-[.is-active]:text-primary mt-[2px] size-3.5 cursor-pointer rounded-full transition-all"
|
||||||
@click.stop="handleUnpinTab(tab)"
|
@click.stop="handleUnpinTab(tab)"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- tab-item-main -->
|
<!-- tab-item-main -->
|
||||||
<div
|
<div
|
||||||
class="tabs-item__main group-[.is-active]:text-primary text-accent-foreground mx-3 mr-4 flex h-full items-center overflow-hidden rounded-tl-[5px] rounded-tr-[5px] pr-3 transition-all duration-300"
|
class="group-[.is-active]:text-primary text-accent-foreground mx-3 mr-4 flex h-full items-center overflow-hidden rounded-tl-[5px] rounded-tr-[5px] pr-3 transition-all duration-300"
|
||||||
>
|
>
|
||||||
<!-- <div
|
<!-- <div
|
||||||
class="mx-3 ml-3 mr-2 flex h-full items-center overflow-hidden rounded-tl-[5px] rounded-tr-[5px] transition-all duration-300 group-hover:mr-2 group-hover:pr-4 group-[.is-active]:pr-4"
|
class="mx-3 ml-3 mr-2 flex h-full items-center overflow-hidden rounded-tl-[5px] rounded-tr-[5px] transition-all duration-300 group-hover:mr-2 group-hover:pr-4 group-[.is-active]:pr-4"
|
||||||
|
@ -141,15 +141,3 @@ function handleUnpinTab(tab: TabConfig) {
|
||||||
</VbenScrollbar>
|
</VbenScrollbar>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
/* html.dark {
|
|
||||||
.tabs-item {
|
|
||||||
&.is-active {
|
|
||||||
.tabs-item__main {
|
|
||||||
@apply text-accent-foreground;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} */
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vben-core/helpers": "workspace:*",
|
"@vben-core/helpers": "workspace:*",
|
||||||
|
"@vben-core/hooks": "workspace:*",
|
||||||
"@vben-core/icons": "workspace:*",
|
"@vben-core/icons": "workspace:*",
|
||||||
"@vben-core/layout-ui": "workspace:*",
|
"@vben-core/layout-ui": "workspace:*",
|
||||||
"@vben-core/locales": "workspace:*",
|
"@vben-core/locales": "workspace:*",
|
||||||
|
|
|
@ -8,14 +8,17 @@ defineOptions({
|
||||||
name: 'AuthenticationFormView',
|
name: 'AuthenticationFormView',
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
class="flex-col-center bg-background-content relative px-6 py-10 lg:flex-initial lg:px-8"
|
class="flex-col-center bg-background-content relative px-6 py-10 lg:flex-initial lg:px-8"
|
||||||
>
|
>
|
||||||
|
<!-- Toolbar Slot -->
|
||||||
<slot name="toolbar">
|
<slot name="toolbar">
|
||||||
<Toolbar />
|
<Toolbar />
|
||||||
</slot>
|
</slot>
|
||||||
|
|
||||||
|
<!-- Router View with Transition and KeepAlive -->
|
||||||
<RouterView v-slot="{ Component, route }">
|
<RouterView v-slot="{ Component, route }">
|
||||||
<Transition appear mode="out-in" name="slide-right">
|
<Transition appear mode="out-in" name="slide-right">
|
||||||
<KeepAlive :include="['Login']">
|
<KeepAlive :include="['Login']">
|
||||||
|
@ -28,6 +31,7 @@ defineOptions({
|
||||||
</Transition>
|
</Transition>
|
||||||
</RouterView>
|
</RouterView>
|
||||||
|
|
||||||
|
<!-- Footer Copyright -->
|
||||||
<div
|
<div
|
||||||
class="text-muted-foreground absolute bottom-3 flex text-center text-xs"
|
class="text-muted-foreground absolute bottom-3 flex text-center text-xs"
|
||||||
>
|
>
|
||||||
|
|
|
@ -10,14 +10,17 @@ defineOptions({
|
||||||
name: 'AuthenticationToolbar',
|
name: 'AuthenticationToolbar',
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
class="flex-center bg-background dark:bg-accent absolute right-2 top-4 rounded-3xl px-3 py-1"
|
class="flex-center bg-background dark:bg-accent absolute right-2 top-4 rounded-3xl px-3 py-1"
|
||||||
>
|
>
|
||||||
|
<!-- Only show on medium and larger screens -->
|
||||||
<div class="hidden md:flex">
|
<div class="hidden md:flex">
|
||||||
<AuthenticationColorToggle />
|
<AuthenticationColorToggle />
|
||||||
<AuthenticationLayoutToggle />
|
<AuthenticationLayoutToggle />
|
||||||
</div>
|
</div>
|
||||||
|
<!-- Always show Language and Theme toggles -->
|
||||||
<LanguageToggle />
|
<LanguageToggle />
|
||||||
<ThemeToggle />
|
<ThemeToggle />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { RouteLocationNormalizedLoaded } from 'vue-router';
|
import type { RouteLocationNormalizedLoaded } from 'vue-router';
|
||||||
|
|
||||||
|
import { useContentHeight } from '@vben-core/hooks';
|
||||||
import { preferences, usePreferences } from '@vben-core/preferences';
|
import { preferences, usePreferences } from '@vben-core/preferences';
|
||||||
import { Spinner } from '@vben-core/shadcn-ui';
|
import { Spinner } from '@vben-core/shadcn-ui';
|
||||||
import { storeToRefs, useCoreTabbarStore } from '@vben-core/stores';
|
import { storeToRefs, useCoreTabbarStore } from '@vben-core/stores';
|
||||||
|
@ -13,6 +14,7 @@ defineOptions({ name: 'LayoutContent' });
|
||||||
const tabbarStore = useCoreTabbarStore();
|
const tabbarStore = useCoreTabbarStore();
|
||||||
const { keepAlive } = usePreferences();
|
const { keepAlive } = usePreferences();
|
||||||
const { spinning } = useContentSpinner();
|
const { spinning } = useContentSpinner();
|
||||||
|
const { contentStyles } = useContentHeight();
|
||||||
|
|
||||||
const { getCachedTabs, getExcludeCachedTabs, renderRouteView } =
|
const { getCachedTabs, getExcludeCachedTabs, renderRouteView } =
|
||||||
storeToRefs(tabbarStore);
|
storeToRefs(tabbarStore);
|
||||||
|
@ -47,7 +49,7 @@ function getTransitionName(route: RouteLocationNormalizedLoaded) {
|
||||||
<Spinner
|
<Spinner
|
||||||
v-if="preferences.transition.loading"
|
v-if="preferences.transition.loading"
|
||||||
:spinning="spinning"
|
:spinning="spinning"
|
||||||
class="h-[var(--vben-content-client-height)]"
|
:style="contentStyles"
|
||||||
/>
|
/>
|
||||||
<IFrameRouterView />
|
<IFrameRouterView />
|
||||||
<RouterView v-slot="{ Component, route }">
|
<RouterView v-slot="{ Component, route }">
|
||||||
|
|
|
@ -7,9 +7,10 @@ function useContentSpinner() {
|
||||||
const spinning = ref(false);
|
const spinning = ref(false);
|
||||||
const startTime = ref(0);
|
const startTime = ref(0);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const minShowTime = 500;
|
const minShowTime = 500; // 最小显示时间
|
||||||
const enableLoading = computed(() => preferences.transition.loading);
|
const enableLoading = computed(() => preferences.transition.loading);
|
||||||
|
|
||||||
|
// 结束加载动画
|
||||||
const onEnd = () => {
|
const onEnd = () => {
|
||||||
if (!enableLoading.value) {
|
if (!enableLoading.value) {
|
||||||
return;
|
return;
|
||||||
|
@ -24,6 +25,7 @@ function useContentSpinner() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 路由前置守卫
|
||||||
router.beforeEach((to) => {
|
router.beforeEach((to) => {
|
||||||
if (to.meta.loaded || !enableLoading.value || to.meta.iframeSrc) {
|
if (to.meta.loaded || !enableLoading.value || to.meta.iframeSrc) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -33,14 +35,12 @@ function useContentSpinner() {
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 路由后置守卫
|
||||||
router.afterEach((to) => {
|
router.afterEach((to) => {
|
||||||
if (to.meta.loaded || !enableLoading.value || to.meta.iframeSrc) {
|
if (to.meta.loaded || !enableLoading.value || to.meta.iframeSrc) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 关闭加载动画
|
|
||||||
onEnd();
|
onEnd();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -22,19 +22,23 @@ withDefaults(defineProps<Props>(), {
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="text-md flex-center">
|
<div class="text-md flex-center">
|
||||||
|
<!-- ICP Link -->
|
||||||
<a
|
<a
|
||||||
v-if="icp"
|
v-if="icp"
|
||||||
:href="icpLink || 'javascript:void 0'"
|
:href="icpLink || 'javascript:void(0)'"
|
||||||
class="hover:text-primary-hover"
|
class="hover:text-primary-hover"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
{{ icp }}
|
{{ icp }}
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
<!-- Copyright Text -->
|
||||||
Copyright © {{ date }}
|
Copyright © {{ date }}
|
||||||
|
|
||||||
|
<!-- Company Link -->
|
||||||
<a
|
<a
|
||||||
v-if="companyName"
|
v-if="companyName"
|
||||||
:href="companySiteLink || 'javascript:void 0'"
|
:href="companySiteLink || 'javascript:void(0)'"
|
||||||
class="hover:text-primary-hover mx-1"
|
class="hover:text-primary-hover mx-1"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
|
|
|
@ -634,6 +634,31 @@ importers:
|
||||||
specifier: ^4.4.0
|
specifier: ^4.4.0
|
||||||
version: 4.4.0(vue@3.4.31(typescript@5.5.3))
|
version: 4.4.0(vue@3.4.31(typescript@5.5.3))
|
||||||
|
|
||||||
|
packages/@core/hooks:
|
||||||
|
dependencies:
|
||||||
|
'@vben-core/constants':
|
||||||
|
specifier: workspace:*
|
||||||
|
version: link:../shared/constants
|
||||||
|
'@vben-core/toolkit':
|
||||||
|
specifier: workspace:*
|
||||||
|
version: link:../shared/toolkit
|
||||||
|
'@vueuse/core':
|
||||||
|
specifier: ^10.11.0
|
||||||
|
version: 10.11.0(vue@3.4.31(typescript@5.5.3))
|
||||||
|
radix-vue:
|
||||||
|
specifier: ^1.9.1
|
||||||
|
version: 1.9.1(vue@3.4.31(typescript@5.5.3))
|
||||||
|
sortablejs:
|
||||||
|
specifier: ^1.15.2
|
||||||
|
version: 1.15.2
|
||||||
|
vue:
|
||||||
|
specifier: ^3.4.31
|
||||||
|
version: 3.4.31(typescript@5.5.3)
|
||||||
|
devDependencies:
|
||||||
|
'@types/sortablejs':
|
||||||
|
specifier: ^1.15.8
|
||||||
|
version: 1.15.8
|
||||||
|
|
||||||
packages/@core/locales:
|
packages/@core/locales:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@intlify/core-base':
|
'@intlify/core-base':
|
||||||
|
@ -657,19 +682,6 @@ importers:
|
||||||
specifier: ^2.0.0
|
specifier: ^2.0.0
|
||||||
version: 2.0.0
|
version: 2.0.0
|
||||||
|
|
||||||
packages/@core/shared/hooks:
|
|
||||||
dependencies:
|
|
||||||
radix-vue:
|
|
||||||
specifier: ^1.9.1
|
|
||||||
version: 1.9.1(vue@3.4.31(typescript@5.5.3))
|
|
||||||
sortablejs:
|
|
||||||
specifier: ^1.15.2
|
|
||||||
version: 1.15.2
|
|
||||||
devDependencies:
|
|
||||||
'@types/sortablejs':
|
|
||||||
specifier: ^1.15.8
|
|
||||||
version: 1.15.8
|
|
||||||
|
|
||||||
packages/@core/shared/icons:
|
packages/@core/shared/icons:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@iconify/vue':
|
'@iconify/vue':
|
||||||
|
@ -724,6 +736,9 @@ importers:
|
||||||
|
|
||||||
packages/@core/ui-kit/layout-ui:
|
packages/@core/ui-kit/layout-ui:
|
||||||
dependencies:
|
dependencies:
|
||||||
|
'@vben-core/hooks':
|
||||||
|
specifier: workspace:*
|
||||||
|
version: link:../../hooks
|
||||||
'@vben-core/icons':
|
'@vben-core/icons':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../../shared/icons
|
version: link:../../shared/icons
|
||||||
|
@ -747,7 +762,7 @@ importers:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@vben-core/hooks':
|
'@vben-core/hooks':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../../shared/hooks
|
version: link:../../hooks
|
||||||
'@vben-core/icons':
|
'@vben-core/icons':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../../shared/icons
|
version: link:../../shared/icons
|
||||||
|
@ -801,7 +816,7 @@ importers:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@vben-core/hooks':
|
'@vben-core/hooks':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../../shared/hooks
|
version: link:../../hooks
|
||||||
'@vben-core/icons':
|
'@vben-core/icons':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../../shared/icons
|
version: link:../../shared/icons
|
||||||
|
@ -861,7 +876,7 @@ importers:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@vben-core/hooks':
|
'@vben-core/hooks':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../../@core/shared/hooks
|
version: link:../../@core/hooks
|
||||||
'@vben-core/icons':
|
'@vben-core/icons':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../../@core/shared/icons
|
version: link:../../@core/shared/icons
|
||||||
|
@ -899,6 +914,9 @@ importers:
|
||||||
'@vben-core/helpers':
|
'@vben-core/helpers':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../../@core/forward/helpers
|
version: link:../../@core/forward/helpers
|
||||||
|
'@vben-core/hooks':
|
||||||
|
specifier: workspace:*
|
||||||
|
version: link:../../@core/hooks
|
||||||
'@vben-core/icons':
|
'@vben-core/icons':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../../@core/shared/icons
|
version: link:../../@core/shared/icons
|
||||||
|
@ -943,7 +961,7 @@ importers:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@vben-core/hooks':
|
'@vben-core/hooks':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../@core/shared/hooks
|
version: link:../@core/hooks
|
||||||
|
|
||||||
packages/icons:
|
packages/icons:
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
|
@ -7,6 +7,7 @@ packages:
|
||||||
- "packages/@core/forward/*"
|
- "packages/@core/forward/*"
|
||||||
- "packages/@core/helpers"
|
- "packages/@core/helpers"
|
||||||
- "packages/@core/locales"
|
- "packages/@core/locales"
|
||||||
|
- "packages/@core/hooks"
|
||||||
- "packages/effects/*"
|
- "packages/effects/*"
|
||||||
- "apps/*"
|
- "apps/*"
|
||||||
- "scripts/*"
|
- "scripts/*"
|
||||||
|
|
|
@ -60,6 +60,10 @@
|
||||||
"name": "@vben-core/stores",
|
"name": "@vben-core/stores",
|
||||||
"path": "packages/@core/forward/stores",
|
"path": "packages/@core/forward/stores",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "@vben-core/hooks",
|
||||||
|
"path": "packages/@core/hooks",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "@vben-core/locales",
|
"name": "@vben-core/locales",
|
||||||
"path": "packages/@core/locales",
|
"path": "packages/@core/locales",
|
||||||
|
@ -72,10 +76,6 @@
|
||||||
"name": "@vben-core/design",
|
"name": "@vben-core/design",
|
||||||
"path": "packages/@core/shared/design",
|
"path": "packages/@core/shared/design",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "@vben-core/hooks",
|
|
||||||
"path": "packages/@core/shared/hooks",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "@vben-core/icons",
|
"name": "@vben-core/icons",
|
||||||
"path": "packages/@core/shared/icons",
|
"path": "packages/@core/shared/icons",
|
||||||
|
|
Loading…
Reference in New Issue