# Avatar

**When to use:** User or entity image — profile pictures, comment authors, member lists. Falls back to initials (derived from `name`) or an icon when there's no image, or the image fails to load. Use `AvatarGroup` to stack several with overlap and a `+N` overflow indicator.

**Keywords:** user icon, photo

**Import:** `import { Avatar, AvatarGroup } from '@ahrowe/ui'`

**Theming:** shape defaults to `var(--default-border-radius)`. Set `--avatar-radius` (per `Avatar`/`AvatarGroup` via `style`, or theme-wide via `ThemeProvider`'s `variables`) to override it — `'50%'` for fully circular avatars is the most common case. See [ThemeProvider.md](ThemeProvider.md).

```tsx
import { Avatar, AvatarGroup } from '@ahrowe/ui';

// Image, with initials/icon fallback if it 404s
<Avatar src="https://example.com/avatar.jpg" name="Jane Doe" />

// No image — shows initials
<Avatar name="Jane Doe" />

// No image, no name — shows a default person icon (or pass a custom `icon`)
<Avatar />

// Status dot
<Avatar name="Jane Doe" status="online" />

// Resize — sizing is `em`-based, so font-size scales the whole avatar
<Avatar name="Jane Doe" style={{ fontSize: '32px' }} />

// Fully circular instead of the default --default-border-radius — set on one Avatar,
// or on an AvatarGroup to cascade to every avatar inside (and its separator ring)
<Avatar name="Jane Doe" style={{ '--avatar-radius': '50%' }} />

// Group with overlap, capped with a "+N" overflow indicator
<AvatarGroup max={3}>
  <Avatar name="Jane Doe" />
  <Avatar name="Carlos Diaz" />
  <Avatar name="Amy Lin" />
  <Avatar name="Sam Patel" />
</AvatarGroup>
```

**Avatar props:**

| Prop | Type | Description |
|------|------|-------------|
| `src` | `string` | Image URL |
| `alt` | `string` | Image alt text (falls back to `name`) |
| `name` | `string` | Used to derive fallback initials, and as `alt` text when `alt` isn't given. The initials are the first letters of the first and last word, or the first two letters of a single word, so `sam@acme.io` gives `SA` |
| `icon` | `IconDefinition \| ReactElement` | Icon shown when there's no `src` and no `name` — FontAwesome icon or any React element (default a person icon) |
| `content` | `ReactNode` | Custom fallback content overriding the computed initials/icon (e.g. `"+3"` — what `AvatarGroup` uses for its overflow indicator) |
| `status` | `'online' \| 'away' \| 'busy' \| 'offline'` | Small status dot on the bottom-right corner, rendered via `Badge` |
| `className` / `style` | | Root element — sizing is `em`-based, so `style={{ fontSize }}` scales the whole avatar. Shape defaults to `var(--default-border-radius)`; override via the `--avatar-radius` custom property (e.g. `'50%'` for fully circular) |

**AvatarGroup props:**

| Prop | Type | Description |
|------|------|-------------|
| `children` | `ReactNode` | `Avatar` elements to stack |
| `max` | `number` | Cap on visible avatars before collapsing the rest into a `+N` indicator |

The `+N` overflow indicator is itself an `Avatar` (with `content="+N"`), so it always matches whatever the avatar circle looks like. Setting `--avatar-radius` on `AvatarGroup` (rather than per-`Avatar`) cascades to every avatar inside *and* their separator rings, so the shape stays consistent across the group.

**Slots (Avatar):** `image` `fallback` `status`
**Slots (AvatarGroup):** `item` (wrapper around each visible avatar) `overflow` (wrapper around the `+N` avatar)
