Avatar
An image element with a fallback for representing the user.
Installation
npx vayu-ui init # Add Theme CSS if not addednpx vayu-ui add avatarnpx vayu-ui add -t avatar # with test case needsUsage
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>| Element | Description |
|---|---|
| Avatar | Root container providing size, shape, and accessibility context |
| Avatar.Image | Displays a profile image with loading state and error fallback |
| Avatar.Fallback | Default image shown when primary image fails to load |
| Avatar.Initials | Auto-generated initials with deterministic background color |
| Avatar.Status | Status indicator dot (online, offline, away, busy) |
Accessibility
Keyboard Support
- Interactive avatars (with
onClick) receivetabIndex={0}and can be focused via Tab - Enter and Space activate the
onClickhandler - Static avatars are not focusable
ARIA Attributes
| Element | Role | ARIA Attributes |
|---|---|---|
| Avatar (static) | img | aria-label="{username}'s avatar" |
| Avatar (interactive) | button | aria-label="{username}'s avatar", tabIndex={0} |
| Avatar.Status | status | aria-label="{status}", aria-live="polite" |
| Loading spinner | status | aria-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
statusis 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.mdProps
Avatar (Root)
| Prop | Type | Default | Description |
|---|---|---|---|
size | "small" | "medium" | "large" | "xlarge" | number | "medium" | Size of the avatar container |
username | string | "" | Used for aria-label and initials generation |
alt | string | - | 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) |
tabIndex | number | 0 | Tab index when interactive |
className | string | - | Additional CSS classes |
children | ReactNode | - | Subcomponents (Image, Initials, Fallback, Status) |
Avatar.Image
| Prop | Type | Default | Description |
|---|---|---|---|
src | string | - | Image source URL |
fallbackSrc | string | - | Secondary URL used if primary src fails |
alt | string | "" | Alt text for the image |
onError | (e: SyntheticEvent) => void | - | Callback when image fails to load |
onLoad | (e: SyntheticEvent) => void | - | Callback when image loads successfully |
className | string | - | Additional CSS classes |
Avatar.Initials
| Prop | Type | Default | Description |
|---|---|---|---|
username | string | - | Name to generate initials and background color |
className | string | - | Additional CSS classes |
Avatar.Fallback
| Prop | Type | Default | Description |
|---|---|---|---|
src | string | Placeholder URL | Default image when primary image fails |
alt | string | "Default avatar" | Alt text for the fallback image |
className | string | - | Additional CSS classes |
Avatar.Status
| Prop | Type | Default | Description |
|---|---|---|---|
status | "online" | "offline" | "away" | "busy" | - | Status to display visually |
label | string | - | Accessible label (overrides default) |
className | string | - | Additional CSS classes |