mirror of
https://github.com/vbenjs/vue-vben-admin.git
synced 2025-08-26 00:26:20 +08:00
Compare commits
21 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
41612f7723 | ||
![]() |
83ecae7c4e | ||
![]() |
3332b20fd0 | ||
![]() |
2d0153a841 | ||
![]() |
95a4a85c3b | ||
![]() |
3f2dcb8281 | ||
![]() |
67f3d63066 | ||
![]() |
277e98c42c | ||
![]() |
1063b2268e | ||
![]() |
8404c12129 | ||
![]() |
a7d322019e | ||
![]() |
f23821ff46 | ||
![]() |
2b0aedbaba | ||
![]() |
071cc0dcec | ||
![]() |
7db7d6ec5f | ||
![]() |
b3e3e05990 | ||
![]() |
cc678a2b51 | ||
![]() |
7d2bcf476f | ||
![]() |
cfbe379ee4 | ||
![]() |
388e5b5cb3 | ||
![]() |
c1dfbc1ebf |
16
.github/labeler.yml
vendored
16
.github/labeler.yml
vendored
@@ -1,16 +0,0 @@
|
||||
# Add 'feature' label to any PR where the head branch name starts with `feature` or has a `feature` section in the name
|
||||
feature:
|
||||
- head-branch: ["^feat", "feat"]
|
||||
|
||||
bug:
|
||||
- head-branch: ["^fix", "fix"]
|
||||
|
||||
chore:
|
||||
- head-branch: ["^chore", "chore"]
|
||||
|
||||
perf:
|
||||
- head-branch: ["^perf", "perf"]
|
||||
|
||||
documentation:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: ["**/*.md", "docs/**"]
|
22
.github/workflows/labeler.yml
vendored
22
.github/workflows/labeler.yml
vendored
@@ -1,22 +0,0 @@
|
||||
name: PR Labeler
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, edited, synchronize]
|
||||
|
||||
jobs:
|
||||
label:
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
runs-on: ubuntu-latest
|
||||
if: github.actor != 'dependabot[bot]' && !contains(github.event.head_commit.message, '[skip ci]')
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Label PR based on title or file changes
|
||||
uses: actions/labeler@v5
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
configuration-path: .github/labeler.yml
|
28
.ls-lint.yml
28
.ls-lint.yml
@@ -1,28 +0,0 @@
|
||||
ls:
|
||||
.js: kebab-case | pointcase
|
||||
.vue: kebab-case | pointcase
|
||||
.ts: kebab-case | pointcase
|
||||
.tsx: kebab-case | pointcase
|
||||
.jsx: kebab-case | pointcase
|
||||
.css: kebab-case | pointcase
|
||||
.d.ts: kebab-case | pointcase
|
||||
# shadcn 自动生成文件为 PascalCase 格式
|
||||
packages/@core/ui-kit/shadcn-ui/src/components/ui:
|
||||
.vue: PascalCase
|
||||
|
||||
ignore:
|
||||
- "**/*.png"
|
||||
- "**/*.jpg"
|
||||
- "**/*.jpeg"
|
||||
- "**/*.jpeg"
|
||||
- "**/*.gif"
|
||||
- "**/_util.ts"
|
||||
- "**/deps/**"
|
||||
- "**/dist/**"
|
||||
- "**/node_modules/**"
|
||||
- "**/.turbo/**"
|
||||
- .git
|
||||
- .vscode
|
||||
- .idea
|
||||
- node_modules
|
||||
- .cache
|
8
.vscode/launch.json
vendored
8
.vscode/launch.json
vendored
@@ -9,7 +9,7 @@
|
||||
"url": "http://localhost:5555",
|
||||
"env": { "NODE_ENV": "development" },
|
||||
"sourceMaps": true,
|
||||
"webRoot": "${workspaceFolder}/playground/src"
|
||||
"webRoot": "${workspaceFolder}"
|
||||
},
|
||||
{
|
||||
"type": "chrome",
|
||||
@@ -18,7 +18,7 @@
|
||||
"url": "http://localhost:5666",
|
||||
"env": { "NODE_ENV": "development" },
|
||||
"sourceMaps": true,
|
||||
"webRoot": "${workspaceFolder}/apps/web-antd/src"
|
||||
"webRoot": "${workspaceFolder}"
|
||||
},
|
||||
{
|
||||
"type": "chrome",
|
||||
@@ -27,7 +27,7 @@
|
||||
"url": "http://localhost:5777",
|
||||
"env": { "NODE_ENV": "development" },
|
||||
"sourceMaps": true,
|
||||
"webRoot": "${workspaceFolder}/apps/web-ele/src"
|
||||
"webRoot": "${workspaceFolder}"
|
||||
},
|
||||
{
|
||||
"type": "chrome",
|
||||
@@ -36,7 +36,7 @@
|
||||
"url": "http://localhost:5888",
|
||||
"env": { "NODE_ENV": "development" },
|
||||
"sourceMaps": true,
|
||||
"webRoot": "${workspaceFolder}/apps/web-naive/src"
|
||||
"webRoot": "${workspaceFolder}"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@@ -213,7 +213,7 @@
|
||||
"README.md": "README*,CHANGELOG*,LICENSE,CNAME",
|
||||
"package.json": "pnpm-lock.yaml,pnpm-workspace.yaml,.gitattributes,.gitignore,.gitpod.yml,.npmrc,.browserslistrc,.node-version,.git*,.tazerc.json",
|
||||
"Dockerfile": "Dockerfile,.docker*,docker-entrypoint.sh,build-local-docker*,nginx.conf",
|
||||
"eslint.config.mjs": ".eslintignore,.prettierignore,.stylelintignore,.commitlintrc.*,.prettierrc.*,stylelint.config.*,.lintstagedrc.mjs,.ls-lint*,cspell.json",
|
||||
"eslint.config.mjs": ".eslintignore,.prettierignore,.stylelintignore,.commitlintrc.*,.prettierrc.*,stylelint.config.*,.lintstagedrc.mjs,cspell.json",
|
||||
"tailwind.config.mjs": "postcss.*"
|
||||
},
|
||||
"commentTranslate.hover.enabled": false,
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/web-antd",
|
||||
"version": "5.2.0",
|
||||
"version": "5.2.2",
|
||||
"homepage": "https://vben.pro",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
@@ -44,7 +44,7 @@
|
||||
"ant-design-vue": "^4.2.3",
|
||||
"dayjs": "^1.11.13",
|
||||
"pinia": "2.2.2",
|
||||
"vue": "^3.4.38",
|
||||
"vue": "^3.5.1",
|
||||
"vue-router": "^4.4.3"
|
||||
}
|
||||
}
|
||||
|
23
apps/web-antd/src/layouts/auth.vue
Normal file
23
apps/web-antd/src/layouts/auth.vue
Normal file
@@ -0,0 +1,23 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { AuthPageLayout } from '@vben/layouts';
|
||||
import { preferences } from '@vben/preferences';
|
||||
|
||||
import { $t } from '#/locales';
|
||||
|
||||
const appName = computed(() => preferences.app.name);
|
||||
const logo = computed(() => preferences.logo.source);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AuthPageLayout
|
||||
:app-name="appName"
|
||||
:logo="logo"
|
||||
:page-description="$t('authentication.pageDesc')"
|
||||
:page-title="$t('authentication.pageTitle')"
|
||||
>
|
||||
<!-- 自定义工具栏 -->
|
||||
<!-- <template #toolbar></template> -->
|
||||
</AuthPageLayout>
|
||||
</template>
|
@@ -1,8 +1,6 @@
|
||||
const BasicLayout = () => import('./basic.vue');
|
||||
const AuthPageLayout = () => import('./auth.vue');
|
||||
|
||||
const IFrameView = () => import('@vben/layouts').then((m) => m.IFrameView);
|
||||
|
||||
const AuthPageLayout = () =>
|
||||
import('@vben/layouts').then((m) => m.AuthPageLayout);
|
||||
|
||||
export { AuthPageLayout, BasicLayout, IFrameView };
|
||||
|
@@ -55,12 +55,27 @@ onMounted(() => {
|
||||
},
|
||||
trigger: 'axis',
|
||||
},
|
||||
// xAxis: {
|
||||
// axisTick: {
|
||||
// show: false,
|
||||
// },
|
||||
// boundaryGap: false,
|
||||
// data: Array.from({ length: 18 }).map((_item, index) => `${index + 6}:00`),
|
||||
// type: 'category',
|
||||
// },
|
||||
xAxis: {
|
||||
axisTick: {
|
||||
show: false,
|
||||
},
|
||||
boundaryGap: false,
|
||||
data: Array.from({ length: 18 }).map((_item, index) => `${index + 6}:00`),
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
type: 'solid',
|
||||
width: 1,
|
||||
},
|
||||
show: true,
|
||||
},
|
||||
type: 'category',
|
||||
},
|
||||
yAxis: [
|
||||
@@ -69,7 +84,10 @@ onMounted(() => {
|
||||
show: false,
|
||||
},
|
||||
max: 80_000,
|
||||
|
||||
splitArea: {
|
||||
show: true,
|
||||
},
|
||||
splitNumber: 4,
|
||||
type: 'value',
|
||||
},
|
||||
],
|
||||
|
@@ -214,7 +214,11 @@ const trendItems: WorkbenchTrendItem[] = [
|
||||
<WorkbenchTrends :items="trendItems" class="mt-5" title="最新动态" />
|
||||
</div>
|
||||
<div class="w-full lg:w-2/5">
|
||||
<WorkbenchQuickNav :items="quickNavItems" title="快捷导航" />
|
||||
<WorkbenchQuickNav
|
||||
:items="quickNavItems"
|
||||
class="mt-5 lg:mt-0"
|
||||
title="快捷导航"
|
||||
/>
|
||||
<WorkbenchTodo :items="todoItems" class="mt-5" title="待办事项" />
|
||||
<AnalysisChartCard class="mt-5" title="访问来源">
|
||||
<AnalyticsVisitsSource />
|
||||
|
@@ -37,7 +37,7 @@ function notify(type: NotificationType) {
|
||||
description="支持多语言,主题功能集成切换等"
|
||||
title="Ant Design Vue组件使用演示"
|
||||
>
|
||||
<Card title="按钮">
|
||||
<Card class="mb-5" title="按钮">
|
||||
<Space>
|
||||
<Button>Default</Button>
|
||||
<Button type="primary"> Primary </Button>
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/web-ele",
|
||||
"version": "5.2.0",
|
||||
"version": "5.2.2",
|
||||
"homepage": "https://vben.pro",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
@@ -44,7 +44,7 @@
|
||||
"dayjs": "^1.11.13",
|
||||
"element-plus": "^2.8.1",
|
||||
"pinia": "2.2.2",
|
||||
"vue": "^3.4.38",
|
||||
"vue": "^3.5.1",
|
||||
"vue-router": "^4.4.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
23
apps/web-ele/src/layouts/auth.vue
Normal file
23
apps/web-ele/src/layouts/auth.vue
Normal file
@@ -0,0 +1,23 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { AuthPageLayout } from '@vben/layouts';
|
||||
import { preferences } from '@vben/preferences';
|
||||
|
||||
import { $t } from '#/locales';
|
||||
|
||||
const appName = computed(() => preferences.app.name);
|
||||
const logo = computed(() => preferences.logo.source);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AuthPageLayout
|
||||
:app-name="appName"
|
||||
:logo="logo"
|
||||
:page-description="$t('authentication.pageDesc')"
|
||||
:page-title="$t('authentication.pageTitle')"
|
||||
>
|
||||
<!-- 自定义工具栏 -->
|
||||
<!-- <template #toolbar></template> -->
|
||||
</AuthPageLayout>
|
||||
</template>
|
@@ -1,8 +1,6 @@
|
||||
const BasicLayout = () => import('./basic.vue');
|
||||
const AuthPageLayout = () => import('./auth.vue');
|
||||
|
||||
const IFrameView = () => import('@vben/layouts').then((m) => m.IFrameView);
|
||||
|
||||
const AuthPageLayout = () =>
|
||||
import('@vben/layouts').then((m) => m.AuthPageLayout);
|
||||
|
||||
export { AuthPageLayout, BasicLayout, IFrameView };
|
||||
|
@@ -55,12 +55,27 @@ onMounted(() => {
|
||||
},
|
||||
trigger: 'axis',
|
||||
},
|
||||
// xAxis: {
|
||||
// axisTick: {
|
||||
// show: false,
|
||||
// },
|
||||
// boundaryGap: false,
|
||||
// data: Array.from({ length: 18 }).map((_item, index) => `${index + 6}:00`),
|
||||
// type: 'category',
|
||||
// },
|
||||
xAxis: {
|
||||
axisTick: {
|
||||
show: false,
|
||||
},
|
||||
boundaryGap: false,
|
||||
data: Array.from({ length: 18 }).map((_item, index) => `${index + 6}:00`),
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
type: 'solid',
|
||||
width: 1,
|
||||
},
|
||||
show: true,
|
||||
},
|
||||
type: 'category',
|
||||
},
|
||||
yAxis: [
|
||||
@@ -69,7 +84,10 @@ onMounted(() => {
|
||||
show: false,
|
||||
},
|
||||
max: 80_000,
|
||||
|
||||
splitArea: {
|
||||
show: true,
|
||||
},
|
||||
splitNumber: 4,
|
||||
type: 'value',
|
||||
},
|
||||
],
|
||||
|
@@ -214,7 +214,11 @@ const trendItems: WorkbenchTrendItem[] = [
|
||||
<WorkbenchTrends :items="trendItems" class="mt-5" title="最新动态" />
|
||||
</div>
|
||||
<div class="w-full lg:w-2/5">
|
||||
<WorkbenchQuickNav :items="quickNavItems" title="快捷导航" />
|
||||
<WorkbenchQuickNav
|
||||
:items="quickNavItems"
|
||||
class="mt-5 lg:mt-0"
|
||||
title="快捷导航"
|
||||
/>
|
||||
<WorkbenchTodo :items="todoItems" class="mt-5" title="待办事项" />
|
||||
<AnalysisChartCard class="mt-5" title="访问来源">
|
||||
<AnalyticsVisitsSource />
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/web-naive",
|
||||
"version": "5.2.0",
|
||||
"version": "5.2.2",
|
||||
"homepage": "https://vben.pro",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
@@ -43,7 +43,7 @@
|
||||
"@vueuse/core": "^11.0.3",
|
||||
"naive-ui": "^2.39.0",
|
||||
"pinia": "2.2.2",
|
||||
"vue": "^3.4.38",
|
||||
"vue": "^3.5.1",
|
||||
"vue-router": "^4.4.3"
|
||||
}
|
||||
}
|
||||
|
23
apps/web-naive/src/layouts/auth.vue
Normal file
23
apps/web-naive/src/layouts/auth.vue
Normal file
@@ -0,0 +1,23 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { AuthPageLayout } from '@vben/layouts';
|
||||
import { preferences } from '@vben/preferences';
|
||||
|
||||
import { $t } from '#/locales';
|
||||
|
||||
const appName = computed(() => preferences.app.name);
|
||||
const logo = computed(() => preferences.logo.source);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AuthPageLayout
|
||||
:app-name="appName"
|
||||
:logo="logo"
|
||||
:page-description="$t('authentication.pageDesc')"
|
||||
:page-title="$t('authentication.pageTitle')"
|
||||
>
|
||||
<!-- 自定义工具栏 -->
|
||||
<!-- <template #toolbar></template> -->
|
||||
</AuthPageLayout>
|
||||
</template>
|
@@ -1,8 +1,6 @@
|
||||
const BasicLayout = () => import('./basic.vue');
|
||||
const AuthPageLayout = () => import('./auth.vue');
|
||||
|
||||
const IFrameView = () => import('@vben/layouts').then((m) => m.IFrameView);
|
||||
|
||||
const AuthPageLayout = () =>
|
||||
import('@vben/layouts').then((m) => m.AuthPageLayout);
|
||||
|
||||
export { AuthPageLayout, BasicLayout, IFrameView };
|
||||
|
@@ -55,12 +55,27 @@ onMounted(() => {
|
||||
},
|
||||
trigger: 'axis',
|
||||
},
|
||||
// xAxis: {
|
||||
// axisTick: {
|
||||
// show: false,
|
||||
// },
|
||||
// boundaryGap: false,
|
||||
// data: Array.from({ length: 18 }).map((_item, index) => `${index + 6}:00`),
|
||||
// type: 'category',
|
||||
// },
|
||||
xAxis: {
|
||||
axisTick: {
|
||||
show: false,
|
||||
},
|
||||
boundaryGap: false,
|
||||
data: Array.from({ length: 18 }).map((_item, index) => `${index + 6}:00`),
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
type: 'solid',
|
||||
width: 1,
|
||||
},
|
||||
show: true,
|
||||
},
|
||||
type: 'category',
|
||||
},
|
||||
yAxis: [
|
||||
@@ -69,7 +84,10 @@ onMounted(() => {
|
||||
show: false,
|
||||
},
|
||||
max: 80_000,
|
||||
|
||||
splitArea: {
|
||||
show: true,
|
||||
},
|
||||
splitNumber: 4,
|
||||
type: 'value',
|
||||
},
|
||||
],
|
||||
|
@@ -214,7 +214,11 @@ const trendItems: WorkbenchTrendItem[] = [
|
||||
<WorkbenchTrends :items="trendItems" class="mt-5" title="最新动态" />
|
||||
</div>
|
||||
<div class="w-full lg:w-2/5">
|
||||
<WorkbenchQuickNav :items="quickNavItems" title="快捷导航" />
|
||||
<WorkbenchQuickNav
|
||||
:items="quickNavItems"
|
||||
class="mt-5 lg:mt-0"
|
||||
title="快捷导航"
|
||||
/>
|
||||
<WorkbenchTodo :items="todoItems" class="mt-5" title="待办事项" />
|
||||
<AnalysisChartCard class="mt-5" title="访问来源">
|
||||
<AnalyticsVisitsSource />
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/docs",
|
||||
"version": "5.2.0",
|
||||
"version": "5.2.2",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "vitepress build",
|
||||
@@ -11,15 +11,15 @@
|
||||
"@vben-core/shadcn-ui": "workspace:*",
|
||||
"@vben/common-ui": "workspace:*",
|
||||
"@vben/styles": "workspace:*",
|
||||
"lucide-vue-next": "^0.436.0",
|
||||
"lucide-vue-next": "^0.438.0",
|
||||
"medium-zoom": "^1.1.0",
|
||||
"radix-vue": "^1.9.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nolebase/vitepress-plugin-git-changelog": "^2.4.0",
|
||||
"@nolebase/vitepress-plugin-git-changelog": "^2.5.0",
|
||||
"@vben/vite-config": "workspace:*",
|
||||
"@vite-pwa/vitepress": "^0.5.0",
|
||||
"@vite-pwa/vitepress": "^0.5.1",
|
||||
"vitepress": "^1.3.4",
|
||||
"vue": "^3.4.38"
|
||||
"vue": "^3.5.1"
|
||||
}
|
||||
}
|
||||
|
@@ -74,6 +74,8 @@ const [Drawer, drawerApi] = useVbenDrawer({
|
||||
| closeOnPressEscape | esc 关闭弹窗 | `boolean` | `true` |
|
||||
| confirmText | 确认按钮文本 | `string\|slot` | `确认` |
|
||||
| cancelText | 取消按钮文本 | `string\|slot` | `取消` |
|
||||
| showCancelButton | 显示取消按钮 | `boolean` | `true` |
|
||||
| showConfirmButton | 显示确认按钮文本 | `boolean` | `true` |
|
||||
| class | modal的class,宽度通过这个配置 | `string` | - |
|
||||
| contentClass | modal内容区域的class | `string` | - |
|
||||
| footerClass | modal底部区域的class | `string` | - |
|
||||
|
@@ -84,6 +84,8 @@ const [Modal, modalApi] = useVbenModal({
|
||||
| closeOnPressEscape | esc 关闭弹窗 | `boolean` | `true` |
|
||||
| confirmText | 确认按钮文本 | `string\|slot` | `确认` |
|
||||
| cancelText | 取消按钮文本 | `string\|slot` | `取消` |
|
||||
| showCancelButton | 显示取消按钮 | `boolean` | `true` |
|
||||
| showConfirmButton | 显示确认按钮文本 | `boolean` | `true` |
|
||||
| class | modal的class,宽度通过这个配置 | `string` | - |
|
||||
| contentClass | modal内容区域的class | `string` | - |
|
||||
| footerClass | modal底部区域的class | `string` | - |
|
||||
|
@@ -240,7 +240,7 @@ const defaultPreferences: Preferences = {
|
||||
theme: {
|
||||
builtinType: 'default',
|
||||
colorDestructive: 'hsl(348 100% 61%)',
|
||||
colorPrimary: 'hsl(231 98% 65%)',
|
||||
colorPrimary: 'hsl(212 100% 45%)',
|
||||
colorSuccess: 'hsl(144 57% 58%)',
|
||||
colorWarning: 'hsl(42 84% 61%)',
|
||||
mode: 'dark',
|
||||
|
@@ -35,7 +35,7 @@ import { defineOverridesPreferences } from '@vben/preferences';
|
||||
export const overridesPreferences = defineOverridesPreferences({
|
||||
// overrides
|
||||
app: {
|
||||
loginExpiredMode: 'model',
|
||||
loginExpiredMode: 'modal',
|
||||
},
|
||||
});
|
||||
```
|
||||
|
@@ -18,7 +18,7 @@ You just need to configure the `props` parameter of `AuthPageLayout` in `src/rou
|
||||
pageTitle: "开箱即用的大型中后台管理系统",
|
||||
pageDescription: "工程化、高性能、跨组件库的前端模版",
|
||||
toolbar: true,
|
||||
toolbarList: () => ['color', 'language', 'layout', 'theme'],
|
||||
toolbarList: ['color', 'language', 'layout', 'theme'],
|
||||
}
|
||||
// ...
|
||||
},
|
||||
|
@@ -36,7 +36,7 @@ You can check the list below to understand all the available variables.
|
||||
--background: 0 0% 100%;
|
||||
|
||||
/* Main area background color */
|
||||
--background-deep: 210 11.11% 96.47%;
|
||||
--background-deep: 216 20.11% 95.47%;
|
||||
--foreground: 210 6% 21%;
|
||||
|
||||
/* Background color for <Card /> */
|
||||
@@ -53,7 +53,7 @@ You can check the list below to understand all the available variables.
|
||||
|
||||
/* Theme Colors */
|
||||
|
||||
--primary: 231 98% 65%;
|
||||
--primary: 212 100% 45%;
|
||||
--primary-foreground: 0 0% 98%;
|
||||
|
||||
/* Used for destructive actions such as <Button variant="destructive"> */
|
||||
@@ -111,7 +111,7 @@ You can check the list below to understand all the available variables.
|
||||
|
||||
/* menu */
|
||||
--sidebar: 0 0% 100%;
|
||||
--sidebar-deep: 210 11.11% 96.47%;
|
||||
--sidebar-deep: 216 20.11% 95.47%;
|
||||
--menu: var(--sidebar);
|
||||
|
||||
/* header */
|
||||
@@ -264,7 +264,7 @@ export const overridesPreferences = defineOverridesPreferences({
|
||||
// Error color
|
||||
colorDestructive: 'hsl(348 100% 61%)',
|
||||
// Primary color
|
||||
colorPrimary: 'hsl(231 98% 65%)',
|
||||
colorPrimary: 'hsl(212 100% 45%)',
|
||||
// Success color
|
||||
colorSuccess: 'hsl(144 57% 58%)',
|
||||
// Warning color
|
||||
@@ -330,7 +330,7 @@ type BuiltinThemeType =
|
||||
--background: 0 0% 100%;
|
||||
|
||||
/* Main area background color */
|
||||
--background-deep: 210 11.11% 96.47%;
|
||||
--background-deep: 216 20.11% 95.47%;
|
||||
--foreground: 222 84% 5%;
|
||||
|
||||
/* Background color for <Card /> */
|
||||
@@ -351,7 +351,7 @@ type BuiltinThemeType =
|
||||
|
||||
/* Theme Colors */
|
||||
|
||||
--primary: 231 98% 65%;
|
||||
--primary: 212 100% 45%;
|
||||
--primary-foreground: 0 0% 98%;
|
||||
|
||||
/* Used for destructive actions such as <Button variant="destructive"> */
|
||||
|
@@ -262,7 +262,7 @@ const defaultPreferences: Preferences = {
|
||||
theme: {
|
||||
builtinType: 'default',
|
||||
colorDestructive: 'hsl(348 100% 61%)',
|
||||
colorPrimary: 'hsl(231 98% 65%)',
|
||||
colorPrimary: 'hsl(212 100% 45%)',
|
||||
colorSuccess: 'hsl(144 57% 58%)',
|
||||
colorWarning: 'hsl(42 84% 61%)',
|
||||
mode: 'dark',
|
||||
|
@@ -35,7 +35,7 @@ import { defineOverridesPreferences } from '@vben/preferences';
|
||||
export const overridesPreferences = defineOverridesPreferences({
|
||||
// overrides
|
||||
app: {
|
||||
loginExpiredMode: 'model',
|
||||
loginExpiredMode: 'modal',
|
||||
},
|
||||
});
|
||||
```
|
||||
|
@@ -8,28 +8,21 @@
|
||||
|
||||

|
||||
|
||||
只需要在应用下的 `src/router/routes/core.ts` 内,配置`AuthPageLayout`的 `props`参数即可:
|
||||
只需要在应用下的 `src/layouts/auth.vue` 内,配置`AuthPageLayout`的 `props`参数即可:
|
||||
|
||||
```ts {4-8}
|
||||
{
|
||||
component: AuthPageLayout,
|
||||
props: {
|
||||
sloganImage: "xxx/xxx.png",
|
||||
pageTitle: "开箱即用的大型中后台管理系统",
|
||||
pageDescription: "工程化、高性能、跨组件库的前端模版",
|
||||
toolbar: true,
|
||||
toolbarList: () => ['color', 'language', 'layout', 'theme'],
|
||||
}
|
||||
// ...
|
||||
},
|
||||
```vue {2-7}
|
||||
<AuthPageLayout
|
||||
:copyright="true"
|
||||
:toolbar="true"
|
||||
:toolbarList="['color', 'language', 'layout', 'theme']"
|
||||
:app-name="appName"
|
||||
:logo="logo"
|
||||
:page-description="$t('authentication.pageDesc')"
|
||||
:page-title="$t('authentication.pageTitle')"
|
||||
>
|
||||
</AuthPageLayout>
|
||||
```
|
||||
|
||||
::: tip
|
||||
|
||||
如果这些配置不能满足你的需求,你可以自行实现登录页面。直接实现自己的 `AuthPageLayout`即可。
|
||||
|
||||
:::
|
||||
|
||||
## 登录表单调整
|
||||
|
||||
如果你想调整登录表单的相关内容,你可以在应用下的 `src/views/_core/authentication/login.vue` 内,配置`AuthenticationLogin` 组件参数即可:
|
||||
|
@@ -36,7 +36,7 @@ css 变量内的颜色,必须使用 `hsl` 格式,如 `0 0% 100%`,不需要
|
||||
--background: 0 0% 100%;
|
||||
|
||||
/* 主体区域背景色 */
|
||||
--background-deep: 210 11.11% 96.47%;
|
||||
--background-deep: 216 20.11% 95.47%;
|
||||
--foreground: 210 6% 21%;
|
||||
|
||||
/* Background color for <Card /> */
|
||||
@@ -53,7 +53,7 @@ css 变量内的颜色,必须使用 `hsl` 格式,如 `0 0% 100%`,不需要
|
||||
|
||||
/* 主题颜色 */
|
||||
|
||||
--primary: 231 98% 65%;
|
||||
--primary: 212 100% 45%;
|
||||
--primary-foreground: 0 0% 98%;
|
||||
|
||||
/* Used for destructive actions such as <Button variant="destructive"> */
|
||||
@@ -111,7 +111,7 @@ css 变量内的颜色,必须使用 `hsl` 格式,如 `0 0% 100%`,不需要
|
||||
|
||||
/* menu */
|
||||
--sidebar: 0 0% 100%;
|
||||
--sidebar-deep: 210 11.11% 96.47%;
|
||||
--sidebar-deep: 216 20.11% 95.47%;
|
||||
--menu: var(--sidebar);
|
||||
|
||||
/* header */
|
||||
@@ -264,7 +264,7 @@ export const overridesPreferences = defineOverridesPreferences({
|
||||
// 错误色
|
||||
colorDestructive: 'hsl(348 100% 61%)',
|
||||
// 主题色
|
||||
colorPrimary: 'hsl(231 98% 65%)',
|
||||
colorPrimary: 'hsl(212 100% 45%)',
|
||||
// 成功色
|
||||
colorSuccess: 'hsl(144 57% 58%)',
|
||||
// 警告色
|
||||
@@ -330,7 +330,7 @@ type BuiltinThemeType =
|
||||
--background: 0 0% 100%;
|
||||
|
||||
/* 主体区域背景色 */
|
||||
--background-deep: 210 11.11% 96.47%;
|
||||
--background-deep: 216 20.11% 95.47%;
|
||||
--foreground: 222 84% 5%;
|
||||
|
||||
/* Background color for <Card /> */
|
||||
@@ -351,7 +351,7 @@ type BuiltinThemeType =
|
||||
|
||||
/* 主题颜色 */
|
||||
|
||||
--primary: 231 98% 65%;
|
||||
--primary: 212 100% 45%;
|
||||
--primary-foreground: 0 0% 98%;
|
||||
|
||||
/* Used for destructive actions such as <Button variant="destructive"> */
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/commitlint-config",
|
||||
"version": "5.2.0",
|
||||
"version": "5.2.2",
|
||||
"private": true,
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
|
@@ -27,15 +27,15 @@
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"eslint-config-turbo": "^2.1.0",
|
||||
"eslint-config-turbo": "^2.1.1",
|
||||
"eslint-plugin-command": "^0.2.3",
|
||||
"eslint-plugin-import-x": "^4.1.0"
|
||||
"eslint-plugin-import-x": "^4.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.9.1",
|
||||
"@types/eslint": "^9.6.1",
|
||||
"@typescript-eslint/eslint-plugin": "^8.3.0",
|
||||
"@typescript-eslint/parser": "^8.3.0",
|
||||
"@typescript-eslint/eslint-plugin": "^8.4.0",
|
||||
"@typescript-eslint/parser": "^8.4.0",
|
||||
"eslint": "^9.9.1",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-eslint-comments": "^3.2.0",
|
||||
@@ -49,7 +49,7 @@
|
||||
"eslint-plugin-unicorn": "^55.0.0",
|
||||
"eslint-plugin-unused-imports": "^4.1.3",
|
||||
"eslint-plugin-vitest": "^0.5.4",
|
||||
"eslint-plugin-vue": "^9.27.0",
|
||||
"eslint-plugin-vue": "^9.28.0",
|
||||
"globals": "^15.9.0",
|
||||
"jsonc-eslint-parser": "^2.4.0",
|
||||
"vue-eslint-parser": "^9.4.3"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/stylelint-config",
|
||||
"version": "5.2.0",
|
||||
"version": "5.2.2",
|
||||
"private": true,
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
@@ -28,7 +28,7 @@
|
||||
"stylelint-scss": "^6.5.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"postcss": "^8.4.41",
|
||||
"postcss": "^8.4.45",
|
||||
"postcss-html": "^1.7.0",
|
||||
"postcss-scss": "^4.0.9",
|
||||
"prettier": "^3.3.3",
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/node-utils",
|
||||
"version": "5.2.0",
|
||||
"version": "5.2.2",
|
||||
"private": true,
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
@@ -28,7 +28,7 @@
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@changesets/git": "^3.0.0",
|
||||
"@changesets/git": "^3.0.1",
|
||||
"@manypkg/get-packages": "^2.2.2",
|
||||
"chalk": "^5.3.0",
|
||||
"consola": "^3.2.3",
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/tailwind-config",
|
||||
"version": "5.2.0",
|
||||
"version": "5.2.2",
|
||||
"private": true,
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
@@ -46,13 +46,13 @@
|
||||
"tailwindcss": "^3.4.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@iconify/json": "^2.2.242",
|
||||
"@iconify/json": "^2.2.244",
|
||||
"@iconify/tailwind": "^1.1.3",
|
||||
"@tailwindcss/nesting": "0.0.0-insiders.565cd3e",
|
||||
"@tailwindcss/typography": "^0.5.15",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"cssnano": "^7.0.5",
|
||||
"postcss": "^8.4.41",
|
||||
"postcss": "^8.4.45",
|
||||
"postcss-antd-fixes": "^0.2.0",
|
||||
"postcss-import": "^16.1.0",
|
||||
"postcss-preset-env": "^10.0.2",
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/tsconfig",
|
||||
"version": "5.2.0",
|
||||
"version": "5.2.2",
|
||||
"private": true,
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
@@ -20,6 +20,6 @@
|
||||
],
|
||||
"dependencies": {
|
||||
"@vben/types": "workspace:*",
|
||||
"vite": "^5.4.2"
|
||||
"vite": "^5.4.3"
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/vite-config",
|
||||
"version": "5.2.0",
|
||||
"version": "5.2.2",
|
||||
"private": true,
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
@@ -28,7 +28,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@intlify/unplugin-vue-i18n": "^4.0.0",
|
||||
"@jspm/generator": "^2.1.3",
|
||||
"@jspm/generator": "^2.2.0",
|
||||
"archiver": "^7.0.1",
|
||||
"cheerio": "1.0.0",
|
||||
"get-port": "^7.1.0",
|
||||
@@ -36,23 +36,23 @@
|
||||
"nitropack": "^2.9.7",
|
||||
"resolve.exports": "^2.0.2",
|
||||
"vite-plugin-lib-inject-css": "^2.1.1",
|
||||
"vite-plugin-pwa": "^0.20.1",
|
||||
"vite-plugin-vue-devtools": "^7.3.9"
|
||||
"vite-plugin-pwa": "^0.20.4",
|
||||
"vite-plugin-vue-devtools": "^7.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/archiver": "^6.0.2",
|
||||
"@types/html-minifier-terser": "^7.0.2",
|
||||
"@vben/node-utils": "workspace:*",
|
||||
"@vitejs/plugin-vue": "^5.1.2",
|
||||
"@vitejs/plugin-vue": "^5.1.3",
|
||||
"@vitejs/plugin-vue-jsx": "^4.0.1",
|
||||
"dayjs": "^1.11.13",
|
||||
"dotenv": "^16.4.5",
|
||||
"rollup": "^4.21.1",
|
||||
"rollup": "^4.21.2",
|
||||
"rollup-plugin-visualizer": "^5.12.0",
|
||||
"sass": "^1.77.8",
|
||||
"vite": "^5.4.2",
|
||||
"sass": "^1.78.0",
|
||||
"vite": "^5.4.3",
|
||||
"vite-plugin-compression": "^0.5.1",
|
||||
"vite-plugin-dts": "4.0.3",
|
||||
"vite-plugin-dts": "4.1.0",
|
||||
"vite-plugin-html": "^3.2.2"
|
||||
}
|
||||
}
|
||||
|
21
package.json
21
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "vben-admin-pro",
|
||||
"version": "5.2.0",
|
||||
"version": "5.2.2",
|
||||
"private": true,
|
||||
"keywords": [
|
||||
"monorepo",
|
||||
@@ -62,10 +62,9 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@changesets/changelog-github": "^0.5.0",
|
||||
"@changesets/cli": "^2.27.7",
|
||||
"@ls-lint/ls-lint": "^2.2.3",
|
||||
"@changesets/cli": "^2.27.8",
|
||||
"@types/jsdom": "^21.1.7",
|
||||
"@types/node": "^22.5.1",
|
||||
"@types/node": "^22.5.3",
|
||||
"@vben/commitlint-config": "workspace:*",
|
||||
"@vben/eslint-config": "workspace:*",
|
||||
"@vben/prettier-config": "workspace:*",
|
||||
@@ -75,7 +74,7 @@
|
||||
"@vben/turbo-run": "workspace:*",
|
||||
"@vben/vite-config": "workspace:*",
|
||||
"@vben/vsh": "workspace:*",
|
||||
"@vitejs/plugin-vue": "^5.1.2",
|
||||
"@vitejs/plugin-vue": "^5.1.3",
|
||||
"@vitejs/plugin-vue-jsx": "^4.0.1",
|
||||
"@vue/test-utils": "^2.4.6",
|
||||
"autoprefixer": "^10.4.20",
|
||||
@@ -84,16 +83,16 @@
|
||||
"husky": "^9.1.5",
|
||||
"is-ci": "^3.0.1",
|
||||
"jsdom": "^25.0.0",
|
||||
"lint-staged": "^15.2.9",
|
||||
"lint-staged": "^15.2.10",
|
||||
"rimraf": "^6.0.1",
|
||||
"tailwindcss": "^3.4.10",
|
||||
"turbo": "^2.1.0",
|
||||
"turbo": "^2.1.1",
|
||||
"typescript": "^5.5.4",
|
||||
"unbuild": "^2.0.0",
|
||||
"vite": "^5.4.2",
|
||||
"vite": "^5.4.3",
|
||||
"vitest": "^2.0.5",
|
||||
"vue": "^3.4.38",
|
||||
"vue-tsc": "^2.0.29"
|
||||
"vue": "^3.5.1",
|
||||
"vue-tsc": "^2.1.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20",
|
||||
@@ -110,7 +109,7 @@
|
||||
"@ctrl/tinycolor": "4.1.0",
|
||||
"clsx": "2.1.1",
|
||||
"pinia": "2.2.2",
|
||||
"vue": "3.4.38"
|
||||
"vue": "3.5.0"
|
||||
},
|
||||
"neverBuiltDependencies": [
|
||||
"canvas",
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben-core/design",
|
||||
"version": "5.2.0",
|
||||
"version": "5.2.2",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
@@ -136,7 +136,7 @@
|
||||
}
|
||||
|
||||
.card-box {
|
||||
@apply bg-card text-card-foreground border-border rounded-xl border shadow;
|
||||
@apply bg-card text-card-foreground border-border rounded-xl border;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -7,7 +7,7 @@
|
||||
--background: 0 0% 100%;
|
||||
|
||||
/* 主体区域背景色 */
|
||||
--background-deep: 210 11.11% 96.47%;
|
||||
--background-deep: 216 20.11% 95.47%;
|
||||
--foreground: 210 6% 21%;
|
||||
|
||||
/* Background color for <Card /> */
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
/* 主题颜色 */
|
||||
|
||||
--primary: 231 98% 65%;
|
||||
--primary: 212 100% 45%;
|
||||
--primary-foreground: 0 0% 98%;
|
||||
|
||||
/* Used for destructive actions such as <Button variant="destructive"> */
|
||||
@@ -77,7 +77,8 @@
|
||||
/* ============= custom ============= */
|
||||
|
||||
/* 遮罩颜色 */
|
||||
--overlay: 0 0% 0% / 30%;
|
||||
--overlay: 0 0% 0% / 45%;
|
||||
--overlay-light: 0 0% 95% / 45%;
|
||||
|
||||
/* 基本文字大小 */
|
||||
--font-size-base: 16px;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben-core/icons",
|
||||
"version": "5.2.0",
|
||||
"version": "5.2.2",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
@@ -35,7 +35,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@iconify/vue": "^4.1.2",
|
||||
"lucide-vue-next": "^0.436.0",
|
||||
"vue": "^3.4.38"
|
||||
"lucide-vue-next": "^0.438.0",
|
||||
"vue": "^3.5.1"
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben-core/shared",
|
||||
"version": "5.2.0",
|
||||
"version": "5.2.2",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
@@ -62,7 +62,7 @@
|
||||
"dependencies": {
|
||||
"@ctrl/tinycolor": "^4.1.0",
|
||||
"@tanstack/vue-store": "^0.5.5",
|
||||
"@vue/shared": "^3.4.38",
|
||||
"@vue/shared": "^3.5.1",
|
||||
"clsx": "^2.1.1",
|
||||
"defu": "^6.1.4",
|
||||
"lodash.clonedeep": "^4.5.0",
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben-core/typings",
|
||||
"version": "5.2.0",
|
||||
"version": "5.2.2",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
@@ -38,7 +38,7 @@
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"vue": "^3.4.38",
|
||||
"vue": "^3.5.1",
|
||||
"vue-router": "^4.4.3"
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben-core/composables",
|
||||
"version": "5.2.0",
|
||||
"version": "5.2.2",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
@@ -38,8 +38,8 @@
|
||||
"@vben-core/shared": "workspace:*",
|
||||
"@vueuse/core": "^11.0.3",
|
||||
"radix-vue": "^1.9.5",
|
||||
"sortablejs": "^1.15.2",
|
||||
"vue": "^3.4.38"
|
||||
"sortablejs": "^1.15.3",
|
||||
"vue": "^3.5.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/sortablejs": "^1.15.8"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben-core/preferences",
|
||||
"version": "5.2.0",
|
||||
"version": "5.2.2",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
@@ -32,6 +32,6 @@
|
||||
"@vben-core/shared": "workspace:*",
|
||||
"@vben-core/typings": "workspace:*",
|
||||
"@vueuse/core": "^11.0.3",
|
||||
"vue": "^3.4.38"
|
||||
"vue": "^3.5.1"
|
||||
}
|
||||
}
|
||||
|
@@ -70,12 +70,12 @@ const defaultPreferences: Preferences = {
|
||||
expandOnHover: true,
|
||||
extraCollapse: true,
|
||||
hidden: false,
|
||||
width: 230,
|
||||
width: 224,
|
||||
},
|
||||
tabbar: {
|
||||
dragable: true,
|
||||
enable: true,
|
||||
height: 36,
|
||||
height: 38,
|
||||
keepAlive: true,
|
||||
persist: true,
|
||||
showIcon: true,
|
||||
@@ -87,7 +87,7 @@ const defaultPreferences: Preferences = {
|
||||
theme: {
|
||||
builtinType: 'default',
|
||||
colorDestructive: 'hsl(348 100% 61%)',
|
||||
colorPrimary: 'hsl(231 98% 65%)',
|
||||
colorPrimary: 'hsl(212 100% 45%)',
|
||||
colorSuccess: 'hsl(144 57% 58%)',
|
||||
colorWarning: 'hsl(42 84% 61%)',
|
||||
mode: 'dark',
|
||||
|
@@ -9,7 +9,7 @@ interface BuiltinThemePreset {
|
||||
|
||||
const BUILT_IN_THEME_PRESETS: BuiltinThemePreset[] = [
|
||||
{
|
||||
color: 'hsl(231 98% 65%)',
|
||||
color: 'hsl(212 100% 45%)',
|
||||
type: 'default',
|
||||
},
|
||||
{
|
||||
@@ -25,7 +25,7 @@ const BUILT_IN_THEME_PRESETS: BuiltinThemePreset[] = [
|
||||
type: 'yellow',
|
||||
},
|
||||
{
|
||||
color: 'hsl(212 100% 45%)',
|
||||
color: 'hsl(231 98% 65%)',
|
||||
type: 'sky-blue',
|
||||
},
|
||||
{
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben-core/layout-ui",
|
||||
"version": "5.2.0",
|
||||
"version": "5.2.2",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
@@ -42,6 +42,6 @@
|
||||
"@vben-core/shadcn-ui": "workspace:*",
|
||||
"@vben-core/typings": "workspace:*",
|
||||
"@vueuse/core": "^11.0.3",
|
||||
"vue": "^3.4.38"
|
||||
"vue": "^3.5.1"
|
||||
}
|
||||
}
|
||||
|
@@ -5,6 +5,7 @@ import type { CSSProperties } from 'vue';
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { useContentStyle } from '@vben-core/composables';
|
||||
import { Slot } from '@vben-core/shadcn-ui';
|
||||
|
||||
interface Props {
|
||||
/**
|
||||
@@ -54,7 +55,9 @@ const style = computed((): CSSProperties => {
|
||||
|
||||
<template>
|
||||
<main ref="contentElement" :style="style" class="bg-background-deep relative">
|
||||
<slot :overlay-style="overlayStyle" name="overlay"></slot>
|
||||
<Slot :style="overlayStyle">
|
||||
<slot name="overlay"></slot>
|
||||
</Slot>
|
||||
<slot></slot>
|
||||
</main>
|
||||
</template>
|
||||
|
@@ -217,18 +217,21 @@ function handleMouseenter() {
|
||||
if (!expandOnHovering.value) {
|
||||
collapse.value = false;
|
||||
}
|
||||
isLocked.value = true;
|
||||
if (props.isSidebarMixed) {
|
||||
isLocked.value = true;
|
||||
}
|
||||
expandOnHovering.value = true;
|
||||
}
|
||||
|
||||
function handleMouseleave() {
|
||||
emit('leave');
|
||||
|
||||
if (props.isSidebarMixed) {
|
||||
isLocked.value = false;
|
||||
}
|
||||
if (expandOnHover.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
isLocked.value = false;
|
||||
expandOnHovering.value = false;
|
||||
collapse.value = true;
|
||||
extraVisible.value = false;
|
||||
@@ -294,7 +297,7 @@ function handleMouseleave() {
|
||||
</div>
|
||||
<VbenScrollbar
|
||||
:style="extraContentStyle"
|
||||
class="border-border border-t py-2"
|
||||
class="border-border py-2"
|
||||
shadow
|
||||
shadow-border
|
||||
>
|
||||
|
@@ -50,7 +50,7 @@ const props = withDefaults(defineProps<Props>(), {
|
||||
sidebarWidth: 180,
|
||||
sideCollapseWidth: 60,
|
||||
tabbarEnable: true,
|
||||
tabbarHeight: 36,
|
||||
tabbarHeight: 40,
|
||||
zIndex: 200,
|
||||
});
|
||||
|
||||
@@ -534,8 +534,8 @@ function handleHeaderToggle() {
|
||||
>
|
||||
<slot name="content"></slot>
|
||||
|
||||
<template #overlay="{ overlayStyle }">
|
||||
<slot :overlay-style="overlayStyle" name="content-overlay"></slot>
|
||||
<template #overlay>
|
||||
<slot name="content-overlay"></slot>
|
||||
</template>
|
||||
</LayoutContent>
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben-core/menu-ui",
|
||||
"version": "5.2.0",
|
||||
"version": "5.2.2",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
@@ -43,6 +43,6 @@
|
||||
"@vben-core/shared": "workspace:*",
|
||||
"@vben-core/typings": "workspace:*",
|
||||
"@vueuse/core": "^11.0.3",
|
||||
"vue": "^3.4.38"
|
||||
"vue": "^3.5.1"
|
||||
}
|
||||
}
|
||||
|
@@ -42,6 +42,6 @@
|
||||
"@vben-core/shadcn-ui": "workspace:*",
|
||||
"@vben-core/shared": "workspace:*",
|
||||
"@vueuse/core": "^11.0.3",
|
||||
"vue": "^3.4.38"
|
||||
"vue": "^3.5.1"
|
||||
}
|
||||
}
|
||||
|
@@ -36,6 +36,8 @@ export class DrawerApi {
|
||||
isOpen: false,
|
||||
loading: false,
|
||||
modal: true,
|
||||
showCancelButton: true,
|
||||
showConfirmButton: true,
|
||||
title: '',
|
||||
};
|
||||
|
||||
|
@@ -50,6 +50,16 @@ export interface DrawerProps {
|
||||
* @default true
|
||||
*/
|
||||
modal?: boolean;
|
||||
/**
|
||||
* 是否显示取消按钮
|
||||
* @default true
|
||||
*/
|
||||
showCancelButton?: boolean;
|
||||
/**
|
||||
* 是否显示确认按钮
|
||||
* @default true
|
||||
*/
|
||||
showConfirmButton?: boolean;
|
||||
/**
|
||||
* 弹窗标题
|
||||
*/
|
||||
|
@@ -54,6 +54,8 @@ const cancelText = usePriorityValue('cancelText', props, state);
|
||||
const confirmText = usePriorityValue('confirmText', props, state);
|
||||
const closeOnClickModal = usePriorityValue('closeOnClickModal', props, state);
|
||||
const closeOnPressEscape = usePriorityValue('closeOnPressEscape', props, state);
|
||||
const showCancelButton = usePriorityValue('showCancelButton', props, state);
|
||||
const showConfirmButton = usePriorityValue('showConfirmButton', props, state);
|
||||
|
||||
watch(
|
||||
() => showLoading.value,
|
||||
@@ -167,12 +169,17 @@ function pointerDownOutside(e: Event) {
|
||||
>
|
||||
<slot name="prepend-footer"></slot>
|
||||
<slot name="footer">
|
||||
<VbenButton variant="ghost" @click="() => drawerApi?.onCancel()">
|
||||
<VbenButton
|
||||
v-if="showCancelButton"
|
||||
variant="ghost"
|
||||
@click="() => drawerApi?.onCancel()"
|
||||
>
|
||||
<slot name="cancelText">
|
||||
{{ cancelText || $t('cancel') }}
|
||||
</slot>
|
||||
</VbenButton>
|
||||
<VbenButton
|
||||
v-if="showConfirmButton"
|
||||
:loading="confirmLoading"
|
||||
@click="() => drawerApi?.onConfirm()"
|
||||
>
|
||||
|
@@ -40,6 +40,8 @@ export class ModalApi {
|
||||
isOpen: false,
|
||||
loading: false,
|
||||
modal: true,
|
||||
showCancelButton: true,
|
||||
showConfirmButton: true,
|
||||
title: '',
|
||||
};
|
||||
|
||||
|
@@ -75,6 +75,16 @@ export interface ModalProps {
|
||||
* @default true
|
||||
*/
|
||||
modal?: boolean;
|
||||
/**
|
||||
* 是否显示取消按钮
|
||||
* @default true
|
||||
*/
|
||||
showCancelButton?: boolean;
|
||||
/**
|
||||
* 是否显示确认按钮
|
||||
* @default true
|
||||
*/
|
||||
showConfirmButton?: boolean;
|
||||
/**
|
||||
* 弹窗标题
|
||||
*/
|
||||
|
@@ -69,6 +69,8 @@ const draggable = usePriorityValue('draggable', props, state);
|
||||
const fullscreenButton = usePriorityValue('fullscreenButton', props, state);
|
||||
const closeOnClickModal = usePriorityValue('closeOnClickModal', props, state);
|
||||
const closeOnPressEscape = usePriorityValue('closeOnPressEscape', props, state);
|
||||
const showCancelButton = usePriorityValue('showCancelButton', props, state);
|
||||
const showConfirmButton = usePriorityValue('showConfirmButton', props, state);
|
||||
|
||||
const shouldFullscreen = computed(
|
||||
() => (fullscreen.value && header.value) || isMobile.value,
|
||||
@@ -153,13 +155,13 @@ function pointerDownOutside(e: Event) {
|
||||
{
|
||||
'left-0 top-0 size-full max-h-full !translate-x-0 !translate-y-0':
|
||||
shouldFullscreen,
|
||||
'top-1/2 -translate-y-1/2': centered && !shouldFullscreen,
|
||||
'top-1/2 !-translate-y-1/2': centered && !shouldFullscreen,
|
||||
'duration-300': !dragging,
|
||||
},
|
||||
)
|
||||
"
|
||||
:show-close="closable"
|
||||
close-class="top-4"
|
||||
close-class="top-3"
|
||||
@escape-key-down="escapeKeyDown"
|
||||
@interact-outside="interactOutside"
|
||||
@pointer-down-outside="pointerDownOutside"
|
||||
@@ -219,7 +221,7 @@ function pointerDownOutside(e: Event) {
|
||||
|
||||
<VbenIconButton
|
||||
v-if="fullscreenButton"
|
||||
class="hover:bg-accent hover:text-accent-foreground text-foreground/80 flex-center absolute right-10 top-4 hidden size-6 rounded-full px-1 text-lg opacity-70 transition-opacity hover:opacity-100 focus:outline-none disabled:pointer-events-none sm:block"
|
||||
class="hover:bg-accent hover:text-accent-foreground text-foreground/80 flex-center absolute right-10 top-3 hidden size-6 rounded-full px-1 text-lg opacity-70 transition-opacity hover:opacity-100 focus:outline-none disabled:pointer-events-none sm:block"
|
||||
@click="handleFullscreen"
|
||||
>
|
||||
<Shrink v-if="fullscreen" class="size-3.5" />
|
||||
@@ -238,12 +240,17 @@ function pointerDownOutside(e: Event) {
|
||||
>
|
||||
<slot name="prepend-footer"></slot>
|
||||
<slot name="footer">
|
||||
<VbenButton variant="ghost" @click="() => modalApi?.onCancel()">
|
||||
<VbenButton
|
||||
v-if="showCancelButton"
|
||||
variant="ghost"
|
||||
@click="() => modalApi?.onCancel()"
|
||||
>
|
||||
<slot name="cancelText">
|
||||
{{ cancelText || $t('cancel') }}
|
||||
</slot>
|
||||
</VbenButton>
|
||||
<VbenButton
|
||||
v-if="showConfirmButton"
|
||||
:loading="confirmLoading"
|
||||
@click="() => modalApi?.onConfirm()"
|
||||
>
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben-core/shadcn-ui",
|
||||
"version": "5.2.0",
|
||||
"version": "5.2.2",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
@@ -48,8 +48,8 @@
|
||||
"@vben-core/typings": "workspace:*",
|
||||
"@vueuse/core": "^11.0.3",
|
||||
"class-variance-authority": "^0.7.0",
|
||||
"lucide-vue-next": "^0.436.0",
|
||||
"lucide-vue-next": "^0.438.0",
|
||||
"radix-vue": "^1.9.5",
|
||||
"vue": "^3.4.38"
|
||||
"vue": "^3.5.1"
|
||||
}
|
||||
}
|
||||
|
@@ -28,12 +28,12 @@ const props = withDefaults(defineProps<Props>(), {
|
||||
});
|
||||
|
||||
const text = computed(() => {
|
||||
return props.alt.slice(0, 2).toUpperCase();
|
||||
return props.alt.slice(-2).toUpperCase();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div :class="props.class" class="relative flex-shrink-0">
|
||||
<div :class="props.class" class="relative flex flex-shrink-0 items-center">
|
||||
<Avatar :class="props.class" class="size-full">
|
||||
<AvatarImage :alt="alt" :src="src" />
|
||||
<AvatarFallback>{{ text }}</AvatarFallback>
|
||||
|
@@ -32,7 +32,7 @@ const { handleClick, visible } = useBackTop(props);
|
||||
<VbenButton
|
||||
v-if="visible"
|
||||
:style="backTopStyle"
|
||||
class="dark:bg-accent dark:hover:bg-heavy bg-background hover:bg-heavy data shadow-float fixed bottom-10 z-[1000] h-10 w-10 rounded-full duration-500"
|
||||
class="dark:bg-accent dark:hover:bg-heavy bg-background hover:bg-heavy data shadow-float fixed bottom-10 z-[1000] size-10 rounded-full duration-500"
|
||||
size="icon"
|
||||
variant="icon"
|
||||
@click="handleClick"
|
||||
|
@@ -1,12 +1,9 @@
|
||||
<script lang="ts" setup>
|
||||
import type { IBreadcrumb } from './types';
|
||||
import type { BreadcrumbProps } from './types';
|
||||
|
||||
import { VbenIcon } from '../icon';
|
||||
|
||||
interface Props {
|
||||
breadcrumbs: IBreadcrumb[];
|
||||
showIcon?: boolean;
|
||||
}
|
||||
interface Props extends BreadcrumbProps {}
|
||||
|
||||
defineOptions({ name: 'Breadcrumb' });
|
||||
withDefaults(defineProps<Props>(), {
|
||||
|
@@ -0,0 +1,22 @@
|
||||
<script lang="ts" setup>
|
||||
import type { BreadcrumbProps } from './types';
|
||||
|
||||
import { useForwardPropsEmits } from 'radix-vue';
|
||||
|
||||
import Breadcrumb from './breadcrumb.vue';
|
||||
import BreadcrumbBackground from './breadcrumb-background.vue';
|
||||
|
||||
interface Props extends BreadcrumbProps {
|
||||
class?: any;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {});
|
||||
|
||||
const emit = defineEmits<{ select: [string] }>();
|
||||
|
||||
const forward = useForwardPropsEmits(props, emit);
|
||||
</script>
|
||||
<template>
|
||||
<Breadcrumb v-if="styleType === 'normal'" v-bind="forward" />
|
||||
<BreadcrumbBackground v-if="styleType === 'background'" v-bind="forward" />
|
||||
</template>
|
@@ -1,5 +1,5 @@
|
||||
<script lang="ts" setup>
|
||||
import type { IBreadcrumb } from './types';
|
||||
import type { BreadcrumbProps } from './types';
|
||||
|
||||
import { ChevronDown } from '@vben-core/icons';
|
||||
|
||||
@@ -19,10 +19,7 @@ import {
|
||||
DropdownMenuTrigger,
|
||||
} from '../ui/dropdown-menu';
|
||||
|
||||
interface Props {
|
||||
breadcrumbs: IBreadcrumb[];
|
||||
showIcon?: boolean;
|
||||
}
|
||||
interface Props extends BreadcrumbProps {}
|
||||
|
||||
defineOptions({ name: 'Breadcrumb' });
|
||||
withDefaults(defineProps<Props>(), {
|
||||
|
@@ -1,4 +1,3 @@
|
||||
export { default as VbenBreadcrumb } from './breadcrumb.vue';
|
||||
export { default as VbenBackgroundBreadcrumb } from './breadcrumb-background.vue';
|
||||
export { default as VbenBreadcrumbView } from './breadcrumb-view.vue';
|
||||
|
||||
export type * from './types';
|
||||
|
@@ -1,6 +1,8 @@
|
||||
import type { BreadcrumbStyleType } from '@vben-core/typings';
|
||||
|
||||
import type { Component } from 'vue';
|
||||
|
||||
interface IBreadcrumb {
|
||||
export interface IBreadcrumb {
|
||||
icon?: Component | string;
|
||||
isHome?: boolean;
|
||||
items?: IBreadcrumb[];
|
||||
@@ -8,4 +10,8 @@ interface IBreadcrumb {
|
||||
title?: string;
|
||||
}
|
||||
|
||||
export type { IBreadcrumb };
|
||||
export interface BreadcrumbProps {
|
||||
breadcrumbs: IBreadcrumb[];
|
||||
showIcon?: boolean;
|
||||
styleType?: BreadcrumbStyleType;
|
||||
}
|
||||
|
@@ -25,7 +25,7 @@ const show = ref(false);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<form class="relative">
|
||||
<div class="relative">
|
||||
<VbenInput
|
||||
v-model="modelValue"
|
||||
v-bind="{ ...forward, ...$attrs }"
|
||||
@@ -48,5 +48,5 @@ const show = ref(false);
|
||||
<Eye v-if="show" class="size-4" />
|
||||
<EyeOff v-else class="size-4" />
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</template>
|
||||
|
@@ -1,27 +1,29 @@
|
||||
<script setup lang="ts">
|
||||
import { VbenAvatar } from '../avatar';
|
||||
|
||||
interface Props {
|
||||
/**
|
||||
* 是否收起文本
|
||||
* @zh_CN 是否收起文本
|
||||
*/
|
||||
collapsed?: boolean;
|
||||
/**
|
||||
* Logo 跳转地址
|
||||
* @zh_CN Logo 跳转地址
|
||||
*/
|
||||
href?: string;
|
||||
/**
|
||||
* Logo 图片大小
|
||||
* @zh_CN Logo 图片大小
|
||||
*/
|
||||
logoSize?: number;
|
||||
/**
|
||||
* Logo 图标
|
||||
* @zh_CN Logo 图标
|
||||
*/
|
||||
src?: string;
|
||||
/**
|
||||
* Logo 文本
|
||||
* @zh_CN Logo 文本
|
||||
*/
|
||||
text: string;
|
||||
/**
|
||||
* Logo 主题
|
||||
* @zh_CN Logo 主题
|
||||
*/
|
||||
theme?: string;
|
||||
}
|
||||
@@ -44,16 +46,18 @@ withDefaults(defineProps<Props>(), {
|
||||
<a
|
||||
:class="$attrs.class"
|
||||
:href="href"
|
||||
class="flex h-full items-center gap-2 overflow-hidden px-3 text-lg font-semibold leading-normal transition-all duration-500"
|
||||
class="flex h-full items-center gap-2 overflow-hidden px-3 text-lg leading-normal transition-all duration-500"
|
||||
>
|
||||
<img
|
||||
<VbenAvatar
|
||||
v-if="src"
|
||||
:alt="text"
|
||||
:src="src"
|
||||
:width="logoSize"
|
||||
class="relative rounded-none bg-transparent"
|
||||
class="relative w-8 rounded-none bg-transparent"
|
||||
/>
|
||||
<span v-if="!collapsed" class="text-foreground truncate text-nowrap">
|
||||
<span
|
||||
v-if="!collapsed"
|
||||
class="text-foreground truncate text-nowrap font-semibold"
|
||||
>
|
||||
{{ text }}
|
||||
</span>
|
||||
</a>
|
||||
|
@@ -69,7 +69,7 @@ function onTransitionEnd() {
|
||||
<div
|
||||
:class="
|
||||
cn(
|
||||
'bg-overlay z-100 pointer-events-none absolute left-0 top-0 flex size-full flex-col items-center justify-center transition-all duration-500',
|
||||
'z-100 dark:bg-overlay pointer-events-none absolute left-0 top-0 flex size-full flex-col items-center justify-center bg-[hsl(var(--overlay-light))] transition-all duration-500',
|
||||
{
|
||||
'invisible opacity-0': !showSpinner,
|
||||
},
|
||||
|
@@ -63,7 +63,7 @@ function onTransitionEnd() {
|
||||
<div
|
||||
:class="
|
||||
cn(
|
||||
'flex-center bg-overlay z-100 absolute left-0 top-0 size-full backdrop-blur-sm transition-all duration-500',
|
||||
'flex-center z-100 dark:bg-overlay absolute left-0 top-0 size-full bg-[hsl(var(--overlay-light))] backdrop-blur-sm transition-all duration-500',
|
||||
{
|
||||
'invisible opacity-0': !showSpinner,
|
||||
},
|
||||
|
@@ -12,7 +12,7 @@ const props = defineProps<{
|
||||
<div
|
||||
:class="
|
||||
cn(
|
||||
'bg-card text-card-foreground border-border rounded-xl border shadow-sm',
|
||||
'bg-card text-card-foreground border-border rounded-xl border',
|
||||
props.class,
|
||||
)
|
||||
"
|
||||
|
@@ -1,2 +1,2 @@
|
||||
export * from './components';
|
||||
export { VisuallyHidden } from 'radix-vue';
|
||||
export { Slot, VisuallyHidden } from 'radix-vue';
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben-core/tabs-ui",
|
||||
"version": "5.2.0",
|
||||
"version": "5.2.2",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
@@ -42,6 +42,6 @@
|
||||
"@vben-core/shadcn-ui": "workspace:*",
|
||||
"@vben-core/typings": "workspace:*",
|
||||
"@vueuse/core": "^11.0.3",
|
||||
"vue": "^3.4.38"
|
||||
"vue": "^3.5.1"
|
||||
}
|
||||
}
|
||||
|
@@ -60,9 +60,9 @@ const tabsView = computed((): TabConfig[] => {
|
||||
ref="contentRef"
|
||||
:class="contentClass"
|
||||
:style="style"
|
||||
class="tabs-chrome !flex h-full w-max pr-6"
|
||||
class="tabs-chrome !flex h-full w-max overflow-y-hidden pr-6"
|
||||
>
|
||||
<TransitionGroup name="slide-right">
|
||||
<TransitionGroup name="slide-down">
|
||||
<div
|
||||
v-for="(tab, i) in tabsView"
|
||||
:key="tab.key"
|
||||
@@ -84,14 +84,14 @@ const tabsView = computed((): TabConfig[] => {
|
||||
<!-- divider -->
|
||||
<div
|
||||
v-if="i !== 0 && tab.key !== active"
|
||||
class="tabs-chrome__divider bg-foreground/50 absolute left-[var(--gap)] top-1/2 z-0 h-4 w-[1px] translate-y-[-50%] transition-all"
|
||||
class="tabs-chrome__divider bg-border 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"
|
||||
>
|
||||
<div
|
||||
class="tabs-chrome__background-content group-[.is-active]:bg-heavy dark:group-[.is-active]:bg-accent h-full rounded-tl-[var(--gap)] rounded-tr-[var(--gap)] duration-150"
|
||||
class="tabs-chrome__background-content group-[.is-active]:bg-primary/15 dark:group-[.is-active]:bg-accent h-full rounded-tl-[var(--gap)] rounded-tr-[var(--gap)] duration-150"
|
||||
></div>
|
||||
<svg
|
||||
class="tabs-chrome__background-before group-[.is-active]:fill-primary/15 dark:group-[.is-active]:fill-accent absolute bottom-0 left-[-1px] fill-transparent transition-all duration-150"
|
||||
@@ -128,7 +128,7 @@ const tabsView = computed((): TabConfig[] => {
|
||||
|
||||
<!-- tab-item-main -->
|
||||
<div
|
||||
class="tabs-chrome__item-main group-[.is-active]:text-accent-foreground dark:group-[.is-active]:text-accent-foreground text-accent-foreground z-[2] mx-[calc(var(--gap)*2)] my-0 flex h-full items-center overflow-hidden rounded-tl-[5px] rounded-tr-[5px] pl-2 pr-4 duration-150"
|
||||
class="tabs-chrome__item-main group-[.is-active]:text-primary dark:group-[.is-active]:text-accent-foreground text-accent-foreground z-[2] mx-[calc(var(--gap)*2)] my-0 flex h-full items-center overflow-hidden rounded-tl-[5px] rounded-tr-[5px] pl-2 pr-4 duration-150"
|
||||
>
|
||||
<VbenIcon
|
||||
v-if="showIcon"
|
||||
@@ -168,7 +168,7 @@ const tabsView = computed((): TabConfig[] => {
|
||||
@apply pb-[2px];
|
||||
|
||||
&-content {
|
||||
@apply bg-accent-hover mx-[2px] rounded-md;
|
||||
@apply bg-accent mx-[2px] rounded-md;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -30,14 +30,15 @@ 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 border-l border-border`,
|
||||
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 [&:not(:first-child)]:border-l last:border-r last:border-r border-border`,
|
||||
},
|
||||
card: {
|
||||
content:
|
||||
'h-[calc(100%-6px)] rounded-md ml-2 border border-border transition-all',
|
||||
},
|
||||
plain: {
|
||||
content: 'h-full border-l border-border',
|
||||
content:
|
||||
'h-full [&:not(:first-child)]:border-l last:border-r border-border',
|
||||
},
|
||||
};
|
||||
|
||||
@@ -63,9 +64,9 @@ const tabsView = computed((): TabConfig[] => {
|
||||
<template>
|
||||
<div
|
||||
:class="contentClass"
|
||||
class="relative !flex h-full w-max items-center pr-6"
|
||||
class="relative !flex h-full w-max items-center overflow-y-hidden pr-6"
|
||||
>
|
||||
<TransitionGroup name="slide-right">
|
||||
<TransitionGroup name="slide-down">
|
||||
<div
|
||||
v-for="(tab, i) in tabsView"
|
||||
:key="tab.key"
|
||||
|
@@ -4,7 +4,11 @@ import type { TabsProps } from './types';
|
||||
|
||||
import { nextTick, onMounted, onUnmounted, ref, watch } from 'vue';
|
||||
|
||||
import { type Sortable, useSortable } from '@vben-core/composables';
|
||||
import {
|
||||
type Sortable,
|
||||
useIsMobile,
|
||||
useSortable,
|
||||
} from '@vben-core/composables';
|
||||
|
||||
// 可能会找到拖拽的子元素,这里需要确保拖拽的dom时tab元素
|
||||
function findParentElement(element: HTMLElement) {
|
||||
@@ -90,6 +94,12 @@ export function useTabsDrag(props: TabsProps, emit: EmitType) {
|
||||
}
|
||||
|
||||
async function init() {
|
||||
const { isMobile } = useIsMobile();
|
||||
|
||||
// 移动端下tab不需要拖拽
|
||||
if (isMobile.value) {
|
||||
return;
|
||||
}
|
||||
await nextTick();
|
||||
initTabsSortable();
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/constants",
|
||||
"version": "5.2.0",
|
||||
"version": "5.2.2",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/access",
|
||||
"version": "5.2.0",
|
||||
"version": "5.2.2",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
@@ -24,6 +24,6 @@
|
||||
"@vben/stores": "workspace:*",
|
||||
"@vben/types": "workspace:*",
|
||||
"@vben/utils": "workspace:*",
|
||||
"vue": "^3.4.38"
|
||||
"vue": "^3.5.1"
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/common-ui",
|
||||
"version": "5.2.0",
|
||||
"version": "5.2.2",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
@@ -29,7 +29,7 @@
|
||||
"@vben/types": "workspace:*",
|
||||
"@vueuse/integrations": "^11.0.3",
|
||||
"qrcode": "^1.5.4",
|
||||
"vue": "^3.4.38",
|
||||
"vue": "^3.5.1",
|
||||
"vue-router": "^4.4.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@@ -92,14 +92,16 @@ function handleGo(path: string) {
|
||||
|
||||
<template>
|
||||
<div @keydown.enter.prevent="handleSubmit">
|
||||
<Title>
|
||||
{{ title || `${$t('authentication.welcomeBack')} 👋🏻` }}
|
||||
<template #desc>
|
||||
<span class="text-muted-foreground">
|
||||
{{ subTitle || $t('authentication.loginSubtitle') }}
|
||||
</span>
|
||||
</template>
|
||||
</Title>
|
||||
<slot name="title">
|
||||
<Title>
|
||||
{{ title || `${$t('authentication.welcomeBack')} 👋🏻` }}
|
||||
<template #desc>
|
||||
<span class="text-muted-foreground">
|
||||
{{ subTitle || $t('authentication.loginSubtitle') }}
|
||||
</span>
|
||||
</template>
|
||||
</Title>
|
||||
</slot>
|
||||
|
||||
<VbenInput
|
||||
v-model="formState.username"
|
||||
@@ -123,7 +125,10 @@ function handleGo(path: string) {
|
||||
type="password"
|
||||
/>
|
||||
|
||||
<div class="mb-6 mt-4 flex justify-between">
|
||||
<div
|
||||
v-if="showRememberMe || showForgetPassword"
|
||||
class="mb-6 mt-4 flex justify-between"
|
||||
>
|
||||
<div v-if="showRememberMe" class="flex-center">
|
||||
<VbenCheckbox v-model:checked="formState.rememberMe" name="rememberMe">
|
||||
{{ $t('authentication.rememberMe') }}
|
||||
@@ -142,7 +147,10 @@ function handleGo(path: string) {
|
||||
{{ $t('common.login') }}
|
||||
</VbenButton>
|
||||
|
||||
<div class="mb-2 mt-4 flex items-center justify-between">
|
||||
<div
|
||||
v-if="showCodeLogin || showQrcodeLogin"
|
||||
class="mb-2 mt-4 flex items-center justify-between"
|
||||
>
|
||||
<VbenButton
|
||||
v-if="showCodeLogin"
|
||||
class="w-1/2"
|
||||
@@ -162,16 +170,20 @@ function handleGo(path: string) {
|
||||
</div>
|
||||
|
||||
<!-- 第三方登录 -->
|
||||
<ThirdPartyLogin v-if="showThirdPartyLogin" />
|
||||
<slot name="third-party-login">
|
||||
<ThirdPartyLogin v-if="showThirdPartyLogin" />
|
||||
</slot>
|
||||
|
||||
<div v-if="showRegister" class="text-center text-sm">
|
||||
{{ $t('authentication.accountTip') }}
|
||||
<span
|
||||
class="text-primary hover:text-primary-hover active:text-primary-active cursor-pointer text-sm font-normal"
|
||||
@click="handleGo(registerPath)"
|
||||
>
|
||||
{{ $t('authentication.createAccount') }}
|
||||
</span>
|
||||
</div>
|
||||
<slot name="to-register">
|
||||
<div v-if="showRegister" class="mt-3 text-center text-sm">
|
||||
{{ $t('authentication.accountTip') }}
|
||||
<span
|
||||
class="text-primary hover:text-primary-hover active:text-primary-active cursor-pointer text-sm font-normal"
|
||||
@click="handleGo(registerPath)"
|
||||
>
|
||||
{{ $t('authentication.createAccount') }}
|
||||
</span>
|
||||
</div>
|
||||
</slot>
|
||||
</div>
|
||||
</template>
|
||||
|
@@ -23,7 +23,7 @@ const defaultValue = computed(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="card-box w-full px-4 pb-5 pt-3 shadow">
|
||||
<div class="card-box w-full px-4 pb-5 pt-3">
|
||||
<Tabs :default-value="defaultValue">
|
||||
<TabsList>
|
||||
<template v-for="tab in tabs" :key="tab.label">
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/hooks",
|
||||
"version": "5.2.0",
|
||||
"version": "5.2.2",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
@@ -25,8 +25,8 @@
|
||||
"@vben/stores": "workspace:*",
|
||||
"@vben/types": "workspace:*",
|
||||
"@vben/utils": "workspace:*",
|
||||
"vue": "^3.4.38",
|
||||
"vue": "^3.5.1",
|
||||
"vue-router": "^4.4.3",
|
||||
"watermark-js-plus": "^1.5.3"
|
||||
"watermark-js-plus": "^1.5.4"
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import { reactive, watch } from 'vue';
|
||||
|
||||
import { preferences } from '@vben/preferences';
|
||||
import { preferences, usePreferences } from '@vben/preferences';
|
||||
import { convertToRgb, updateCSSVariables } from '@vben/utils';
|
||||
|
||||
/**
|
||||
@@ -160,53 +160,64 @@ export function useNaiveDesignTokens() {
|
||||
}
|
||||
|
||||
export function useElementPlusDesignTokens() {
|
||||
const { isDark } = usePreferences();
|
||||
const rootStyles = getComputedStyle(document.documentElement);
|
||||
|
||||
const getCssVariableValueRaw = (variable: string) => {
|
||||
return rootStyles.getPropertyValue(variable);
|
||||
};
|
||||
|
||||
const getCssVariableValue = (variable: string, isColor: boolean = true) => {
|
||||
const value = rootStyles.getPropertyValue(variable);
|
||||
const value = getCssVariableValueRaw(variable);
|
||||
return isColor ? convertToRgb(`hsl(${value})`) : value;
|
||||
};
|
||||
|
||||
watch(
|
||||
() => preferences.theme,
|
||||
() => {
|
||||
const background = getCssVariableValue('--background');
|
||||
const border = getCssVariableValue('--border');
|
||||
const accent = getCssVariableValue('--accent');
|
||||
|
||||
const variables: Record<string, string> = {
|
||||
'--el-bg-color': background,
|
||||
'--el-bg-color-overlay': getCssVariableValue('--popover'),
|
||||
'--el-bg-color-page': getCssVariableValue('--background-deep'),
|
||||
'--el-border-color': border,
|
||||
'--el-border-color-dark': border,
|
||||
'--el-border-color-hover': accent,
|
||||
'--el-border-color-light': border,
|
||||
'--el-border-color-lighter': border,
|
||||
'--el-border-radius-base': getCssVariableValue('--radius', false),
|
||||
|
||||
'--el-border-radius-base': getCssVariableValue('--radius', false),
|
||||
'--el-color-danger': getCssVariableValue('--destructive-500'),
|
||||
'--el-color-danger-dark-2': getCssVariableValue('--destructive'),
|
||||
'--el-color-danger-light-3': getCssVariableValue('--destructive-400'),
|
||||
'--el-color-danger-light-5': getCssVariableValue('--destructive-300'),
|
||||
'--el-color-danger-light-7': getCssVariableValue('--destructive-200'),
|
||||
'--el-color-danger-light-8': getCssVariableValue('--destructive-100'),
|
||||
'--el-color-danger-light-9': getCssVariableValue('--destructive-50'),
|
||||
|
||||
'--el-color-danger-light-9': getCssVariableValue('--destructive-50'),
|
||||
'--el-color-error': getCssVariableValue('--destructive-500'),
|
||||
'--el-color-error-dark-2': getCssVariableValue('--destructive'),
|
||||
'--el-color-error-light-3': getCssVariableValue('--destructive-400'),
|
||||
'--el-color-error-light-5': getCssVariableValue('--destructive-300'),
|
||||
'--el-color-error-light-7': getCssVariableValue('--destructive-200'),
|
||||
'--el-color-error-light-8': getCssVariableValue('--destructive-100'),
|
||||
|
||||
'--el-color-error-light-9': getCssVariableValue('--destructive-50'),
|
||||
|
||||
'--el-color-info-light-8': border,
|
||||
'--el-color-info-light-9': background,
|
||||
|
||||
'--el-color-info-light-9': background,
|
||||
'--el-color-primary': getCssVariableValue('--primary-500'),
|
||||
'--el-color-primary-dark-2': getCssVariableValue('--primary'),
|
||||
'--el-color-primary-light-3': getCssVariableValue('--primary-400'),
|
||||
'--el-color-primary-light-5': getCssVariableValue('--primary-300'),
|
||||
'--el-color-primary-light-7': getCssVariableValue('--primary-200'),
|
||||
'--el-color-primary-light-8': getCssVariableValue('--primary-100'),
|
||||
'--el-color-primary-light-9': getCssVariableValue('--primary-50'),
|
||||
'--el-color-primary-light-9': isDark.value
|
||||
? accent
|
||||
: getCssVariableValue('--primary-50'),
|
||||
|
||||
'--el-color-success': getCssVariableValue('--success-500'),
|
||||
'--el-color-success-dark-2': getCssVariableValue('--success'),
|
||||
@@ -214,18 +225,20 @@ export function useElementPlusDesignTokens() {
|
||||
'--el-color-success-light-5': getCssVariableValue('--success-300'),
|
||||
'--el-color-success-light-7': getCssVariableValue('--success-200'),
|
||||
'--el-color-success-light-8': getCssVariableValue('--success-100'),
|
||||
'--el-color-success-light-9': getCssVariableValue('--success-50'),
|
||||
|
||||
'--el-color-success-light-9': getCssVariableValue('--success-50'),
|
||||
'--el-color-warning': getCssVariableValue('--warning-500'),
|
||||
'--el-color-warning-dark-2': getCssVariableValue('--warning'),
|
||||
'--el-color-warning-light-3': getCssVariableValue('--warning-400'),
|
||||
'--el-color-warning-light-5': getCssVariableValue('--warning-300'),
|
||||
'--el-color-warning-light-7': getCssVariableValue('--warning-200'),
|
||||
'--el-color-warning-light-8': getCssVariableValue('--warning-100'),
|
||||
'--el-color-warning-light-9': getCssVariableValue('--warning-50'),
|
||||
|
||||
'--el-color-warning-light-9': getCssVariableValue('--warning-50'),
|
||||
'--el-fill-color-blank': background,
|
||||
'--el-fill-color-light': getCssVariableValue('--accent'),
|
||||
'--el-text-color-primary': getCssVariableValue('--foreground'),
|
||||
|
||||
'--el-text-color-regular': getCssVariableValue('--foreground'),
|
||||
};
|
||||
updateCSSVariables(variables, `__vben_design_styles__`);
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/layouts",
|
||||
"version": "5.2.0",
|
||||
"version": "5.2.2",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
@@ -34,7 +34,7 @@
|
||||
"@vben/types": "workspace:*",
|
||||
"@vben/utils": "workspace:*",
|
||||
"@vueuse/core": "^11.0.3",
|
||||
"vue": "^3.4.38",
|
||||
"vue": "^3.5.1",
|
||||
"vue-router": "^4.4.3"
|
||||
}
|
||||
}
|
||||
|
@@ -1,24 +1,28 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import type { ToolbarType } from './types';
|
||||
|
||||
import { $t } from '@vben/locales';
|
||||
import { preferences, usePreferences } from '@vben/preferences';
|
||||
|
||||
import { Copyright } from '../basic/copyright';
|
||||
import AuthenticationFormView from './form.vue';
|
||||
import SloganIcon from './icons/slogan.vue';
|
||||
import Toolbar from './toolbar.vue';
|
||||
|
||||
interface Props {
|
||||
appName?: string;
|
||||
logo?: string;
|
||||
pageTitle?: string;
|
||||
pageDescription?: string;
|
||||
sloganImage?: string;
|
||||
toolbar?: boolean;
|
||||
toolbarList?: ('color' | 'language' | 'layout' | 'theme')[];
|
||||
copyright?: boolean;
|
||||
toolbarList?: ToolbarType[];
|
||||
}
|
||||
|
||||
defineOptions({ name: 'Authentication' });
|
||||
|
||||
withDefaults(defineProps<Props>(), {
|
||||
appName: '',
|
||||
copyright: true,
|
||||
logo: '',
|
||||
pageDescription: '',
|
||||
pageTitle: '',
|
||||
sloganImage: '',
|
||||
@@ -26,31 +30,42 @@ withDefaults(defineProps<Props>(), {
|
||||
toolbarList: () => ['color', 'language', 'layout', 'theme'],
|
||||
});
|
||||
|
||||
const { authPanelCenter, authPanelLeft, authPanelRight } = usePreferences();
|
||||
const appName = computed(() => preferences.app.name);
|
||||
const logoSource = computed(() => preferences.logo.source);
|
||||
const { authPanelCenter, authPanelLeft, authPanelRight, isDark } =
|
||||
usePreferences();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex min-h-full flex-1 select-none overflow-x-hidden">
|
||||
<div
|
||||
:class="[isDark]"
|
||||
class="flex min-h-full flex-1 select-none overflow-x-hidden"
|
||||
>
|
||||
<template v-if="toolbar">
|
||||
<slot name="toolbar">
|
||||
<Toolbar :toolbar-list="toolbarList" />
|
||||
</slot>
|
||||
</template>
|
||||
<!-- 左侧认证面板 -->
|
||||
<AuthenticationFormView
|
||||
v-if="authPanelLeft"
|
||||
class="min-h-full w-2/5"
|
||||
class="min-h-full w-2/5 flex-1"
|
||||
transition-name="slide-left"
|
||||
>
|
||||
<template v-if="toolbar" #toolbar>
|
||||
<Toolbar :toolbar-list="toolbarList" />
|
||||
<template v-if="copyright" #copyright>
|
||||
<slot name="copyright">
|
||||
<Copyright
|
||||
v-if="preferences.copyright.enable"
|
||||
v-bind="preferences.copyright"
|
||||
/>
|
||||
</slot>
|
||||
</template>
|
||||
</AuthenticationFormView>
|
||||
|
||||
<!-- 头部 Logo 和应用名称 -->
|
||||
<div class="absolute left-0 top-0 z-10 flex flex-1">
|
||||
<div
|
||||
:class="authPanelRight ? 'lg:text-white' : 'lg:text-foreground'"
|
||||
class="text-foreground ml-4 mt-4 flex flex-1 items-center sm:left-6 sm:top-6"
|
||||
class="text-foreground lg:text-foreground ml-4 mt-4 flex flex-1 items-center sm:left-6 sm:top-6"
|
||||
>
|
||||
<img :alt="appName" :src="logoSource" class="mr-2" width="42" />
|
||||
<img :alt="appName" :src="logo" class="mr-2" width="42" />
|
||||
<p class="text-xl font-medium">
|
||||
{{ appName }}
|
||||
</p>
|
||||
@@ -59,7 +74,9 @@ const logoSource = computed(() => preferences.logo.source);
|
||||
|
||||
<!-- 系统介绍 -->
|
||||
<div v-if="!authPanelCenter" class="relative hidden w-0 flex-1 lg:block">
|
||||
<div class="absolute inset-0 h-full w-full bg-[#070709]">
|
||||
<div
|
||||
class="bg-background-deep absolute inset-0 h-full w-full dark:bg-[#070709]"
|
||||
>
|
||||
<div class="login-background absolute left-0 top-0 size-full"></div>
|
||||
<div class="flex-col-center -enter-x mr-20 h-full">
|
||||
<template v-if="sloganImage">
|
||||
@@ -70,11 +87,11 @@ const logoSource = computed(() => preferences.logo.source);
|
||||
/>
|
||||
</template>
|
||||
<SloganIcon v-else :alt="appName" class="animate-float h-64 w-2/5" />
|
||||
<div class="text-1xl mt-6 font-sans text-white lg:text-2xl">
|
||||
{{ pageTitle || $t('authentication.pageTitle') }}
|
||||
<div class="text-1xl text-foreground mt-6 font-sans lg:text-2xl">
|
||||
{{ pageTitle }}
|
||||
</div>
|
||||
<div class="dark:text-muted-foreground mt-2 text-white/60">
|
||||
{{ pageDescription || $t('authentication.pageDesc') }}
|
||||
<div class="dark:text-muted-foreground mt-2">
|
||||
{{ pageDescription }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -84,10 +101,15 @@ const logoSource = computed(() => preferences.logo.source);
|
||||
<div v-if="authPanelCenter" class="flex-center relative w-full">
|
||||
<div class="login-background absolute left-0 top-0 size-full"></div>
|
||||
<AuthenticationFormView
|
||||
class="md:bg-background shadow-primary/10 w-full rounded-3xl pb-20 shadow-2xl md:w-2/3 lg:w-1/2 xl:w-[36%]"
|
||||
class="md:bg-background shadow-primary/5 shadow-float w-full rounded-3xl pb-20 md:w-2/3 lg:w-1/2 xl:w-[36%]"
|
||||
>
|
||||
<template v-if="toolbar" #toolbar>
|
||||
<Toolbar :toolbar-list="toolbarList" />
|
||||
<template v-if="copyright" #copyright>
|
||||
<slot name="copyright">
|
||||
<Copyright
|
||||
v-if="preferences.copyright.enable"
|
||||
v-bind="preferences.copyright"
|
||||
/>
|
||||
</slot>
|
||||
</template>
|
||||
</AuthenticationFormView>
|
||||
</div>
|
||||
@@ -95,10 +117,15 @@ const logoSource = computed(() => preferences.logo.source);
|
||||
<!-- 右侧认证面板 -->
|
||||
<AuthenticationFormView
|
||||
v-if="authPanelRight"
|
||||
class="min-h-full w-2/5 flex-1"
|
||||
class="min-h-full w-[34%] flex-1"
|
||||
>
|
||||
<template v-if="toolbar" #toolbar>
|
||||
<Toolbar :toolbar-list="toolbarList" />
|
||||
<template v-if="copyright" #copyright>
|
||||
<slot name="copyright">
|
||||
<Copyright
|
||||
v-if="preferences.copyright.enable"
|
||||
v-bind="preferences.copyright"
|
||||
/>
|
||||
</slot>
|
||||
</template>
|
||||
</AuthenticationFormView>
|
||||
</div>
|
||||
@@ -109,9 +136,21 @@ const logoSource = computed(() => preferences.logo.source);
|
||||
background: linear-gradient(
|
||||
154deg,
|
||||
#07070915 30%,
|
||||
hsl(var(--primary) / 15%) 48%,
|
||||
hsl(var(--primary) / 30%) 48%,
|
||||
#07070915 64%
|
||||
);
|
||||
filter: blur(100px);
|
||||
}
|
||||
|
||||
.dark {
|
||||
.login-background {
|
||||
background: linear-gradient(
|
||||
154deg,
|
||||
#07070915 30%,
|
||||
hsl(var(--primary) / 20%) 48%,
|
||||
#07070915 64%
|
||||
);
|
||||
filter: blur(100px);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@@ -1,8 +1,4 @@
|
||||
<script setup lang="ts">
|
||||
import { preferences } from '@vben/preferences';
|
||||
|
||||
import { Copyright } from '../basic/copyright';
|
||||
|
||||
defineOptions({
|
||||
name: 'AuthenticationFormView',
|
||||
});
|
||||
@@ -10,11 +6,9 @@ defineOptions({
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="flex-col-center bg-background-deep relative px-6 py-10 lg:flex-initial lg:px-8"
|
||||
class="flex-col-center dark:bg-background-deep bg-background relative px-6 py-10 lg:flex-initial lg:px-8"
|
||||
>
|
||||
<!-- Toolbar Slot -->
|
||||
<slot name="toolbar"> </slot>
|
||||
|
||||
<slot></slot>
|
||||
<!-- Router View with Transition and KeepAlive -->
|
||||
<RouterView v-slot="{ Component, route }">
|
||||
<Transition appear mode="out-in" name="slide-right">
|
||||
@@ -29,13 +23,11 @@ defineOptions({
|
||||
</RouterView>
|
||||
|
||||
<!-- Footer Copyright -->
|
||||
|
||||
<div
|
||||
class="text-muted-foreground absolute bottom-3 flex text-center text-xs"
|
||||
>
|
||||
<Copyright
|
||||
v-if="preferences.copyright.enable"
|
||||
v-bind="preferences.copyright"
|
||||
/>
|
||||
<slot name="copyright"> </slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@@ -1,4 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import type { ToolbarType } from './types';
|
||||
|
||||
import { computed } from 'vue';
|
||||
|
||||
import {
|
||||
@@ -9,7 +11,7 @@ import {
|
||||
} from '../widgets';
|
||||
|
||||
interface Props {
|
||||
toolbarList?: ('color' | 'language' | 'layout' | 'theme')[];
|
||||
toolbarList?: ToolbarType[];
|
||||
}
|
||||
|
||||
defineOptions({
|
||||
@@ -29,8 +31,7 @@ const showTheme = computed(() => props.toolbarList.includes('theme'));
|
||||
<template>
|
||||
<div
|
||||
:class="{
|
||||
'bg-background dark:bg-accent rounded-3xl px-3 py-1':
|
||||
toolbarList.length > 1,
|
||||
'bg-accent z-10 rounded-3xl px-3 py-1': toolbarList.length > 1,
|
||||
}"
|
||||
class="flex-center absolute right-2 top-4"
|
||||
>
|
||||
|
1
packages/effects/layouts/src/authentication/types.ts
Normal file
1
packages/effects/layouts/src/authentication/types.ts
Normal file
@@ -0,0 +1 @@
|
||||
export type ToolbarType = 'color' | 'language' | 'layout' | 'theme';
|
@@ -1,16 +1,12 @@
|
||||
<script lang="ts" setup>
|
||||
import type { CSSProperties } from 'vue';
|
||||
|
||||
import { VbenSpinner } from '@vben-core/shadcn-ui';
|
||||
|
||||
import { useContentSpinner } from './use-content-spinner';
|
||||
|
||||
defineOptions({ name: 'LayoutContentSpinner' });
|
||||
|
||||
defineProps<{ overlayStyle: CSSProperties }>();
|
||||
|
||||
const { spinning } = useContentSpinner();
|
||||
</script>
|
||||
<template>
|
||||
<VbenSpinner :spinning="spinning" :style="overlayStyle" />
|
||||
<VbenSpinner :spinning="spinning" />
|
||||
</template>
|
||||
|
@@ -78,7 +78,7 @@ const isMenuRounded = computed(() => {
|
||||
});
|
||||
|
||||
const logoCollapsed = computed(() => {
|
||||
if (isMobile.value) {
|
||||
if (isMobile.value && sidebarCollapsed.value) {
|
||||
return true;
|
||||
}
|
||||
if (isHeaderNav.value || isMixedNav.value) {
|
||||
@@ -295,11 +295,8 @@ const headerSlots = computed(() => {
|
||||
<template #content>
|
||||
<LayoutContent />
|
||||
</template>
|
||||
<template
|
||||
v-if="preferences.transition.loading"
|
||||
#content-overlay="{ overlayStyle }"
|
||||
>
|
||||
<LayoutContentSpinner :overlay-style="overlayStyle" />
|
||||
<template v-if="preferences.transition.loading" #content-overlay>
|
||||
<LayoutContentSpinner />
|
||||
</template>
|
||||
|
||||
<!-- 页脚 -->
|
||||
|
@@ -6,7 +6,7 @@ import { computed } from 'vue';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
|
||||
import { $t } from '@vben/locales';
|
||||
import { VbenBackgroundBreadcrumb, VbenBreadcrumb } from '@vben-core/shadcn-ui';
|
||||
import { VbenBreadcrumbView } from '@vben-core/shadcn-ui';
|
||||
|
||||
interface Props {
|
||||
hideWhenOnlyOne?: boolean;
|
||||
@@ -62,17 +62,10 @@ function handleSelect(path: string) {
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<VbenBreadcrumb
|
||||
v-if="type === 'normal'"
|
||||
:breadcrumbs="breadcrumbs"
|
||||
:show-icon="showIcon"
|
||||
class="ml-2"
|
||||
@select="handleSelect"
|
||||
/>
|
||||
<VbenBackgroundBreadcrumb
|
||||
v-if="type === 'background'"
|
||||
<VbenBreadcrumbView
|
||||
:breadcrumbs="breadcrumbs"
|
||||
:show-icon="showIcon"
|
||||
:style-type="type"
|
||||
class="ml-2"
|
||||
@select="handleSelect"
|
||||
/>
|
||||
|
@@ -61,7 +61,7 @@ async function checkForUpdates() {
|
||||
}
|
||||
function handleNotice(versionTag: string) {
|
||||
const { dismiss } = toast({
|
||||
action: h('div', [
|
||||
action: h('div', { class: 'inline-flex items-center' }, [
|
||||
h(
|
||||
ToastAction,
|
||||
{
|
||||
@@ -76,7 +76,8 @@ function handleNotice(versionTag: string) {
|
||||
ToastAction,
|
||||
{
|
||||
altText: $t('common.refresh'),
|
||||
class: 'bg-primary hover:bg-primary-hover mx-1',
|
||||
class:
|
||||
'bg-primary text-primary-foreground hover:bg-primary-hover mx-1',
|
||||
onClick: () => {
|
||||
lastVersionTag.value = versionTag;
|
||||
window.location.reload();
|
||||
@@ -94,7 +95,11 @@ function handleNotice(versionTag: string) {
|
||||
}
|
||||
|
||||
function start() {
|
||||
// 每5分钟检查一次
|
||||
if (props.checkUpdatesInterval <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 每 checkUpdatesInterval(默认值为1) 分钟检查一次
|
||||
timer.value = setInterval(
|
||||
checkForUpdates,
|
||||
props.checkUpdatesInterval * 60 * 1000,
|
||||
|
@@ -23,7 +23,9 @@ const modelValue = defineModel<string>();
|
||||
class="hover:bg-accent flex w-full items-center justify-between rounded-md px-2 py-2"
|
||||
disabled
|
||||
>
|
||||
<span class="text-sm"><slot></slot></span>
|
||||
<span class="text-sm">
|
||||
<slot></slot>
|
||||
</span>
|
||||
<ToggleGroup
|
||||
v-model="modelValue"
|
||||
class="gap-2"
|
||||
|
@@ -309,8 +309,8 @@ async function handleReset() {
|
||||
|
||||
<Block :title="$t('preferences.header.title')">
|
||||
<Header
|
||||
v-model:headerEnable="headerEnable"
|
||||
v-model:headerMode="headerMode"
|
||||
v-model:header-enable="headerEnable"
|
||||
v-model:header-mode="headerMode"
|
||||
:disabled="isFullContent"
|
||||
/>
|
||||
</Block>
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/plugins",
|
||||
"version": "5.2.0",
|
||||
"version": "5.2.2",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
@@ -23,6 +23,6 @@
|
||||
"@vben/preferences": "workspace:*",
|
||||
"@vueuse/core": "^11.0.3",
|
||||
"echarts": "^5.5.1",
|
||||
"vue": "^3.4.38"
|
||||
"vue": "^3.5.1"
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vben/request",
|
||||
"version": "5.2.0",
|
||||
"version": "5.2.2",
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
@@ -22,7 +22,7 @@
|
||||
"dependencies": {
|
||||
"@vben/locales": "workspace:*",
|
||||
"@vben/utils": "workspace:*",
|
||||
"axios": "^1.7.5"
|
||||
"axios": "^1.7.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"axios-mock-adapter": "^2.0.0"
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user