@mshafiqyajid/react-avatar-group
Headless hook + styled component for avatar groups. Overflow badge, tooltip on hover, size/shape/spacing variants, accessible role=group labelling.
Playground #
Props
TSX
import { AvatarGroupStyled } from "@mshafiqyajid/react-avatar-group/styled";
import "@mshafiqyajid/react-avatar-group/styles.css";
<AvatarGroupStyled />Install #
npm install @mshafiqyajid/react-avatar-group Quick start #
import { AvatarGroupStyled } from "@mshafiqyajid/react-avatar-group/styled";
import "@mshafiqyajid/react-avatar-group/styles.css";
const avatars = [
{ name: "Alice", src: "https://i.pravatar.cc/150?u=alice" },
{ name: "Bob" },
{ name: "Carol", src: "https://i.pravatar.cc/150?u=carol" },
{ name: "Dave" },
{ name: "Eve", src: "https://i.pravatar.cc/150?u=eve" },
];
<AvatarGroupStyled avatars={avatars} max={4} size="md" shape="circle" /> With overflow click handler #
<AvatarGroupStyled
avatars={avatars}
max={4}
onOverflowClick={() => setShowAll(true)}
/> Headless #
import { useAvatarGroup } from "@mshafiqyajid/react-avatar-group";
const { groupProps, visibleAvatars, overflowCount, overflowProps, getAvatarProps } =
useAvatarGroup({ avatars, max: 4 });
return (
<div {...groupProps} style={{ display: "flex" }}>
{visibleAvatars.map((avatar, i) => (
<span key={i} {...getAvatarProps(avatar, i)}>
{avatar.name?.[0]}
</span>
))}
{overflowCount > 0 && (
<span {...overflowProps}>+{overflowCount}</span>
)}
</div>
); AvatarGroupItem shape #
interface AvatarGroupItem {
src?: string; // image URL — rendered as <img> when provided
name?: string; // display name — used for initials and aria-label
fallback?: string; // override initials text
href?: string; // wraps avatar in <a> when provided
} API #
| Prop | Type | Default | Description |
|---|---|---|---|
| avatars | AvatarGroupItem[] | — | Array of avatar data objects |
| max | number | 4 | Max avatars shown before overflow badge |
| size | "xs" | "sm" | "md" | "lg" | "xl" | "md" | Avatar size (24–64 px) |
| shape | "circle" | "square" | "circle" | Avatar shape |
| spacing | "tight" | "normal" | "loose" | "normal" | Overlap amount |
| showTooltip | boolean | true | Show name on hover via title attribute |
| overflow | "count" | "avatars" | "count" | Overflow display mode |
| onOverflowClick | () => void | — | Makes overflow badge a focusable button |
| className | string | — | Extra class on the root element |
| style | CSSProperties | — | Inline style override |