Files
lingxi-web/src/components/ui/avatar.tsx
T

57 lines
1.4 KiB
TypeScript

import { cn } from '@/utils/cn'
import { colorFromString, initials } from '@/utils/misc'
export function Avatar({
name,
src,
size = 'md',
className,
online,
}: {
name: string
src?: string
size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl'
className?: string
online?: boolean
}) {
const sizes = {
xs: 'h-6 w-6 text-[10px]',
sm: 'h-8 w-8 text-xs',
md: 'h-10 w-10 text-sm',
lg: 'h-12 w-12 text-base',
xl: 'h-16 w-16 text-lg',
}
return (
<span className={cn('relative inline-flex shrink-0', className)}>
<span
className={cn(
'flex items-center justify-center rounded-full font-medium',
sizes[size],
colorFromString(name || '?'),
)}
>
{src ? (
<img
src={src}
alt={name}
className="h-full w-full rounded-full object-cover"
onError={(event) => {
event.currentTarget.style.display = 'none'
event.currentTarget.nextElementSibling?.classList.remove('hidden')
}}
/>
) : null}
<span className={cn(src && 'hidden')}>{initials(name)}</span>
</span>
{online !== undefined && (
<span
className={cn(
'absolute bottom-0 right-0 h-2.5 w-2.5 rounded-full border-2 border-card',
online ? 'bg-emerald-500' : 'bg-gray-300',
)}
/>
)}
</span>
)
}