# Avatar

Circular profile images built on Radix Avatar with an automatic initials fallback, plus overlapping AvatarGroup and count primitives.

- Category: Data Display
- License: MIT
- Page: https://www.saasuji.com/components/avatar
- Install: npx shadcn@latest add https://www.saasuji.com/r/avatar.json

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| src (AvatarImage) | `string` | — | Image URL rendered inside the avatar. |
| alt (AvatarImage) | `string` | — | Alternative text for the avatar image. |
| onLoadingStatusChange (AvatarImage) | `(status: "idle" | "loading" | "loaded" | "error") => void` | — | Called when the image loading status changes. |
| delayMs (AvatarFallback) | `number` | `0` | Delay in milliseconds before the fallback is rendered. |
| className (all parts) | `string` | — | Additional classes merged onto the avatar part that receives it. |
| children (all parts) | `React.ReactNode` | — | AvatarImage and AvatarFallback inside Avatar; initials or a count inside the group primitives. |
| ...props (Avatar) | `React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>` | — | All remaining Radix Avatar root props are forwarded (asChild, id, aria-*, …). |
| ...props (AvatarImage) | `React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>` | — | All remaining img attributes are forwarded (loading, referrerPolicy, …). |
| ...props (AvatarFallback) | `React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>` | — | All remaining Radix Fallback props are forwarded (asChild, id, aria-*, …). |
| ...props (AvatarGroup, AvatarGroupCount) | `React.HTMLAttributes<HTMLDivElement>` | — | All remaining native div attributes are forwarded. |

## Source

```tsx
"use client"

import * as React from "react"
import * as AvatarPrimitive from "@radix-ui/react-avatar"

import { cn } from "@/lib/utils"

const Avatar = React.forwardRef<
    React.ElementRef<typeof AvatarPrimitive.Root>,
    React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>
>(({ className, ...props }, ref) => (
    <AvatarPrimitive.Root
        ref={ref}
        className={cn(
            "relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full",
            className
        )}
        {...props}
    />
))
Avatar.displayName = AvatarPrimitive.Root.displayName

const AvatarImage = React.forwardRef<
    React.ElementRef<typeof AvatarPrimitive.Image>,
    React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>
>(({ className, ...props }, ref) => (
    <AvatarPrimitive.Image
        ref={ref}
        className={cn("aspect-square h-full w-full", className)}
        {...props}
    />
))
AvatarImage.displayName = AvatarPrimitive.Image.displayName

const AvatarFallback = React.forwardRef<
    React.ElementRef<typeof AvatarPrimitive.Fallback>,
    React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>
>(({ className, ...props }, ref) => (
    <AvatarPrimitive.Fallback
        ref={ref}
        className={cn(
            "flex h-full w-full items-center justify-center rounded-full bg-muted",
            className
        )}
        {...props}
    />
))
AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName

export { Avatar, AvatarImage, AvatarFallback, AvatarGroup, AvatarGroupCount }

function AvatarGroup({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
    return (
        <div
            className={cn("flex -space-x-2 *:ring-2 *:ring-background", className)}
            {...props}
        />
    )
}

function AvatarGroupCount({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
    return (
        <div
            className={cn(
                "relative flex h-10 w-10 shrink-0 items-center justify-center overflow-hidden rounded-full bg-muted text-[10px] font-semibold",
                className
            )}
            {...props}
        />
    )
}

```
