doctor-mail/apps/web/src/components/common/element/Avatar.tsx

50 lines
1.4 KiB
TypeScript
Raw Normal View History

2024-12-31 15:57:32 +08:00
import { useMemo } from 'react';
interface AvatarProps {
src?: string;
name?: string;
size?: number;
className?: string;
}
export function Avatar({ src, name = '', size = 40, className = '' }: AvatarProps) {
const initials = useMemo(() => {
return name
.split(/\s+|(?=[A-Z])/)
.map(word => word[0])
.slice(0, 2)
.join('')
.toUpperCase();
}, [name]);
const backgroundColor = useMemo(() => {
let hash = 0;
for (let i = 0; i < name.length; i++) {
hash = name.charCodeAt(i) + ((hash << 5) - hash);
}
const hue = hash % 360;
return `hsl(${hue}, 70%, 50%)`;
}, [name]);
return (
<div
className={`relative rounded-full overflow-hidden ${className}`}
style={{ width: size, height: size }}
>
{src ? (
<img
src={src}
alt={name}
className="w-full h-full object-cover"
/>
) : (
<div
className="w-full h-full flex items-center justify-center text-white font-medium"
style={{ backgroundColor }}
>
<span style={{ fontSize: `${size * 0.4}px` }}>{initials}</span>
</div>
)}
</div>
);
}