-
Notifications
You must be signed in to change notification settings - Fork 1.2k
/
Avatar.tsx
128 lines (110 loc) · 3.08 KB
/
Avatar.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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import * as React from 'react';
import {classNames, variationName} from '@shopify/react-utilities/styles';
import {withAppProvider, WithAppProviderProps} from '../AppProvider';
import Image from '../Image';
import * as styles from './Avatar.scss';
import * as avatars from './images';
export type Size = 'small' | 'medium' | 'large';
const STYLE_CLASSES = ['one', 'two', 'three', 'four', 'five', 'six'];
const AVATAR_IMAGES = Object.keys(avatars).map(
// import/namespace does not allow computed values by default
// eslint-disable-next-line import/namespace
(key: keyof typeof avatars) => avatars[key],
);
export interface Props {
/**
* Size of avatar
* @default 'medium'
*/
size?: Size;
/** The name of the person */
name?: string;
/** Initials of person to display */
initials?: string;
/** Whether the avatar is for a customer */
customer?: boolean;
/** URL of the avatar image */
source?: string;
/** Accessible label for the avatar image */
accessibilityLabel?: string;
}
export type CombinedProps = Props & WithAppProviderProps;
function Avatar({
name,
source,
initials,
customer,
size = 'medium',
accessibilityLabel,
polaris: {intl},
}: CombinedProps) {
const nameString = name || initials;
let finalSource: string | undefined;
let label: string | undefined;
if (accessibilityLabel) {
label = accessibilityLabel;
} else if (name) {
label = name;
} else if (initials) {
const splitInitials = initials.split('').join(' ');
label = intl.translate('Polaris.Avatar.labelWithInitials', {
initials: splitInitials,
});
} else {
label = intl.translate('Polaris.Avatar.label');
}
if (source) {
finalSource = source;
} else if (customer) {
finalSource = customerPlaceholder(nameString);
}
const className = classNames(
styles.Avatar,
styles[variationName('style', styleClass(nameString))],
size && styles[variationName('size', size)],
finalSource && styles.hasImage,
);
const imageMarkUp = finalSource ? (
<Image
className={styles.Image}
source={finalSource}
alt=""
role="presentation"
/>
) : null;
// Use `dominant-baseline: central` instead of `dy` when Edge supports it.
const verticalOffset = '0.35em';
const initialsMarkup = initials ? (
<span className={styles.Initials}>
<svg className={styles.Svg} viewBox="0 0 48 48">
<text
x="50%"
y="50%"
dy={verticalOffset}
fill="currentColor"
fontSize="26"
textAnchor="middle"
>
{initials}
</text>
</svg>
</span>
) : null;
return (
<span aria-label={label} role="img" className={className}>
{initialsMarkup}
{imageMarkUp}
</span>
);
}
function styleClass(name?: string) {
return name
? STYLE_CLASSES[name.charCodeAt(0) % STYLE_CLASSES.length]
: STYLE_CLASSES[0];
}
function customerPlaceholder(name?: string) {
return name
? AVATAR_IMAGES[name.charCodeAt(0) % AVATAR_IMAGES.length]
: AVATAR_IMAGES[0];
}
export default withAppProvider<Props>()(Avatar);