Vesyl UI

Avatar

A user or entity portrait. Built on base-ui Avatar — the image loads behind the scenes and the fallback shows until it succeeds, so you never flash a broken <img>.

Compose three core parts: Avatar (root, owns the size and the circular clip), AvatarImage (the <img>), and AvatarFallback (initials shown while the image loads or if it never does). Two display helpers stack on top: AvatarGroup + AvatarGroupCount for overlapping clusters, and AvatarBadge for a status dot.

Image with fallback

Give AvatarImage a src and alt, and AvatarFallback the initials. Base UI swaps to the fallback automatically while the image is loading and if it errors, so the fallback is always your safety net — not an either/or.

MW

Fallback only

With no AvatarImage — or an src that fails to load — the AvatarFallback carries the avatar on its own. This is the common case for users without a photo: render their initials on the muted track. The right-hand avatar below points at a broken URL to show the automatic swap.

RDDP

Sizes

size on the root sets the diameter: sm (24px), md (32px, default), or lg (40px). The fallback text and any AvatarBadge scale with it.

PNPNPN

Group with overflow

AvatarGroup lays out a row of overlapping avatars (each gets a ring in the background color to separate it from its neighbor). Cap the visible count yourself and trail an AvatarGroupCount showing the remainder — it matches the avatar dimensions and reads from the group’s size.

MWDPPN
+4

Status badge

AvatarBadge is an absolutely-positioned dot in the bottom-right corner. Left bare it’s a solid status dot — recolor it with a className (e.g. bg-green-500 for online, bg-amber-500 for away). Drop a small lucide icon inside for a verified / decorated state; the icon auto-sizes to the avatar’s size.

MWDPPN

Reference

Avatar

Root container — sets the size and the circular clip. Extends base-ui Avatar.Root props.

PropTypeDefaultDescription
size"sm" | "md" | "lg""md"Diameter: 24px / 32px / 40px. Scales children
classNamestringMerged onto the root

AvatarImage

The <img>. Hidden until it loads; on error it stays hidden and the fallback shows. Extends base-ui Avatar.Image props (a native <img>).

PropTypeDefaultDescription
srcstringImage URL
altstringAlternative text for the image
onLoadingStatusChange(status: "idle" | "loading" | "loaded" | "error") => voidFires as the load state changes
classNamestringMerged onto the <img>

AvatarFallback

Shown while the image loads or if it never does — typically initials. Extends base-ui Avatar.Fallback props.

PropTypeDefaultDescription
delaynumberMilliseconds to wait before showing (avoids a flash)
childrenReactNodeFallback content — usually 1–2 initials
classNamestringMerged onto the fallback

AvatarGroup

Wraps a row of avatars into an overlapping cluster, ringing each one in the background color. Renders a <div>; extends React.ComponentProps<"div">.

PropTypeDefaultDescription
childrenReactNodeAvatar elements + an AvatarGroupCount
classNamestringMerged onto the wrapper

AvatarGroupCount

A trailing “+N” chip sized to match the group’s avatars. Renders a <div>; extends React.ComponentProps<"div">.

PropTypeDefaultDescription
childrenReactNodeThe overflow label, e.g. +4, or an icon
classNamestringMerged onto the chip

AvatarBadge

An absolutely-positioned dot in the avatar’s bottom-right corner. Bare it’s a status dot; an svg child renders as a small icon. Renders a <span>; extends React.ComponentProps<"span">.

PropTypeDefaultDescription
childrenReactNodeOptional svg icon; omit for a plain status dot
classNamestringRecolor here (e.g. bg-green-500); merged onto the badge