1 | import _extends from "@babel/runtime/helpers/esm/extends";
|
2 | import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
|
3 | import * as React from 'react';
|
4 | import PropTypes from 'prop-types';
|
5 | import clsx from 'clsx';
|
6 | import { chainPropTypes } from '@material-ui/utils';
|
7 | import withStyles from '../styles/withStyles';
|
8 | import Person from '../internal/svg-icons/Person';
|
9 | export const styles = theme => ({
|
10 |
|
11 | root: {
|
12 | position: 'relative',
|
13 | display: 'flex',
|
14 | alignItems: 'center',
|
15 | justifyContent: 'center',
|
16 | flexShrink: 0,
|
17 | width: 40,
|
18 | height: 40,
|
19 | fontFamily: theme.typography.fontFamily,
|
20 | fontSize: theme.typography.pxToRem(20),
|
21 | lineHeight: 1,
|
22 | borderRadius: '50%',
|
23 | overflow: 'hidden',
|
24 | userSelect: 'none'
|
25 | },
|
26 |
|
27 |
|
28 | colorDefault: {
|
29 | color: theme.palette.background.default,
|
30 | backgroundColor: theme.palette.type === 'light' ? theme.palette.grey[400] : theme.palette.grey[600]
|
31 | },
|
32 |
|
33 |
|
34 | circle: {},
|
35 |
|
36 |
|
37 | circular: {},
|
38 |
|
39 |
|
40 | rounded: {
|
41 | borderRadius: theme.shape.borderRadius
|
42 | },
|
43 |
|
44 |
|
45 | square: {
|
46 | borderRadius: 0
|
47 | },
|
48 |
|
49 |
|
50 | img: {
|
51 | width: '100%',
|
52 | height: '100%',
|
53 | textAlign: 'center',
|
54 |
|
55 | objectFit: 'cover',
|
56 |
|
57 | color: 'transparent',
|
58 |
|
59 | textIndent: 10000
|
60 | },
|
61 |
|
62 |
|
63 | fallback: {
|
64 | width: '75%',
|
65 | height: '75%'
|
66 | }
|
67 | });
|
68 |
|
69 | function useLoaded({
|
70 | src,
|
71 | srcSet
|
72 | }) {
|
73 | const [loaded, setLoaded] = React.useState(false);
|
74 | React.useEffect(() => {
|
75 | if (!src && !srcSet) {
|
76 | return undefined;
|
77 | }
|
78 |
|
79 | setLoaded(false);
|
80 | let active = true;
|
81 | const image = new Image();
|
82 | image.src = src;
|
83 | image.srcSet = srcSet;
|
84 |
|
85 | image.onload = () => {
|
86 | if (!active) {
|
87 | return;
|
88 | }
|
89 |
|
90 | setLoaded('loaded');
|
91 | };
|
92 |
|
93 | image.onerror = () => {
|
94 | if (!active) {
|
95 | return;
|
96 | }
|
97 |
|
98 | setLoaded('error');
|
99 | };
|
100 |
|
101 | return () => {
|
102 | active = false;
|
103 | };
|
104 | }, [src, srcSet]);
|
105 | return loaded;
|
106 | }
|
107 |
|
108 | const Avatar = React.forwardRef(function Avatar(props, ref) {
|
109 | const {
|
110 | alt,
|
111 | children: childrenProp,
|
112 | classes,
|
113 | className,
|
114 | component: Component = 'div',
|
115 | imgProps,
|
116 | sizes,
|
117 | src,
|
118 | srcSet,
|
119 | variant = 'circular'
|
120 | } = props,
|
121 | other = _objectWithoutPropertiesLoose(props, ["alt", "children", "classes", "className", "component", "imgProps", "sizes", "src", "srcSet", "variant"]);
|
122 |
|
123 | let children = null;
|
124 |
|
125 | const loaded = useLoaded({
|
126 | src,
|
127 | srcSet
|
128 | });
|
129 | const hasImg = src || srcSet;
|
130 | const hasImgNotFailing = hasImg && loaded !== 'error';
|
131 |
|
132 | if (hasImgNotFailing) {
|
133 | children = React.createElement("img", _extends({
|
134 | alt: alt,
|
135 | src: src,
|
136 | srcSet: srcSet,
|
137 | sizes: sizes,
|
138 | className: classes.img
|
139 | }, imgProps));
|
140 | } else if (childrenProp != null) {
|
141 | children = childrenProp;
|
142 | } else if (hasImg && alt) {
|
143 | children = alt[0];
|
144 | } else {
|
145 | children = React.createElement(Person, {
|
146 | className: classes.fallback
|
147 | });
|
148 | }
|
149 |
|
150 | return React.createElement(Component, _extends({
|
151 | className: clsx(classes.root, classes.system, classes[variant], className, !hasImgNotFailing && classes.colorDefault),
|
152 | ref: ref
|
153 | }, other), children);
|
154 | });
|
155 | process.env.NODE_ENV !== "production" ? Avatar.propTypes = {
|
156 |
|
157 |
|
158 |
|
159 |
|
160 |
|
161 | |
162 |
|
163 |
|
164 |
|
165 | alt: PropTypes.string,
|
166 |
|
167 | |
168 |
|
169 |
|
170 |
|
171 | children: PropTypes.node,
|
172 |
|
173 | |
174 |
|
175 |
|
176 |
|
177 | classes: chainPropTypes(PropTypes.object, props => {
|
178 | const {
|
179 | classes
|
180 | } = props;
|
181 |
|
182 | if (classes == null) {
|
183 | return null;
|
184 | }
|
185 |
|
186 | if (classes.circle != null &&
|
187 | classes.circle.split(' ').length > 1) {
|
188 | throw new Error(`Material-UI: The \`circle\` class is deprecated. Use \`circular\` instead.`);
|
189 | }
|
190 |
|
191 | return null;
|
192 | }),
|
193 |
|
194 | |
195 |
|
196 |
|
197 | className: PropTypes.string,
|
198 |
|
199 | |
200 |
|
201 |
|
202 |
|
203 | component: PropTypes
|
204 |
|
205 | .elementType,
|
206 |
|
207 | |
208 |
|
209 |
|
210 |
|
211 | imgProps: PropTypes.object,
|
212 |
|
213 | |
214 |
|
215 |
|
216 | sizes: PropTypes.string,
|
217 |
|
218 | |
219 |
|
220 |
|
221 | src: PropTypes.string,
|
222 |
|
223 | |
224 |
|
225 |
|
226 |
|
227 | srcSet: PropTypes.string,
|
228 |
|
229 | |
230 |
|
231 |
|
232 | variant: chainPropTypes(PropTypes.oneOf(['circle', 'circular', 'rounded', 'square']), props => {
|
233 | const {
|
234 | variant
|
235 | } = props;
|
236 |
|
237 | if (variant === 'circle') {
|
238 | throw new Error('Material-UI: `variant="circle"` is deprecated. Use `variant="circular"` instead.');
|
239 | }
|
240 |
|
241 | return null;
|
242 | })
|
243 | } : void 0;
|
244 | export default withStyles(styles, {
|
245 | name: 'MuiAvatar'
|
246 | })(Avatar); |
\ | No newline at end of file |