-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathindex.tsx
69 lines (64 loc) · 1.91 KB
/
index.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import Image from 'next/image';
import cn from 'classnames';
import { validPhoto } from 'lib/utils';
import styles from './avatar.module.scss';
interface AvatarProps {
size: number | 'dynamic';
className?: string;
priority?: boolean;
loading?: boolean;
src?: string;
}
/**
* This `Avatar` component will fill 100% of the width or height (which ever is
* smaller) while maintaining a 1:1 aspect ratio. It will then scale, center and
* crop the given image to fit that 1:1 area. If no image is given, the `Avatar`
* is rendered as a gray square with the text 'No Photo' centered within.
* @todo Perhaps make the image verification less strict and only check if it is
* able to be optimized instead of it is one of the newest GCP Storage buckets.
*/
export default function Avatar({
size,
className,
priority,
loading,
src,
}: AvatarProps): JSX.Element {
const img = src || 'https://assets.tutorbook.org/pngs/profile.png';
return (
<div
className={cn(styles.wrapper, className, { [styles.loading]: loading })}
>
{!loading && !validPhoto(img) && (
<div className={styles.photoWrapper}>
{priority && <link rel='preload' as='image' href={img} />}
<img data-cy='avatar' className={styles.photo} src={img} alt='' />
</div>
)}
{!loading && validPhoto(img) && size !== 'dynamic' && (
<Image
data-cy='avatar'
priority={priority}
layout='fixed'
height={size}
width={size}
src={img}
alt=''
/>
)}
{!loading && validPhoto(img) && size === 'dynamic' && (
<div className={styles.photoWrapper}>
<Image
data-cy='avatar'
layout='fill'
objectFit='cover'
objectPosition='center 50%'
priority={priority}
src={img}
alt=''
/>
</div>
)}
</div>
);
}