Files
outline/app/components/Avatar/Avatar.tsx
Tom Moor ea63023fca feat: added user avatars in author search dropdown (#4551)
* feat: added user avatars in author search dropdown

* cleanup

* cleanup

* feat: added user avatars in author search dropdown

* cleanup

* cleanup

* added user icon

* Size tweaks

Co-authored-by: Aditya Sharma <aditya167411@gmail.com>
2022-12-06 20:10:56 -08:00

86 lines
1.9 KiB
TypeScript

import * as React from "react";
import styled from "styled-components";
import useBoolean from "~/hooks/useBoolean";
import Initials from "./Initials";
import placeholder from "./placeholder.png";
export interface IAvatar {
avatarUrl: string | null;
color: string;
initial: string;
id: string;
}
type Props = {
size: number;
src?: string;
icon?: React.ReactNode;
model?: IAvatar;
alt?: string;
showBorder?: boolean;
onClick?: React.MouseEventHandler<HTMLImageElement>;
className?: string;
};
function Avatar(props: Props) {
const { icon, showBorder, model, ...rest } = props;
const src = props.src || model?.avatarUrl;
const [error, handleError] = useBoolean(false);
return (
<Relative>
{src ? (
<CircleImg
onError={handleError}
src={error ? placeholder : src}
$showBorder={showBorder}
{...rest}
/>
) : model ? (
<Initials color={model.color} $showBorder={showBorder} {...rest}>
{model.initial}
</Initials>
) : (
<Initials $showBorder={showBorder} {...rest} />
)}
{icon && <IconWrapper>{icon}</IconWrapper>}
</Relative>
);
}
Avatar.defaultProps = {
size: 24,
};
const Relative = styled.div`
position: relative;
flex-shrink: 0;
`;
const IconWrapper = styled.div`
display: flex;
position: absolute;
bottom: -2px;
right: -2px;
background: ${(props) => props.theme.primary};
border: 2px solid ${(props) => props.theme.background};
border-radius: 100%;
width: 20px;
height: 20px;
`;
const CircleImg = styled.img<{ size: number; $showBorder?: boolean }>`
display: block;
width: ${(props) => props.size}px;
height: ${(props) => props.size}px;
border-radius: 50%;
border: ${(props) =>
props.$showBorder === false
? "none"
: `2px solid ${props.theme.background}`};
flex-shrink: 0;
overflow: hidden;
`;
export default Avatar;