Skip to content

HyAvatarGroup ​

Usage examples on this page are written for Lit / plain HTML (<hy-avatar-group>). The same component ships as HyAvatarGroup in @whitespaceux/harmony-react (native React 19), with typed wrappers for Angular, Solid, Svelte, and Vue. The API reference below applies to all frameworks.

A stack of avatars — overlapping, ringed, capped at max with a "+N" indicator that opens the rest.

Key Features ​

  • Sets size and shape once for every child hy-avatar
  • Each avatar after the first moves back by a quarter of its size, first on top
  • A ring in the page color around each stacked avatar, wider at larger sizes
  • Above max, shows max - 1 avatars and a "+N" button opening a list of the rest
  • The hidden avatars move into that list — the same elements, so everything set on them survives
  • A name tooltip on each stacked avatar, on hover and on keyboard focus
  • A marked avatar's ring turns brand — the one editing, speaking or followed — with no change to the overlap; in the overflow list the mark sits just inside its edge

Accessibility: built in ​

  • role="group" named by label (required — a dev warning when missing)
  • One Tab stop for the stack: Left / Right (flipped right-to-left) and Home / End move between the names, each tooltip showing as its avatar is focused
  • The "+N" indicator is a button named by overflow-label ("3 more"), with its popup
  • An interactive avatar in the stack stays its own Tab stop; the arrow keys skip it
  • no-tooltips removes the tooltips and the stack's Tab stop, for a stack whose names are printed beside it

Accessibility: your part ​

  • Name every avatar: alt on a photo, aria-label on initials. The tooltip, the overflow list and screen readers all read that name.
  • Put what marked means in that avatar's name ("Ada Lindqvist, editing"), since the ring is visual only. Mark one avatar per group, placed first.
  • Set no-tooltips only when the names are printed beside the stack.

Children ​

Direct hy-avatar children only. The group writes three things on each: size, shape, and a slot attribute (avatar-0, avatar-1, …) placing it in the stack or in the overflow list. A wrapped avatar (hy-tooltip > hy-avatar) is not part of the group and triggers a dev warning.

When to use

  • Who is in a team, a thread or a document, shown as one summary.

Do

  • Set max to the number that fits, with the count for the rest.

When not to use

  • Four people or fewer with room to spare: separate hy-avatar elements with each name printed beside them.
  • People who each need an action (remove, message, reassign): hy-list with a row per person.
  • Where the exact membership matters, such as permissions or an audit trail: a full hy-list of names. A stack is a summary.
  • An avatar that does something: set interactive on the hy-avatar. Never wrap it in a link or an hy-tooltip; a wrapped avatar is not shown.

Examples ​

Basic group ​

html
<hy-avatar-group label="Project members">
  <hy-avatar src="/ada.jpg" alt="Ada Lindqvist"></hy-avatar>
  <hy-avatar initials="BK" aria-label="Ben Kato"></hy-avatar>
  <hy-avatar initials="CM" aria-label="Chloé Martin"></hy-avatar>
</hy-avatar-group>

One avatar marked — the person editing, first in the stack ​

html
<hy-avatar-group label="People in this design system">
  <hy-avatar initials="AL" aria-label="Ada Lindqvist — editing" marked></hy-avatar>
  <hy-avatar initials="BK" aria-label="Ben Kato" presence="away"></hy-avatar>
  <hy-avatar initials="CM" aria-label="Chloé Martin"></hy-avatar>
</hy-avatar-group>

Over max, square, on another surface ​

html
<hy-avatar-group label="Connected apps" shape="square" max="3" size="large">
  <hy-avatar initials="GH" aria-label="GitHub"></hy-avatar>
  <hy-avatar initials="FI" aria-label="Figma"></hy-avatar>
  <hy-avatar initials="SL" aria-label="Slack"></hy-avatar>
  <hy-avatar initials="LI" aria-label="Linear"></hy-avatar>
</hy-avatar-group>

API ​

Properties ​

PropertyAttributeTypeDefaultDescription
labellabelstring''Accessible name of the group ("Project members"). Required.
sizesize'small' | 'medium' | 'large''medium'Size of every avatar and of the "+N" indicator.
shapeshape'circle' | 'square''circle'Shape of every avatar — one shape per group.
maxmaxnumber5Most avatars shown, the "+N" indicator included: above it, max - 1 avatars and the indicator. 0 shows all; 1 is read as 2 (a dev warning).
noTooltipsno-tooltipsbooleanfalseTurns off the name tooltips and the stack's arrow-key focus.
overflowLabeloverflow-labelstring'{count} more'The indicator's accessible name, a template: {count} is the number of hidden avatars, formatted for the resolved locale. Use for internationalization.

Events ​

EventDetailDescription
show—The overflow list opened (does not bubble). Detail: AvatarGroupVisibilityDetail
hide—The overflow list closed (does not bubble). Detail: AvatarGroupVisibilityDetail

Slots ​

SlotDescription
defaultThe hy-avatar children

CSS Parts ​

PartDescription
baseThe group wrapper (role="group")
indicatorThe "+N" button
overflow-listThe list of hidden avatars in the popover

CSS Custom Properties ​

The documented hooks. Every override hook the component reads — one per token it paints — is listed in @whitespaceux/harmony/theme-api.json, and @whitespaceux/harmony/component-bindings.json (the Harmony MCP get-bindings tool) says which part and state each one paints.

PropertyDefaultDescription
--hy-avatar-group-control-height-xsvar(--hy-control-height-xs)Size of a small avatar, which the overlap is a quarter of
--hy-avatar-group-control-height-smvar(--hy-control-height-sm)Size of a medium avatar, which the overlap is a quarter of
--hy-avatar-group-control-height-mdvar(--hy-control-height-md)Size of a large avatar, which the overlap is a quarter of
--hy-avatar-group-stroke-smvar(--hy-stroke-sm)Ring width at the small size
--hy-avatar-group-stroke-mdvar(--hy-stroke-md)Ring width at the medium size
--hy-avatar-group-stroke-lgvar(--hy-stroke-lg)Ring width at the large size
--hy-avatar-group-background-surface-basevar(--hy-background-surface-base)Ring color, and the presence dot's cutout — re-point it on another surface
--hy-avatar-group-border-brand-restvar(--hy-border-brand-rest)Ring color of a marked avatar (the stack's ring, recolored)
--hy-avatar-group-background-muted-hovervar(--hy-background-muted-hover)The "+N" indicator's fill on hover
--hy-avatar-group-background-muted-pressedvar(--hy-background-muted-pressed)The "+N" indicator's fill when pressed
--hy-avatar-group-background-surface-elevation-4var(--hy-background-surface-elevation-4)The presence dot's cutout in the overflow list (the popover's surface)
--hy-avatar-group-radius-pill-circlevar(--hy-radius-pill-circle)Focus ring corner around a circle avatar
--hy-avatar-group-radius-container-smvar(--hy-radius-container-sm)Focus ring corner around a square avatar
--hy-avatar-group-gap-row-list-xs-blockvar(--hy-gap-row-list-xs-block)Gap between the rows of the overflow list
--hy-avatar-group-gap-row-list-sm-inlinevar(--hy-gap-row-list-sm-inline)Gap between an avatar and its name in the overflow list
--hy-avatar-group-foreground-default-restvar(--hy-foreground-default-rest)Color of the names in the overflow list

Methods ​

focus() ​

Focuses the stack's Tab stop, else the first interactive avatar, else the indicator.

show() ​

Opens the overflow list, when there is one.

hide() ​

Closes the overflow list.

Built with Lit. Documented with VitePress.