/
index.tsx
81 lines (74 loc) · 2.45 KB
/
index.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import * as React from 'react';
import * as PropTypes from 'prop-types';
import {isValidElementType} from 'react-is';
import {Text} from '@twilio-paste/text';
import {Box, safelySpreadBoxProps} from '@twilio-paste/box';
import {isIconSizeTokenProp} from '@twilio-paste/style-props';
import {getComputedTokenNames, getInitialsFromName} from './utils';
import type {AvatarProps, AvatarContentProps} from './types';
const DEFAULT_SIZE = 'sizeIcon70';
const AvatarContents: React.FC<AvatarContentProps> = ({name, size = DEFAULT_SIZE, src, icon: Icon}) => {
const computedTokenNames = getComputedTokenNames(size);
if (src != null) {
return <Box as="img" alt={name} maxWidth="100%" src={src} size={size} title={name} />;
}
if (Icon != null) {
if (!isValidElementType(Icon) || typeof Icon.displayName !== 'string' || !Icon.displayName.includes('Icon')) {
throw new Error('[Paste Avatar]: icon prop expected to be a Paste icon only.');
}
return (
<Box maxWidth="100%" size={size} display="flex" alignItems="center" justifyContent="center">
<Icon decorative={false} title={name} size={computedTokenNames.iconSize} />
</Box>
);
}
return (
<Text
as="abbr"
display="block"
fontSize={computedTokenNames.fontSize}
fontWeight="fontWeightBold"
lineHeight={computedTokenNames.lineHeight}
textAlign="center"
textDecoration="none"
title={name}
color="inherit"
>
{getInitialsFromName(name)}
</Text>
);
};
const Avatar = React.forwardRef<HTMLDivElement, AvatarProps>(
({name, children, size = DEFAULT_SIZE, element = 'AVATAR', src, icon, ...props}, ref) => {
if (name === undefined) {
console.error('[Paste Avatar]: name prop is required');
}
return (
<Box
{...safelySpreadBoxProps(props)}
as="div"
element={element}
backgroundColor="colorBackgroundUser"
borderRadius="borderRadiusCircle"
overflow="hidden"
ref={ref}
size={size}
color="colorText"
>
<AvatarContents name={name} size={size} icon={icon} src={src} />
</Box>
);
}
);
Avatar.displayName = 'Avatar';
Avatar.propTypes = {
size: isIconSizeTokenProp,
name: PropTypes.string.isRequired,
element: PropTypes.string,
src: PropTypes.string,
icon: (props) => {
if (typeof props.icon !== 'function') new Error('[Paste Avatar]: icon prop must be a Paste Icon');
return null;
},
};
export {Avatar};