Avatar Circles
Stacked initials avatars with a +N badge — zero images.
0.6 KB gzippedZero dependenciesReduced-motion safeBase UI & Radix compatible
MCTOSLDR+2k
Installation
npx shadcn@latest add https://velora.colorlib.com/r/avatar-circles.jsonSource
import { cn } from "@/lib/utils";
interface AvatarCirclesProps extends React.HTMLAttributes<HTMLDivElement> {
/** Names rendered as initials */
people: string[];
/** "+N" badge count */
extra?: number;
}
const tones = [
"bg-blue-600",
"bg-slate-600",
"bg-sky-700",
"bg-indigo-600",
"bg-slate-700",
"bg-blue-800",
];
export function AvatarCircles({
people,
extra,
className,
...props
}: AvatarCirclesProps) {
return (
<div
data-slot="avatar-circles"
className={cn("flex -space-x-3", className)}
{...props}
>
{people.map((name, i) => {
const initials = name
.split(" ")
.map((w) => w[0])
.slice(0, 2)
.join("");
return (
<span
key={name}
title={name}
className={cn(
"flex size-10 items-center justify-center rounded-full text-xs font-semibold text-white ring-2 ring-background",
tones[i % tones.length]
)}
>
{initials}
</span>
);
})}
{extra && (
<span className="flex size-10 items-center justify-center rounded-full bg-muted text-xs font-semibold ring-2 ring-background">
+{extra >= 1000 ? `${Math.floor(extra / 1000)}k` : extra}
</span>
)}
</div>
);
}