{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "avatar-group-shadcnui",
  "type": "registry:component",
  "title": "Avatar Group",
  "description": "Stacked avatar group with hover reveal and tooltips",
  "registryDependencies": [
    "button"
  ],
  "dependencies": [
    "framer-motion",
    "react"
  ],
  "files": [
    {
      "path": "@uitripled/react-shadcn/src/components/avatars/avatar-group.tsx",
      "content": "\"use client\";\n\nimport { motion, useReducedMotion, type Transition } from \"framer-motion\";\nimport { User } from \"lucide-react\";\nimport { useId, useMemo } from \"react\";\n\ntype Avatar = {\n  id: number;\n  name: string;\n  handle: string;\n  color: string;\n};\n\nconst avatars: Avatar[] = [\n  {\n    id: 1,\n    name: \"Avery Nolan\",\n    handle: \"@averydesigns\",\n    color: \"bg-[#4f46e5]\",\n  },\n  { id: 2, name: \"Lena Ortiz\", handle: \"@lena_motion\", color: \"bg-[#10b981]\" },\n  { id: 3, name: \"Miles Chen\", handle: \"@mileslabs\", color: \"bg-[#38bdf8]\" },\n  { id: 4, name: \"Nia Calder\", handle: \"@niacalder\", color: \"bg-[#f97316]\" },\n  { id: 5, name: \"Theo Sato\", handle: \"@theosato\", color: \"bg-[#a855f7]\" },\n];\n\nexport function AvatarGroup() {\n  const shouldReduceMotion = useReducedMotion();\n  const groupId = useId();\n\n  const animationConfig = useMemo(\n    () =>\n      shouldReduceMotion\n        ? {\n            initial: { opacity: 1, x: 0, scale: 1 },\n            animate: { opacity: 1, x: 0, scale: 1 },\n            whileHover: { scale: 1.08, zIndex: 10 },\n            transition: { duration: 0 },\n          }\n        : {\n            initial: (index: number) => ({\n              opacity: 0,\n              x: -12 * index,\n              scale: 0.85,\n            }),\n            animate: { opacity: 1, x: 0, scale: 1 },\n            whileHover: { scale: 1.18, zIndex: 10 },\n            transition: (index: number) => ({\n              delay: 0.08 * index,\n              type: \"spring\",\n              stiffness: 320,\n              damping: 24,\n              mass: 0.7,\n            }),\n          },\n    [shouldReduceMotion]\n  );\n\n  return (\n    <section\n      aria-labelledby={`${groupId}-label`}\n      className=\"relative inline-flex items-center gap-4\"\n    >\n      <div\n        aria-hidden\n        className=\"pointer-events-none absolute -left-4 top-0 h-16 w-16 rounded-full bg-primary/20 blur-[60px]\"\n      />\n      <div\n        aria-hidden\n        className=\"pointer-events-none absolute -right-6 bottom-0 h-14 w-14 rounded-full bg-emerald-400/20 blur-[70px]\"\n      />\n\n      <div\n        role=\"group\"\n        aria-describedby={`${groupId}-description`}\n        className=\"flex items-center\"\n      >\n        <motion.ul className=\"flex -space-x-3\" role=\"list\">\n          {avatars.map((avatar, index) => (\n            <motion.li\n              key={avatar.id}\n              role=\"listitem\"\n              initial={\n                typeof animationConfig.initial === \"function\"\n                  ? animationConfig.initial(index)\n                  : animationConfig.initial\n              }\n              animate={animationConfig.animate}\n              whileHover={\n                animationConfig.whileHover ?? animationConfig.whileHover\n              }\n              transition={\n                (typeof animationConfig.transition === \"function\"\n                  ? animationConfig.transition(index)\n                  : animationConfig.transition) as Transition\n              }\n              className=\"relative\"\n              style={{ zIndex: avatars.length - index }}\n            >\n              <div\n                className={`flex h-11 w-11 items-center justify-center rounded-full border-2 border-card shadow-[0_10px_30px_rgba(2,6,23,0.35)] ${avatar.color}`}\n                aria-label={`${avatar.name} ${avatar.handle}`}\n              >\n                <User\n                  className=\"h-5 w-5 text-[var(--muted-foreground)]\"\n                  aria-hidden\n                />\n              </div>\n              <motion.div\n                initial={{ opacity: 0, y: 8, filter: \"blur(6px)\" }}\n                whileHover={\n                  shouldReduceMotion\n                    ? { opacity: 1, y: 0, filter: \"blur(0px)\" }\n                    : { opacity: 1, y: 0, filter: \"blur(0px)\" }\n                }\n                transition={\n                  shouldReduceMotion\n                    ? { duration: 0 }\n                    : { duration: 0.25, ease: [0.18, 0.89, 0.32, 1.12] }\n                }\n                className=\"pointer-events-none absolute bottom-full left-1/2 mb-3 -translate-x-1/2 whitespace-nowrap rounded-2xl border border-border/60 bg-card/90 px-4 py-2 text-xs text-[var(--muted-foreground)] shadow-[0_18px_45px_rgba(15,23,42,0.46)] backdrop-blur-xl\"\n              >\n                <p className=\"font-medium\">{avatar.name}</p>\n                <span className=\"text-[var(--muted-foreground)]\">\n                  {avatar.handle}\n                </span>\n              </motion.div>\n            </motion.li>\n          ))}\n        </motion.ul>\n        <motion.span\n          id={`${groupId}-description`}\n          initial={{\n            opacity: shouldReduceMotion ? 1 : 0,\n            y: shouldReduceMotion ? 0 : 6,\n          }}\n          animate={{ opacity: 1, y: 0 }}\n          transition={\n            shouldReduceMotion\n              ? { duration: 0 }\n              : { delay: 0.08 * avatars.length, duration: 0.3, ease: \"easeOut\" }\n          }\n          className=\"ml-4 rounded-full border border-border/60 bg-card/70 px-4 py-2 text-xs uppercase tracking-[0.32em] text-[var(--muted-foreground)] backdrop-blur-md\"\n        >\n          +{avatars.length} collaborators\n        </motion.span>\n      </div>\n    </section>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/uitripled/avatar-group-shadcnui.tsx"
    }
  ]
}