77 lines
2.0 KiB
TypeScript
77 lines
2.0 KiB
TypeScript
import React from 'react';
|
||
import { UserCircle } from 'lucide-react';
|
||
|
||
interface AvatarProps {
|
||
children: React.ReactNode;
|
||
className?: string;
|
||
}
|
||
|
||
export function Avatar({ children, className = '' }: AvatarProps) {
|
||
return (
|
||
<div className={`relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full ${className}`}>
|
||
{children}
|
||
</div>
|
||
);
|
||
}
|
||
|
||
interface AvatarImageProps {
|
||
src?: string;
|
||
alt?: string;
|
||
className?: string;
|
||
}
|
||
|
||
export function AvatarImage({ src, alt, className = '' }: AvatarImageProps) {
|
||
if (!src) return null;
|
||
|
||
return (
|
||
<img
|
||
src={src}
|
||
alt={alt || '头像'}
|
||
className={`aspect-square h-full w-full object-cover ${className}`}
|
||
onError={(e) => {
|
||
// 图片加载失败时隐藏图片,显示fallback
|
||
const target = e.target as HTMLImageElement;
|
||
target.style.display = 'none';
|
||
}}
|
||
/>
|
||
);
|
||
}
|
||
|
||
interface AvatarFallbackProps {
|
||
children?: React.ReactNode;
|
||
className?: string;
|
||
variant?: 'default' | 'gradient' | 'solid' | 'outline';
|
||
showUserIcon?: boolean;
|
||
}
|
||
|
||
export function AvatarFallback({
|
||
children,
|
||
className = '',
|
||
variant = 'default',
|
||
showUserIcon = true
|
||
}: AvatarFallbackProps) {
|
||
const getVariantClasses = () => {
|
||
switch (variant) {
|
||
case 'gradient':
|
||
return 'bg-gradient-to-br from-blue-500 to-purple-600 text-white shadow-lg';
|
||
case 'solid':
|
||
return 'bg-blue-500 text-white';
|
||
case 'outline':
|
||
return 'bg-white border-2 border-blue-500 text-blue-500';
|
||
default:
|
||
return 'bg-gradient-to-br from-blue-100 to-blue-200 text-blue-600';
|
||
}
|
||
};
|
||
|
||
return (
|
||
<div className={`flex h-full w-full items-center justify-center rounded-full ${getVariantClasses()} ${className}`}>
|
||
{children ? (
|
||
<span className="text-sm font-medium">{children}</span>
|
||
) : showUserIcon ? (
|
||
<UserCircle className="h-1/2 w-1/2" />
|
||
) : (
|
||
<span className="text-sm font-medium">用户</span>
|
||
)}
|
||
</div>
|
||
);
|
||
}
|