From b1cfd835f5927a445cfc3ff72d15204d9f403cfb Mon Sep 17 00:00:00 2001 From: yyh <92089059+lyzno1@users.noreply.github.com> Date: Wed, 25 Mar 2026 13:43:46 +0800 Subject: [PATCH] refactor(web): expose avatar primitives for composition (#34057) --- web/app/components/base/avatar/index.tsx | 28 +++++++++++++++--------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/web/app/components/base/avatar/index.tsx b/web/app/components/base/avatar/index.tsx index 2d55ec2720..461154226d 100644 --- a/web/app/components/base/avatar/index.tsx +++ b/web/app/components/base/avatar/index.tsx @@ -2,7 +2,7 @@ import type { ImageLoadingStatus } from '@base-ui/react/avatar' import { Avatar as BaseAvatar } from '@base-ui/react/avatar' import { cn } from '@/utils/classnames' -const SIZES = { +export const avatarSizeClasses = { 'xxs': { root: 'size-4', text: 'text-[7px]' }, 'xs': { root: 'size-5', text: 'text-[8px]' }, 'sm': { root: 'size-6', text: 'text-[10px]' }, @@ -13,7 +13,9 @@ const SIZES = { '3xl': { root: 'size-16', text: 'text-2xl' }, } as const -export type AvatarSize = keyof typeof SIZES +export type AvatarSize = keyof typeof avatarSizeClasses + +export const getAvatarSizeClassNames = (size: AvatarSize) => avatarSizeClasses[size] export type AvatarProps = { name: string @@ -23,7 +25,13 @@ export type AvatarProps = { onLoadingStatusChange?: (status: ImageLoadingStatus) => void } -const BASE_CLASS = 'relative inline-flex shrink-0 select-none items-center justify-center overflow-hidden rounded-full bg-primary-600' +export const AvatarRoot = BaseAvatar.Root +export const AvatarImage = BaseAvatar.Image +export const AvatarFallback = BaseAvatar.Fallback + +const ROOT_CLASS_NAME = 'relative inline-flex shrink-0 select-none items-center justify-center overflow-hidden rounded-full bg-primary-600' +const IMAGE_CLASS_NAME = 'absolute inset-0 size-full object-cover' +const FALLBACK_CLASS_NAME = 'flex size-full items-center justify-center font-medium text-white' export const Avatar = ({ name, @@ -32,21 +40,21 @@ export const Avatar = ({ className, onLoadingStatusChange, }: AvatarProps) => { - const sizeConfig = SIZES[size] + const sizeClassNames = getAvatarSizeClassNames(size) return ( - + {avatar && ( - )} - + {name?.[0]?.toLocaleUpperCase()} - - + + ) }