@helpscout/hsds-react
Version:
React component library for Help Scout's Design System
419 lines (340 loc) • 15.6 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
exports.__esModule = true;
exports.default = exports.Avatar = void 0;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose"));
var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose"));
var _react = _interopRequireDefault(require("react"));
var _propTypes = _interopRequireDefault(require("prop-types"));
var _getValidProps = _interopRequireDefault(require("@helpscout/react-utils/dist/getValidProps"));
var _classnames = _interopRequireDefault(require("classnames"));
var _easing = require("../../utilities/easing");
var _Icon = _interopRequireDefault(require("../Icon"));
var _StatusDot = _interopRequireDefault(require("../StatusDot"));
var _Tooltip = _interopRequireDefault(require("../Tooltip"));
var _Avatar = _interopRequireDefault(require("./Avatar.Crop"));
var _Avatar2 = _interopRequireDefault(require("./Avatar.Image"));
var _Avatar3 = require("./Avatar.utils");
var _AvatarList = require("../AvatarList/AvatarList");
var _Avatar4 = require("./Avatar.css");
var _jsxRuntime = require("react/jsx-runtime");
function noop() {}
var Avatar = /*#__PURE__*/function (_React$PureComponent) {
(0, _inheritsLoose2.default)(Avatar, _React$PureComponent);
function Avatar(props) {
var _this;
_this = _React$PureComponent.call(this, props) || this;
_this.src = void 0;
_this.state = {
imageLoaded: false,
imageFailed: false
};
_this.onImageLoadedError = function () {
_this.setState({
imageLoaded: false,
imageFailed: true
});
_this.props.onError();
};
_this.onImageLoadedSuccess = function () {
_this.setState({
imageLoaded: true
});
_this.props.onLoad();
};
_this.getShapeClassNames = function () {
var _this$props = _this.props,
shape = _this$props.shape,
size = _this$props.size;
return (0, _classnames.default)(shape && "is-" + shape, size && "is-" + size);
};
_this.renderCrop = function () {
var _this$props2 = _this.props,
animationDuration = _this$props2.animationDuration,
animationEasing = _this$props2.animationEasing,
animation = _this$props2.animation,
name = _this$props2.name,
withShadow = _this$props2.withShadow,
fallbackImage = _this$props2.fallbackImage,
removingAvatarAnimation = _this$props2.removingAvatarAnimation,
light = _this$props2.light;
var shapeClassnames = _this.getShapeClassNames();
var hasImage = _this.src.length > 0 && !_this.state.imageFailed;
var initials = _this.getInitials();
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_Avatar.default, {
className: shapeClassnames,
isImageLoaded: _this.state.imageLoaded,
withShadow: withShadow,
hasImage: hasImage,
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Avatar2.default, {
animation: animation,
animationDuration: animationDuration,
animationEasing: animationEasing,
className: (0, _classnames.default)('c-Avatar__imageMainWrapper', shapeClassnames),
src: _this.src,
name: name,
initials: initials,
light: light,
onError: _this.onImageLoadedError,
onLoad: _this.onImageLoadedSuccess
}), removingAvatarAnimation && /*#__PURE__*/(0, _jsxRuntime.jsx)(_Avatar2.default, {
animation: false,
className: (0, _classnames.default)('c-Avatar__imageStaticWrapper', shapeClassnames),
src: fallbackImage,
name: name,
initials: initials,
light: light
}), _this.renderAction()]
});
};
_this.renderStatus = function () {
var _this$props3 = _this.props,
borderColor = _this$props3.borderColor,
showStatusBorderColor = _this$props3.showStatusBorderColor,
size = _this$props3.size,
statusIcon = _this$props3.statusIcon,
status = _this$props3.status;
var componentClassName = (0, _classnames.default)('c-Avatar__status', _this.getShapeClassNames(), statusIcon && 'is-withStatusIcon', showStatusBorderColor && 'is-withBorder');
return status && /*#__PURE__*/(0, _jsxRuntime.jsx)(_Avatar4.StatusUI, {
className: componentClassName,
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_StatusDot.default, {
icon: statusIcon,
outerBorderColor: showStatusBorderColor ? borderColor : undefined,
size: size === 'lg' ? 'md' : 'sm',
status: status
})
});
};
_this.renderCropBorder = function () {
var _this$props4 = _this.props,
borderColor = _this$props4.borderColor,
shape = _this$props4.shape;
var componentClassName = (0, _classnames.default)('c-Avatar__cropBorder', shape && "is-" + shape);
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Avatar4.CropBorderUI, {
className: componentClassName,
borderColor: borderColor
});
};
_this.renderOuterBorder = function () {
var _this$props5 = _this.props,
outerBorderColor = _this$props5.outerBorderColor,
shape = _this$props5.shape;
var componentClassName = (0, _classnames.default)('c-Avatar__outerBorder', shape && "is-" + shape);
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Avatar4.OuterBorderUI, {
className: componentClassName,
borderColor: outerBorderColor
});
};
_this.renderFocusBorder = function () {
var _this$props6 = _this.props,
shape = _this$props6.shape,
onRemoveAnimationEnd = _this$props6.onRemoveAnimationEnd,
size = _this$props6.size;
var componentClassName = (0, _classnames.default)('c-Avatar__focusBorder', shape && "is-" + shape);
var borderAnimationClassName = (0, _classnames.default)('c-Avatar__borderAnimation', _this.getShapeClassNames());
var sz = _Avatar4.config.size[size].size;
var _getCircleProps = (0, _Avatar4.getCircleProps)(sz),
svgSize = _getCircleProps.size,
circleProps = (0, _objectWithoutPropertiesLoose2.default)(_getCircleProps, ["size"]);
return [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Avatar4.FocusUI, {
"data-cy": "Avatar.FocusBorder",
className: componentClassName
}, "focusBorder"), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Avatar4.BorderAnimationUI, {
className: borderAnimationClassName,
"data-cy": "Avatar.BorderAnimation",
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Avatar4.CircleAnimationUI, (0, _extends2.default)({
id: "anime",
onAnimationEnd: onRemoveAnimationEnd
}, circleProps))
}, "borderAnimation")];
};
_this.src = (0, _Avatar3.getImageSrc)(props);
return _this;
}
var _proto = Avatar.prototype;
_proto.UNSAFE_componentWillReceiveProps = function UNSAFE_componentWillReceiveProps(newProps) {
var imageHasChanged = newProps.image !== this.props.image;
var fallbackHasChanged = newProps.fallbackImage !== this.props.fallbackImage;
if (imageHasChanged || fallbackHasChanged) {
this.src = (0, _Avatar3.getImageSrc)(newProps);
this.setState({
imageLoaded: false,
imageFailed: false
});
}
};
_proto.renderAction = function renderAction() {
var _this$props7 = this.props,
actionable = _this$props7.actionable,
actionIcon = _this$props7.actionIcon,
actionIconSize = _this$props7.actionIconSize,
removingAvatarAnimation = _this$props7.removingAvatarAnimation;
if (!actionable || removingAvatarAnimation) {
return null;
}
var actionClassName = (0, _classnames.default)('c-Avatar__action', this.getShapeClassNames());
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Avatar4.ActionUI, {
"data-cy": "Avatar.Action",
className: actionClassName,
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.default, {
name: actionIcon,
size: actionIconSize
})
});
};
_proto.getInitials = function getInitials() {
var _this$props8 = this.props,
count = _this$props8.count,
initials = _this$props8.initials,
name = _this$props8.name;
return count || initials || (0, _Avatar3.nameToInitials)(name);
};
_proto.getStyles = function getStyles() {
var _this$props9 = this.props,
animationDuration = _this$props9.animationDuration,
animationEasing = _this$props9.animationEasing,
style = _this$props9.style;
return (0, _extends2.default)({}, style, {
transition: "width " + animationDuration + "ms " + (0, _easing.getEasingTiming)(animationEasing) + ",\n height " + animationDuration + "ms " + (0, _easing.getEasingTiming)(animationEasing)
});
};
_proto.render = function render() {
var _this$props10 = this.props,
actionable = _this$props10.actionable,
active = _this$props10.active,
borderColor = _this$props10.borderColor,
className = _this$props10.className,
count = _this$props10.count,
image = _this$props10.image,
name = _this$props10.name,
light = _this$props10.light,
initials = _this$props10.initials,
onLoad = _this$props10.onLoad,
outerBorderColor = _this$props10.outerBorderColor,
showStatusBorderColor = _this$props10.showStatusBorderColor,
removingAvatarAnimation = _this$props10.removingAvatarAnimation,
size = _this$props10.size,
shape = _this$props10.shape,
status = _this$props10.status,
statusIcon = _this$props10.statusIcon,
withShadow = _this$props10.withShadow,
fallbackImage = _this$props10.fallbackImage,
onActionClick = _this$props10.onActionClick,
tooltipProps = _this$props10.tooltipProps,
rest = (0, _objectWithoutPropertiesLoose2.default)(_this$props10, ["actionable", "active", "borderColor", "className", "count", "image", "name", "light", "initials", "onLoad", "outerBorderColor", "showStatusBorderColor", "removingAvatarAnimation", "size", "shape", "status", "statusIcon", "withShadow", "fallbackImage", "onActionClick", "tooltipProps"]);
var componentClassName = (0, _classnames.default)('c-Avatar', borderColor && 'has-borderColor', statusIcon && 'has-statusIcon', light && 'is-light', active && 'is-active', outerBorderColor && 'has-outerBorderColor', status && "is-" + status, actionable && "has-action", removingAvatarAnimation && 'is-animating', this.getShapeClassNames(), className);
var Component = actionable ? _Avatar4.AvatarButtonUI : _Avatar4.AvatarUI;
var extraProps = actionable ? {
onClick: onActionClick
} : {};
var withTooltip = Boolean(tooltipProps);
var AvatarComponent = /*#__PURE__*/(0, _jsxRuntime.jsxs)(Component, (0, _extends2.default)({}, (0, _getValidProps.default)(rest), {
"data-cy": "Avatar",
className: componentClassName,
style: this.getStyles(),
title: !withTooltip ? name : null
}, extraProps, {
children: [this.renderCrop(), this.renderStatus(), this.renderCropBorder(), this.renderOuterBorder(), actionable && this.renderFocusBorder()]
}));
return !withTooltip ? AvatarComponent : /*#__PURE__*/(0, _jsxRuntime.jsx)(_Tooltip.default, (0, _extends2.default)({
withTriggerWrapper: false
}, tooltipProps, {
children: AvatarComponent
}));
};
return Avatar;
}(_react.default.PureComponent);
exports.Avatar = Avatar;
var AvatarConsumer = function AvatarConsumer(props) {
var contextValue = _react.default.useContext(_AvatarList.AvatarListContext);
if (contextValue) {
var newProps = (0, _extends2.default)({}, props, contextValue);
newProps.className = (0, _classnames.default)(props.className, contextValue.className);
return /*#__PURE__*/(0, _jsxRuntime.jsx)(Avatar, (0, _extends2.default)({}, newProps));
}
return /*#__PURE__*/(0, _jsxRuntime.jsx)(Avatar, (0, _extends2.default)({}, props));
};
Avatar.defaultProps = {
actionable: false,
actionIcon: 'trash',
actionIconSize: '24',
active: false,
animation: true,
animationDuration: 160,
animationEasing: 'ease',
borderColor: 'transparent',
'data-cy': 'Avatar',
fallbackImage: null,
light: false,
name: '',
outerBorderColor: 'transparent',
showStatusBorderColor: false,
size: 'md',
shape: 'circle',
style: {},
withShadow: false,
onError: noop,
onLoad: noop
};
var avatarPropTypes = {
active: _propTypes.default.bool,
animation: _propTypes.default.bool,
animationDuration: _propTypes.default.number,
animationEasing: _propTypes.default.string,
/** Activate the action overlay that will appear on hover */
actionable: _propTypes.default.bool,
/** Name of the [Icon](../Icon) to render into the action overlay */
actionIcon: _propTypes.default.string,
/** Set the size of the action overlay icon */
actionIconSize: _propTypes.default.string,
/** Color for the Avatar border. */
borderColor: _propTypes.default.string,
/** Custom class names to be added to the component. */
className: _propTypes.default.string,
/** Used to display an additional avatar count. */
count: _propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.string]),
/** Data attr for Cypress tests. */
'data-cy': _propTypes.default.string,
fallbackImage: _propTypes.default.string,
/** URL of the image to display. */
image: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.bool]),
/** Custom initials to display. */
initials: _propTypes.default.string,
/** Applies a "light" style to the component. */
light: _propTypes.default.bool,
/** Name of the user. Required. */
name: _propTypes.default.string,
/** Callback when avatar overlay was clicked. */
onActionClick: _propTypes.default.func,
/** Callback when avatar image fails to load. */
onError: _propTypes.default.func,
/** Callback when avatar image loads. */
onLoad: _propTypes.default.func,
/** Callback when the remove avatar animation has ended. */
onRemoveAnimationEnd: _propTypes.default.func,
/** Color for the Avatar's outer border. */
outerBorderColor: _propTypes.default.string,
/** Activate an animation sequence that will remove the actual avatar and replace it will the fallback image. */
removingAvatarAnimation: _propTypes.default.bool,
/** Shape of the avatar. */
shape: _propTypes.default.oneOf(['circle', 'rounded', 'square']),
/** Renders the `StatusDot` border. */
showStatusBorderColor: _propTypes.default.bool,
/** Size of the avatar. */
size: _propTypes.default.oneOf(['xl', 'lg', 'md', 'smmd', 'sm', 'xs', 'xxs']),
/** Renders a `StatusDot` with the status type. */
status: _propTypes.default.string,
/** Name of the `Icon` to render into the `StatusDot`. */
statusIcon: _propTypes.default.string,
/** Text for the image `alt` and `title` attributes. */
title: _propTypes.default.string,
/** Wrap the avatar with a Tooltip, accepts all Tooltip props */
tooltipProps: _propTypes.default.object,
withShadow: _propTypes.default.bool
};
Avatar.propTypes = avatarPropTypes;
AvatarConsumer.propTypes = avatarPropTypes;
AvatarConsumer.defaultProps = Avatar.defaultProps;
var _default = AvatarConsumer;
exports.default = _default;