UNPKG

@wix/design-system

Version:

@wix/design-system

79 lines 4.69 kB
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