Source: https://monarchui.dev/components/avatar/

Components · Identity

# Avatar

Person or entity image with an initials and icon fallback, presence status and stacked groups.

@rookcom/monarch-react

Component

## Sizes and fallback

## Usage examples

### Status, numeric size and token palette

### Group with overflow

## Purpose

A person or entity image, falling back to initials on a colour stable per seed, then to an icon. AvatarGroup stacks several with a “+N” overflow.

### Use when

- Identifying a person, workspace, organisation or brand next to their content.
- Showing several assignees or participants in little space (AvatarGroup).

### Avoid when

- A decorative icon: use the icon directly.
- A selectable list of people: use a picker (assignee-picker, entity-picker).

## Design principles

- The same name always gets the same fallback colour, everywhere.
- Fallback colours keep AA contrast for every hue in light and dark themes (tested).
- Set `decorative` when the name is already visible next to the avatar.
- Circles are people; squares are workspaces, organisations and brands.
- Presence is never colour alone: the status is part of the accessible name.

## API reference

```tsx
import { Avatar, AvatarGroup, avatarPaletteIndex, initials } from '@rookcom/monarch-react';
```

| Export | Kind | Rendering | Root class |
| --- | --- | --- | --- |
| `Avatar` | component | client | `.mn-color-data-` |
| `AvatarGroup` | component | client | `.mn-color-data-` |
| `avatarPaletteIndex` | utility | client | – |
| `initials` | utility | client | – |

`initials(name)` is exported: first and last word initials, upper-cased, "?" for an empty name.

`avatarPaletteIndex(seed)` returns the data token (1–5) a seed maps to with `palette="tokens"`, for matching colours elsewhere.

Avatar and AvatarGroup forward their refs to the root `<span>` and `<div>`.

Generated from the TypeScript declarations of `packages/react/src/components/identity/avatar`.

## Properties

### `Avatar`

A person or entity image with a fallback chain: image, then initials on a colour stable per seed, then an icon.

| Prop | Type | Description |
| --- | --- | --- |
| `name` required | `string` | Person or entity name. Used for the image alt text and the initials fallback. |
| `className` | `string` |  |
| `decorative` | `boolean` | Set when a visible name sits next to the avatar, so screen readers do not hear the name twice. |
| `fallback` | `"icon" \| "initials"` | What to show when there is no image: `initials` (default), or `icon` for entities such as an organisation without a logo. Initials also fall back to the icon when the name has no letters. |
| `icon` | `ReactNode` | Icon for the `icon` fallback. Default: a neutral person glyph. Decorative. |
| `id` | `string` |  |
| `palette` | `"hue" \| "tokens"` | Fallback colour source. `hue` (default) derives a soft colour from the seed; `tokens` picks one of the five `--mn-color-data-*` tokens, so the colour follows the theme and contrast mode. |
| `seed` | `string` | Hashed to pick the fallback colour. Default `name`. Pass a stable id so a renamed person keeps their colour. |
| `shape` | `"circle" \| "square"` | `circle` for people; `square` for workspaces, organisations and brands. |
| `size` | `number \| AvatarSize` | A preset, or a number in CSS pixels (e.g. `28`) for sizes between the presets. |
| `src` | `string \| null` |  |
| `status` | `AvatarStatus` | Presence dot. Its text alternative is added to the accessible name. |
| `statusLabel` | `string` | Text alternative for `status`, e.g. a translated "Online". Default: the English status name. |

### `AvatarGroup`

Overlapping stack of avatars with a "+N" overflow tile. Each avatar keeps its own name, so the group reads as a list of people.

| Prop | Type | Description |
| --- | --- | --- |
| `children` required | `ReactNode` | `Avatar` elements. |
| `label` required | `string` | Names the group for assistive technology, e.g. "Assignees". |
| `className` | `string` |  |
| `id` | `string` |  |
| `max` | `number` | Show at most this many avatars, then a "+N" tile. Default: show all. |
| `overflowLabel` | `((hidden: number) => string)` | Text alternative for the "+N" tile. Default `(n) => \`${n} more\``. |
| `shape` | `"circle" \| "square"` | Applied to every avatar that does not set its own shape. |
| `size` | `number \| AvatarSize` | Applied to every avatar that does not set its own size. |

## Variants

| Prop | Values | Description |
| --- | --- | --- |
| `size` | `'xs'``'sm'``'md'``'lg'``'xl'` | 1.25–3.5rem. Default `md` (2rem). Exposed as `data-size`. A number is a size in CSS pixels (`data-size="custom"`, `--mn-avatar-size`). |
| `shape` | `'circle'``'square'` | Default `circle`; `square` for organisations and brands. Exposed as `data-shape`. |
| `palette` | `'hue'``'tokens'` | `hue` (default) derives a soft colour from the seed; `tokens` uses one of the five `--mn-color-data-*` tokens (`data-palette`). |
| `status` | `'online'``'away'``'busy'``'offline'` | Presence dot at the bottom end edge (`data-status`). |
| `fallback` | `'initials'``'icon'` | What shows without an image. `icon` suits organisations without a logo. |

## States

| State | Exposed as | Behaviour |
| --- | --- | --- |
| Image | – | Shows `src` when given and it loads. |
| Initials fallback | – | Shows initials when there is no `src` or the image fails to load. A new `src` is tried again. |
| Icon fallback | – | Shows `icon` (default a person glyph) with `fallback="icon"` or when the name has no letters or digits. |
| Status | `data-status` | Online, away, busy (filled dot) or offline (ring). |
| Overflow | – | AvatarGroup shows `max` avatars and a “+N” tile; it never shows “+1”, it shows that avatar instead. |

## Interaction behaviour

- None. If the image errors, the avatar switches to initials (or the icon).
- AvatarGroup applies its `size` and `shape` to children that do not set their own.

## Keyboard support

Not interactive, so there is no keyboard behaviour.

## Accessibility

Role

img (or aria-hidden when decorative); AvatarGroup is a labelled group

Accessible name

name

becomes

aria-label

, plus the status: “Ada Lovelace (Online)”. AvatarGroup requires

label

.

- The inner image has empty alt and the initials are `aria-hidden`, so the name is announced once.
- `decorative` hides the avatar, its status included, when the name is printed beside it.
- The “+N” tile is an image named by `overflowLabel` (default “N more”).
- Avatars are not focusable; when an avatar alone identifies a person (board cards), keep it labelled (not `decorative`) and, for sighted users, add a Tooltip on the focusable card or link around it.

## Responsive behaviour

- Fixed size per `size`; no breakpoints. AvatarGroup overlaps by a quarter of the avatar size and does not wrap.

## Theme support

- Fallback colours are derived from a per-seed hue (`--mn-avatar-hue`) with separate light and dark lightness values.
- `palette="tokens"` tints the surface with a data token and mixes it into the default text colour (AA in light and dark, tested); in more-contrast mode the text is the default text colour.
- Status dots use the success, warning and danger solid tokens with a surface-coloured ring.

## Do and don't

### Do

- Always pass the real `name`; it drives the label and initials.
- Pass a stable `seed` (a user id) so the colour survives a rename.
- Translate `statusLabel` and `overflowLabel` with the rest of the interface.

### Don't

- Do not leave `decorative` off when the name is printed beside the avatar.
- Do not use status colours for anything other than presence.

## Related components

- [MemberRow](https://monarchui.dev/components/member-row/): Planned row with avatar, name and role.
- [AssigneePicker](https://monarchui.dev/components/assignee-picker/): Planned picker showing avatars.
- [Tooltip](https://monarchui.dev/components/tooltip/): Names an avatar shown without its name.

## Dependencies

| Kind | Depends on |
| --- | --- |
| npm packages | `react` |
| Monarch components | None |

## Testing coverage

- Computes initials.
- Falls back to initials when the image fails.
- Fallback colours keep AA contrast for every hue.
- Decorative avatars are aria-hidden.
- Default markup is unchanged from 0.3.
- Numeric size, seed colour, token palette mapping and its AA contrast.
- Fallback chain image → initials → icon, and retry on a new `src`.
- Status is added to the accessible name, with a custom label.
- AvatarGroup: labelled group, `max` with “+N”, no “+1”, size inheritance, custom overflow label, no tab stop.

| Check | Covered |
| --- | --- |
| Axe in jsdom | Yes |
| Server rendering | Yes |
| Browser suites | Visual baselines: /__gallery |

Tests: `packages/react/src/components/identity/avatar`

## All example code

### Sizes and fallback

```tsx
import { Avatar } from '@rookcom/monarch-react';

<Avatar name="Ada Lovelace" size="xs" />
<Avatar name="Grace Hopper" size="sm" />
<Avatar name="Katherine Johnson" />
<Avatar name="Margaret Hamilton" size="lg" shape="square" />
<Avatar name="Rook" size="xl" />
```

### Status, numeric size and token palette

```tsx
import { Avatar } from '@rookcom/monarch-react';

<Avatar name="Ada Lovelace" status="online" />
<Avatar name="Grace Hopper" status="away" size={28} />
<Avatar name="Katherine Johnson" status="busy" palette="tokens" />
<Avatar name="Margaret Hamilton" status="offline" palette="tokens" seed="user_4" />
<Avatar name="Northfield Labs" shape="square" fallback="icon" size="lg" />
```

### Group with overflow

```tsx
import { Avatar, AvatarGroup } from '@rookcom/monarch-react';

<AvatarGroup label="Assignees" max={3}>
  <Avatar name="Ada Lovelace" />
  <Avatar name="Grace Hopper" />
  <Avatar name="Katherine Johnson" />
  <Avatar name="Margaret Hamilton" />
  <Avatar name="Hedy Lamarr" />
</AvatarGroup>
```
