{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "realtime-avatar-stack-react",
"title": "Realtime Avatar Stack (React)",
"description": "Display a stack of avatars showing users currently present in a room. Updates in realtime as users join and leave. Includes full Convex backend with presence tracking.",
"dependencies": ["convex@latest", "@auth/core", "@convex-dev/auth@latest"],
"registryDependencies": ["avatar", "tooltip"],
"files": [
{
"path": "src/registry/convex/blocks/realtime-avatar-stack-react/components/avatar-stack.tsx",
"content": "import { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from \"@/components/ui/tooltip\";\n\nimport { cn } from \"@/lib/utils\";\n\ninterface AvatarStackUser {\n id: string;\n name: string;\n image?: string;\n color?: string;\n}\n\ninterface AvatarStackProps {\n users: AvatarStackUser[];\n maxVisible?: number;\n size?: \"sm\" | \"md\" | \"lg\";\n className?: string;\n}\n\nconst sizeClasses = {\n sm: \"h-6 w-6 text-xs\",\n md: \"h-8 w-8 text-sm\",\n lg: \"h-10 w-10 text-base\",\n};\n\nconst overlapClasses = {\n sm: \"-ml-2\",\n md: \"-ml-3\",\n lg: \"-ml-4\",\n};\n\nfunction getInitials(name: string): string {\n return name\n .split(\" \")\n .map((n: any) => n[0])\n .join(\"\")\n .toUpperCase()\n .slice(0, 2);\n}\n\nfunction getColorFromName(name: string): string {\n const colors = [\n \"#ef4444\",\n \"#f97316\",\n \"#f59e0b\",\n \"#84cc16\",\n \"#22c55e\",\n \"#14b8a6\",\n \"#06b6d4\",\n \"#3b82f6\",\n \"#6366f1\",\n \"#8b5cf6\",\n \"#a855f7\",\n \"#d946ef\",\n \"#ec4899\",\n \"#f43f5e\",\n ];\n let hash = 0;\n for (let i = 0; i < name.length; i++) {\n hash = name.charCodeAt(i) + ((hash << 5) - hash);\n }\n return colors[Math.abs(hash) % colors.length];\n}\n\nexport function AvatarStack({\n users,\n maxVisible = 5,\n size = \"md\",\n className,\n}: AvatarStackProps) {\n const visibleUsers = users.slice(0, maxVisible);\n const remainingCount = users.length - maxVisible;\n\n return (\n {user.name} {remainingCount} more users