Write on the margins of the internet. Powered by the AT Protocol. margin.at
extension web atproto comments
at main 61 lines 1.4 kB view raw
1import React from "react"; 2import { User } from "lucide-react"; 3import { clsx } from "clsx"; 4import { getAvatarUrl } from "../../api/client"; 5 6type AvatarSize = "xs" | "sm" | "md" | "lg" | "xl"; 7 8interface AvatarProps { 9 did?: string; 10 avatar?: string; 11 src?: string; 12 alt?: string; 13 size?: AvatarSize; 14 className?: string; 15} 16 17const sizes: Record<AvatarSize, { container: string; icon: number }> = { 18 xs: { container: "h-6 w-6", icon: 12 }, 19 sm: { container: "h-8 w-8", icon: 14 }, 20 md: { container: "h-10 w-10", icon: 18 }, 21 lg: { container: "h-14 w-14", icon: 24 }, 22 xl: { container: "h-20 w-20", icon: 32 }, 23}; 24 25export default function Avatar({ 26 did, 27 avatar, 28 src, 29 alt = "Avatar", 30 size = "md", 31 className, 32}: AvatarProps) { 33 const imageUrl = src || getAvatarUrl(did, avatar); 34 const { container, icon } = sizes[size]; 35 36 if (imageUrl) { 37 return ( 38 <img 39 src={imageUrl} 40 alt={alt} 41 className={clsx( 42 container, 43 "rounded-full object-cover bg-surface-100 dark:bg-surface-800", 44 className, 45 )} 46 /> 47 ); 48 } 49 50 return ( 51 <div 52 className={clsx( 53 container, 54 "rounded-full bg-surface-100 dark:bg-surface-800 flex items-center justify-center text-surface-400 dark:text-surface-500", 55 className, 56 )} 57 > 58 <User size={icon} /> 59 </div> 60 ); 61}