UNPKG

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