- Use real logo/isotype SVGs across app and emails - Token-based color system aligned with landing (brand scale + semantic tokens) - ThemeProvider (light/dark/system) with header toggle and settings card - Embed logo in transactional emails; centralize email colors
41 lines
966 B
TypeScript
41 lines
966 B
TypeScript
import { forwardRef, type HTMLAttributes } from 'react'
|
|
import { cn } from '../../lib/utils'
|
|
|
|
export type AvatarProps = HTMLAttributes<HTMLDivElement> & {
|
|
name?: string
|
|
src?: string
|
|
}
|
|
|
|
function initials(name?: string) {
|
|
if (!name) return '?'
|
|
return name
|
|
.split(/\s+/)
|
|
.filter(Boolean)
|
|
.slice(0, 2)
|
|
.map((part) => part[0]?.toUpperCase() ?? '')
|
|
.join('')
|
|
}
|
|
|
|
export const Avatar = forwardRef<HTMLDivElement, AvatarProps>(
|
|
({ className, name, src, ...props }, ref) => {
|
|
return (
|
|
<div
|
|
ref={ref}
|
|
className={cn(
|
|
'flex size-9 shrink-0 items-center justify-center overflow-hidden rounded-xl bg-accent text-sm font-semibold text-on-accent',
|
|
className,
|
|
)}
|
|
{...props}
|
|
>
|
|
{src ? (
|
|
<img src={src} alt={name ?? 'avatar'} className="size-full object-cover" />
|
|
) : (
|
|
initials(name)
|
|
)}
|
|
</div>
|
|
)
|
|
},
|
|
)
|
|
|
|
Avatar.displayName = 'Avatar'
|