Data display
Avatar
Who’s who across the product — assignees, members, commenters. Falls back gracefully from photo to colored initials to a generic icon, and stacks into groups when space is tight.
npx shadcn@latest add @orbit/avatarOverview
Photo, initials, presence, count badges, and stacks.
Fallbacks
A photo when there is one; otherwise initials on a color derived from the name — stable per person — and a neutral icon when there’s no identity at all.
Sizes
xs 20 · sm 26 · md 32 (default) · lg 40 · xl 56 · 2xl 80px. Initials, presence dots, and badges scale with the avatar.
Shape, presence & badge
Circle by default, square for entities like teams or bots. A presence dot or a count badge sits on the ring.
Deterministic colors
Each name hashes to a fixed slot in the palette (12 solid · 8 soft), so a person keeps the same color everywhere. Solid by default; a soft tint is available for light surfaces.
Group stacks
Pass people or names to overlap avatars into a stack (34% of the diameter); max caps the count and rolls the rest into a +N chip.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| name | string | — | Person's name — initials, deterministic color, alt text, and title all derive from it. |
| image | string | — | Photo URL, cover-fit. Falls back to initials if it fails to load. |
| size | "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "md" | Diameter: 20 / 26 / 32 / 40 / 56 / 80px. |
| shape | "circle" | "square" | "circle" | Square suits entities like teams or bots. |
| soft | boolean | false | Soft tint instead of a solid fill for initials. |
| icon | boolean | false | Generic person glyph — automatic when there’s no name or image. |
| presence | "none" | "online" | "away" | "busy" | "offline" | "none" | Presence dot on the bottom-right rim, ringed with ringColor. |
| badge | number | string | — | Count badge on the top-right rim; values over 99 clamp to 99+. |
| ringColor | string | var(--surface) | Ring behind the presence dot / badge and between stacked avatars. |
| people / names / max | AvatarPerson[] / string / number | — | Group mode — delegates to AvatarGroup (spec parity). |
| …rest | HTMLAttributes<HTMLSpanElement> | — | Everything else is forwarded to the root, including ref. |
AvatarGroup props
| Prop | Type | Default | Description |
|---|---|---|---|
| people | { name: string; image?: string }[] | — | Members, in display order. |
| names | string | — | Comma-separated names shorthand for people. |
| max | number | 4 | Max visible avatars before the rest roll into a +N chip. |
| size / shape / soft | AvatarSize / AvatarShape / boolean | "md" / "circle" / false | Forwarded to each member avatar. |
| ringColor | string | var(--surface) | Ring separating overlapped avatars — match the surface behind the stack. |
| …rest | HTMLAttributes<HTMLDivElement> | — | Forwarded to the role=“group” root, including ref. |
Usage
Identity should always be legible.
Always provide a name
Initials and color come from it — and it’s the alt text and tooltip for the photo.
Put many big avatars in a row
Beyond a few, switch to a stack with +N so the layout stays calm.
Keep one color per person
The deterministic hash does this for free — don’t override it per screen.
Use presence as the only signal
Pair the dot with text where the state actually matters; color alone isn’t enough.
Keyboard & accessibility
The single avatar renders role=img with aria-label and title set to the name (alt on photos); stacks render role=group with a member count. White text meets AA on every palette fill, and presence dots are aria-hidden — pair them with text where the state matters.