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.
Sizes
Three size variants keep avatar dimensions consistent: sm (1.5rem), default (2rem), and lg (2.5rem).
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 avatarThis copies two files into your project:
components/ui/avatar/avatar.tsx— the componentcomponents/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
| Prop | Type | Default | Description |
|---|---|---|---|
avatars | (string | undefined | AvatarStackItem)[] | — | Avatars in display order. Strings are image URLs; undefined renders a placeholder · disc; objects support initials, src, alt, and style. |
total | number | — | Total member count, may exceed avatars.length for server-truncated lists. |
max | number | 6 | Maximum avatar slots before the +N overflow indicator. |
overflowCount | number | — | Explicit overflow value; overrides the derived total - visible count. |
size | "sm" | "default" | "lg" | "sm" | Avatar size pass-through. |
label | string | "${total} members" | Accessible label override. |
AvatarStackItem
| Field | Type | Description |
|---|---|---|
initials | ReactNode | Initials rendered inside the disc fallback. |
src | string | Optional image source; covers the disc when present. |
alt | string | Accessible label for the disc. |
style | CSSProperties | Per-disc style escape hatch for gradient background + color. |
Sub-components
| Component | Purpose |
|---|---|
Avatar | Root container with size variants |
AvatarImage | Image element with object-fit cover |
AvatarFallback | Centered fallback content shown when the image is unavailable |
AvatarStack | Overlapping avatar group with +N overflow indicator |