> Markdown version of [Avatar](https://vaadin.com/docs/next/components/avatar). Section index: [llms.txt](https://vaadin.com/docs/next/components/llms.txt)

# Avatar

Avatar is a graphical representation of an object or entity, for example, a person or an organization.

**Lit** — `avatar-basic.ts`

```html
<vaadin-avatar></vaadin-avatar>

<vaadin-avatar
  .name="${`${this.person?.firstName} ${this.person?.lastName}`}"
></vaadin-avatar>

<vaadin-avatar
  .img="${this.person?.pictureUrl}"
  .name="${`${this.person?.firstName} ${this.person?.lastName}`}"
></vaadin-avatar>
```

**Flow** — `AvatarBasic.java`

```java
Avatar avatarBasic = new Avatar();

Avatar avatarName = new Avatar(name);

Avatar avatarImage = new Avatar(name);
avatarImage.setImage(pictureUrl);
```

**React** — `avatar-basic.tsx`

```tsx
<Avatar />

<Avatar name={`${person.value?.firstName} ${person.value?.lastName}`} />

<Avatar
  img={person.value?.pictureUrl}
  name={`${person.value?.firstName} ${person.value?.lastName}`}
/>
```

> **Note: Real-time collaboration**
>
> This component is optimized for use with [Collaboration Kit](https://vaadin.com/collaboration) — a simple way to build real-time collaboration into your app — but can also be used standalone as a regular component.

## <a id="content"></a>Content

Avatar has three properties: **name**, **abbreviation**, and **image**.

<!-- vale Microsoft.Auto = NO -->

### <a id="name-and-abbreviation"></a>Name and Abbreviation

The name is shown on hover in a tooltip. When a name is set, Avatar auto-generates and display an abbreviation of the specified name. For example, “Allison Torres” becomes “AT”, “John Smith” becomes “JS”, and so on.

<!-- vale Microsoft.Auto = YES -->

**Lit** — `avatar-name.ts`

```html
<vaadin-avatar .name="${`${this.person?.firstName} ${this.person?.lastName}`}">
</vaadin-avatar>
```

**Flow** — `AvatarName.java`

```java
Avatar avatarName = new Avatar(name);
```

**React** — `avatar-name.tsx`

```tsx
<Avatar name={`${person.value?.firstName} ${person.value?.lastName}`} />
```

The abbreviation can also be set manually. Abbreviations should be kept to a maximum of 2–3 characters.

**Lit** — `avatar-abbreviation.ts`

```html
<vaadin-avatar name="Augusta Ada King"></vaadin-avatar>

<vaadin-avatar name="Augusta Ada King" abbr="AK"></vaadin-avatar>
```

**Flow** — `AvatarAbbreviation.java`

```java
Avatar avatarName = new Avatar("Augusta Ada King");

Avatar avatarAbbr = new Avatar("Augusta Ada King");
avatarAbbr.setAbbreviation("AK");
```

**React** — `avatar-abbreviation.tsx`

```tsx
<Avatar name="Augusta Ada King" />

<Avatar name="Augusta Ada King" abbr="AK" />
```

### <a id="image"></a>Image

Avatar can be used to display images, such as user profile pictures or company logos. Abbreviations aren’t shown when images are used.

**Lit** — `avatar-image.ts`

```html
<vaadin-avatar
  .img="${this.person?.pictureUrl}"
  .name="${`${this.person?.firstName} ${this.person?.lastName}`}"
></vaadin-avatar>

<vaadin-avatar .img="${companyLogo}" name="Company Inc."></vaadin-avatar>
```

**Flow** — `AvatarImage.java`

```java
Avatar user = new Avatar(name);
user.setImage(pictureUrl);

Avatar company = new Avatar("Company Inc.");
DownloadHandler imageHandler = DownloadHandler.forClassResource(
        getClass(), "/images/company-logo.png", "company-logo.png");
company.setImageHandler(imageHandler);
```

**React** — `avatar-image.tsx`

```tsx
<Avatar
  img={person.value?.pictureUrl}
  name={`${person.value?.firstName} ${person.value?.lastName}`}
/>

<Avatar img={companyLogo} name="Company Inc." />
```

## <a id="avatar-group"></a>Avatar Group

Avatar Group is used to group multiple Avatars together. It can be used, for example, to show that there are multiple users viewing the same page or for listing members of a project.

**Lit** — `avatar-group-basic.ts`

```html
<vaadin-avatar-group
  .items="${this.items.map((person) => ({
    name: `${person.firstName} ${person.lastName}`,
  }))}"
></vaadin-avatar-group>
```

**Flow** — `AvatarGroupBasic.java`

```java
AvatarGroup avatarGroup = new AvatarGroup();

for (Person person : people) {
    String name = person.getFirstName() + " " + person.getLastName();
    AvatarGroupItem avatar = new AvatarGroupItem(name);
    avatarGroup.add(avatar);
}
```

**React** — `avatar-group-basic.tsx`

```tsx
const avatars = useComputed(() =>
  peopleData.value.map((person) => ({
    name: `${person.firstName} ${person.lastName}`,
  }))
);

return <AvatarGroup items={avatars.value} />;
```

### <a id="maximum-number-of-items"></a>Maximum Number of Items

You can specify the maximum number of items an Avatar Group should display. Items that overflow are grouped into a single Avatar that displays the overflow count. The name of each hidden item is shown on hover in a tooltip. Clicking the overflow item displays the overflowing avatars and names in a list.

**Lit** — `avatar-group-max-items.ts`

```typescript
<vaadin-avatar-group
  .maxItemsVisible="${3}"
  .items="${this.items.map((person) => ({
    name: `${person.firstName} ${person.lastName}`,
  }))}"
></vaadin-avatar-group>
```

**Flow** — `AvatarGroupMaxItems.java`

```java
AvatarGroup avatarGroup = new AvatarGroup();
avatarGroup.setMaxItemsVisible(3);

for (Person person : people) {
    String name = person.getFirstName() + " " + person.getLastName();
    AvatarGroup.AvatarGroupItem avatar = new AvatarGroup.AvatarGroupItem(
            name);
    avatarGroup.add(avatar);
}
```

**React** — `avatar-group-max-items.tsx`

```tsx
<AvatarGroup maxItemsVisible={3} items={avatars.value} />
```

## <a id="background-color"></a>Background Color

By default, there are 7 different background colors you can use for Avatar. The background color is set using a color index.

**Lit** — `avatar-group-bg-color.ts`

```html
<vaadin-avatar-group
  .items="${this.items.map((person, index) => ({
    name: `${person.firstName} ${person.lastName}`,
    colorIndex: index,
  }))}"
></vaadin-avatar-group>
```

**Flow** — `AvatarGroupBgColor.java`

```java
AvatarGroup avatarGroup = new AvatarGroup();

for (Person person : people) {
    String name = person.getFirstName() + " " + person.getLastName();
    AvatarGroupItem avatar = new AvatarGroupItem(name);
    avatar.setColorIndex(colorIndex++);
    avatarGroup.add(avatar);
}
```

**React** — `avatar-group-bg-color.tsx`

```tsx
const avatars = useComputed(() =>
  peopleData.value.map((person, index) => ({
    name: `${person.firstName} ${person.lastName}`,
    colorIndex: index,
  }))
);

return <AvatarGroup items={avatars.value} />;
```

Using different background colors can be useful when you need to be able to distinguish between users, for example during collaborative work.

## <a id="internationalisation-i18n"></a>Internationalisation (i18n)

All texts in Avatar and Avatar Group are configurable:

### <a id="avatar-texts"></a>Avatar Texts

| Property    | Text        | Description                                                                                                    |
| ----------- | ----------- | -------------------------------------------------------------------------------------------------------------- |
| `anonymous` | "Anonymous" | Avatar’s default name. Shown on hover in a tooltip and announced by screen readers when the Avatar is focused. |

### <a id="avatar-group-texts"></a>Avatar Group Texts

| Property           | Text                             | Description                                                                                                                                                                                            |
| ------------------ | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `anonymous`        | "Anonymous"                      | Default name for all Avatars in the Avatar Group.                                                                                                                                                      |
| `activeUsers.one`  | "Currently one active user"      | Announced by screen readers when there is exactly one Avatar in an Avatar Group and the Avatar is focused. The name of the Avatar is read aloud first.                                                 |
| `activeUsers.many` | "Currently {count} active users" | Announced by screen readers when there are multiple Avatars in an Avatar Group and an Avatar is focused. The name of the focused Avatar is read aloud first. \*{count} is the Avatar Group item count. |
| `joined`           | "{user} joined"                  | Announced by screen readers when an Avatar is added to the group. \*{user} is the Avatar’s name.                                                                                                       |
| `left`             | "{user} left"                    | Announced by screen readers when an Avatar is removed from the group. \*{user} is the Avatar’s name.                                                                                                   |

**Lit** — `avatar-group-internationalisation.ts`

```typescript
private i18n: AvatarGroupI18n = {
  anonymous: 'Anonyymi',
  activeUsers: {
    one: 'Yksi käyttäjä aktiivisena',
    many: '{count} käyttäjää aktiivisena',
  },
  joined: 'liittyi',
  left: 'lähti',
};

protected override render() {
  return html`
    <vaadin-avatar-group
      .i18n="${this.i18n}"
      .items="${this.items.map((person) => ({
        name: `${person.firstName} ${person.lastName}`,
      }))}"
    ></vaadin-avatar-group>
  `;
}
```

**Flow** — `AvatarGroupInternationalisation.java`

```java
AvatarGroupI18n i18n = new AvatarGroupI18n();
i18n.setAnonymous("Anonyymi");
i18n.setManyActiveUsers("Yksi käyttäjä aktiivisena");
i18n.setOneActiveUser("{count} käyttäjää aktiivisena");

AvatarGroup avatarGroup = new AvatarGroup();
avatarGroup.setI18n(i18n);

// Add anonymous user
avatarGroup.add(new AvatarGroupItem());

for (Person person : people) {
    String name = person.getFirstName() + " " + person.getLastName();
    AvatarGroupItem avatar = new AvatarGroupItem(name);
    avatarGroup.add(avatar);
}
```

**React** — `avatar-group-internationalisation.tsx`

```tsx
const i18n: AvatarGroupI18n = {
  anonymous: 'Anonyymi',
  activeUsers: {
    one: 'Yksi käyttäjä aktiivisena',
    many: '{count} käyttäjää aktiivisena',
  },
  joined: 'liittyi',
  left: 'lähti',
};
  return <AvatarGroup i18n={i18n} items={items.value} />;
```

## <a id="use-cases"></a>Use Cases

Avatar can be paired with Popover to create a user account menu.

**Lit** — `popover-user-menu.ts`

```html
<vaadin-popover
  for="avatar"
  position="bottom-end"
  modal
  role="menu"
  aria-label="User menu"
  theme="no-padding"
>
  ${this.renderUserMenu(this.person)}
</vaadin-popover>
```

**Flow** — `PopoverUserMenu.java`

```java
String name = person.getFirstName() + " " + person.getLastName();
String pictureUrl = person.getPictureUrl();

Avatar avatar = new Avatar(name);
avatar.setImage(pictureUrl);
avatar.getStyle().set("display", "block");
avatar.getStyle().set("cursor", "var(--vaadin-clickable-cursor)");
avatar.getElement().setAttribute("tabindex", "-1");

Button button = new Button(avatar);
button.addThemeVariants(ButtonVariant.LUMO_ICON,
        ButtonVariant.TERTIARY);
button.getStyle().set("margin", "var(--vaadin-gap-s)");
button.getStyle().set("margin-inline-start", "auto");
button.getStyle().set("padding", "0");
button.getStyle().set("border-radius", "50%");

Popover popover = new Popover();
popover.setModal(true);
popover.setAriaRole("menu");
popover.setAriaLabel("User menu");
popover.setTarget(button);
popover.setPosition(PopoverPosition.BOTTOM_END);
popover.addThemeVariants(PopoverVariant.NO_PADDING);
```

**React** — `popover-user-menu.tsx`

```tsx
<Popover
  for="avatar"
  position="bottom-end"
  role="menu"
  modal
  aria-label="User menu"
  theme="no-padding"
>
  <div className="person-item" style={{ padding: 'var(--vaadin-padding-s)' }}>
    <Avatar img={pictureUrl} name={`${firstName} ${lastName}`} />
    <span>
      {firstName} {lastName}
    </span>
    <span>{nickName}</span>
  </div>
  <VerticalLayout className="userMenuLinks" style={{ alignItems: 'stretch', width: '100%' }}>
    <a href="#" role="menuitem">
      User profile
    </a>
    <a href="#" role="menuitem">
      Preferences
    </a>
    <a href="#" role="menuitem">
      Sign out
    </a>
  </VerticalLayout>
</Popover>
```

`popover-user-menu.css`

```css
.userMenuLinks {
  padding-bottom: var(--vaadin-padding-xs);
  border-top: 1px solid var(--vaadin-border-color-secondary);

  & a {
    padding: var(--vaadin-padding-xs) var(--vaadin-padding-m);
    color: var(--vaadin-text-color);
    text-decoration: none;

    &:hover {
      background: var(--vaadin-background-container);
    }
  }
}
```

`57551FAE-0B53-46FB-B384-71C3EB9D2CE1`
