# Avatars

> **Info:** This is release candidate documentation for **Stream Chat React Native SDK v10**. For the latest stable version, see the [latest version (v9)](https://getstream.io/chat/docs/sdk/react-native/).

The avatar components draw a user, a channel, or a group of users as a circle. They're the building blocks of the avatars in the channel list, the message list, threads, polls and channel details, and you can render them in your own UI. Every component on this page is exported from `stream-chat-react-native` and `stream-chat-expo`.

## Best practices

- Render `UserAvatar` for a user and `ChannelAvatar` for a channel. They pick the image, the initials, the background color and the accessibility label. `Avatar` is the base they share, for content of your own.
- Every avatar reads the theme, which `OverlayProvider` and `Chat` provide. `ChannelAvatar` also reads the chat client, so render it inside `Chat`.
- To change the avatar of every channel list row, override `ChannelPreviewAvatar`. It's the only override key whose default is one of these components. Elsewhere, override the part that renders the avatar, such as `MessageAuthor`, `MessageRepliesAvatars` or `MessageUserReactionsAvatar`.
- `UserAvatar` doesn't read `user.online`. Pass it as `showOnlineIndicator`, as the SDK does.

## Available components

| Component         | What it shows                                                   | Where the SDK renders it                                                                                                        |
| ----------------- | --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| `Avatar`          | An image in a circle, or a placeholder                          | Inside the other avatars, and the avatars of the message menu's reactions                                                       |
| `UserAvatar`      | A user's image or initials, with an optional presence dot       | Message authors, thread list items, mention suggestions, poll votes, and the member, add members, media and pinned message rows |
| `ChannelAvatar`   | The channel's image, or its members' avatars                    | Channel list rows, through `ChannelPreviewAvatar`, the profile of channel details, the edit form, and the channel actions sheet |
| `AvatarGroup`     | Up to four nodes arranged in a circle, and a count for the rest | Inside `UserAvatarGroup`                                                                                                        |
| `UserAvatarGroup` | An `AvatarGroup` of users                                       | `ChannelAvatar`, for a channel without an image                                                                                 |
| `AvatarStack`     | A row of overlapping nodes, and a count for the rest            | Inside `UserAvatarStack`                                                                                                        |
| `UserAvatarStack` | An `AvatarStack` of users                                       | The typing indicator, thread replies, thread list items and poll options                                                        |

The sizes are named. Each name is a diameter in points:

| Size  | `2xl` | `xl` | `lg` | `md` | `sm` | `xs` |
| ----- | ----- | ---- | ---- | ---- | ---- | ---- |
| Width | 80    | 48   | 40   | 32   | 24   | 20   |

## Avatar

`Avatar` renders `imageUrl` with the `ImageComponent` key of `ComponentsContext`. Without `imageUrl`, or once the image fails to load, it renders `placeholder` instead. After a load error it keeps the placeholder, even if `imageUrl` changes.

The avatar gets an accessibility label from `accessibilityLabel`, or, with SDK accessibility on, from `name` through the `avatar.accessibilityLabel` key, "Avatar of Cleo". A labeled avatar has the `image` role. Without a label, screen readers skip it.

| Prop                 | Type                                            | Default                      | Description                                                            |
| -------------------- | ----------------------------------------------- | ---------------------------- | ---------------------------------------------------------------------- |
| `size`               | `'2xl' \| 'xl' \| 'lg' \| 'md' \| 'sm' \| 'xs'` | required                     | The diameter, from the table above.                                    |
| `accessibilityLabel` | `string`                                        |                              | The label screen readers announce. Replaces the one built from `name`. |
| `backgroundColor`    | `ColorValue`                                    | `semantics.avatarPaletteBg1` | The color behind the image or the placeholder.                         |
| `imageUrl`           | `string`                                        |                              | The image to show.                                                     |
| `name`               | `string`                                        |                              | The user's or channel's name, for the accessibility label.             |
| `placeholder`        | `React.ReactNode`                               |                              | What shows without an image, such as initials or an icon.              |
| `showBorder`         | `boolean`                                       |                              | Draws a 1-point border in `semantics.borderCoreOpacitySubtle`.         |
| `style`              | `StyleProp<ViewStyle>`                          |                              | Applied to the circle, after the theme.                                |

## UserAvatar

`UserAvatar` shows `user.image`. Without one, it shows the initials of `user.name`, one letter at `xs` and `sm` and two at the larger sizes, or a people icon when the user has no name. The background and text colors come from the five `avatarPalette` colors of the theme, picked by a hash of the user's id, so a user keeps the same color everywhere. The accessibility label is built from `user.name`, or `user.id` without one.

With `showOnlineIndicator`, it adds an `OnlineIndicator` on the top right of the circle, sized to the avatar.

| Prop                  | Type                   | Default        | Description                                           |
| --------------------- | ---------------------- | -------------- | ----------------------------------------------------- |
| `user`                | `UserResponse`         | required       | The user.                                             |
| `size`                | `AvatarProps['size']`  | required       | The diameter.                                         |
| `showBorder`          | `boolean`              | `!!user.image` | Draws the border of `Avatar`.                         |
| `showOnlineIndicator` | `boolean`              |                | Shows the presence dot. It's always the online color. |
| `style`               | `StyleProp<ViewStyle>` |                | Passed to `Avatar`.                                   |

## ChannelAvatar

`ChannelAvatar` picks what to show from the channel's state:

1. With an image in the channel's data, `custom.image`, it shows the image on a background picked by a hash of the `cid`.
2. Otherwise, when more than one member besides the current user is loaded, it shows a `UserAvatarGroup` of the loaded members.
3. Otherwise, it shows a `UserAvatar` of the other member, or a people icon in a channel where you're alone.

It re-renders when the image, the members or the other member's presence changes. With SDK accessibility on, screen readers announce it once, as "Direct chat with Cleo" or as "Channel with 5 members". A channel counts as a group when it has a name or more than two members.

| Prop                  | Type                    | Default                                                    | Description                                                                                                         |
| --------------------- | ----------------------- | ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| `channel`             | `Channel`               | required                                                   | The channel.                                                                                                        |
| `size`                | `'lg' \| 'xl' \| '2xl'` | `'xl'`                                                     | The diameter.                                                                                                       |
| `showBorder`          | `boolean`               | `true`                                                     | Draws the border, around the image or the single user avatar.                                                       |
| `showOnlineIndicator` | `boolean`               | whether the other member of a two-member channel is online | Shows the presence dot on the user avatar or the group.                                                             |
| `isPreview`           | `boolean`               | `false`                                                    | Shows `previewUri` in place of the channel's image.                                                                 |
| `previewUri`          | `string \| null`        | `null`                                                     | The image to show while `isPreview` is `true`. `null` shows the members' avatars, as when the channel has no image. |

The channel edit form uses `isPreview` to show a picked image, or none, before it's saved.

## AvatarGroup and UserAvatarGroup

`AvatarGroup` places its `items` in a circle of the given size:

- one item, beside a placeholder with a people icon;
- two items, top left and bottom right;
- three items, one on top and two below;
- four items, in a grid;
- five or more, the first two on top and a `BadgeCount` with `+` and the rest below.

`UserAvatarGroup` renders an `AvatarGroup` of `UserAvatar`s, each with a 2-point border in `semantics.borderCoreInverse`, and a presence dot on the top right of the group. The inner avatars are `sm`, `md` and `xl` for a group of `lg`, `xl` and `2xl`.

| Prop    | Type                    | Default  | Description                         |
| ------- | ----------------------- | -------- | ----------------------------------- |
| `size`  | `'lg' \| 'xl' \| '2xl'` | required | The diameter of the group.          |
| `items` | `React.ReactNode[]`     | required | The avatars, usually four or fewer. |

`UserAvatarGroupProps`:

| Prop                  | Type                    | Default  | Description                                           |
| --------------------- | ----------------------- | -------- | ----------------------------------------------------- |
| `size`                | `'lg' \| 'xl' \| '2xl'` | required | The diameter of the group.                            |
| `users`               | `UserResponse[]`        | required | The users.                                            |
| `showOnlineIndicator` | `boolean`               | `true`   | Shows the presence dot. It's always the online color. |

## AvatarStack and UserAvatarStack

`AvatarStack` lays out the first `maxVisible` items in a row, each shifted over the one before it by `overlap`, a fraction of the diameter. When there are more items, a `BadgeCount` with the number of the others follows the row.

`UserAvatarStack` renders an `AvatarStack` of `UserAvatar`s, each with a 2-point border in `semantics.borderCoreInverse`.

| Prop         | Type                   | Default  | Description                                                                    |
| ------------ | ---------------------- | -------- | ------------------------------------------------------------------------------ |
| `items`      | `React.ReactNode[]`    | required | The avatars.                                                                   |
| `avatarSize` | `'md' \| 'sm' \| 'xs'` | `'sm'`   | The diameter of each item, used for the spacing and for the size of the count. |
| `maxVisible` | `number`               | `3`      | How many items show before the count.                                          |
| `overlap`    | `number`               | `0`      | From `0`, side by side, toward `1`, one on top of the other.                   |

`UserAvatarStackProps`:

| Prop         | Type                   | Default  | Description                    |
| ------------ | ---------------------- | -------- | ------------------------------ |
| `users`      | `UserResponse[]`       | required | The users.                     |
| `avatarSize` | `'md' \| 'sm' \| 'xs'` | `'sm'`   | The size of each `UserAvatar`. |
| `maxVisible` | `number`               | `3`      | Passed to `AvatarStack`.       |
| `overlap`    | `number`               | `0`      | Passed to `AvatarStack`.       |

## Theming

The theme styles the base avatar with `avatar.container`, `avatar.image` and `avatar.border`, and the bordered avatars of `UserAvatarStack` with `avatarStack.userAvatarWrapper`. The colors come from the `avatarPalette` semantic tokens. See [Theme object](https://getstream.io/chat/docs/sdk/react-native/v10/reference/theme/theme-object/#avatar).

## Example

A channel list without presence dots, and a row of the people in a call:

```tsx title="src/avatars.tsx"
import { Text, View } from "react-native";
import type { UserResponse } from "stream-chat";
import { ChannelAvatar, UserAvatarStack } from "stream-chat-react-native";
import type {
  ChannelAvatarProps,
  ComponentOverrides,
} from "stream-chat-react-native";

const ChannelPreviewAvatar = (props: ChannelAvatarProps) => (
  <ChannelAvatar {...props} showOnlineIndicator={false} />
);

// Pass these to WithComponents around ChannelList.
export const avatarOverrides: ComponentOverrides = {
  ChannelPreviewAvatar,
};

export const CallParticipants = ({ users }: { users: UserResponse[] }) => (
  <View style={{ alignItems: "center", flexDirection: "row", gap: 8 }}>
    <UserAvatarStack
      avatarSize="md"
      maxVisible={4}
      overlap={0.3}
      users={users}
    />
    <Text>{users.length} in the call</Text>
  </View>
);
```

`ChannelPreviewView` renders `ChannelPreviewAvatar` with the `channel` and `size="xl"`.

## Related

- [Badges](https://getstream.io/chat/docs/sdk/react-native/v10/component-reference/base-ui/badges/): `OnlineIndicator` and `BadgeCount`, which the avatars render.
- [Channel and thread hooks](https://getstream.io/chat/docs/sdk/react-native/v10/reference/hooks/channel-and-thread-hooks/#usechannelimage): `useChannelImage` and `useChannelName`, which read what `ChannelAvatar` shows.
- [Channel preview hooks](https://getstream.io/chat/docs/sdk/react-native/v10/reference/hooks/channel-preview-hooks/#usechannelpreviewdisplaypresence): `useChannelPreviewDisplayPresence`, the default of `showOnlineIndicator`.
- [Overriding components](https://getstream.io/chat/docs/sdk/react-native/v10/ui/customizing/overriding-components/): `WithComponents` and the `ImageComponent` key.

---

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/sdk/react-native/v10/component-reference/base-ui/avatars/](https://getstream.io/chat/docs/sdk/react-native/v10/component-reference/base-ui/avatars/).