mirror of
https://github.com/morten-olsen/refocus.dev.git
synced 2026-02-08 00:46:25 +01:00
init
This commit is contained in:
84
packages/ui/src/base/avatar/index.tsx
Normal file
84
packages/ui/src/base/avatar/index.tsx
Normal file
@@ -0,0 +1,84 @@
|
||||
import styled from 'styled-components';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
type AvatarProps = {
|
||||
url?: string;
|
||||
name?: string;
|
||||
decal?: React.ReactNode;
|
||||
size?: 'sm' | 'md' | 'lg';
|
||||
};
|
||||
|
||||
const sizes = {
|
||||
sm: 28,
|
||||
md: 50,
|
||||
lg: 75,
|
||||
};
|
||||
|
||||
const fontSizes = {
|
||||
sm: 10,
|
||||
md: 24,
|
||||
lg: 32,
|
||||
};
|
||||
|
||||
const Wrapper = styled.div<{
|
||||
size: AvatarProps['size'];
|
||||
}>`
|
||||
position: relative;
|
||||
flex-shrink: 0;
|
||||
${({ size }) => (size ? `width: ${sizes[size]}px;` : '')}
|
||||
${({ size }) => (size ? `height: ${sizes[size]}px;` : '')}
|
||||
`;
|
||||
|
||||
const Image = styled.img`
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 3px solid ${({ theme }) => theme.colors.text.base};
|
||||
border-radius: 50%;
|
||||
`;
|
||||
|
||||
const WithoutImage = styled.div<{
|
||||
size: AvatarProps['size'];
|
||||
}>`
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 3px solid ${({ theme }) => theme.colors.text.base};
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
font-weight: bold;
|
||||
align-items: center;
|
||||
color: ${({ theme }) => theme.colors.text.base};
|
||||
${({ size }) => (size ? `font-size: ${fontSizes[size]}px;` : '')}
|
||||
`;
|
||||
|
||||
const Decal = styled.div`
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: -5px;
|
||||
min-width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 10px;
|
||||
padding: 0 5px;
|
||||
background-color: ${({ theme }) => theme.colors.text.base};
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: ${({ theme }) => theme.colors.bg.base};
|
||||
font-size: 12px;
|
||||
`;
|
||||
|
||||
const Avatar: React.FC<AvatarProps> = ({ url, name, decal, size = 'md' }) => {
|
||||
const initials = useMemo(() => {
|
||||
const [firstName, lastName] = name?.split(' ') || [];
|
||||
return `${firstName?.[0] || ''}${lastName?.[0] || ''}`;
|
||||
}, [name]);
|
||||
return (
|
||||
<Wrapper size={size}>
|
||||
{!url && <WithoutImage size={size}>{initials}</WithoutImage>}
|
||||
{url && <Image src={url} alt={name || ''} />}
|
||||
{decal && <Decal>{decal}</Decal>}
|
||||
</Wrapper>
|
||||
);
|
||||
};
|
||||
|
||||
export { Avatar };
|
||||
Reference in New Issue
Block a user