{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "avatar-group",
  "title": "Avatar Group",
  "description": "Stacked avatars with presence dots and a +N overflow that lists the rest.",
  "dependencies": [],
  "registryDependencies": [
    "utils",
    "avatar",
    "popover"
  ],
  "files": [
    {
      "path": "registry/default/ui/avatar-group.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { cn } from \"@/registry/default/lib/utils\"\nimport {\n  Avatar,\n  AvatarFallback,\n  AvatarImage,\n} from \"@/registry/default/ui/avatar\"\nimport {\n  Popover,\n  PopoverContent,\n  PopoverTrigger,\n} from \"@/registry/default/ui/popover\"\n\ntype AvatarStatus = \"online\" | \"away\" | \"busy\" | \"offline\"\n\ntype AvatarGroupItemProps = React.ComponentProps<\"span\"> & {\n  src?: string\n  name: string\n  status?: AvatarStatus\n}\n\nconst STATUS_CLASSES: Record<AvatarStatus, string> = {\n  online: \"bg-chart-2\",\n  away: \"border-2 border-chart-2 bg-background\",\n  busy: \"bg-destructive\",\n  offline: \"bg-muted-foreground\",\n}\n\nfunction initialsOf(name: string) {\n  return name\n    .split(/\\s+/)\n    .filter(Boolean)\n    .slice(0, 2)\n    .map((word) => word[0])\n    .join(\"\")\n    .toUpperCase()\n}\n\nfunction AvatarGroupItem({\n  src,\n  name,\n  status,\n  className,\n  ...props\n}: AvatarGroupItemProps) {\n  return (\n    <span\n      data-slot=\"avatar-group-item\"\n      title={name}\n      className={cn(\"relative inline-flex size-8 shrink-0\", className)}\n      {...props}\n    >\n      <Avatar aria-hidden className=\"size-full ring-2 ring-background\">\n        <AvatarImage src={src} alt=\"\" />\n        <AvatarFallback className=\"text-xs font-medium\">\n          {initialsOf(name)}\n        </AvatarFallback>\n      </Avatar>\n      {status && (\n        <span\n          aria-hidden\n          data-status={status}\n          className={cn(\n            \"absolute -right-0.5 -bottom-0.5 size-2.5 rounded-full ring-2 ring-background\",\n            STATUS_CLASSES[status]\n          )}\n        />\n      )}\n      <span className=\"sr-only\">{status ? `${name} (${status})` : name}</span>\n    </span>\n  )\n}\n\nfunction AvatarGroup({\n  max,\n  className,\n  children,\n  ...props\n}: React.ComponentProps<\"div\"> & { max?: number }) {\n  const items = React.Children.toArray(children).filter(\n    (child): child is React.ReactElement<AvatarGroupItemProps> =>\n      React.isValidElement(child)\n  )\n  const visible = max === undefined ? items : items.slice(0, max)\n  const hidden = items.slice(visible.length)\n\n  return (\n    <div\n      role=\"group\"\n      data-slot=\"avatar-group\"\n      className={cn(\"flex items-center -space-x-1.5\", className)}\n      {...props}\n    >\n      {visible.map((item, index) =>\n        React.cloneElement(item, {\n          style: { zIndex: visible.length - index, ...item.props.style },\n        })\n      )}\n      {hidden.length > 0 && (\n        <Popover>\n          <PopoverTrigger\n            data-slot=\"avatar-group-overflow\"\n            aria-label={`${hidden.length} more`}\n            className=\"relative inline-flex size-8 shrink-0 items-center justify-center rounded-full bg-muted text-xs font-medium ring-2 ring-background outline-none hover:bg-accent focus-visible:ring-[3px] focus-visible:ring-ring/50\"\n          >\n            +{hidden.length}\n          </PopoverTrigger>\n          <PopoverContent\n            align=\"start\"\n            aria-label={`${hidden.length} more`}\n            className=\"w-56 p-1\"\n          >\n            <ul className=\"grid max-h-64 overflow-y-auto\">\n              {hidden.map((item) => (\n                <li\n                  key={item.key}\n                  className=\"flex items-center gap-2 rounded-sm px-2 py-1.5 text-sm\"\n                >\n                  {React.cloneElement(item, {\n                    \"aria-hidden\": true,\n                    className: cn(item.props.className, \"size-7\"),\n                  })}\n                  <span className=\"truncate\">{item.props.name}</span>\n                  {item.props.status && (\n                    <span className=\"ml-auto text-xs text-muted-foreground capitalize\">\n                      {item.props.status}\n                    </span>\n                  )}\n                </li>\n              ))}\n            </ul>\n          </PopoverContent>\n        </Popover>\n      )}\n    </div>\n  )\n}\n\nexport { AvatarGroup, AvatarGroupItem, type AvatarStatus }\n",
      "type": "registry:ui"
    }
  ],
  "type": "registry:ui"
}