perf: improve overall theme color matching
parent
caf1fc4375
commit
f95d9aa609
|
@ -12,7 +12,7 @@ const routes: RouteRecordRaw[] = [
|
|||
badgeType: 'dot',
|
||||
icon: VBEN_LOGO_URL,
|
||||
order: 9999,
|
||||
title: 'Vben Admin',
|
||||
title: 'Vben',
|
||||
},
|
||||
name: 'AboutLayout',
|
||||
path: '/vben-admin',
|
||||
|
|
|
@ -27,6 +27,8 @@ packages.forEach((pkg) => {
|
|||
const shadcnUiColors = {
|
||||
accent: {
|
||||
DEFAULT: 'hsl(var(--accent))',
|
||||
dark: 'hsl(var(--accent-dark))',
|
||||
'dark-hover': 'hsl(var(--accent-dark-hover))',
|
||||
foreground: 'hsl(var(--accent-foreground))',
|
||||
hover: 'hsl(var(--accent-hover))',
|
||||
},
|
||||
|
@ -34,17 +36,23 @@ const shadcnUiColors = {
|
|||
DEFAULT: 'hsl(var(--background))',
|
||||
content: 'hsl(var(--background-content))',
|
||||
},
|
||||
border: 'hsl(var(--border))',
|
||||
border: {
|
||||
DEFAULT: 'hsl(var(--border))',
|
||||
dark: 'hsl(var(--border-dark))',
|
||||
},
|
||||
card: {
|
||||
DEFAULT: 'hsl(var(--card))',
|
||||
foreground: 'hsl(var(--card-foreground))',
|
||||
},
|
||||
destructive: {
|
||||
...createColorsPattern('destructive'),
|
||||
...createColorsPalette('destructive'),
|
||||
DEFAULT: 'hsl(var(--destructive))',
|
||||
},
|
||||
|
||||
foreground: 'hsl(var(--foreground))',
|
||||
foreground: {
|
||||
DEFAULT: 'hsl(var(--foreground))',
|
||||
dark: 'hsl(var(--foreground-dark))',
|
||||
},
|
||||
|
||||
input: {
|
||||
DEFAULT: 'hsl(var(--input))',
|
||||
|
@ -59,7 +67,7 @@ const shadcnUiColors = {
|
|||
foreground: 'hsl(var(--popover-foreground))',
|
||||
},
|
||||
primary: {
|
||||
...createColorsPattern('primary'),
|
||||
...createColorsPalette('primary'),
|
||||
DEFAULT: 'hsl(var(--primary))',
|
||||
},
|
||||
|
||||
|
@ -76,7 +84,7 @@ const customColors = {
|
|||
DEFAULT: 'hsl(var(--authentication))',
|
||||
},
|
||||
green: {
|
||||
...createColorsPattern('green'),
|
||||
...createColorsPalette('green'),
|
||||
foreground: 'hsl(var(--success-foreground))',
|
||||
},
|
||||
heavy: {
|
||||
|
@ -88,19 +96,19 @@ const customColors = {
|
|||
},
|
||||
overlay: 'hsl(var(--overlay))',
|
||||
red: {
|
||||
...createColorsPattern('red'),
|
||||
...createColorsPalette('red'),
|
||||
foreground: 'hsl(var(--destructive-foreground))',
|
||||
},
|
||||
success: {
|
||||
...createColorsPattern('success'),
|
||||
...createColorsPalette('success'),
|
||||
DEFAULT: 'hsl(var(--success))',
|
||||
},
|
||||
warning: {
|
||||
...createColorsPattern('warning'),
|
||||
...createColorsPalette('warning'),
|
||||
DEFAULT: 'hsl(var(--warning))',
|
||||
},
|
||||
yellow: {
|
||||
...createColorsPattern('yellow'),
|
||||
...createColorsPalette('yellow'),
|
||||
foreground: 'hsl(var(--warning-foreground))',
|
||||
},
|
||||
};
|
||||
|
@ -189,7 +197,31 @@ export default {
|
|||
},
|
||||
} 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 {
|
||||
50: `hsl(var(--${name}-50))`,
|
||||
100: `hsl(var(--${name}-100))`,
|
||||
|
@ -199,18 +231,29 @@ function createColorsPattern(name: string) {
|
|||
500: `hsl(var(--${name}-500))`,
|
||||
600: `hsl(var(--${name}-600))`,
|
||||
700: `hsl(var(--${name}-700))`,
|
||||
800: `hsl(var(--${name}-800))`,
|
||||
900: `hsl(var(--${name}-900))`,
|
||||
950: `hsl(var(--${name}-950))`,
|
||||
active: `hsl(var(--${name}-600))`,
|
||||
background: `hsl(var(--${name}-50))`,
|
||||
'background-hover': `hsl(var(--${name}-100))`,
|
||||
border: `hsl(var(--${name}-200))`,
|
||||
'border-hover': `hsl(var(--${name}-300))`,
|
||||
// 800: `hsl(var(--${name}-800))`,
|
||||
// 900: `hsl(var(--${name}-900))`,
|
||||
// 950: `hsl(var(--${name}-950))`,
|
||||
// 激活状态下的颜色,适用于按钮按下时的背景色或边框色。
|
||||
active: `hsl(var(--${name}-700))`,
|
||||
// 浅色背景,适用于输入框或表单区域的背景。
|
||||
'background-light': `hsl(var(--${name}-200))`,
|
||||
// 适用于略浅的背景色,通常用于次要背景或略浅的区域。
|
||||
'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))`,
|
||||
hover: `hsl(var(--${name}-400))`,
|
||||
text: `hsl(var(--${name}-800))`,
|
||||
'text-active': `hsl(var(--${name}-900))`,
|
||||
'text-hover': `hsl(var(--${name}-700))`,
|
||||
// 鼠标悬停状态下的颜色,适用于按钮悬停时的背景色或边框色。
|
||||
hover: `hsl(var(--${name}-600))`,
|
||||
// 主色文本
|
||||
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) {
|
||||
document.documentElement.style.setProperty(
|
||||
'--primary',
|
||||
colorVariables['--primary-600'],
|
||||
colorVariables['--primary-500'],
|
||||
);
|
||||
}
|
||||
|
||||
if (colorVariables['--green-600']) {
|
||||
colorVariables['--success'] = colorVariables['--green-600'];
|
||||
if (colorVariables['--green-500']) {
|
||||
colorVariables['--success'] = colorVariables['--green-500'];
|
||||
}
|
||||
if (colorVariables['--yellow-600']) {
|
||||
colorVariables['--warning'] = colorVariables['--yellow-600'];
|
||||
if (colorVariables['--yellow-500']) {
|
||||
colorVariables['--warning'] = colorVariables['--yellow-500'];
|
||||
}
|
||||
if (colorVariables['--red-600']) {
|
||||
colorVariables['--destructive'] = colorVariables['--red-600'];
|
||||
if (colorVariables['--red-500']) {
|
||||
colorVariables['--destructive'] = colorVariables['--red-500'];
|
||||
}
|
||||
updateCSSVariables(colorVariables);
|
||||
}
|
||||
|
|
|
@ -36,8 +36,12 @@
|
|||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@vben-core/constants": "workspace:*",
|
||||
"@vben-core/toolkit": "workspace:*",
|
||||
"@vueuse/core": "^10.11.0",
|
||||
"radix-vue": "^1.9.1",
|
||||
"sortablejs": "^1.15.2"
|
||||
"sortablejs": "^1.15.2",
|
||||
"vue": "^3.4.31"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/sortablejs": "^1.15.8"
|
|
@ -1,3 +1,4 @@
|
|||
export * from './use-content-height';
|
||||
export * from './use-namespace';
|
||||
export * from './use-sortable';
|
||||
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 @@
|
|||
/**
|
||||
* @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 };
|
||||
export * from './global';
|
||||
export * from './vben';
|
||||
|
|
|
@ -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);
|
||||
|
||||
/* Default border color */
|
||||
--border: 215 27.9% 16.9%;
|
||||
--border: 240 3.7% 15.9%;
|
||||
|
||||
/* Border color for inputs such as <Input />, <Select />, <Textarea /> */
|
||||
--input: 0deg 0% 100% / 10%;
|
||||
|
@ -90,6 +90,7 @@
|
|||
|
||||
:root.dark[data-theme='violet'] {
|
||||
--background: 224 71.4% 4.1%;
|
||||
--background-content: var(--background);
|
||||
--foreground: 210 20% 98%;
|
||||
--card: 224 71.4% 4.1%;
|
||||
--card-foreground: 210 20% 98%;
|
||||
|
@ -111,6 +112,7 @@
|
|||
|
||||
:root.dark[data-theme='pink'] {
|
||||
--background: 20 14.3% 4.1%;
|
||||
--background-content: var(--background);
|
||||
--foreground: 0 0% 95%;
|
||||
--card: 24 9.8% 10%;
|
||||
--card-foreground: 0 0% 95%;
|
||||
|
@ -132,6 +134,7 @@
|
|||
|
||||
:root.dark[data-theme='rose'] {
|
||||
--background: 0 0% 3.9%;
|
||||
--background-content: var(--background);
|
||||
--foreground: 0 0% 98%;
|
||||
--card: 0 0% 3.9%;
|
||||
--card-foreground: 0 0% 98%;
|
||||
|
@ -153,6 +156,7 @@
|
|||
|
||||
:root.dark[data-theme='sky-blue'] {
|
||||
--background: 222.2 84% 4.9%;
|
||||
--background-content: var(--background);
|
||||
--foreground: 210 40% 98%;
|
||||
--card: 222.2 84% 4.9%;
|
||||
--card-foreground: 210 40% 98%;
|
||||
|
@ -174,6 +178,7 @@
|
|||
|
||||
:root.dark[data-theme='deep-blue'] {
|
||||
--background: 222.2 84% 4.9%;
|
||||
--background-content: var(--background);
|
||||
--foreground: 210 40% 98%;
|
||||
--card: 222.2 84% 4.9%;
|
||||
--card-foreground: 210 40% 98%;
|
||||
|
@ -195,6 +200,7 @@
|
|||
|
||||
:root.dark[data-theme='green'] {
|
||||
--background: 20 14.3% 4.1%;
|
||||
--background-content: var(--background);
|
||||
--foreground: 0 0% 95%;
|
||||
--card: 24 9.8% 10%;
|
||||
--card-foreground: 0 0% 95%;
|
||||
|
@ -216,6 +222,7 @@
|
|||
|
||||
:root.dark[data-theme='deep-green'] {
|
||||
--background: 20 14.3% 4.1%;
|
||||
--background-content: var(--background);
|
||||
--foreground: 0 0% 95%;
|
||||
--card: 24 9.8% 10%;
|
||||
--card-foreground: 0 0% 95%;
|
||||
|
@ -237,6 +244,7 @@
|
|||
|
||||
:root.dark[data-theme='orange'] {
|
||||
--background: 20 14.3% 4.1%;
|
||||
--background-content: var(--background);
|
||||
--foreground: 60 9.1% 97.8%;
|
||||
--card: 20 14.3% 4.1%;
|
||||
--card-foreground: 60 9.1% 97.8%;
|
||||
|
@ -258,6 +266,7 @@
|
|||
|
||||
:root.dark[data-theme='yellow'] {
|
||||
--background: 20 14.3% 4.1%;
|
||||
--background-content: var(--background);
|
||||
--foreground: 60 9.1% 97.8%;
|
||||
--card: 20 14.3% 4.1%;
|
||||
--card-foreground: 60 9.1% 97.8%;
|
||||
|
@ -279,6 +288,7 @@
|
|||
|
||||
:root.dark[data-theme='zinc'] {
|
||||
--background: 240 10% 3.9%;
|
||||
--background-content: var(--background);
|
||||
--foreground: 0 0% 98%;
|
||||
--card: 240 10% 3.9%;
|
||||
--card-foreground: 0 0% 98%;
|
||||
|
@ -300,6 +310,7 @@
|
|||
|
||||
:root.dark[data-theme='neutral'] {
|
||||
--background: 0 0% 3.9%;
|
||||
--background-content: var(--background);
|
||||
--foreground: 0 0% 98%;
|
||||
--card: 0 0% 3.9%;
|
||||
--card-foreground: 0 0% 98%;
|
||||
|
@ -321,6 +332,7 @@
|
|||
|
||||
:root.dark[data-theme='slate'] {
|
||||
--background: 222.2 84% 4.9%;
|
||||
--background-content: var(--background);
|
||||
--foreground: 210 40% 98%;
|
||||
--card: 222.2 84% 4.9%;
|
||||
--card-foreground: 210 40% 98%;
|
||||
|
@ -342,6 +354,7 @@
|
|||
|
||||
:root.dark[data-theme='gray'] {
|
||||
--background: 224 71.4% 4.1%;
|
||||
--background-content: var(--background);
|
||||
--foreground: 210 20% 98%;
|
||||
--card: 224 71.4% 4.1%;
|
||||
--card-foreground: 210 20% 98%;
|
||||
|
|
|
@ -86,20 +86,20 @@
|
|||
--authentication: 231deg 61% 44%;
|
||||
|
||||
/* 用于浅色主题下一些暗色主题的颜色 */
|
||||
--dark-foreground: 220 13% 91%;
|
||||
--dark-border: 0deg 0% 100% / 10%;
|
||||
--dark-accent: 0deg 0% 100% / 8%;
|
||||
--dark-accent-hover: 0deg 0% 100% / 12%;
|
||||
--accent-dark-hover: 0deg 0% 100% / 12%;
|
||||
--foreground-dark: 220 13% 91%;
|
||||
--accent-dark: 0deg 0% 100% / 8%;
|
||||
--border-dark: 240 3.7% 15.9%;
|
||||
|
||||
/* =============component & UI============= */
|
||||
|
||||
/* menu */
|
||||
--menu: 0deg 0% 100%;
|
||||
--menu-deep: 0deg 0% 95%;
|
||||
--menu-deep: 210 11.11% 96.47%;
|
||||
|
||||
/* menu-dark */
|
||||
--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);
|
||||
color-scheme: light;
|
||||
|
@ -124,6 +124,12 @@
|
|||
--border: 220 13% 91%;
|
||||
--input: 220 13% 91%;
|
||||
--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'] {
|
||||
|
@ -145,6 +151,12 @@
|
|||
--border: 240 5.9% 90%;
|
||||
--input: 240 5.9% 90%;
|
||||
--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'] {
|
||||
|
@ -166,6 +178,12 @@
|
|||
--border: 240 5.9% 90%;
|
||||
--input: 240 5.9% 90%;
|
||||
--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'] {
|
||||
|
@ -187,6 +205,12 @@
|
|||
--border: 214.3 31.8% 91.4%;
|
||||
--input: 214.3 31.8% 91.4%;
|
||||
--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'] {
|
||||
|
@ -208,6 +232,12 @@
|
|||
--border: 214.3 31.8% 91.4%;
|
||||
--input: 214.3 31.8% 91.4%;
|
||||
--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'] {
|
||||
|
@ -229,6 +259,12 @@
|
|||
--border: 240 5.9% 90%;
|
||||
--input: 240 5.9% 90%;
|
||||
--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'] {
|
||||
|
@ -250,6 +286,12 @@
|
|||
--border: 240 5.9% 90%;
|
||||
--input: 240 5.9% 90%;
|
||||
--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'] {
|
||||
|
@ -271,6 +313,12 @@
|
|||
--border: 20 5.9% 90%;
|
||||
--input: 20 5.9% 90%;
|
||||
--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'] {
|
||||
|
@ -292,6 +340,12 @@
|
|||
--border: 20 5.9% 90%;
|
||||
--input: 20 5.9% 90%;
|
||||
--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'] {
|
||||
|
@ -313,6 +367,12 @@
|
|||
--border: 240 5.9% 90%;
|
||||
--input: 240 5.9% 90%;
|
||||
--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'] {
|
||||
|
@ -334,6 +394,12 @@
|
|||
--border: 0 0% 89.8%;
|
||||
--input: 0 0% 89.8%;
|
||||
--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'] {
|
||||
|
@ -355,6 +421,12 @@
|
|||
--border: 214.3 31.8% 91.4%;
|
||||
--input: 214.3 31.8% 91.4%;
|
||||
--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'] {
|
||||
|
@ -376,4 +448,10 @@
|
|||
--border: 220 13% 91%;
|
||||
--input: 220 13% 91%;
|
||||
--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": {
|
||||
"@vben-core/hooks": "workspace:*",
|
||||
"@vben-core/icons": "workspace:*",
|
||||
"@vben-core/shadcn-ui": "workspace:*",
|
||||
"@vben-core/toolkit": "workspace:*",
|
||||
|
|
|
@ -2,11 +2,9 @@
|
|||
import type { ContentCompactType } from '@vben-core/typings';
|
||||
|
||||
import type { CSSProperties } from 'vue';
|
||||
import { computed, onMounted, ref, watch } from 'vue';
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { getElementVisibleHeight } from '@vben-core/toolkit';
|
||||
|
||||
import { useCssVar, useDebounceFn, useWindowSize } from '@vueuse/core';
|
||||
import { useContentHeightListener } from '@vben-core/hooks';
|
||||
|
||||
interface Props {
|
||||
/**
|
||||
|
@ -56,13 +54,7 @@ const props = withDefaults(defineProps<Props>(), {
|
|||
paddingTop: 16,
|
||||
});
|
||||
|
||||
const contentElement = ref<HTMLDivElement | null>();
|
||||
|
||||
const { height, width } = useWindowSize();
|
||||
const contentClientHeight = useCssVar('--vben-content-client-height');
|
||||
const debouncedCalcHeight = useDebounceFn(() => {
|
||||
contentClientHeight.value = `${getElementVisibleHeight(contentElement.value)}px`;
|
||||
}, 200);
|
||||
const { contentElement } = useContentHeightListener();
|
||||
|
||||
const style = computed((): CSSProperties => {
|
||||
const {
|
||||
|
@ -88,14 +80,6 @@ const style = computed((): CSSProperties => {
|
|||
paddingTop: `${paddingTop}px`,
|
||||
};
|
||||
});
|
||||
|
||||
watch([height, width], () => {
|
||||
debouncedCalcHeight();
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
debouncedCalcHeight();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
|
@ -7,10 +7,6 @@ import { VbenScrollbar } from '@vben-core/shadcn-ui';
|
|||
import { SidebarCollapseButton, SidebarFixedButton } from './widgets';
|
||||
|
||||
interface Props {
|
||||
/**
|
||||
* 背景颜色
|
||||
*/
|
||||
backgroundColor: string;
|
||||
/**
|
||||
* 折叠区域高度
|
||||
* @default 32
|
||||
|
@ -26,10 +22,6 @@ interface Props {
|
|||
* @default true
|
||||
*/
|
||||
domVisible?: boolean;
|
||||
/**
|
||||
* 扩展区域背景颜色
|
||||
*/
|
||||
extraBackgroundColor: string;
|
||||
/**
|
||||
* 扩展区域宽度
|
||||
* @default 180
|
||||
|
@ -113,15 +105,15 @@ const slots = useSlots();
|
|||
|
||||
const asideRef = shallowRef<HTMLDivElement | null>();
|
||||
|
||||
const hiddenSideStyle = computed((): CSSProperties => {
|
||||
return calcMenuWidthStyle(true);
|
||||
});
|
||||
const hiddenSideStyle = computed((): CSSProperties => calcMenuWidthStyle(true));
|
||||
|
||||
const isDark = computed(() => props.theme === 'dark');
|
||||
|
||||
const style = computed((): CSSProperties => {
|
||||
const { isSidebarMixed, paddingTop, theme, zIndex } = props;
|
||||
const { isSidebarMixed, paddingTop, zIndex } = props;
|
||||
|
||||
return {
|
||||
'--scroll-shadow': theme === 'dark' ? 'var(--menu-dark)' : 'var(--menu)',
|
||||
'--scroll-shadow': isDark.value ? 'var(--menu-dark)' : 'var(--menu)',
|
||||
...calcMenuWidthStyle(false),
|
||||
paddingTop: `${paddingTop}px`,
|
||||
zIndex,
|
||||
|
@ -130,9 +122,14 @@ const style = 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 {
|
||||
backgroundColor: extraBackgroundColor,
|
||||
backgroundColor,
|
||||
left: `${width}px`,
|
||||
width: extraVisible.value && show ? `${extraWidth}px` : 0,
|
||||
zIndex,
|
||||
|
@ -196,14 +193,7 @@ watchEffect(() => {
|
|||
});
|
||||
|
||||
function calcMenuWidthStyle(isHiddenDom: boolean): CSSProperties {
|
||||
const {
|
||||
backgroundColor,
|
||||
extraWidth,
|
||||
fixedExtra,
|
||||
isSidebarMixed,
|
||||
show,
|
||||
width,
|
||||
} = props;
|
||||
const { extraWidth, fixedExtra, isSidebarMixed, show, width } = props;
|
||||
|
||||
let widthValue = `${width + (isSidebarMixed && fixedExtra && extraVisible.value ? extraWidth : 0)}px`;
|
||||
|
||||
|
@ -213,6 +203,18 @@ function calcMenuWidthStyle(isHiddenDom: boolean): CSSProperties {
|
|||
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 {
|
||||
...(widthValue === '0px' ? { overflow: 'hidden' } : {}),
|
||||
backgroundColor,
|
||||
|
@ -254,8 +256,9 @@ function handleMouseleave() {
|
|||
class="h-full transition-all duration-200"
|
||||
></div>
|
||||
<aside
|
||||
:data-theme="theme"
|
||||
: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"
|
||||
@mouseleave="handleMouseleave"
|
||||
>
|
||||
|
@ -280,8 +283,9 @@ function handleMouseleave() {
|
|||
<div
|
||||
v-if="isSidebarMixed"
|
||||
ref="asideRef"
|
||||
:data-theme="theme"
|
||||
: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
|
||||
v-if="isSidebarMixed && expandOnHover"
|
||||
|
@ -294,10 +298,15 @@ function handleMouseleave() {
|
|||
v-model:expand-on-hover="expandOnHover"
|
||||
:theme="theme"
|
||||
/>
|
||||
<div v-if="!extraCollapse" :style="extraTitleStyle">
|
||||
<div v-if="!extraCollapse" :style="extraTitleStyle" class="pl-2">
|
||||
<slot name="extra-title"></slot>
|
||||
</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>
|
||||
</VbenScrollbar>
|
||||
</div>
|
||||
|
|
|
@ -5,7 +5,7 @@ interface Props {
|
|||
theme: string;
|
||||
}
|
||||
|
||||
withDefaults(defineProps<Props>(), {});
|
||||
defineProps<Props>();
|
||||
|
||||
const collapsed = defineModel<boolean>('collapsed');
|
||||
|
||||
|
@ -17,7 +17,7 @@ function handleCollapsed() {
|
|||
<template>
|
||||
<div
|
||||
: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"
|
||||
>
|
||||
<MdiMenuClose v-if="collapsed" />
|
||||
|
|
|
@ -5,7 +5,7 @@ interface Props {
|
|||
theme: string;
|
||||
}
|
||||
|
||||
withDefaults(defineProps<Props>(), {});
|
||||
defineProps<Props>();
|
||||
|
||||
const expandOnHover = defineModel<boolean>('expandOnHover');
|
||||
|
||||
|
@ -17,7 +17,7 @@ function toggleFixed() {
|
|||
<template>
|
||||
<div
|
||||
: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"
|
||||
>
|
||||
<MdiPinOff v-if="!expandOnHover" />
|
||||
|
|
|
@ -41,11 +41,6 @@ interface VbenLayoutProps {
|
|||
* @default 16
|
||||
*/
|
||||
contentPaddingTop?: number;
|
||||
/**
|
||||
* footer背景颜色
|
||||
* @default #fff
|
||||
*/
|
||||
footerBackgroundColor?: string;
|
||||
/**
|
||||
* footer 是否可见
|
||||
* @default false
|
||||
|
@ -61,11 +56,7 @@ interface VbenLayoutProps {
|
|||
* @default 32
|
||||
*/
|
||||
footerHeight?: number;
|
||||
/**
|
||||
* 背景颜色
|
||||
* @default #fff
|
||||
*/
|
||||
headerBackgroundColor?: string;
|
||||
|
||||
/**
|
||||
* header高度
|
||||
* @default 48
|
||||
|
@ -157,11 +148,6 @@ interface VbenLayoutProps {
|
|||
* @default 210
|
||||
*/
|
||||
sidebarWidth?: number;
|
||||
/**
|
||||
* footer背景颜色
|
||||
* @default #fff
|
||||
*/
|
||||
tabbarBackgroundColor?: string;
|
||||
/**
|
||||
* tab是否可见
|
||||
* @default true
|
||||
|
|
|
@ -205,25 +205,7 @@ const showSidebar = computed(() => {
|
|||
const sidebarFace = computed(() => {
|
||||
const { sidebarSemiDark, sidebarTheme } = props;
|
||||
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 {
|
||||
backgroundColor,
|
||||
extraBackgroundColor,
|
||||
theme: isDark ? 'dark' : 'light',
|
||||
};
|
||||
});
|
||||
|
@ -476,9 +458,9 @@ function handleOpenMenu() {
|
|||
:mixed-width="sidebarMixedWidth"
|
||||
:padding-top="sidePaddingTop"
|
||||
:show="showSidebar"
|
||||
:theme="sidebarFace.theme"
|
||||
:width="getSidebarWidth"
|
||||
:z-index="sidebarZIndex"
|
||||
v-bind="sidebarFace"
|
||||
@leave="() => emit('sideMouseLeave')"
|
||||
>
|
||||
<template v-if="isSideMode && !isMixedNav" #logo>
|
||||
|
|
|
@ -423,9 +423,9 @@ $namespace: vben;
|
|||
--menu-title-width: 140px;
|
||||
--menu-item-icon-width: 20px;
|
||||
--menu-item-height: 38px;
|
||||
--menu-item-padding-y: 26px;
|
||||
--menu-item-padding-y: 22px;
|
||||
--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-margin-y: 4px;
|
||||
--menu-item-margin-x: 0px;
|
||||
|
@ -443,14 +443,14 @@ $namespace: vben;
|
|||
--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-color: hsl(var(--foreground-dark) / 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-item-active-color: hsl(var(--foreground-dark));
|
||||
--menu-item-active-background-color: hsl(var(--menu-dark-background));
|
||||
--menu-submenu-hover-color: hsl(var(--foreground-dark));
|
||||
--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-background-color: var(--menu-background-color);
|
||||
}
|
||||
|
@ -462,8 +462,8 @@ $namespace: vben;
|
|||
--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-item-active-color: hsl(var(--primary));
|
||||
--menu-item-active-background-color: hsl(var(--primary) / 15%);
|
||||
--menu-submenu-hover-color: hsl(var(--primary));
|
||||
--menu-submenu-hover-background-color: hsl(var(--menu-light-background));
|
||||
--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-hover-background-color: hsl(var(--menu-light-background));
|
||||
--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-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}-menu-item {
|
||||
&.is-active {
|
||||
color: hsl(var(--primary-foreground)) !important;
|
||||
// color: hsl(var(--primary-foreground)) !important;
|
||||
background: var(--menu-item-active-background-color) !important;
|
||||
}
|
||||
}
|
||||
|
@ -788,6 +788,7 @@ $namespace: vben;
|
|||
&.is-active {
|
||||
div[data-state='open'] > .#{$namespace}-sub-menu-content,
|
||||
> .#{$namespace}-sub-menu-content {
|
||||
font-weight: 500;
|
||||
color: var(--menu-submenu-active-color);
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
|
@ -806,7 +807,7 @@ $namespace: vben;
|
|||
&__icon-arrow {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 6px;
|
||||
right: 10px;
|
||||
width: inherit;
|
||||
margin-top: -8px;
|
||||
margin-right: 0;
|
||||
|
|
|
@ -63,7 +63,7 @@ $namespace: vben;
|
|||
.#{$namespace}-normal-menu {
|
||||
--menu-item-margin-y: 4px;
|
||||
--menu-item-margin-x: 0px;
|
||||
--menu-item-padding-y: 11px;
|
||||
--menu-item-padding-y: 8px;
|
||||
--menu-item-padding-x: 0px;
|
||||
--menu-item-radius: 0px;
|
||||
--menu-dark-background: 0deg 0% 100% / 10%;
|
||||
|
@ -77,12 +77,21 @@ $namespace: vben;
|
|||
|
||||
&.is-dark {
|
||||
.#{$namespace}-normal-menu__item {
|
||||
color: hsl(var(--dark-foreground) / 80%);
|
||||
color: hsl(var(--foreground-dark) / 80%);
|
||||
|
||||
&:not(.is-active):hover {
|
||||
color: hsl(var(--primary-foreground));
|
||||
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);
|
||||
transition:
|
||||
background 0.15s ease,
|
||||
// color 0.15s ease,
|
||||
padding 0.15s ease,
|
||||
border-color 0.15s ease;
|
||||
|
||||
&.is-active {
|
||||
font-weight: 700;
|
||||
color: hsl(var(--primary-foreground));
|
||||
background-color: hsl(var(--primary));
|
||||
|
||||
.#{$namespace}-normal-menu__name {
|
||||
color: hsl(var(--primary-foreground));
|
||||
}
|
||||
@apply text-primary bg-primary/20;
|
||||
|
||||
.#{$namespace}-normal-menu__name,
|
||||
.#{$namespace}-normal-menu__icon {
|
||||
color: hsl(var(--primary-foreground));
|
||||
@apply text-primary font-semibold;
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.is-active):hover {
|
||||
color: hsl(var(--foreground));
|
||||
@apply text-foreground;
|
||||
|
||||
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
|
||||
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 }}
|
||||
<!-- <span class="text-primary ml-1 align-super text-[smaller]">Pro</span> -->
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
|
|
|
@ -43,7 +43,7 @@ const badgeStyle = computed(() => {
|
|||
});
|
||||
</script>
|
||||
<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" />
|
||||
<div
|
||||
v-else
|
||||
|
|
|
@ -6,7 +6,7 @@ import type { TabConfig, TabsProps } from '../../types';
|
|||
import { computed, nextTick, onMounted, ref, watch } from 'vue';
|
||||
|
||||
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 {}
|
||||
|
||||
|
@ -21,7 +21,7 @@ const props = withDefaults(defineProps<Props>(), {
|
|||
contextMenus: () => [],
|
||||
gap: 7,
|
||||
maxWidth: 150,
|
||||
minWidth: 40,
|
||||
minWidth: 80,
|
||||
tabs: () => [],
|
||||
});
|
||||
|
||||
|
@ -40,20 +40,20 @@ const style = computed(() => {
|
|||
});
|
||||
|
||||
const layout = () => {
|
||||
const { gap, maxWidth, minWidth, tabs } = props;
|
||||
const { maxWidth, minWidth } = props;
|
||||
if (!contentRef.value) {
|
||||
return Math.max(maxWidth, minWidth);
|
||||
}
|
||||
const contentWidth = contentRef.value.clientWidth - gap * 3;
|
||||
let width = contentWidth / tabs.length;
|
||||
width += gap * 2;
|
||||
if (width > maxWidth) {
|
||||
width = maxWidth;
|
||||
}
|
||||
if (width < minWidth) {
|
||||
width = minWidth;
|
||||
}
|
||||
tabWidth.value = width;
|
||||
// const contentWidth = contentRef.value.clientWidth - gap * 3;
|
||||
// let width = contentWidth / tabs.length;
|
||||
// width += gap * 2;
|
||||
// if (width > maxWidth) {
|
||||
// width = maxWidth;
|
||||
// }
|
||||
// if (width < minWidth) {
|
||||
// width = minWidth;
|
||||
// }
|
||||
tabWidth.value = maxWidth;
|
||||
};
|
||||
|
||||
const tabsView = computed((): TabConfig[] => {
|
||||
|
@ -95,121 +95,115 @@ function handleUnpinTab(tab: TabConfig) {
|
|||
|
||||
<template>
|
||||
<div :style="style" class="tabs-chrome size-full flex-1 overflow-hidden pt-1">
|
||||
<!-- footer -> 4px -->
|
||||
<div
|
||||
ref="contentRef"
|
||||
:class="contentClass"
|
||||
class="relative h-full overflow-hidden"
|
||||
>
|
||||
<TransitionGroup name="slide-down">
|
||||
<div
|
||||
v-for="(tab, i) in tabsView"
|
||||
:key="tab.key"
|
||||
ref="tabRef"
|
||||
:class="[
|
||||
{ 'is-active': tab.key === active, dragable: !tab.affixTab },
|
||||
]"
|
||||
:data-index="i"
|
||||
:style="{
|
||||
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"
|
||||
>
|
||||
<VbenContextMenu
|
||||
:handler-data="tab"
|
||||
:menus="contextMenus"
|
||||
:modal="false"
|
||||
item-class="pr-6"
|
||||
<VbenScrollbar class="h-full" horizontal>
|
||||
<!-- footer -> 4px -->
|
||||
<div
|
||||
ref="contentRef"
|
||||
:class="contentClass"
|
||||
class="relative !flex h-full w-max"
|
||||
>
|
||||
<TransitionGroup name="slide-down">
|
||||
<div
|
||||
v-for="(tab, i) in tabsView"
|
||||
:key="tab.key"
|
||||
ref="tabRef"
|
||||
:class="[
|
||||
{ 'is-active': tab.key === active, dragable: !tab.affixTab },
|
||||
]"
|
||||
:data-index="i"
|
||||
:style="{
|
||||
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"
|
||||
>
|
||||
<div class="size-full">
|
||||
<!-- divider -->
|
||||
<div
|
||||
v-if="i !== 0"
|
||||
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>
|
||||
<!-- background -->
|
||||
<div
|
||||
class="tabs-chrome__background absolute z-[1] size-full px-[calc(var(--gap)-1px)] py-0 transition-opacity duration-150"
|
||||
>
|
||||
<VbenContextMenu
|
||||
:handler-data="tab"
|
||||
:menus="contextMenus"
|
||||
:modal="false"
|
||||
item-class="pr-6"
|
||||
>
|
||||
<div class="size-full">
|
||||
<!-- divider -->
|
||||
<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>
|
||||
<svg
|
||||
class="tabs-chrome__background-before absolute bottom-[-1px] left-[-1px] fill-transparent transition-all duration-150"
|
||||
height="7"
|
||||
width="7"
|
||||
<!-- background -->
|
||||
<div
|
||||
class="tabs-chrome__background absolute z-[1] size-full px-[calc(var(--gap)-1px)] py-0 transition-opacity duration-150"
|
||||
>
|
||||
<path d="M 0 7 A 7 7 0 0 0 7 0 L 7 7 Z" />
|
||||
</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>
|
||||
<div
|
||||
class="tabs-chrome__background-content h-full rounded-tl-[var(--gap)] rounded-tr-[var(--gap)] duration-150"
|
||||
></div>
|
||||
<svg
|
||||
class="tabs-chrome__background-before absolute bottom-[-1px] left-[-1px] fill-transparent transition-all duration-150"
|
||||
height="7"
|
||||
width="7"
|
||||
>
|
||||
<path d="M 0 7 A 7 7 0 0 0 7 0 L 7 7 Z" />
|
||||
</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 -->
|
||||
<div
|
||||
class="tabs-chrome__extra absolute right-[calc(var(--gap)*2)] top-1/2 z-[3] size-4 translate-y-[-50%]"
|
||||
>
|
||||
<!-- <div
|
||||
<!-- extra -->
|
||||
<div
|
||||
class="tabs-chrome__extra absolute right-[calc(var(--gap)*1.5)] top-1/2 z-[3] size-4 translate-y-[-50%]"
|
||||
>
|
||||
<!-- <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"
|
||||
> -->
|
||||
<!-- close-icon -->
|
||||
<IcRoundClose
|
||||
v-show="!tab.affixTab && tabsView.length > 1 && tab.closable"
|
||||
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"
|
||||
@click.stop="handleClose(tab.key)"
|
||||
/>
|
||||
<MdiPin
|
||||
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"
|
||||
@click.stop="handleUnpinTab(tab)"
|
||||
/>
|
||||
</div>
|
||||
<!-- close-icon -->
|
||||
<IcRoundClose
|
||||
v-show="
|
||||
!tab.affixTab && tabsView.length > 1 && tab.closable
|
||||
"
|
||||
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"
|
||||
@click.stop="handleClose(tab.key)"
|
||||
/>
|
||||
<MdiPin
|
||||
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"
|
||||
@click.stop="handleUnpinTab(tab)"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- tab-item-main -->
|
||||
<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"
|
||||
>
|
||||
<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-item-main -->
|
||||
<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"
|
||||
>
|
||||
{{ tab.title }}
|
||||
</span>
|
||||
<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 }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</VbenContextMenu>
|
||||
</div>
|
||||
</TransitionGroup>
|
||||
</div>
|
||||
<!-- footer -->
|
||||
<div class="bg-background h-1"></div>
|
||||
</VbenContextMenu>
|
||||
</div>
|
||||
</TransitionGroup>
|
||||
</div>
|
||||
<!-- footer -->
|
||||
<div class="bg-background h-1"></div>
|
||||
</VbenScrollbar>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
/* html.dark {
|
||||
.tabs-chrome {
|
||||
.is-active {
|
||||
.tabs-chrome__item-main {
|
||||
@apply text-accent-foreground;
|
||||
}
|
||||
}
|
||||
}
|
||||
} */
|
||||
|
||||
.tabs-chrome {
|
||||
.dragging {
|
||||
.tabs-chrome__item-main {
|
||||
|
@ -222,7 +216,7 @@ function handleUnpinTab(tab: TabConfig) {
|
|||
}
|
||||
|
||||
&__item {
|
||||
&:hover {
|
||||
&:hover:not(.is-active) {
|
||||
& + .tabs-chrome__item {
|
||||
.tabs-chrome__divider {
|
||||
@apply opacity-0;
|
||||
|
@ -235,12 +229,12 @@ function handleUnpinTab(tab: TabConfig) {
|
|||
|
||||
.tabs-chrome__background {
|
||||
&-content {
|
||||
@apply bg-heavy;
|
||||
@apply bg-primary/10 mx-1 rounded-md pb-2;
|
||||
}
|
||||
|
||||
&-before,
|
||||
&-after {
|
||||
@apply fill-heavy;
|
||||
@apply fill-primary/0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -248,16 +242,22 @@ function handleUnpinTab(tab: TabConfig) {
|
|||
&.is-active {
|
||||
@apply z-[2];
|
||||
|
||||
& + .tabs-chrome__item {
|
||||
.tabs-chrome__divider {
|
||||
@apply opacity-0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.tabs-chrome__background {
|
||||
@apply opacity-100;
|
||||
|
||||
&-content {
|
||||
@apply bg-background-content;
|
||||
@apply bg-primary/15;
|
||||
}
|
||||
|
||||
&-before,
|
||||
&-after {
|
||||
@apply fill-background-content;
|
||||
@apply fill-primary/15;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,14 +26,14 @@ const active = defineModel<string>('active');
|
|||
const typeWithClass = computed(() => {
|
||||
const typeClasses: Record<string, { content: string }> = {
|
||||
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: {
|
||||
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: {
|
||||
content: 'h-full',
|
||||
content: 'h-full border-l border-border',
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -77,7 +77,7 @@ function handleUnpinTab(tab: TabConfig) {
|
|||
:key="tab.key"
|
||||
:class="[
|
||||
{
|
||||
'tabs-item is-active bg-background-content': tab.key === active,
|
||||
'is-active bg-primary/15': tab.key === active,
|
||||
dragable: !tab.affixTab,
|
||||
},
|
||||
typeWithClass.content,
|
||||
|
@ -110,14 +110,14 @@ function handleUnpinTab(tab: TabConfig) {
|
|||
/>
|
||||
<MdiPin
|
||||
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)"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- tab-item-main -->
|
||||
<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
|
||||
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>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
/* html.dark {
|
||||
.tabs-item {
|
||||
&.is-active {
|
||||
.tabs-item__main {
|
||||
@apply text-accent-foreground;
|
||||
}
|
||||
}
|
||||
}
|
||||
} */
|
||||
</style>
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@vben-core/helpers": "workspace:*",
|
||||
"@vben-core/hooks": "workspace:*",
|
||||
"@vben-core/icons": "workspace:*",
|
||||
"@vben-core/layout-ui": "workspace:*",
|
||||
"@vben-core/locales": "workspace:*",
|
||||
|
|
|
@ -8,14 +8,17 @@ defineOptions({
|
|||
name: 'AuthenticationFormView',
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="flex-col-center bg-background-content relative px-6 py-10 lg:flex-initial lg:px-8"
|
||||
>
|
||||
<!-- Toolbar Slot -->
|
||||
<slot name="toolbar">
|
||||
<Toolbar />
|
||||
</slot>
|
||||
|
||||
<!-- Router View with Transition and KeepAlive -->
|
||||
<RouterView v-slot="{ Component, route }">
|
||||
<Transition appear mode="out-in" name="slide-right">
|
||||
<KeepAlive :include="['Login']">
|
||||
|
@ -28,6 +31,7 @@ defineOptions({
|
|||
</Transition>
|
||||
</RouterView>
|
||||
|
||||
<!-- Footer Copyright -->
|
||||
<div
|
||||
class="text-muted-foreground absolute bottom-3 flex text-center text-xs"
|
||||
>
|
||||
|
|
|
@ -10,14 +10,17 @@ defineOptions({
|
|||
name: 'AuthenticationToolbar',
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
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">
|
||||
<AuthenticationColorToggle />
|
||||
<AuthenticationLayoutToggle />
|
||||
</div>
|
||||
<!-- Always show Language and Theme toggles -->
|
||||
<LanguageToggle />
|
||||
<ThemeToggle />
|
||||
</div>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<script lang="ts" setup>
|
||||
import type { RouteLocationNormalizedLoaded } from 'vue-router';
|
||||
|
||||
import { useContentHeight } from '@vben-core/hooks';
|
||||
import { preferences, usePreferences } from '@vben-core/preferences';
|
||||
import { Spinner } from '@vben-core/shadcn-ui';
|
||||
import { storeToRefs, useCoreTabbarStore } from '@vben-core/stores';
|
||||
|
@ -13,6 +14,7 @@ defineOptions({ name: 'LayoutContent' });
|
|||
const tabbarStore = useCoreTabbarStore();
|
||||
const { keepAlive } = usePreferences();
|
||||
const { spinning } = useContentSpinner();
|
||||
const { contentStyles } = useContentHeight();
|
||||
|
||||
const { getCachedTabs, getExcludeCachedTabs, renderRouteView } =
|
||||
storeToRefs(tabbarStore);
|
||||
|
@ -47,7 +49,7 @@ function getTransitionName(route: RouteLocationNormalizedLoaded) {
|
|||
<Spinner
|
||||
v-if="preferences.transition.loading"
|
||||
:spinning="spinning"
|
||||
class="h-[var(--vben-content-client-height)]"
|
||||
:style="contentStyles"
|
||||
/>
|
||||
<IFrameRouterView />
|
||||
<RouterView v-slot="{ Component, route }">
|
||||
|
|
|
@ -7,9 +7,10 @@ function useContentSpinner() {
|
|||
const spinning = ref(false);
|
||||
const startTime = ref(0);
|
||||
const router = useRouter();
|
||||
const minShowTime = 500;
|
||||
const minShowTime = 500; // 最小显示时间
|
||||
const enableLoading = computed(() => preferences.transition.loading);
|
||||
|
||||
// 结束加载动画
|
||||
const onEnd = () => {
|
||||
if (!enableLoading.value) {
|
||||
return;
|
||||
|
@ -24,6 +25,7 @@ function useContentSpinner() {
|
|||
}
|
||||
};
|
||||
|
||||
// 路由前置守卫
|
||||
router.beforeEach((to) => {
|
||||
if (to.meta.loaded || !enableLoading.value || to.meta.iframeSrc) {
|
||||
return true;
|
||||
|
@ -33,14 +35,12 @@ function useContentSpinner() {
|
|||
return true;
|
||||
});
|
||||
|
||||
// 路由后置守卫
|
||||
router.afterEach((to) => {
|
||||
if (to.meta.loaded || !enableLoading.value || to.meta.iframeSrc) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 关闭加载动画
|
||||
onEnd();
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
|
|
|
@ -22,19 +22,23 @@ withDefaults(defineProps<Props>(), {
|
|||
|
||||
<template>
|
||||
<div class="text-md flex-center">
|
||||
<!-- ICP Link -->
|
||||
<a
|
||||
v-if="icp"
|
||||
:href="icpLink || 'javascript:void 0'"
|
||||
:href="icpLink || 'javascript:void(0)'"
|
||||
class="hover:text-primary-hover"
|
||||
target="_blank"
|
||||
>
|
||||
{{ icp }}
|
||||
</a>
|
||||
|
||||
<!-- Copyright Text -->
|
||||
Copyright © {{ date }}
|
||||
|
||||
<!-- Company Link -->
|
||||
<a
|
||||
v-if="companyName"
|
||||
:href="companySiteLink || 'javascript:void 0'"
|
||||
:href="companySiteLink || 'javascript:void(0)'"
|
||||
class="hover:text-primary-hover mx-1"
|
||||
target="_blank"
|
||||
>
|
||||
|
|
|
@ -634,6 +634,31 @@ importers:
|
|||
specifier: ^4.4.0
|
||||
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:
|
||||
dependencies:
|
||||
'@intlify/core-base':
|
||||
|
@ -657,19 +682,6 @@ importers:
|
|||
specifier: ^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:
|
||||
dependencies:
|
||||
'@iconify/vue':
|
||||
|
@ -724,6 +736,9 @@ importers:
|
|||
|
||||
packages/@core/ui-kit/layout-ui:
|
||||
dependencies:
|
||||
'@vben-core/hooks':
|
||||
specifier: workspace:*
|
||||
version: link:../../hooks
|
||||
'@vben-core/icons':
|
||||
specifier: workspace:*
|
||||
version: link:../../shared/icons
|
||||
|
@ -747,7 +762,7 @@ importers:
|
|||
dependencies:
|
||||
'@vben-core/hooks':
|
||||
specifier: workspace:*
|
||||
version: link:../../shared/hooks
|
||||
version: link:../../hooks
|
||||
'@vben-core/icons':
|
||||
specifier: workspace:*
|
||||
version: link:../../shared/icons
|
||||
|
@ -801,7 +816,7 @@ importers:
|
|||
dependencies:
|
||||
'@vben-core/hooks':
|
||||
specifier: workspace:*
|
||||
version: link:../../shared/hooks
|
||||
version: link:../../hooks
|
||||
'@vben-core/icons':
|
||||
specifier: workspace:*
|
||||
version: link:../../shared/icons
|
||||
|
@ -861,7 +876,7 @@ importers:
|
|||
dependencies:
|
||||
'@vben-core/hooks':
|
||||
specifier: workspace:*
|
||||
version: link:../../@core/shared/hooks
|
||||
version: link:../../@core/hooks
|
||||
'@vben-core/icons':
|
||||
specifier: workspace:*
|
||||
version: link:../../@core/shared/icons
|
||||
|
@ -899,6 +914,9 @@ importers:
|
|||
'@vben-core/helpers':
|
||||
specifier: workspace:*
|
||||
version: link:../../@core/forward/helpers
|
||||
'@vben-core/hooks':
|
||||
specifier: workspace:*
|
||||
version: link:../../@core/hooks
|
||||
'@vben-core/icons':
|
||||
specifier: workspace:*
|
||||
version: link:../../@core/shared/icons
|
||||
|
@ -943,7 +961,7 @@ importers:
|
|||
dependencies:
|
||||
'@vben-core/hooks':
|
||||
specifier: workspace:*
|
||||
version: link:../@core/shared/hooks
|
||||
version: link:../@core/hooks
|
||||
|
||||
packages/icons:
|
||||
dependencies:
|
||||
|
|
|
@ -7,6 +7,7 @@ packages:
|
|||
- "packages/@core/forward/*"
|
||||
- "packages/@core/helpers"
|
||||
- "packages/@core/locales"
|
||||
- "packages/@core/hooks"
|
||||
- "packages/effects/*"
|
||||
- "apps/*"
|
||||
- "scripts/*"
|
||||
|
|
|
@ -60,6 +60,10 @@
|
|||
"name": "@vben-core/stores",
|
||||
"path": "packages/@core/forward/stores",
|
||||
},
|
||||
{
|
||||
"name": "@vben-core/hooks",
|
||||
"path": "packages/@core/hooks",
|
||||
},
|
||||
{
|
||||
"name": "@vben-core/locales",
|
||||
"path": "packages/@core/locales",
|
||||
|
@ -72,10 +76,6 @@
|
|||
"name": "@vben-core/design",
|
||||
"path": "packages/@core/shared/design",
|
||||
},
|
||||
{
|
||||
"name": "@vben-core/hooks",
|
||||
"path": "packages/@core/shared/hooks",
|
||||
},
|
||||
{
|
||||
"name": "@vben-core/icons",
|
||||
"path": "packages/@core/shared/icons",
|
||||
|
|
Loading…
Reference in New Issue