Skip to content
TopClass UI

Avatar group

Overlapping avatars with a +N counter for the rest. Render every member; max is clamped from 1 to 20.

server - 0 KB

Avatar group

server - 0 KB

Overlapping avatars with a +N counter for the rest. Render every member; max is clamped from 1 to 20.

Install

Try it

max
size

The code

avatar-group.tsx
import { AvatarFallback, AvatarRoot } from 'topclassui/avatar'
import { AvatarGroup } from 'topclassui/avatar-group'

<AvatarGroup aria-label="Project team">
  {TEAM.map(([initials, name]) => (
    <AvatarRoot key={initials} size={props.size} role="img" aria-label={name}>
      <AvatarFallback>{initials}</AvatarFallback>
    </AvatarRoot>
  ))}
</AvatarGroup>

max counts children, so render every member and let the group hide the overflow.

Every state

1 state
Two
Four
Overflow

Import from the package

topclassui/avatar-group
import { AvatarGroup } from 'topclassui/avatar-group'

Install once:npm i topclassui@beta zod

Examples

  • The first max children show, and a last circle says +N. size reaches that circle only, so give each avatar the same size.
  • One avatar per child: an array or a map() counts one by one, but a fragment counts as one child, so pass the array itself.
  • A count too long for a circle widens the counter into a pill, so +12,345 keeps its plus and every digit.
  • The ring between avatars is the page colour. On a Card, in a Table or on any other surface, give it that surface: className="*:ring-surface-raised".
  • A group wider than its container wraps onto another row; in a table cell it keeps one row, so keep max small there.
  • Wrap an avatar in a link made inline-flex and give the link a focus ring: the group rounds it and lifts the focused face.
max
two
four
Omar AbedSara Khalil
overflow
counts
sizes
linked
on-card

Design team

in-table
Projects
ProjectTeamWith a countIn a boxDue
Billing redesign3 people
12 Mar 2026
Mobile onboarding5 people
4 Apr 2026
Search migration20 people
30 Jun 2026
many
custom-size
In Arabic, right to left

Props

The props of AvatarGroup
PropTypeDefaultLimitsDescription
childrenReactNode--Every member, one avatar per child; the group shows the first max and counts the rest.
labelsLabels--The built-in strings; the counter is named by labels.avatar.more. Defaults to English.
localestring--The BCP 47 tag the count is formatted in. Defaults to en.
maxinteger, min 1, max 204min 1, max 20How many children show before the +N counter takes the rest; clamped to 1-20.
sizexs | sm | md | lg | xl | custom"md"-The size of the +N counter and the depth of the overlap; pass the size the avatars carry. custom leaves the counter unsized.

Keyboard and accessibility

The keyboard of AvatarGroup
KeysWhat it does
TabMoves to the next face only when it is a link or a button you wrapped; the group itself is not a tab stop.
  • Give the group an aria-label or aria-labelledby that says who the faces are; it renders role="group".
  • Name each avatar, by the alt of its picture or by aria-label on AvatarRoot: initials alone are silent.
  • The counter is read as labels.avatar.more ("1 more"); for Arabic pass labels and locale from getLabels('ar').

Right to left

The row starts at the inline start and each face overlaps the one before it, so in Arabic it starts on the right; the +N keeps its plus before the digits.

Server and client

Renders on the server and ships no JavaScript.

Files: index.tsx.

On the chip: server - 0 KB.