Propel

Avatar Group

An overlapping stack of avatars that share one size and show a "+N" overflow count.

ALGHLT+4
Show code
import { Avatar } from "@makeplane/propel/components/avatar";
import { AvatarGroup } from "@makeplane/propel/components/avatar-group";

export default function BasicDemo() {
  return (
    <AvatarGroup size="sm">
      <Avatar alt="Ada Lovelace" fallback="AL" src="https://i.pravatar.cc/64?img=47" />
      <Avatar alt="Grace Hopper" fallback="GH" src="https://i.pravatar.cc/64?img=32" />
      <Avatar alt="Linus Torvalds" fallback="LT" />
      <Avatar alt="4 more members" fallback="+4" />
    </AvatarGroup>
  );
}

Installation

import { Avatar } from "@makeplane/propel/components/avatar";
import { AvatarGroup } from "@makeplane/propel/components/avatar-group";

Usage

import { Avatar } from "@makeplane/propel/components/avatar";
import { AvatarGroup } from "@makeplane/propel/components/avatar-group";

export default function BasicDemo() {
  return (
    <AvatarGroup size="sm">
      <Avatar alt="Ada Lovelace" fallback="AL" src="https://i.pravatar.cc/64?img=47" />
      <Avatar alt="Grace Hopper" fallback="GH" src="https://i.pravatar.cc/64?img=32" />
      <Avatar alt="Linus Torvalds" fallback="LT" />
      <Avatar alt="4 more members" fallback="+4" />
    </AvatarGroup>
  );
}

Examples

Sizes

size on the group sizes every avatar at once — the children don’t set it. Groups support the three Figma sizes: 2xs, xs, and sm.

ALGHLT
ALGHLT
ALGHLT
Show code
import { Avatar } from "@makeplane/propel/components/avatar";
import { AvatarGroup, type AvatarGroupSize } from "@makeplane/propel/components/avatar-group";

const SIZES: AvatarGroupSize[] = ["2xs", "xs", "sm"];

export default function SizesDemo() {
  return (
    <div className="flex flex-wrap items-center gap-4">
      {SIZES.map((size) => (
        <AvatarGroup key={size} size={size}>
          <Avatar alt="Ada Lovelace" fallback="AL" src="https://i.pravatar.cc/64?img=47" />
          <Avatar alt="Grace Hopper" fallback="GH" src="https://i.pravatar.cc/64?img=32" />
          <Avatar alt="Linus Torvalds" fallback="LT" />
        </AvatarGroup>
      ))}
    </div>
  );
}

Fallbacks

An avatar shows its photo when a src is available, falls back to initials when it isn’t, and finally to an anonymous person icon when no initials are given either.

ALGH
Show code
import { Avatar } from "@makeplane/propel/components/avatar";
import { AvatarGroup } from "@makeplane/propel/components/avatar-group";

export default function FallbacksDemo() {
  return (
    <AvatarGroup size="sm">
      {/* Photo, when a `src` is available. */}
      <Avatar alt="Ada Lovelace" fallback="AL" src="https://i.pravatar.cc/64?img=47" />
      {/* No image — falls back to initials, tinted from the member's name. */}
      <Avatar alt="Grace Hopper" fallback="GH" />
      {/* No image and no initials — falls back to an anonymous person icon. */}
      <Avatar alt="Unassigned member" />
    </AvatarGroup>
  );
}

Variants

Each initials avatar’s background variant is derived stably from the member’s name — there is no variant prop.

DSENPRRSMK
Show code
import { Avatar } from "@makeplane/propel/components/avatar";
import { AvatarGroup } from "@makeplane/propel/components/avatar-group";

export default function VariantsDemo() {
  return (
    <AvatarGroup size="sm">
      <Avatar alt="Design" fallback="DS" />
      <Avatar alt="Engineering" fallback="EN" />
      <Avatar alt="Product" fallback="PR" />
      <Avatar alt="Research" fallback="RS" />
      <Avatar alt="Marketing" fallback="MK" />
    </AvatarGroup>
  );
}

API Reference

AvatarGroup

The ready-made overlapping avatar stack: shares `size` with every `Avatar` inside via context (an avatar's own `size` still wins), composed around the styled `elements/avatar-group` container. Each `Avatar`'s own `border-subtle` is the single ring that separates them.

PropTypeDefaultDescription
size(required)"2xs" | "xs" | "sm"Shared size for every avatar in the group; an avatar's own `size` overrides it.
renderReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, {}>Allows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a `ReactElement` or a function that returns the element to render.

Avatar

The ready-made avatar: an image that falls back to initials (or an anonymous person icon), composed from the `elements/avatar` parts (`Avatar` root + `AvatarImage` + `AvatarFallback`). Pass `src` for the photo and `fallback` for initials; the initials color is chosen automatically and is not a consumer prop.

PropTypeDefaultDescription
renderReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, {}>Allows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a `ReactElement` or a function that returns the element to render.
size"2xs" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl""md"Avatar size. Optional here — resolved from the `AvatarGroup` context, else `md`.
srcstringImage URL. When omitted, or while it is loading/failing, the fallback shows.
altstringAccessible name for the avatar (the person it represents).
fallbackReactNodeInitials shown when there is no image. When omitted too, a person icon shows.
delaynumberMilliseconds before the fallback shows, to avoid a flash while `src` loads quickly.