Avatar
PortedA person's photo in a circle, or their initials. Native <span> attributes and ref pass through.
import { Avatar } from "@etched/monet/avatar";
// A stand-in photo, so the page needs no network.
const photo = `data:image/svg+xml,${encodeURIComponent(
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect width="64" height="64" fill="#c3eac9"/><circle cx="32" cy="26" r="12" fill="#194f29"/><rect x="12" y="42" width="40" height="30" rx="20" fill="#194f29"/></svg>',
)}`;
export function Preview() {
return (
<div className="row">
<Avatar name="Ana Ruiz" size="lg" />
<Avatar name="Lee Park" src={photo} size="lg" />
<Avatar name="José Núñez" size="lg" />
</div>
);
}Installation
import { Avatar, AvatarGroup } from "@etched/monet/avatar";Examples
Initials
import { Avatar, type AvatarSize } from "@etched/monet/avatar";
const sizes: AvatarSize[] = ["xs", "sm", "base", "lg"];
export function Initials() {
return (
<div className="row">
{sizes.map((size) => (
<Avatar key={size} name="Ana Ruiz" size={size} />
))}
</div>
);
}Photo
import { Avatar, type AvatarSize } from "@etched/monet/avatar";
const sizes: AvatarSize[] = ["xs", "sm", "base", "lg"];
// A stand-in photo, so the page needs no network.
const photo = `data:image/svg+xml,${encodeURIComponent(
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect width="64" height="64" fill="#c3eac9"/><circle cx="32" cy="26" r="12" fill="#194f29"/><rect x="12" y="42" width="40" height="30" rx="20" fill="#194f29"/></svg>',
)}`;
export function Photo() {
return (
<div className="row">
{sizes.map((size) => (
<Avatar key={size} name="Lee Park" src={photo} size={size} />
))}
</div>
);
}A photo that fails shows the initials
import { Avatar } from "@etched/monet/avatar";
export function APhotoThatFailsShowsTheInitials() {
return (
<div className="row">
<Avatar name="José Núñez" src="data:image/png;base64,broken" />
</div>
);
}Beside the name: alt="" so the name is read once
Mira Osei
import { Avatar } from "@etched/monet/avatar";
export function BesideTheNameAltSoTheNameIsReadOnce() {
return (
<div className="row">
<Avatar name="Mira Osei" alt="" size="sm" />
<span>Mira Osei</span>
</div>
);
}Group
AvatarGroup overlaps the avatars. With more people than max (4 by default, the count included), a "+N" circle stands for the rest, and screen readers read their names. moreLabel writes that name, for example in another language. Name the group with aria-label.
+3
+4
import { AvatarGroup } from "@etched/monet/avatar";
// A stand-in photo, so the page needs no network.
const photo = `data:image/svg+xml,${encodeURIComponent(
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect width="64" height="64" fill="#c3eac9"/><circle cx="32" cy="26" r="12" fill="#194f29"/><rect x="12" y="42" width="40" height="30" rx="20" fill="#194f29"/></svg>',
)}`;
const team = [{ name: "Priya Shah" }, { name: "Tom Becker", src: photo }, { name: "Noor Haddad" }, { name: "Wei Chen" }, { name: "Dana Cole" }, { name: "Omar Farah" }];
export function Group() {
return (
<div className="rows">
<AvatarGroup aria-label="Interviewers" people={team} size="sm" />
<AvatarGroup aria-label="Hiring team" people={team.slice(0, 3)} />
<AvatarGroup aria-label="Referrers" people={team} max={3} size="lg" moreLabel={(names) => `${names.length} more referrers: ${names.join(", ")}`} />
</div>
);
}Accessibility
- An
img, named byname, or byaltwhen set;alt=""hides it. The photo and the initials are hidden; the name stands for both. AvatarGroupis agroup. Pastmax, the "+N" circle is animgnamed by the hidden names: "3 more: Wei Chen, Dana Cole, and Omar Farah".- Set
alt=""when the name shows next to the avatar, so it is not read twice. - Name an
AvatarGroupwitharia-label, such as "Interviewers". Pass translated text tomoreLabel.
API reference
AvatarGroup
| Prop | Type | Default | Description |
|---|---|---|---|
| people * | Omit<AvatarProps, "size">[] | – | The people, in order. Each takes Avatar's props, such as name and src. |
| max | number | 4 | The most circles to show, the count included. With more people, the last circle is "+N". |
| size | "xs" | "sm" | "base" | "lg" | "base" | For every avatar and the count. |
| moreLabel | (names: string[]) => string | "2 more: Lee Park and Mira Osei" | Names the "+N" circle from the names of the people it stands for. Pass translated text. |
Avatar
| Prop | Type | Default | Description |
|---|---|---|---|
| name * | string | – | The person's name. It names the avatar, and its first two words give the initials. |
| src | string | – | Photo URL. Until it loads, or when it fails, the initials show. |
| size | "xs" | "sm" | "base" | "lg" | "base" | |
| alt | string | name | "" when the name is already beside the avatar, so screen readers do not read it twice. |