/
avatar-image.tsx
105 lines (96 loc) · 2.61 KB
/
avatar-image.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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import { ImageProps, useImage } from "@chakra-ui/image"
import { chakra, ChakraComponent, SystemStyleObject } from "@chakra-ui/system"
import { cloneElement } from "react"
import { AvatarName } from "./avatar-name"
type AvatarImageProps = ImageProps & {
getInitials?: (name: string) => string
borderRadius?: SystemStyleObject["borderRadius"]
icon: React.ReactElement
iconLabel?: string
name?: string
}
export function AvatarImage(props: AvatarImageProps) {
const {
src,
srcSet,
onError,
getInitials,
name,
borderRadius,
loading,
iconLabel,
icon = <GenericAvatarIcon />,
ignoreFallback,
referrerPolicy,
} = props
/**
* use the image hook to only show the image when it has loaded
*/
const status = useImage({ src, onError, ignoreFallback })
const hasLoaded = status === "loaded"
/**
* Fallback avatar applies under 2 conditions:
* - If `src` was passed and the image has not loaded or failed to load
* - If `src` wasn't passed
*
* In this case, we'll show either the name avatar or default avatar
*/
const showFallback = !src || !hasLoaded
if (showFallback) {
return name ? (
<AvatarName
className="chakra-avatar__initials"
getInitials={getInitials}
name={name}
/>
) : (
cloneElement(icon, {
role: "img",
"aria-label": iconLabel,
})
)
}
/**
* If `src` was passed and the image has loaded, we'll show it
*/
return (
<chakra.img
src={src}
srcSet={srcSet}
alt={name}
referrerPolicy={referrerPolicy}
className="chakra-avatar__img"
loading={loading}
__css={{
width: "100%",
height: "100%",
objectFit: "cover",
borderRadius,
}}
/>
)
}
AvatarImage.displayName = "AvatarImage"
/**
* Fallback avatar react component.
* This should be a generic svg used to represent an avatar
*/
export const GenericAvatarIcon: ChakraComponent<"svg"> = (props) => (
<chakra.svg
viewBox="0 0 128 128"
color="#fff"
width="100%"
height="100%"
className="chakra-avatar__svg"
{...props}
>
<path
fill="currentColor"
d="M103,102.1388 C93.094,111.92 79.3504,118 64.1638,118 C48.8056,118 34.9294,111.768 25,101.7892 L25,95.2 C25,86.8096 31.981,80 40.6,80 L87.4,80 C96.019,80 103,86.8096 103,95.2 L103,102.1388 Z"
/>
<path
fill="currentColor"
d="M63.9961647,24 C51.2938136,24 41,34.2938136 41,46.9961647 C41,59.7061864 51.2938136,70 63.9961647,70 C76.6985159,70 87,59.7061864 87,46.9961647 C87,34.2938136 76.6985159,24 63.9961647,24"
/>
</chakra.svg>
)