@wix/design-system
Version:
@wix/design-system
79 lines • 4.69 kB
JavaScript
import React from 'react';
import IconButton from '../IconButton';
import { avatarShapes, dataHooks } from './constants';
import Loader from '../Loader';
import { placeholderSVGs } from './assets';
import { st, classes } from './Avatar.st.css.js';
import { capitalize } from '../utils/cssClassUtils';
import stringToColor from './string-to-color';
import AvatarCore from './AvatarCore';
const getSizeNumber = size => Number(size.substring(4));
const defaultSize = 48;
const minSmallIconButton = 60;
/**
* Avatar is a type of element that visually represents a user, either as an image, name initials or placeholder icon.
*/
class Avatar extends React.PureComponent {
constructor(props) {
super(props);
this._onMouseEnter = () => {
if (this.props.showIndicationOnHover) {
this.setState({ showIndication: true });
}
};
this._onMouseLeave = () => {
if (this.props.showIndicationOnHover) {
this.setState({ fadeIndication: true });
setTimeout(() => this.setState({ fadeIndication: false, showIndication: false }), 150);
}
};
this.state = {
fadeIndication: false,
showIndication: false,
};
}
render() {
const { size, presence, indication, color, customIndication, onIndicationClick, dataHook, className, shape, text, placeholder, name, onClick, showIndicationOnHover, loading, ...rest } = this.props;
const { fadeIndication, showIndication } = this.state;
const calculatedColor = color || stringToColor(text || name); // if color is provided as a prop use it, otherwise, generate a color based on the text
const sizeNumber = getSizeNumber(size);
const renderOnHover = !showIndicationOnHover || showIndication;
const indicationConstraints = renderOnHover && sizeNumber >= defaultSize;
const renderIndication = indicationConstraints && !customIndication && indication;
const renderCustomIndication = indicationConstraints && customIndication;
const renderLoader = loading && sizeNumber >= defaultSize;
return (React.createElement("div", { "data-hook": dataHook, className: st(className, classes.root) },
React.createElement("div", { "data-hook": dataHooks.avatarWSR, onMouseEnter: this._onMouseEnter, onMouseLeave: this._onMouseLeave, className: st(classes.avatarContainer, {
shape,
size,
indication: Boolean(customIndication || indication),
presence: Boolean(presence),
presenceType: presence,
clickable: !!onClick,
fade: fadeIndication,
hasText: !!text,
}) },
React.createElement("div", { className: classes.coreAvatar },
React.createElement(AvatarCore, { ...rest, placeholder: placeholder ?? (React.createElement(AvatarDefaultPlaceholder, { shape: shape, size: size })), text: text, name: name, onClick: onClick, initialsLimit: sizeNumber < 30 ? 1 : undefined, "data-hook": dataHooks.avatarCore, className: st(classes.avatar, classes[`color${capitalize(calculatedColor)}`]) })),
renderLoader && [
React.createElement("div", { key: "overlay", className: st(classes.loaderContainer, classes.overlay) }),
React.createElement("div", { key: "loader", className: st(classes.loaderContainer, classes.loader) },
React.createElement(Loader, { dataHook: dataHooks.loader, size: "tiny" })),
],
presence && React.createElement("div", { className: classes.presence }),
renderIndication && (React.createElement("div", { className: classes.indication },
React.createElement(IconButton, { className: classes.iconButtonShadow, dataHook: dataHooks.indication, skin: "light", onClick: onIndicationClick, shape: shape, size: sizeNumber > minSmallIconButton ? 'small' : 'tiny' }, indication))),
renderCustomIndication && (React.createElement("div", { className: classes.indication, "data-hook": dataHooks.customIndication, onClick: onIndicationClick }, customIndication)))));
}
}
const AvatarDefaultPlaceholder = ({ shape, size }) => shape !== avatarShapes.square
? placeholderSVGs[size][avatarShapes.circle]
: placeholderSVGs[size][avatarShapes.square];
Avatar.displayName = 'Avatar';
Avatar.defaultProps = {
size: 'size48',
shape: 'circle',
showIndicationOnHover: false,
};
export default Avatar;
//# sourceMappingURL=Avatar.js.map