Skip to content

Avatar

Terminal-inspired avatar with image support, monospace initials fallback, and group stacking with overflow.

Preview

Installation

$pnpm exec dgadd add ui/avatar
[Installs to]src/components/ui/avatar[Item]ui/avatar

dgadd ships in @diffgazer/add on npm: pnpm add -D @diffgazer/add puts it on pnpm exec, and npx @diffgazer/add runs it without the install.

UI components require Tailwind CSS v4. Local copy mode imports src/styles/styles.css; package mode uses @diffgazer/ui CSS from the installed package.

Usage

tsx
import { Avatar } from "@/components/ui/avatar";export default function AvatarDefault() {  return (    <div className="flex items-center gap-4">      <Avatar        src="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2064%2064'%3E%3Crect%20width='64'%20height='64'%20fill='%23111827'/%3E%3Cpath%20fill='%2322d3ee'%20d='M12%2012h16v16H12zM36%2012h16v16H36zM20%2036h24v12H20z'/%3E%3Cpath%20fill='%23f8fafc'%20d='M28%2028h8v8h-8zM12%2052h40v4H12z'/%3E%3C/svg%3E"        alt="Felix"        fallback="FX"      />      <Avatar fallback="JD" />      <Avatar fallback="AB" size="lg" />    </div>  );}

Examples

Sizes

Preview

Group with Overflow

Preview

API Reference

Avatar

NameTypeDefaultDescription
srcstring—Image URL. Ignored when children are provided.
altstring—Image alt text and accessible name. When omitted, falls back to a string `fallback`. When neither is set, the avatar uses role="presentation".
fallbackReactNode"?"Shown when the image is loading, missing, or fails.
size"sm" | "md" | "lg""md"Square size token. Inherits from an AvatarGroup parent when unset.
onStatusChange(status: "loading" | "loaded" | "error") => void—Fired when the image load status changes. Fires for the active image only.
childrenReactNode—Custom inner content. Replaces the default AvatarImage + AvatarFallback composition.

AvatarImage

NameTypeDefaultDescription
srcstring—Image URL.
altstring""Accessible name for the image. Defaults to `""`, treating the avatar as decorative so it is skipped by assistive tech and the surrounding control supplies the accessible name. Pass an explicit `alt` when the avatar is the sole label for its container.

AvatarFallback

NameTypeDefaultDescription
srcstring—Cascading fallback image. Tried before rendering children.
childrenReactNode—Initials or icon shown when no fallback image is available.

AvatarGroup

NameTypeDefaultDescription
maxnumber—Hard cap on visible avatars. Values are rounded down; negative and non-finite values become zero. When omitted, AvatarGroup measures overflow with Overflow.
spacing"overlap" | "gap""overlap"Overlap stacks avatars; gap spaces them apart.
size"sm" | "md" | "lg" | null"md"Default size applied to descendant Avatars that do not set their own size.
aria-labelstring"Avatars"Accessible label for the group container (rendered with role="group").
childrenrequiredReactNode—Avatar elements.

AvatarIndicator

NameTypeDefaultDescription
countrequirednumber—Number rendered as "+N". Used by AvatarGroup for overflow but available standalone.
size"sm" | "md" | "lg"—Size override. Falls back to the AvatarGroup size.
getLabel(count: number) => string—Localizes the indicator accessible name. Defaults to the "N more" pattern when neither getLabel nor aria-label is provided.

Accessibility

Notes

Image Fallback

When src fails to load, Avatar falls back to the fallback initials. If no fallback is provided, '?' is shown.

Terminal Style

Square shape with a border and monospace font for initials — following the @diffgazer/ui terminal-inspired aesthetic.

Spacing

AvatarGroup supports spacing='overlap' (default, stacked look) or spacing='gap' (spaced apart). Use 'gap' inside Select triggers or inline layouts where overlap looks cramped.

Composition

Avatar works standalone or inside AvatarGroup. Combine Avatar with public Select parts to build avatar pickers.

Source

Install via CLI: pnpm exec dgadd add ui/avatar. Keyboard hooks are included as standalone copies. For the full experience, use --integration keys.

Highlighted source loads after this disclosure opens. Browse the source repository.