Components

Avatar Group

A component for displaying multiple avatars with tooltips, borders, and spacing. Built on top of Avatar and Tooltip from shadcn UI.

CLCBGT+1

Installation

pnpm dlx shadcn@latest add https://rafay.sh/r/avatar-group.json

Usage

1import { AvatarGroup, type AvatarData } from "@/components/ui/avatar-group";
1const avatars: AvatarData[] = [ 2 { imageUrl: "/avatars/1.jpg", alt: "John Doe", fallback: "JD", tooltipLabel: "John Doe" }, 3 { imageUrl: "/avatars/2.jpg", alt: "Jane Smith", fallback: "JS", tooltipLabel: "Jane Smith" }, 4 { imageUrl: "/avatars/3.jpg", alt: "Alice Lee", fallback: "AL", tooltipLabel: "Alice Lee" }, 5]; 6 7<AvatarGroup 8 data={avatars} 9 size={12} 10 tooltip 11 spacing="tight" 12 max={3} 13 animate 14 translate 15/>

Props

PropTypeDefaultDescription
dataAvatarData[][]Array of avatar objects. Each object can include imageUrl, alt, fallback, and tooltipLabel.
sizenumberundefinedAvatar size (1 = 4px)
tooltipbooleanfalseShow tooltip on hover.
tooltipSide"top" | "right" | "bottom" | "left""top"Tooltip position.
tooltipAlign"center" | "start" | "end""center"Tooltip alignment.
tooltipSideOffsetnumberundefinedOffset of tooltip from avatar
tooltipAlignOffsetnumberundefinedOffset for alignment
borderbooleanfalseAdd border around avatars.
borderWidthnumberundefinedBorder width in pixels.
borderColorstringundefinedBorder color.
avatarClassNamestring""Custom class names for individual avatars.
maxnumberundefinedMax number of avatars to display; remaining shown as +N.
spacing"normal" | "tight" | "loose""tight"Spacing between avatars.
spacingGapnumberundefinedCustom gap in pixels between avatars in px (overrides spacing).
animatebooleanfalseEnable hover scaling animation.
translatebooleanfalseEnable hover translate animation.

Examples

Spacing

CLCBGTSM
example-component.tsx
1import { AvatarGroup } from "@/components/ui/avatar-group" 2 3export function AvatarGroupNormalSpacing() { 4 const data = [ 5 { 6 imageUrl: "https://res.cloudinary.com/dyhub4ung/image/upload/v1765267940/yo_chico_yafmmp.jpg", 7 fallback: "CL", 8 tooltipLabel: "Chico Lachowski", 9 }, 10 { 11 imageUrl: "https://res.cloudinary.com/dyhub4ung/image/upload/v1765267933/christian_bale_m4ectw.png", 12 fallback: "CB", 13 tooltipLabel: "Christian Bale", 14 }, 15 { 16 imageUrl: "https://res.cloudinary.com/dyhub4ung/image/upload/v1765267980/pfp_guts_dowxcb.jpg", 17 fallback: "GT", 18 tooltipLabel: "Guts", 19 }, 20 { 21 imageUrl: "https://res.cloudinary.com/dyhub4ung/image/upload/v1765267967/samurai_d0batp.jpg", 22 fallback: "SM", 23 tooltipLabel: "Samurai", 24 }, 25 ]; 26 27 return ( 28 <div className="flex items-center justify-center"> 29 <AvatarGroup 30 data={data} 31 size={12} 32 spacing="normal" 33 /> 34 </div> 35 ); 36} 37

Tooltip

CLCBGTSM
example-component.tsx
1import { AvatarGroup } from "@/components/ui/avatar-group" 2 3export function AvatarGroupTooltip() { 4 const data = [ 5 { 6 imageUrl: "https://res.cloudinary.com/dyhub4ung/image/upload/v1765267940/yo_chico_yafmmp.jpg", 7 fallback: "CL", 8 tooltipLabel: "Chico Lachowski", 9 }, 10 { 11 imageUrl: "https://res.cloudinary.com/dyhub4ung/image/upload/v1765267933/christian_bale_m4ectw.png", 12 fallback: "CB", 13 tooltipLabel: "Christian Bale", 14 }, 15 { 16 imageUrl: "https://res.cloudinary.com/dyhub4ung/image/upload/v1765267980/pfp_guts_dowxcb.jpg", 17 fallback: "GT", 18 tooltipLabel: "Guts", 19 }, 20 { 21 imageUrl: "https://res.cloudinary.com/dyhub4ung/image/upload/v1765267967/samurai_d0batp.jpg", 22 fallback: "SM", 23 tooltipLabel: "Samurai", 24 }, 25 ]; 26 27 return ( 28 <div className="flex items-center justify-center"> 29 <AvatarGroup 30 data={data} 31 tooltip 32 size={12} 33 /> 34 </div> 35 ); 36} 37

Border & Max

CLCBGT+1
example-component.tsx
1import { AvatarGroup } from "@/components/ui/avatar-group" 2 3export function AvatarGroupBorderAndMax() { 4 const data = [ 5 { 6 imageUrl: "https://res.cloudinary.com/dyhub4ung/image/upload/v1765267940/yo_chico_yafmmp.jpg", 7 fallback: "CL", 8 tooltipLabel: "Chico Lachowski", 9 }, 10 { 11 imageUrl: "https://res.cloudinary.com/dyhub4ung/image/upload/v1765267933/christian_bale_m4ectw.png", 12 fallback: "CB", 13 tooltipLabel: "Christian Bale", 14 }, 15 { 16 imageUrl: "https://res.cloudinary.com/dyhub4ung/image/upload/v1765267980/pfp_guts_dowxcb.jpg", 17 fallback: "GT", 18 tooltipLabel: "Guts", 19 }, 20 { 21 imageUrl: "https://res.cloudinary.com/dyhub4ung/image/upload/v1765267967/samurai_d0batp.jpg", 22 fallback: "SM", 23 tooltipLabel: "Samurai", 24 }, 25 ]; 26 27 return ( 28 <div className="flex items-center justify-center"> 29 <AvatarGroup 30 data={avatarGroupData} 31 tooltip 32 border 33 max={3} 34 borderWidth={2} 35 size={12} 36 /> 37 </div> 38 ); 39} 40

Hover & Translate

CLCBGT+1
example-component.tsx
1import { AvatarGroup } from "@/components/ui/avatar-group" 2 3export function AvatarGroupBorderAndMax() { 4 const data = [ 5 { 6 imageUrl: "https://res.cloudinary.com/dyhub4ung/image/upload/v1765267940/yo_chico_yafmmp.jpg", 7 fallback: "CL", 8 tooltipLabel: "Chico Lachowski", 9 }, 10 { 11 imageUrl: "https://res.cloudinary.com/dyhub4ung/image/upload/v1765267933/christian_bale_m4ectw.png", 12 fallback: "CB", 13 tooltipLabel: "Christian Bale", 14 }, 15 { 16 imageUrl: "https://res.cloudinary.com/dyhub4ung/image/upload/v1765267980/pfp_guts_dowxcb.jpg", 17 fallback: "GT", 18 tooltipLabel: "Guts", 19 }, 20 { 21 imageUrl: "https://res.cloudinary.com/dyhub4ung/image/upload/v1765267967/samurai_d0batp.jpg", 22 fallback: "SM", 23 tooltipLabel: "Samurai", 24 }, 25 ]; 26 27 return ( 28 <div className="flex items-center justify-center"> 29 <AvatarGroup 30 data={avatarGroupData} 31 tooltip 32 max={3} 33 size={12} 34 animate 35 translate 36 /> 37 </div> 38 ); 39} 40