Files
memind/src/components/UserAvatar.tsx
T
John 2e14873f2d Initial commit: Memind H5 portal with MindSpace, Plaza, and agent jobs.
Track application source and tests; exclude local env, user workspaces, and runtime data via .gitignore.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-15 15:04:43 -07:00

57 lines
1.5 KiB
TypeScript

type UserAvatarProps = {
avatarUrl?: string | null;
size?: 'sm' | 'md';
className?: string;
onClick?: () => void;
title?: string;
};
function DefaultUserAvatar() {
return (
<svg viewBox="0 0 40 40" fill="none" aria-hidden="true">
<rect width="40" height="40" rx="6" fill="#c8c8c8" />
<circle cx="20" cy="15" r="6.5" fill="#f5f5f5" />
<path d="M9 31c2.5-5.5 7-8.5 11-8.5s8.5 3 11 8.5" fill="#f5f5f5" />
</svg>
);
}
export function UserAvatar({
avatarUrl,
size = 'sm',
className = '',
onClick,
title,
}: UserAvatarProps) {
const sizeClass = size === 'md' ? 'user-avatar-md' : 'user-avatar-sm';
const interactive = Boolean(onClick);
return (
<div
className={`user-avatar ${sizeClass} ${interactive ? 'user-avatar-interactive' : ''} ${className}`.trim()}
role={interactive ? 'button' : undefined}
tabIndex={interactive ? 0 : undefined}
aria-label={interactive ? title ?? '更换头像' : undefined}
title={title}
onClick={onClick}
onKeyDown={
interactive
? (e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
onClick?.();
}
}
: undefined
}
>
{avatarUrl ? (
<img src={avatarUrl} alt="" className="user-avatar-img" />
) : (
<DefaultUserAvatar />
)}
{interactive && <span className="user-avatar-edit-badge" aria-hidden="true" />}
</div>
);
}