box-ui-elements-mlh
Version:
84 lines (74 loc) • 2.58 kB
Flow
// @flow
import * as React from 'react';
import classNames from 'classnames';
import Badgeable from '../badgeable';
import AvatarImage from './AvatarImage';
import AvatarInitials from './AvatarInitials';
import GlobeBadge16 from '../../icon/fill/GlobeBadge16';
import UnknownUserAvatar from '../../icons/avatars/UnknownUserAvatar';
import './Avatar.scss';
const SIZES = { small: true, large: true };
type Props = {
/**
* Url to avatar image. If passed in, component will render the avatar image instead of the initials
*
* Required if "name" is not specified.
*/
avatarUrl?: ?string,
/** classname to add to the container element. */
className?: string,
/** Users id */
id?: ?string | number,
/** Whether this avatar should be labeled as external in the current context */
isExternal?: boolean,
/**
* Users full name.
*
* Required if "avatarUrl" is not specified.
*/
name?: ?string,
/** Show the external avatar marker if the avatar is marked as for an external user */
shouldShowExternal?: boolean,
/* avatar size (enum) */
size?: $Keys<typeof SIZES>,
};
function Avatar({ avatarUrl, className, name, id, isExternal, shouldShowExternal = false, size = '' }: Props) {
const [hasImageErrored, setHasImageErrored] = React.useState<boolean>(false);
const [prevAvatarUrl, setPrevAvatarUrl] = React.useState<$PropertyType<Props, 'avatarUrl'>>(null);
const classes = classNames([
'avatar',
className,
{ [`avatar--${size}`]: size && SIZES[size], 'avatar--isExternal': shouldShowExternal && isExternal },
]);
// Reset hasImageErrored state when avatarUrl changes
if (avatarUrl !== prevAvatarUrl) {
setHasImageErrored(false);
setPrevAvatarUrl(avatarUrl);
}
let avatar;
if (avatarUrl && !hasImageErrored) {
avatar = (
<AvatarImage
onError={() => {
setHasImageErrored(true);
}}
url={avatarUrl}
/>
);
} else if (name) {
avatar = <AvatarInitials id={id} name={name} />;
} else {
avatar = <UnknownUserAvatar className="avatar-icon" />;
}
return (
<Badgeable
className={classes}
bottomRight={
shouldShowExternal && isExternal ? <GlobeBadge16 className="bdl-Avatar-externalBadge" /> : undefined
}
>
<span role="presentation">{avatar}</span>
</Badgeable>
);
}
export default Avatar;