UNPKG

6.45 kBJavaScriptView Raw
1"use strict";
2
3var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
5Object.defineProperty(exports, "__esModule", {
6 value: true
7});
8exports.default = exports.styles = void 0;
9
10var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
11
12var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
13
14var _react = _interopRequireDefault(require("react"));
15
16var _propTypes = _interopRequireDefault(require("prop-types"));
17
18var _clsx = _interopRequireDefault(require("clsx"));
19
20var _withStyles = _interopRequireDefault(require("../styles/withStyles"));
21
22var _Person = _interopRequireDefault(require("../internal/svg-icons/Person"));
23
24var styles = function styles(theme) {
25 return {
26 /* Styles applied to the root element. */
27 root: {
28 position: 'relative',
29 display: 'flex',
30 alignItems: 'center',
31 justifyContent: 'center',
32 flexShrink: 0,
33 width: 40,
34 height: 40,
35 fontFamily: theme.typography.fontFamily,
36 fontSize: theme.typography.pxToRem(20),
37 lineHeight: 1,
38 borderRadius: '50%',
39 overflow: 'hidden',
40 userSelect: 'none'
41 },
42
43 /* Styles applied to the root element if not `src` or `srcSet`. */
44 colorDefault: {
45 color: theme.palette.background.default,
46 backgroundColor: theme.palette.type === 'light' ? theme.palette.grey[400] : theme.palette.grey[600]
47 },
48
49 /* Styles applied to the root element if `variant="circle"`. */
50 circle: {},
51
52 /* Styles applied to the root element if `variant="rounded"`. */
53 rounded: {
54 borderRadius: theme.shape.borderRadius
55 },
56
57 /* Styles applied to the root element if `variant="square"`. */
58 square: {
59 borderRadius: 0
60 },
61
62 /* Styles applied to the img element if either `src` or `srcSet` is defined. */
63 img: {
64 width: '100%',
65 height: '100%',
66 textAlign: 'center',
67 // Handle non-square image. The property isn't supported by IE 11.
68 objectFit: 'cover',
69 // Hide alt text.
70 color: 'transparent',
71 // Same color as the Skeleton.
72 backgroundColor: theme.palette.action.hover,
73 // Hide the image broken icon, only works on Chrome.
74 textIndent: 10000
75 },
76
77 /* Styles applied to the fallback icon */
78 fallback: {
79 width: '75%',
80 height: '75%'
81 }
82 };
83};
84
85exports.styles = styles;
86
87function useLoaded(_ref) {
88 var src = _ref.src,
89 srcSet = _ref.srcSet;
90
91 var _React$useState = _react.default.useState(false),
92 loaded = _React$useState[0],
93 setLoaded = _React$useState[1];
94
95 _react.default.useEffect(function () {
96 if (!src && !srcSet) {
97 return undefined;
98 }
99
100 setLoaded(false);
101 var active = true;
102 var image = new Image();
103 image.src = src;
104 image.srcSet = srcSet;
105
106 image.onload = function () {
107 if (!active) {
108 return;
109 }
110
111 setLoaded('loaded');
112 };
113
114 image.onerror = function () {
115 if (!active) {
116 return;
117 }
118
119 setLoaded('error');
120 };
121
122 return function () {
123 active = false;
124 };
125 }, [src, srcSet]);
126
127 return loaded;
128}
129
130var Avatar = _react.default.forwardRef(function Avatar(props, ref) {
131 var alt = props.alt,
132 childrenProp = props.children,
133 classes = props.classes,
134 className = props.className,
135 _props$component = props.component,
136 Component = _props$component === void 0 ? 'div' : _props$component,
137 imgProps = props.imgProps,
138 sizes = props.sizes,
139 src = props.src,
140 srcSet = props.srcSet,
141 _props$variant = props.variant,
142 variant = _props$variant === void 0 ? 'circle' : _props$variant,
143 other = (0, _objectWithoutProperties2.default)(props, ["alt", "children", "classes", "className", "component", "imgProps", "sizes", "src", "srcSet", "variant"]);
144 var children = null; // Use a hook instead of onError on the img element to support server-side rendering.
145
146 var loaded = useLoaded({
147 src: src,
148 srcSet: srcSet
149 });
150 var hasImg = src || srcSet;
151 var hasImgNotFailing = hasImg && loaded !== 'error';
152
153 if (hasImgNotFailing) {
154 children = _react.default.createElement("img", (0, _extends2.default)({
155 alt: alt,
156 src: src,
157 srcSet: srcSet,
158 sizes: sizes,
159 className: classes.img
160 }, imgProps));
161 } else if (childrenProp != null) {
162 children = childrenProp;
163 } else if (hasImg && alt) {
164 children = alt[0];
165 } else {
166 children = _react.default.createElement(_Person.default, {
167 className: classes.fallback
168 });
169 }
170
171 return _react.default.createElement(Component, (0, _extends2.default)({
172 className: (0, _clsx.default)(classes.root, classes.system, classes[variant], className, !hasImgNotFailing && classes.colorDefault),
173 ref: ref
174 }, other), children);
175});
176
177process.env.NODE_ENV !== "production" ? Avatar.propTypes = {
178 /**
179 * Used in combination with `src` or `srcSet` to
180 * provide an alt attribute for the rendered `img` element.
181 */
182 alt: _propTypes.default.string,
183
184 /**
185 * Used to render icon or text elements inside the Avatar if `src` is not set.
186 * This can be an element, or just a string.
187 */
188 children: _propTypes.default.node,
189
190 /**
191 * Override or extend the styles applied to the component.
192 * See [CSS API](#css) below for more details.
193 */
194 classes: _propTypes.default.object.isRequired,
195
196 /**
197 * @ignore
198 */
199 className: _propTypes.default.string,
200
201 /**
202 * The component used for the root node.
203 * Either a string to use a DOM element or a component.
204 */
205 component: _propTypes.default.elementType,
206
207 /**
208 * Attributes applied to the `img` element if the component is used to display an image.
209 * It can be used to listen for the loading error event.
210 */
211 imgProps: _propTypes.default.object,
212
213 /**
214 * The `sizes` attribute for the `img` element.
215 */
216 sizes: _propTypes.default.string,
217
218 /**
219 * The `src` attribute for the `img` element.
220 */
221 src: _propTypes.default.string,
222
223 /**
224 * The `srcSet` attribute for the `img` element.
225 * Use this attribute for responsive image display.
226 */
227 srcSet: _propTypes.default.string,
228
229 /**
230 * The shape of the avatar.
231 */
232 variant: _propTypes.default.oneOf(['circle', 'rounded', 'square'])
233} : void 0;
234
235var _default = (0, _withStyles.default)(styles, {
236 name: 'MuiAvatar'
237})(Avatar);
238
239exports.default = _default;
\No newline at end of file