56 lines
1.5 KiB
TypeScript
56 lines
1.5 KiB
TypeScript
import React from 'react';
|
|
import { View, Text, Image } from 'react-native';
|
|
|
|
interface AvatarProps {
|
|
name?: string;
|
|
uri?: string;
|
|
size?: 'sm' | 'md' | 'lg' | 'xl';
|
|
}
|
|
|
|
const sizeClasses = {
|
|
sm: { container: 'w-8 h-8', text: 'text-xs' },
|
|
md: { container: 'w-10 h-10', text: 'text-sm' },
|
|
lg: { container: 'w-14 h-14', text: 'text-xl' },
|
|
xl: { container: 'w-20 h-20', text: 'text-3xl' },
|
|
};
|
|
|
|
const sizePx = { sm: 32, md: 40, lg: 56, xl: 80 };
|
|
|
|
function getInitials(name: string) {
|
|
return name
|
|
.split(' ')
|
|
.slice(0, 2)
|
|
.map((n) => n[0])
|
|
.join('')
|
|
.toUpperCase();
|
|
}
|
|
|
|
function hashColor(name: string) {
|
|
const colors = ['bg-blue-500', 'bg-purple-500', 'bg-green-500', 'bg-orange-500', 'bg-pink-500', 'bg-teal-500'];
|
|
let hash = 0;
|
|
for (const ch of name) hash = (hash * 31 + ch.charCodeAt(0)) & 0xffffffff;
|
|
return colors[Math.abs(hash) % colors.length];
|
|
}
|
|
|
|
export const Avatar: React.FC<AvatarProps> = ({ name = '', uri, size = 'md' }) => {
|
|
const { container, text } = sizeClasses[size];
|
|
const px = sizePx[size];
|
|
|
|
if (uri) {
|
|
return (
|
|
<Image
|
|
source={{ uri }}
|
|
className={`${container} rounded-full`}
|
|
style={{ width: px, height: px, borderRadius: px / 2 }}
|
|
/>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<View className={`${container} ${hashColor(name)} rounded-full items-center justify-center`}
|
|
style={{ width: px, height: px, borderRadius: px / 2 }}>
|
|
<Text className={`${text} font-bold text-white`}>{getInitials(name) || '?'}</Text>
|
|
</View>
|
|
);
|
|
};
|