Avatar Group

An overlapping stack of avatars with built-in overflow. Cap how many show and the rest fold into a +N chip. The group owns the overlap, the ring separation and the hover lift; the children stay plain Avatars.

JEMDLCSR+5

Installation#

# One-time setup (tokens + lib helpers)npx koalaui-cli@latest init# Add this component (its dependencies come along)npx koalaui-cli@latest add avatar-group

Usage#

Wrap your Avatar children in AvatarGroup and set max. The group owns only the layout and the overflow chip: the avatars stay plain Avatars with no per-instance ring or z-index. Match the group's size to its children.

team.tsxTSX
import { AvatarGroup } from "@/components/ui/avatar-group"import { Avatar, AvatarImage, AvatarFallback } from "@/components/ui/avatar"export function Team({ members }: { members: Member[] }) {  return (    <AvatarGroup size="md" max={4} total={members.length}>      {members.slice(0, 4).map((m) => (        <Avatar key={m.id} size="md">          <AvatarImage src={m.avatar} alt={m.name} />          <AvatarFallback>{m.initials}</AvatarFallback>        </Avatar>      ))}    </AvatarGroup>  )}

Sizes#

Set size on the group to match the avatars; it sizes the +N chip and tightens the overlap as the box grows, so the stack stays a single cluster at every size.

sm
JMLS+5
md
JEMDLCSR+5
lg
JEMDLCSR+5

Fallbacks#

With no image the avatar shows its initials. Inside a group, give each fallback a color so the stack reads as distinct people instead of a row of identical gray chips: pass one of the Avatar color hues per child and stride-mix them so no two neighbours share a tint. The neutral gray default is fine for a lone avatar, not for a cluster. The +N chip stays neutral since it's a count, not initials.

NBEMCWWEGO

Overflow#

max caps the avatars shown; everything past it collapses into a single +N chip. Pass total when more people exist than you render (e.g. a server count) so the chip reflects the real number. Omit max to show every avatar.

max 2
JEMD+7
max 3
JEMDLC+6
no max
JEMDLCSR+5

Custom overflow#

Take over the chip with renderOverflow, which receives the overflow count. Return any node: here the chip is a Tooltip that names the people the stack hides, riding the same shared bubble as the avatars.

JEMDLCSR+5

API reference#

AvatarGroup

A <div> that stacks its Avatar children with overlap, a background ring and a hover lift, then appends the +N chip. Children share one gliding tooltip (a TooltipGroup). Forwards all native <div> props; accepts className, merged last.

PropTypeDefaultDescription
size"xs" | "sm" | "md" | "lg" | "xl""md"Sizes the overlap and the +N chip. Pass the same value you set on the children.
maxnumber-Caps the visible avatars; the rest fold into the +N chip.
totalnumber-The real count when it exceeds the rendered avatars (a server count), so +N reflects it.
renderOverflow(overflow: number) => React.ReactNode-Replaces the default chip, e.g. with a Tooltip that names the hidden people.

FAQ#

Use AvatarGroup whenever you stack collaborators: it owns the overlap, the `ring-background` separation, and the hover lift, and adds a `+N` overflow chip via `max`. Hand-rolling those classes on each Avatar drifts the moment the recipe changes, which is exactly what this component prevents.