✦ Asteria UI
Components

Avatar

User portrait with an image, initials fallback, optional status, stacked groups, and an add-member button.

Installation

npx asteria-ui add avatar

Usage

import { Avatar, AvatarAddButton, AvatarGroup } from "@/components/ui/avatar";

<Avatar src="/maya.jpg" alt="Maya Chen" />
<Avatar initials="MC" alt="Maya Chen" status="online" />

<AvatarGroup max={3}>
  <Avatar src="/maya.jpg" alt="Maya Chen" />
  <Avatar src="/rio.jpg" alt="Rio Patel" />
  <Avatar initials="KO" alt="Ken Okada" />
  <Avatar initials="AS" alt="Ana Silva" />
</AvatarGroup>

Examples

Sizes

xs 24px · sm 32px · md 40px · lg 48px · xl 64px · 2xl 80px.

Image and fallback

A missing or failing src falls back to initials on bg-brand-subtle with fg-brand text. If neither src nor initials/alt can produce letters, the avatar shows ?.

Status

Optional presence dot. Online uses success-500; offline uses gray-300. The cutout ring is bg-primary so it punches through the portrait.

Avatar group

Stacked, overlapping avatars with a +N overflow chip (bg-secondary / fg-secondary). Each face gets a border-default ring and a bg-primary stack cutout.

+2

Label group

Pairs an avatar with a name and optional secondary text (email, role) — for lists, comment authors, and member rows.

Anastasia Upton

anastasia@example.com

Add-member button

A dashed-border circular button for adding another person to a group. Sizes match Avatar's own md/lg/xl. The hover state (border-brand + the signature glow-focus shadow) is also applied on focus-visible, since Figma's mockup only shows hover but every interactive component needs a visible keyboard focus indicator.

Composed after an AvatarGroup:

API reference

Prop names and types are taken from AvatarProps / AvatarGroupProps in the registry source.

Avatar

PropTypeDefaultDescription
srcstringImage URL. Falls back to initials if missing or it fails to load.
altstringAccessible name. Also used to derive initials when `initials` is omitted.
initialsstringFallback letters on `bg-brand-subtle` / `fg-brand`. Max two characters.
size"xs" | "sm" | "md" | "lg" | "xl" | "2xl""md"Diameter: 24 / 32 / 40 / 48 / 64 / 80px.
status"online" | "offline"Optional presence dot. Online uses success-500; offline uses gray-300.

AvatarGroup

PropTypeDefaultDescription
maxnumber4How many avatars to show before a +N overflow chip.
size"xs" | "sm" | "md" | "lg" | "xl" | "2xl""md"Applied to every child and the overflow chip.
childrenReactNodeOne or more `<Avatar />` elements.

AvatarAddButton

PropTypeDefaultDescription
size"md" | "lg" | "xl""md"Diameter: 40 / 48 / 64px, matching Avatar's own md/lg/xl.
aria-labelstring"Add"Accessible name — the "+" glyph itself is decorative.

AvatarLabelGroup

PropTypeDefaultDescription
avatarReactNodeAn `<Avatar />` element — its `size` is overridden to match.
nameReactNodePrimary line — `text-ui-sm` / `fg-primary`.
secondaryTextReactNodeOptional supporting line (email, role) — `text-ui-xs` / `fg-secondary`.
size"xs" | "sm" | "md" | "lg" | "xl" | "2xl""md"Passed through to the avatar.

Accessibility

Accessibility

  • Role. Each avatar is role="img" with an aria-label from alt (or initials). Status is appended to that name — Maya Chen, online — not a nested labelled node. The inner <img> uses alt="" so it isn't announced twice.

  • Keyboard. Avatar is presentational. It is not focusable and has no activation keys. Wrap it in a link or button if it should be interactive.

  • ARIA. AvatarGroup uses role="group". Overflow is its own role="img" labelled N more.

  • AvatarAddButton is a native <button> — Enter/Space activates, and it accepts an accessible name via aria-label (defaults to "Add"). Its focus ring uses the same shadow-glow-focus treatment as its hover state.