VisorVisor
ComponentsData Display

Avatar

A circular avatar component with image display and fallback support for initials or icons.

Default

Avatar displays an image with automatic fallback to initials when the image is unavailable.

JDAB

Sizes

Three size variants keep avatar dimensions consistent: sm (1.5rem), default (2rem), and lg (2.5rem).

SMMDLG

AvatarStack

AvatarStack renders a row of overlapping avatar discs with a +N overflow indicator. It accepts both the legacy string-array form and the rich AvatarStackItem object form.

String array (legacy / simple)

Rich item form (initials + gradient discs)

Pass AvatarStackItem objects to render initials with per-disc gradient backgrounds. Set style.background and style.color for the editorial gradient-disc look.

Explicit overflow count

Use overflowCount to override the derived +N value — useful when you already have a precomputed count.

Theming the ring per surface

Each disc in an AvatarStack rings itself against the parent surface so adjacent avatars read as separate circles. That ring color is exposed as the --avatar-stack-ring role hook, defaulting to --surface-default. When a stack sits on a different surface tier — say a card — retint the ring by setting that one custom property on a wrapper, rather than reaching into the component's data-slot internals:

// The stack lives on a card, so ring each disc against --surface-card.
<div style={{ '--avatar-stack-ring': 'var(--surface-card)' } as React.CSSProperties}>
  <AvatarStack avatars={members} total={members.length} />
</div>

Under data-density="editorial" the +N overflow disc font drops to 11px so the count never clips inside the smaller editorial disc — no consumer override required.

Installation

npx visor add avatar

This copies two files into your project:

  • components/ui/avatar/avatar.tsx — the component
  • components/ui/avatar/avatar.module.css — the styles

Usage

import { Avatar, AvatarImage, AvatarFallback, AvatarStack } from '@/components/ui/avatar/avatar';
import type { AvatarStackItem } from '@/components/ui/avatar/avatar';

<Avatar>
  <AvatarImage src="/profile.jpg" alt="Jane Doe" />
  <AvatarFallback>JD</AvatarFallback>
</Avatar>

// Simple string array
<AvatarStack avatars={['/a.jpg', '/b.jpg']} total={5} />

// Rich item form with gradient discs
const members: AvatarStackItem[] = [
  { initials: 'AR', style: { background: 'linear-gradient(135deg, #6366f1, #8b5cf6)', color: '#fff' }, alt: 'Alex Rivera' },
  { initials: 'MK', style: { background: 'linear-gradient(135deg, #f59e0b, #ef4444)', color: '#fff' }, alt: 'Morgan Kim' },
];
<AvatarStack avatars={members} total={members.length} />

API Reference

AvatarProps

No props data available for “avatar”.

AvatarStackProps

PropTypeDefaultDescription
avatars(string | undefined | AvatarStackItem)[]Avatars in display order. Strings are image URLs; undefined renders a placeholder · disc; objects support initials, src, alt, and style.
totalnumberTotal member count, may exceed avatars.length for server-truncated lists.
maxnumber6Maximum avatar slots before the +N overflow indicator.
overflowCountnumberExplicit overflow value; overrides the derived total - visible count.
size"sm" | "default" | "lg""sm"Avatar size pass-through.
labelstring"${total} members"Accessible label override.

AvatarStackItem

FieldTypeDescription
initialsReactNodeInitials rendered inside the disc fallback.
srcstringOptional image source; covers the disc when present.
altstringAccessible label for the disc.
styleCSSPropertiesPer-disc style escape hatch for gradient background + color.

Sub-components

ComponentPurpose
AvatarRoot container with size variants
AvatarImageImage element with object-fit cover
AvatarFallbackCentered fallback content shown when the image is unavailable
AvatarStackOverlapping avatar group with +N overflow indicator