VayuUI

Avatar

An image element with a fallback for representing the user.

Installation

npx vayu-ui init    # Add Theme CSS if not added
npx vayu-ui add avatar
npx vayu-ui add -t avatar # with test case needs

Usage

Avatar Examples

Avatars display user profile images, initials, or fallback placeholders with optional status indicators.

Sizes

Small

Medium

Large

Extra Large

Variants

Image

Initials

Fallback

Status States

Online

Away

Busy

Offline

Interactive

Click or focus these avatars to see WCAG-compliant interactions.

Button

With Status

With Button Component

Avatars can be used inside buttons for profile actions.


<Avatar size="small" username="Small User">
  <Avatar.Initials username="Small User" />
</Avatar>

<Avatar size="medium" username="Rugved Patel">
  <Avatar.Initials username="Rugved Patel" />
</Avatar>

<Avatar size="large" username="John Doe">
  <Avatar.Image
    src="https://images.unsplash.com/photo-1535713875002-d1d0cf377fde?w=800&auto=format&fit=crop&q=60"
    alt=""
  />
</Avatar>

<Avatar size="large" username="Fallback User">
  <Avatar.Image src="https://broken-image-link.com/image.jpg" alt="" />
  <Avatar.Fallback />
</Avatar>

<Avatar size="large" username="Online" status="online">
  <Avatar.Initials username="Online" />
  <Avatar.Status status="online" />
</Avatar>

<Avatar
  size="large"
  username="Profile"
  onClick={() => console.log("clicked")}
>
  <Avatar.Initials username="Profile" />
</Avatar>

<Avatar size={40} username="Custom Size">
  <Avatar.Initials username="Custom Size" />
</Avatar>

Anatomy

<Avatar size="medium" username="John Doe">
  <Avatar.Image src="https://example.com/avatar.jpg" alt="" />
  <Avatar.Fallback />
  <Avatar.Initials username="John Doe" />
  <Avatar.Status status="online" />
</Avatar>
ElementDescription
AvatarRoot container providing size, shape, and accessibility context
Avatar.ImageDisplays a profile image with loading state and error fallback
Avatar.FallbackDefault image shown when primary image fails to load
Avatar.InitialsAuto-generated initials with deterministic background color
Avatar.StatusStatus indicator dot (online, offline, away, busy)

Accessibility

Keyboard Support

  • Interactive avatars (with onClick) receive tabIndex={0} and can be focused via Tab
  • Enter and Space activate the onClick handler
  • Static avatars are not focusable

ARIA Attributes

ElementRoleARIA Attributes
Avatar (static)imgaria-label="{username}'s avatar"
Avatar (interactive)buttonaria-label="{username}'s avatar", tabIndex={0}
Avatar.Statusstatusaria-label="{status}", aria-live="polite"
Loading spinnerstatusaria-busy="true", aria-label="Loading avatar image"

Focus Behavior

  • Visible 2px focus ring with offset using focus-visible:ring-2 focus-visible:ring-focus
  • Focus ring is styled consistently in both light and dark modes
  • Focus only appears on keyboard navigation, not on click (focus-visible)

Screen reader behavior

  • Static avatars are announced as an image: "John Doe's avatar"
  • Interactive avatars are announced as a button: "John Doe's avatar, button"
  • When status is set on the root, it appends to the label: "John Doe's avatar (online)"
  • Status indicators are announced via aria-live="polite" when the status changes
  • Loading state is announced as "Loading avatar image" via aria-busy="true"
  • Initials and fallback images are hidden from screen readers (aria-hidden="true") since the parent provides the label

Component Folder Structure

Avatar/
├── Avatar.tsx           # Root component + compound pattern wiring
├── AvatarImage.tsx      # Image with loading spinner and fallback support
├── AvatarInitials.tsx   # Generated initials with background color
├── AvatarFallback.tsx   # Default avatar image
├── AvatarStatus.tsx     # Status indicator dot
├── hooks.ts             # Initial generation and color hashing
├── types.ts             # Types and WCAG-compliant color palette
├── index.ts             # Public API barrel export
└── README.md

Props

Avatar (Root)

PropTypeDefaultDescription
size"small" | "medium" | "large" | "xlarge" | number"medium"Size of the avatar container
usernamestring""Used for aria-label and initials generation
altstring-Custom alt text for the avatar
status"online" | "offline" | "away" | "busy"-Appends status context to the aria-label
onClick() => void-Makes the avatar interactive (button role)
tabIndexnumber0Tab index when interactive
classNamestring-Additional CSS classes
childrenReactNode-Subcomponents (Image, Initials, Fallback, Status)

Avatar.Image

PropTypeDefaultDescription
srcstring-Image source URL
fallbackSrcstring-Secondary URL used if primary src fails
altstring""Alt text for the image
onError(e: SyntheticEvent) => void-Callback when image fails to load
onLoad(e: SyntheticEvent) => void-Callback when image loads successfully
classNamestring-Additional CSS classes

Avatar.Initials

PropTypeDefaultDescription
usernamestring-Name to generate initials and background color
classNamestring-Additional CSS classes

Avatar.Fallback

PropTypeDefaultDescription
srcstringPlaceholder URLDefault image when primary image fails
altstring"Default avatar"Alt text for the fallback image
classNamestring-Additional CSS classes

Avatar.Status

PropTypeDefaultDescription
status"online" | "offline" | "away" | "busy"-Status to display visually
labelstring-Accessible label (overrides default)
classNamestring-Additional CSS classes

On this page