feat: optimize logo display (#6267)

* feat(VbenAvatar): add fit property to VbenAvatar component

* feat(VbenLogo): add fit property to VbenLogo component

* feat(VbenLogo): add logo fit preference configuration

- Add preferences.logo.fit setting for logo display control
- Include corresponding documentation for the new preference

* feat(preferences): add default value for logo.fit preference

- Set default configuration for logo fit behavior
- Ensures consistent logo display across applications

* test(preferences): update configuration snapshots

---------

Co-authored-by: wyc001122 <wangyongchao@testor.com.cn>
This commit is contained in:
wyc001122 2025-05-23 15:24:01 +08:00 committed by GitHub
parent 48d70182b4
commit 97894a940e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 31 additions and 1 deletions

View File

@ -238,6 +238,7 @@ const defaultPreferences: Preferences = {
}, },
logo: { logo: {
enable: true, enable: true,
fit: 'contain',
source: 'https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.webp', source: 'https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.webp',
}, },
navigation: { navigation: {
@ -431,6 +432,8 @@ interface HeaderPreferences {
interface LogoPreferences { interface LogoPreferences {
/** Whether the logo is visible */ /** Whether the logo is visible */
enable: boolean; enable: boolean;
/** Logo image fitting method */
fit: 'contain' | 'cover' | 'fill' | 'none' | 'scale-down';
/** Logo URL */ /** Logo URL */
source: string; source: string;
} }

View File

@ -237,6 +237,7 @@ const defaultPreferences: Preferences = {
}, },
logo: { logo: {
enable: true, enable: true,
fit: 'contain',
source: 'https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.webp', source: 'https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.webp',
}, },
navigation: { navigation: {
@ -431,6 +432,8 @@ interface HeaderPreferences {
interface LogoPreferences { interface LogoPreferences {
/** logo是否可见 */ /** logo是否可见 */
enable: boolean; enable: boolean;
/** logo图片适应方式 */
fit: 'contain' | 'cover' | 'fill' | 'none' | 'scale-down';
/** logo地址 */ /** logo地址 */
source: string; source: string;
} }

View File

@ -61,6 +61,7 @@ exports[`defaultPreferences immutability test > should not modify the config obj
}, },
"logo": { "logo": {
"enable": true, "enable": true,
"fit": "contain",
"source": "https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.webp", "source": "https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.webp",
}, },
"navigation": { "navigation": {

View File

@ -62,6 +62,7 @@ const defaultPreferences: Preferences = {
logo: { logo: {
enable: true, enable: true,
fit: 'contain',
source: 'https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.webp', source: 'https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.webp',
}, },
navigation: { navigation: {

View File

@ -134,6 +134,8 @@ interface HeaderPreferences {
interface LogoPreferences { interface LogoPreferences {
/** logo是否可见 */ /** logo是否可见 */
enable: boolean; enable: boolean;
/** logo图片适应方式 */
fit: 'contain' | 'cover' | 'fill' | 'none' | 'scale-down';
/** logo地址 */ /** logo地址 */
source: string; source: string;
} }

View File

@ -5,6 +5,8 @@ import type {
AvatarRootProps, AvatarRootProps,
} from 'radix-vue'; } from 'radix-vue';
import type { CSSProperties } from 'vue';
import type { ClassType } from '@vben-core/typings'; import type { ClassType } from '@vben-core/typings';
import { computed } from 'vue'; import { computed } from 'vue';
@ -16,6 +18,7 @@ interface Props extends AvatarFallbackProps, AvatarImageProps, AvatarRootProps {
class?: ClassType; class?: ClassType;
dot?: boolean; dot?: boolean;
dotClass?: ClassType; dotClass?: ClassType;
fit?: 'contain' | 'cover' | 'fill' | 'none' | 'scale-down';
size?: number; size?: number;
} }
@ -28,6 +31,15 @@ const props = withDefaults(defineProps<Props>(), {
as: 'button', as: 'button',
dot: false, dot: false,
dotClass: 'bg-green-500', dotClass: 'bg-green-500',
fit: 'cover',
});
const imageStyle = computed<CSSProperties>(() => {
const { fit } = props;
if (fit) {
return { objectFit: fit };
}
return {};
}); });
const text = computed(() => { const text = computed(() => {
@ -51,7 +63,7 @@ const rootStyle = computed(() => {
class="relative flex flex-shrink-0 items-center" class="relative flex flex-shrink-0 items-center"
> >
<Avatar :class="props.class" class="size-full"> <Avatar :class="props.class" class="size-full">
<AvatarImage :alt="alt" :src="src" /> <AvatarImage :alt="alt" :src="src" :style="imageStyle" />
<AvatarFallback>{{ text }}</AvatarFallback> <AvatarFallback>{{ text }}</AvatarFallback>
</Avatar> </Avatar>
<span <span

View File

@ -6,6 +6,10 @@ interface Props {
* @zh_CN 是否收起文本 * @zh_CN 是否收起文本
*/ */
collapsed?: boolean; collapsed?: boolean;
/**
* @zh_CN Logo 图片适应方式
*/
fit?: 'contain' | 'cover' | 'fill' | 'none' | 'scale-down';
/** /**
* @zh_CN Logo 跳转地址 * @zh_CN Logo 跳转地址
*/ */
@ -38,6 +42,7 @@ withDefaults(defineProps<Props>(), {
logoSize: 32, logoSize: 32,
src: '', src: '',
theme: 'light', theme: 'light',
fit: 'cover',
}); });
</script> </script>
@ -53,6 +58,7 @@ withDefaults(defineProps<Props>(), {
:alt="text" :alt="text"
:src="src" :src="src"
:size="logoSize" :size="logoSize"
:fit="fit"
class="relative rounded-none bg-transparent" class="relative rounded-none bg-transparent"
/> />
<template v-if="!collapsed"> <template v-if="!collapsed">

View File

@ -234,6 +234,7 @@ const headerSlots = computed(() => {
<template #logo> <template #logo>
<VbenLogo <VbenLogo
v-if="preferences.logo.enable" v-if="preferences.logo.enable"
:fit="preferences.logo.fit"
:class="logoClass" :class="logoClass"
:collapsed="logoCollapsed" :collapsed="logoCollapsed"
:src="preferences.logo.source" :src="preferences.logo.source"
@ -324,6 +325,7 @@ const headerSlots = computed(() => {
<template #side-extra-title> <template #side-extra-title>
<VbenLogo <VbenLogo
v-if="preferences.logo.enable" v-if="preferences.logo.enable"
:fit="preferences.logo.fit"
:text="preferences.app.name" :text="preferences.app.name"
:theme="theme" :theme="theme"
> >