فهرست منبع

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>
wyc001122 4 ماه پیش
والد
کامیت
97894a940e

+ 3 - 0
docs/src/en/guide/essentials/settings.md

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

+ 3 - 0
docs/src/guide/essentials/settings.md

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

+ 1 - 0
packages/@core/preferences/__tests__/__snapshots__/config.test.ts.snap

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

+ 1 - 0
packages/@core/preferences/src/config.ts

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

+ 2 - 0
packages/@core/preferences/src/types.ts

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

+ 13 - 1
packages/@core/ui-kit/shadcn-ui/src/components/avatar/avatar.vue

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

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

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

+ 2 - 0
packages/effects/layouts/src/basic/layout.vue

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