All componentsdisplay
Avatar Group
+2
+2
+2
Installation
$ npx shadcn@latest add https://deepmoon.dev/r/avatar-group.jsonProps
AvatarGroupProps
| Prop | Type | Required |
|---|---|---|
| avatars | AvatarGroupAvatar[] | Yes |
| max | number | No |
| size | AvatarGroupSize | No |
Code
avatar-group.tsx
import * as React from "react";
import { cn } from "@/lib/utils";
export type AvatarGroupSize = "sm" | "md" | "lg";
export interface AvatarGroupAvatar {
src?: string;
alt: string;
}
export interface AvatarGroupProps extends React.ComponentPropsWithoutRef<"div"> {
avatars: AvatarGroupAvatar[];
max?: number;
size?: AvatarGroupSize;
}
const sizeClass: Record<AvatarGroupSize, string> = {
sm: "size-6 text-[0.625rem]",
md: "size-8 text-xs",
lg: "size-10 text-sm",
};
export function AvatarGroup({ avatars, max = 4, size = "md", className, ...props }: AvatarGroupProps) {
const visible = avatars.slice(0, max);
const overflow = avatars.length - visible.length;
return (
<div role="group" aria-label={`${avatars.length} people`} className={cn("flex -space-x-2", className)} {...props}>
{visible.map((avatar, index) => (
<span
key={index}
title={avatar.alt}
className={cn(
"relative inline-flex shrink-0 items-center justify-center overflow-hidden rounded-full border-2 border-background bg-muted font-medium text-muted-foreground",
sizeClass[size],
)}
>
{avatar.src ? (
<img src={avatar.src} alt={avatar.alt} className="h-full w-full object-cover" />
) : (
<span aria-hidden="true">{avatar.alt.slice(0, 1).toUpperCase()}</span>
)}
</span>
))}
{overflow > 0 ? (
<span
className={cn(
"relative inline-flex shrink-0 items-center justify-center rounded-full border-2 border-background bg-secondary font-medium text-secondary-foreground",
sizeClass[size],
)}
>
+{overflow}
</span>
) : null}
</div>
);
}