# Avatar

A face with a fallback for when there is no picture, a corner badge for presence, and a row for a group of them.

```slint
import { Avatar, AvatarBadge, AvatarGroup } from "@glint/components/avatar.slint";
import { Tokens } from "@glint/theme/tokens.slint";
import { IconSet } from "@lucide";

export component Demo inherits Window {
    width: 560px;
    height: 200px;
    background: Tokens.color-background;

    VerticalLayout {
        alignment: center;
        padding: 24px;

        HorizontalLayout {
            alignment: center;
            spacing: 24px;

            Avatar {
                fallback: "AL";
                alt: "Ada Lovelace";
            }

            Avatar {
                fallback: "GH";
                alt: "Grace Hopper";

                AvatarBadge {
                    status: "Online";
                }
            }

            Avatar {
                fallback: "TC";
                alt: "Tim Cook";

                AvatarBadge {
                    icon: IconSet.Check;
                    status: "Verified";
                }
            }
        }
    }
}
```

## Usage

```slint
import { Avatar, AvatarBadge } from "@glint/components/avatar.slint";
import { Tokens } from "@glint/theme/tokens.slint";

export component AppWindow inherits Window {
    width: 560px;
    height: 200px;
    background: Tokens.color-background;

    VerticalLayout {
        alignment: center;
        padding: 24px;

        Avatar {
            size: 48px;
            fallback: "JD";
            alt: "Jane Doe";

            AvatarBadge {
                status: "Active";
            }
        }
    }
}
```

`Avatar` renders a circular profile image with fallback initials. `AvatarBadge` mounts in the bottom-right corner to indicate presence or verification status. `AvatarGroup` stacks multiple avatars in an overlapping row.

## Examples

### Sizes

Adjust the `size` property to scale the avatar diameter and fallback typography.

```slint
import { Avatar } from "@glint/components/avatar.slint";
import { Tokens } from "@glint/theme/tokens.slint";

export component Demo inherits Window {
    width: 560px;
    height: 200px;
    background: Tokens.color-background;

    VerticalLayout {
        alignment: center;
        padding: 24px;

        HorizontalLayout {
            alignment: center;
            spacing: 16px;

            Avatar {
                size: 32px;
                fallback: "SM";
                alt: "Small avatar";
            }

            Avatar {
                size: 40px;
                fallback: "MD";
                alt: "Medium avatar";
            }

            Avatar {
                size: 56px;
                fallback: "LG";
                alt: "Large avatar";
            }
        }
    }
}
```

### Badges and status

Mount `AvatarBadge` in the avatar’s corner slot. Customize `tint` or supply a Lucide icon for verified or idle states.

```slint
import { Avatar, AvatarBadge } from "@glint/components/avatar.slint";
import { Tokens } from "@glint/theme/tokens.slint";
import { IconSet } from "@lucide";

export component Demo inherits Window {
    width: 560px;
    height: 200px;
    background: Tokens.color-background;

    VerticalLayout {
        alignment: center;
        padding: 24px;

        HorizontalLayout {
            alignment: center;
            spacing: 24px;

            Avatar {
                fallback: "ON";
                alt: "Online user";

                AvatarBadge {
                    tint: Tokens.color-affirm;
                    status: "Online";
                }
            }

            Avatar {
                fallback: "BS";
                alt: "Busy user";

                AvatarBadge {
                    tint: Tokens.color-destructive;
                    status: "Do not disturb";
                }
            }

            Avatar {
                fallback: "VR";
                alt: "Verified profile";

                AvatarBadge {
                    icon: IconSet.Check;
                    tint: Tokens.color-primary;
                    status: "Verified member";
                }
            }
        }
    }
}
```

### Avatar group

Wrap multiple avatars in `AvatarGroup` to create an overlapping stack with optional `overflow` counter.

```slint
import { Avatar, AvatarGroup } from "@glint/components/avatar.slint";
import { Tokens } from "@glint/theme/tokens.slint";

export component Demo inherits Window {
    width: 560px;
    height: 200px;
    background: Tokens.color-background;

    VerticalLayout {
        alignment: center;
        padding: 24px;

        HorizontalLayout {
            alignment: center;

            AvatarGroup {
                size: 40px;
                overflow: 4;

                Avatar {
                    fallback: "AB";
                    alt: "Alice Brown";
                    ring: true;
                }

                Avatar {
                    fallback: "CD";
                    alt: "Charlie Davis";
                    ring: true;
                }

                Avatar {
                    fallback: "EF";
                    alt: "Emma Frank";
                    ring: true;
                }
            }
        }
    }
}
```

## API Reference

### Properties

| Property     | Type        | Default                   | Description                                                                                                                                                                                            |
| ------------ | ----------- | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `source`     | `in image`  | no default                | Image to display; when empty, `fallback` initials render instead.                                                                                                                                      |
| `fallback`   | `in string` | no default                | 1–2 letter initials shown when `source` is empty.                                                                                                                                                      |
| `size`       | `in length` | `40px`                    | Pixel diameter of the circular avatar.                                                                                                                                                                 |
| `alt`        | `in string` | no default                | Who this is a picture of. Empty leaves the avatar decorative.                                                                                                                                          |
| `ring`       | `in bool`   | `false`                   | Draws a ring in the surface colour around the circle — what separates one face from the next inside an `AvatarGroup`.                                                                                  |
| `ring-color` | `in color`  | `Tokens.color-background` | The surface the ring pretends to be. Override it on a card or any other background the default does not match.                                                                                         |
| `badge-size` | `in length` | `root.size * 0.32`        | Side of the corner box `@children` are laid out in. A badge scales with the face it sits on, so this is the avatar's to decide: Slint gives a component no way to read the parent it was slotted into. |

### AvatarBadge

The marker in the corner of a face — a presence dot, or a glyph. It is ringed in the surface color so it reads against the photo under it, and `status` is what a screen reader hears.

### Properties

| Property     | Type            | Default                           | Description                                                                                                                          |
| ------------ | --------------- | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `tint`       | `in color`      | `Tokens.color-affirm`             | Fill — the presence colour. Affirm reads as "here"; pass the destructive or muted token for the other states.                        |
| `icon`       | `in LucideIcon` | no default                        | Optional glyph inside the dot, normally selected from `IconSet`.                                                                     |
| `icon-tint`  | `in color`      | `Tokens.color-primary-foreground` | Ink for that glyph.                                                                                                                  |
| `ring-color` | `in color`      | `Tokens.color-background`         | The surface the ring pretends to be.                                                                                                 |
| `status`     | `in string`     | no default                        | What the dot means. Colour alone does not reach assistive technology — leave it empty only for a badge that is genuinely decoration. |

### AvatarGroup

A row of overlapping faces. Each face wants `ring: true`, because only the avatar knows what surface it is standing on and a group cannot reach into the children it was handed.

### Properties

| Property     | Type        | Default                   | Description                                                                                                                                                             |
| ------------ | ----------- | ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `size`       | `in length` | `40px`                    | Diameter of the faces in the row. The group only needs it to draw the overflow count at the same size.                                                                  |
| `overlap`    | `in length` | `root.size / 4`           | How far each face is pulled onto the one before it.                                                                                                                     |
| `overflow`   | `in int`    | `0`                       | How many more there are than the row shows. `0` draws no count.                                                                                                         |
| `ring-color` | `in color`  | `Tokens.color-background` | The surface the rings pretend to be — the overflow count wears the same one the faces beside it do, so a group on a card is not the one chip that gives the trick away. |

## Accessibility

- **Accessible image role.** The avatar announces as `accessible-role: image` with `alt` supplying the accessible label.
- **Fallback suppression.** When `alt` is populated, the visual fallback initials are suppressed from the accessibility tree (`accessible-role: none`) to prevent duplicate reading.
- **Status announcement.** `AvatarBadge` publishes `accessible-role: text` with its `status` string, making visual dots legible to screen readers.
