wix-style-react
Version:
wix-style-react
211 lines (209 loc) • 7.87 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
exports.__esModule = true;
exports.default = void 0;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
var React = _interopRequireWildcard(require("react"));
var _classnames = _interopRequireDefault(require("classnames"));
var _AvatarCoreSt = require("./AvatarCore.st.css");
var _propsUtils = require("../../utils/propsUtils");
var _Focusable = require("../../common/Focusable");
var _utils = require("./utils");
var _excluded = ["alt", "className"];
var _jsxFileName = "/home/builduser/work/a9c1ac8876d5057c/packages/wix-style-react/dist/cjs/Avatar/AvatarCore/AvatarCore.tsx";
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
var DEFAULT_CONTENT_TYPE = 'placeholder';
/**
* AvatarCore is a type of element that visually represents a user, either as an image, placeholder or text.
*
* <p>There are 3 props for corresponding content types: `text`, `placeholder` and `imgProps`.
* If more than one of these props is supplied (with `name` prop giving default value to the `text` prop),
* then the resolved content type for display goes according to this priority: image -> text -> placeholder.
*/
class AvatarCore extends React.Component {
constructor() {
super(...arguments);
this.state = {
imgLoaded: false
};
this.img = undefined;
this.loadImg = () => {
var _this$props$imgProps$, _this$props$imgProps;
this.img = new Image();
this.img.onload = () => {
// don't set state after unmount
this.img && this.setState({
imgLoaded: true
});
};
this.img.src = (_this$props$imgProps$ = (_this$props$imgProps = this.props.imgProps) == null ? void 0 : _this$props$imgProps.src) !== null && _this$props$imgProps$ !== void 0 ? _this$props$imgProps$ : '';
};
this.unloadImg = () => {
// TODO: Is this necessary? It is taken from https://github.com/mbrevda/react-image/blob/c402ed3f5d54b88e51eca3326a1e81d964995795/src/index.js#L146
// @ts-ignore
delete this.img.onload;
try {
// @ts-ignore
delete this.img.src;
} catch (e) {
// On Safari in Strict mode this will throw an exception,
// - https://github.com/mbrevda/react-image/issues/187
// We don't need to do anything about it.
}
// @ts-ignore
delete this.img;
};
this._handleKeyDown = event => {
if (event.key === ' ' || event.key === 'Enter' || event.key === 'Space') {
event.preventDefault();
// @ts-ignore
this.props.onClick();
}
};
}
/** This is the resolved content type the consumer wants to display */
getRequestedContentType(props) {
var {
name,
text,
placeholder,
imgProps
} = props;
return imgProps && imgProps.src ? 'image' : text || name ? 'text' : placeholder ? 'placeholder' : DEFAULT_CONTENT_TYPE;
}
/** This is content type that will be displayed. (If img is loading then this will be the fallback) */
getCurrentContentType() {
var requestedType = this.getRequestedContentType(this.props);
if (requestedType === 'image' && !this.state.imgLoaded) {
var {
name,
text,
placeholder
} = this.props;
return text || name ? 'text' : placeholder ? 'placeholder' : DEFAULT_CONTENT_TYPE;
}
return requestedType;
}
componentDidMount() {
this.getRequestedContentType(this.props) === 'image' && !this.state.imgLoaded && this.loadImg();
}
UNSAFE_componentWillReceiveProps(nextProps) {
if (!nextProps.imgProps || !this.props.imgProps || nextProps.imgProps.src !== this.props.imgProps.src) {
this.setState({
imgLoaded: false
});
this.img && this.unloadImg();
}
}
componentDidUpdate() {
this.getRequestedContentType(this.props) === 'image' && !this.img && !this.state.imgLoaded && this.loadImg();
}
componentWillUnmount() {
this.img && this.unloadImg();
}
getContent(contentType) {
switch (contentType) {
case 'text':
{
var {
name,
text
} = this.props;
var textContent = text || (0, _utils.nameToInitials)(name, this.props.initialsLimit);
return /*#__PURE__*/React.createElement("div", {
className: _AvatarCoreSt.classes.content,
"data-hook": "text-container",
__self: this,
__source: {
fileName: _jsxFileName,
lineNumber: 150,
columnNumber: 11
}
}, textContent);
}
case 'placeholder':
{
var {
placeholder
} = this.props;
return !placeholder ? null : /*#__PURE__*/React.cloneElement(placeholder, {
className: (0, _classnames.default)(placeholder.props.className, _AvatarCoreSt.classes.content)
});
}
case 'image':
{
if (!this.props.imgProps) {
return null;
}
var _this$props$imgProps2 = this.props.imgProps,
{
alt,
className
} = _this$props$imgProps2,
rest = (0, _objectWithoutProperties2.default)(_this$props$imgProps2, _excluded);
return /*#__PURE__*/React.createElement("img", (0, _extends2.default)({
"data-hook": "content",
className: (0, _classnames.default)(_AvatarCoreSt.classes.content, className),
alt: alt ? alt : this.props.name
}, rest, {
__self: this,
__source: {
fileName: _jsxFileName,
lineNumber: 175,
columnNumber: 11
}
}));
}
default:
{
return null;
}
}
}
render() {
var {
name,
title,
ariaLabel,
onClick,
focusableOnFocus,
focusableOnBlur
} = this.props;
var contentType = this.getCurrentContentType();
var focusProps = !!onClick && {
role: 'button',
onFocus: focusableOnFocus,
onBlur: focusableOnBlur,
onKeyDown: this._handleKeyDown,
tabIndex: 0
};
return /*#__PURE__*/React.createElement("div", (0, _extends2.default)({
"data-content-type": contentType // for testing
,
"data-img-loaded": this.state.imgLoaded // for testing
,
title: title || name,
"aria-label": ariaLabel || name,
onClick: onClick
}, focusProps, {
className: (0, _AvatarCoreSt.st)(_AvatarCoreSt.classes.root, {
imgLoaded: this.state.imgLoaded,
contentType
}, this.props.className)
}, (0, _propsUtils.filterDataProps)(this.props), {
__self: this,
__source: {
fileName: _jsxFileName,
lineNumber: 217,
columnNumber: 7
}
}), this.getContent(contentType));
}
}
AvatarCore.displayName = 'AvatarCore';
AvatarCore.defaultProps = {
placeholder: undefined
};
var _default = exports.default = (0, _Focusable.withFocusable)(AvatarCore);
//# sourceMappingURL=AvatarCore.js.map