- Gallery
- Data Display
- AvatarStack
New
AvatarStack
Overlapping avatar group with overflow count and hover expansion
Data Displayavatarstackgroupusers
Dependencies
shadcn/ui components needed:
npx shadcn@latest add cardnpx shadcn@latest add avatarHow to use this component
Copy the code below into your project. Make sure you have the required shadcn/ui dependencies installed. Then import and use the component in your pages or layouts.
Code
1"use client"23import * as React from "react"4import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"5import { Avatar, AvatarFallback } from "@/components/ui/avatar"6import { cn } from "@/lib/utils"78interface AvatarStackProps {9 className?: string10 size?: "sm" | "md" | "lg"11}1213interface TeamMember {14 name: string15 initials: string16 color: string17}1819const members: TeamMember[] = [20 { name: "Sarah Chen", initials: "SC", color: "bg-blue-500" },21 { name: "Alex Rivera", initials: "AR", color: "bg-violet-500" },22 { name: "Jordan Lee", initials: "JL", color: "bg-emerald-500" },23 { name: "Morgan Smith", initials: "MS", color: "bg-amber-500" },24 { name: "Taylor Kim", initials: "TK", color: "bg-rose-500" },25 { name: "Casey Brown", initials: "CB", color: "bg-cyan-500" },26 { name: "Drew Wilson", initials: "DW", color: "bg-pink-500" },27]2829const sizeClasses = {30 sm: "w-7 h-7 text-xs",31 md: "w-10 h-10 text-sm",32 lg: "w-12 h-12 text-base",33}3435export function AvatarStack({ className, size = "md" }: AvatarStackProps) {36 const visibleCount = 537 const overflowCount = members.length - visibleCount3839 return (40 <Card className={cn("w-full max-w-sm", className)}>41 <CardHeader>42 <CardTitle>Team Members</CardTitle>43 </CardHeader>44 <CardContent>45 <div className="flex flex-col items-center gap-4">46 <div className="group flex items-center">47 {members.slice(0, visibleCount).map((member, i) => (48 <Avatar49 key={member.id || member.name}50 className={cn(51 "ring-2 ring-background transition-all duration-300",52 sizeClasses[size],53 i === 0 ? "ml-0" : "-ml-3",54 "group-hover:ml-0 group-hover:translate-x-0"55 )}56 style={{ zIndex: visibleCount - i }}57 >58 <AvatarFallback className={cn("text-white font-medium", member.color)}>59 {member.initials}60 </AvatarFallback>61 </Avatar>62 ))}63 {overflowCount > 0 && (64 <div65 className={cn(66 "flex items-center justify-center rounded-full bg-muted ring-2 ring-background font-medium text-muted-foreground transition-all duration-300",67 sizeClasses[size],68 "-ml-3 group-hover:ml-0"69 )}70 style={{ zIndex: 0 }}71 >72 +{overflowCount}73 </div>74 )}75 </div>76 <div className="flex flex-wrap justify-center gap-2 text-xs text-muted-foreground">77 {members.slice(0, 4).map((member) => (78 <span key={member.name}>{member.name}</span>79 ))}80 <span>and {overflowCount + 1} more</span>81 </div>82 </div>83 </CardContent>84 </Card>85 )86}