Skip to content

Commit c7c3904

Browse files
Copilotaonoalikui628
authored
feat: add theme-aware logo support via optional sourceDark configuration (#6866)
* Initial plan * Initial exploration and setup Co-authored-by: aonoa <[email protected]> * Add support for separate light and dark theme logos Co-authored-by: aonoa <[email protected]> * Update documentation with dark theme logo configuration Co-authored-by: aonoa <[email protected]> * feat: Add theme-aware logo support for authentication/login page Co-authored-by: aonoa <[email protected]> * revert: .npmrc Signed-off-by: aonoa <[email protected]> --------- Signed-off-by: aonoa <[email protected]> Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: aonoa <[email protected]> Co-authored-by: Li Kui <[email protected]> Co-authored-by: aonoa <[email protected]>
1 parent f8a7a0a commit c7c3904

File tree

12 files changed

+76
-14
lines changed

12 files changed

+76
-14
lines changed

.npmrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
registry = "https://registry.npmmirror.com"
1+
registry=https://registry.npmmirror.com
22
public-hoist-pattern[]=lefthook
33
public-hoist-pattern[]=eslint
44
public-hoist-pattern[]=prettier

apps/web-antd/src/layouts/auth.vue

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@ import { $t } from '#/locales';
88
99
const appName = computed(() => preferences.app.name);
1010
const logo = computed(() => preferences.logo.source);
11+
const logoDark = computed(() => preferences.logo.sourceDark);
1112
</script>
1213

1314
<template>
1415
<AuthPageLayout
1516
:app-name="appName"
1617
:logo="logo"
18+
:logo-dark="logoDark"
1719
:page-description="$t('authentication.pageDesc')"
1820
:page-title="$t('authentication.pageTitle')"
1921
>

apps/web-ele/src/layouts/auth.vue

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@ import { $t } from '#/locales';
88
99
const appName = computed(() => preferences.app.name);
1010
const logo = computed(() => preferences.logo.source);
11+
const logoDark = computed(() => preferences.logo.sourceDark);
1112
</script>
1213

1314
<template>
1415
<AuthPageLayout
1516
:app-name="appName"
1617
:logo="logo"
18+
:logo-dark="logoDark"
1719
:page-description="$t('authentication.pageDesc')"
1820
:page-title="$t('authentication.pageTitle')"
1921
>

apps/web-naive/src/layouts/auth.vue

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@ import { $t } from '#/locales';
88
99
const appName = computed(() => preferences.app.name);
1010
const logo = computed(() => preferences.logo.source);
11+
const logoDark = computed(() => preferences.logo.sourceDark);
1112
</script>
1213

1314
<template>
1415
<AuthPageLayout
1516
:app-name="appName"
1617
:logo="logo"
18+
:logo-dark="logoDark"
1719
:page-description="$t('authentication.pageDesc')"
1820
:page-title="$t('authentication.pageTitle')"
1921
>

docs/src/en/guide/essentials/settings.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@ const defaultPreferences: Preferences = {
261261
enable: true,
262262
fit: 'contain',
263263
source: 'https://unpkg.com/@vbenjs/[email protected]/source/logo-v1.webp',
264+
// sourceDark: 'https://unpkg.com/@vbenjs/[email protected]/source/logo-dark.webp', // Optional: Dark theme logo
264265
},
265266
navigation: {
266267
accordion: true,
@@ -457,6 +458,8 @@ interface LogoPreferences {
457458
fit: 'contain' | 'cover' | 'fill' | 'none' | 'scale-down';
458459
/** Logo URL */
459460
source: string;
461+
/** Dark theme logo URL (optional, if not set, use source) */
462+
sourceDark?: string;
460463
}
461464

462465
interface NavigationPreferences {

docs/src/guide/essentials/settings.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ const defaultPreferences: Preferences = {
260260
enable: true,
261261
fit: 'contain',
262262
source: 'https://unpkg.com/@vbenjs/[email protected]/source/logo-v1.webp',
263+
// sourceDark: 'https://unpkg.com/@vbenjs/[email protected]/source/logo-dark.webp', // 可选:暗色主题logo
263264
},
264265
navigation: {
265266
accordion: true,
@@ -457,6 +458,8 @@ interface LogoPreferences {
457458
fit: 'contain' | 'cover' | 'fill' | 'none' | 'scale-down';
458459
/** logo地址 */
459460
source: string;
461+
/** 暗色主题logo地址 (可选,若不设置则使用 source) */
462+
sourceDark?: string;
460463
}
461464

462465
interface NavigationPreferences {

packages/@core/base/shared/src/utils/date.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import dayjs from "dayjs";
2-
import timezone from "dayjs/plugin/timezone";
3-
import utc from "dayjs/plugin/utc";
1+
import dayjs from 'dayjs';
2+
import timezone from 'dayjs/plugin/timezone';
3+
import utc from 'dayjs/plugin/utc';
44

55
dayjs.extend(utc);
66
dayjs.extend(timezone);

packages/@core/preferences/src/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,8 @@ interface LogoPreferences {
146146
fit: 'contain' | 'cover' | 'fill' | 'none' | 'scale-down';
147147
/** logo地址 */
148148
source: string;
149+
/** 暗色主题logo地址 (可选,若不设置则使用 source) */
150+
sourceDark?: string;
149151
}
150152

151153
interface NavigationPreferences {

packages/@core/ui-kit/shadcn-ui/src/components/logo/logo.vue

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
<script setup lang="ts">
2+
import { computed } from 'vue';
3+
24
import { VbenAvatar } from '../avatar';
35
46
interface Props {
@@ -22,6 +24,10 @@ interface Props {
2224
* @zh_CN Logo 图标
2325
*/
2426
src?: string;
27+
/**
28+
* @zh_CN 暗色主题 Logo 图标 (可选,若不设置则使用 src)
29+
*/
30+
srcDark?: string;
2531
/**
2632
* @zh_CN Logo 文本
2733
*/
@@ -36,14 +42,27 @@ defineOptions({
3642
name: 'VbenLogo',
3743
});
3844
39-
withDefaults(defineProps<Props>(), {
45+
const props = withDefaults(defineProps<Props>(), {
4046
collapsed: false,
4147
href: 'javascript:void 0',
4248
logoSize: 32,
4349
src: '',
50+
srcDark: '',
4451
theme: 'light',
4552
fit: 'cover',
4653
});
54+
55+
/**
56+
* @zh_CN 根据主题选择合适的 logo 图标
57+
*/
58+
const logoSrc = computed(() => {
59+
// 如果是暗色主题且提供了 srcDark,则使用暗色主题的 logo
60+
if (props.theme === 'dark' && props.srcDark) {
61+
return props.srcDark;
62+
}
63+
// 否则使用默认的 src
64+
return props.src;
65+
});
4766
</script>
4867

4968
<template>
@@ -54,9 +73,9 @@ withDefaults(defineProps<Props>(), {
5473
class="flex h-full items-center gap-2 overflow-hidden px-3 text-lg leading-normal transition-all duration-500"
5574
>
5675
<VbenAvatar
57-
v-if="src"
76+
v-if="logoSrc"
5877
:alt="text"
59-
:src="src"
78+
:src="logoSrc"
6079
:size="logoSize"
6180
:fit="fit"
6281
class="relative rounded-none bg-transparent"

packages/effects/layouts/src/authentication/authentication.vue

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
<script setup lang="ts">
22
import type { ToolbarType } from './types';
33
4+
import { computed } from 'vue';
5+
46
import { preferences, usePreferences } from '@vben/preferences';
57
68
import { Copyright } from '../basic/copyright';
@@ -11,6 +13,7 @@ import Toolbar from './toolbar.vue';
1113
interface Props {
1214
appName?: string;
1315
logo?: string;
16+
logoDark?: string;
1417
pageTitle?: string;
1518
pageDescription?: string;
1619
sloganImage?: string;
@@ -20,10 +23,11 @@ interface Props {
2023
clickLogo?: () => void;
2124
}
2225
23-
withDefaults(defineProps<Props>(), {
26+
const props = withDefaults(defineProps<Props>(), {
2427
appName: '',
2528
copyright: true,
2629
logo: '',
30+
logoDark: '',
2731
pageDescription: '',
2832
pageTitle: '',
2933
sloganImage: '',
@@ -34,6 +38,18 @@ withDefaults(defineProps<Props>(), {
3438
3539
const { authPanelCenter, authPanelLeft, authPanelRight, isDark } =
3640
usePreferences();
41+
42+
/**
43+
* @zh_CN 根据主题选择合适的 logo 图标
44+
*/
45+
const logoSrc = computed(() => {
46+
// 如果是暗色主题且提供了 logoDark,则使用暗色主题的 logo
47+
if (isDark.value && props.logoDark) {
48+
return props.logoDark;
49+
}
50+
// 否则使用默认的 logo
51+
return props.logo;
52+
});
3753
</script>
3854

3955
<template>
@@ -65,14 +81,21 @@ const { authPanelCenter, authPanelLeft, authPanelRight, isDark } =
6581
<slot name="logo">
6682
<!-- 头部 Logo 和应用名称 -->
6783
<div
68-
v-if="logo || appName"
84+
v-if="logoSrc || appName"
6985
class="absolute left-0 top-0 z-10 flex flex-1"
7086
@click="clickLogo"
7187
>
7288
<div
7389
class="text-foreground lg:text-foreground ml-4 mt-4 flex flex-1 items-center sm:left-6 sm:top-6"
7490
>
75-
<img v-if="logo" :alt="appName" :src="logo" class="mr-2" width="42" />
91+
<img
92+
v-if="logoSrc"
93+
:key="logoSrc"
94+
:alt="appName"
95+
:src="logoSrc"
96+
class="mr-2"
97+
width="42"
98+
/>
7699
<p v-if="appName" class="m-0 text-xl font-medium">
77100
{{ appName }}
78101
</p>

0 commit comments

Comments
 (0)