{
  "name": "animated-tabs",
  "type": "registry:ui",
  "componentName": "animated-background",
  "description": "Tab interface with animated background highlighting the active tab.",
  "files": [
    {
      "path": "animated-tabs.tsx",
      "content": "import { Home, PhoneCall, Settings, User } from 'lucide-react';\nimport { AnimatedBackground } from '@/components/core/animated-background';\n\nexport function AnimatedTabs() {\n  const TABS = [\n    {\n      label: 'Home',\n      icon: <Home className='h-5 w-5' />,\n    },\n    {\n      label: 'About',\n      icon: <User className='h-5 w-5' />,\n    },\n    {\n      label: 'Services',\n      icon: <Settings className='h-5 w-5' />,\n    },\n    {\n      label: 'Contact',\n      icon: <PhoneCall className='h-5 w-5' />,\n    },\n  ];\n\n  return (\n    <div className='absolute bottom-8'>\n      <div className='flex w-full space-x-2 rounded-xl border border-zinc-950/10 bg-white p-2'>\n        <AnimatedBackground\n          defaultValue={TABS[0].label}\n          className='rounded-lg bg-zinc-100'\n          transition={{\n            type: 'spring',\n            bounce: 0.2,\n            duration: 0.3,\n          }}\n        >\n          {TABS.map((tab) => (\n            <button\n              key={tab.label}\n              data-id={tab.label}\n              type='button'\n              className='inline-flex h-9 w-9 items-center justify-center text-zinc-500 transition-colors duration-100 focus-visible:outline-2 data-[checked=true]:text-zinc-950'\n            >\n              {tab.icon}\n            </button>\n          ))}\n        </AnimatedBackground>\n      </div>\n    </div>\n  );\n}\n",
      "type": "registry:component"
    },
    {
      "path": "components/core/animated-background.tsx",
      "content": "'use client';\nimport { cn } from '@/lib/utils';\nimport { AnimatePresence, Transition, motion } from 'motion/react';\nimport {\n  Children,\n  cloneElement,\n  ReactElement,\n  useEffect,\n  useState,\n  useId,\n} from 'react';\n\nexport type AnimatedBackgroundProps = {\n  children:\n    | ReactElement<{ 'data-id': string }>[]\n    | ReactElement<{ 'data-id': string }>;\n  defaultValue?: string;\n  onValueChange?: (newActiveId: string | null) => void;\n  className?: string;\n  transition?: Transition;\n  enableHover?: boolean;\n};\n\nexport function AnimatedBackground({\n  children,\n  defaultValue,\n  onValueChange,\n  className,\n  transition,\n  enableHover = false,\n}: AnimatedBackgroundProps) {\n  const [activeId, setActiveId] = useState<string | null>(null);\n  const uniqueId = useId();\n\n  const handleSetActiveId = (id: string | null) => {\n    setActiveId(id);\n\n    if (onValueChange) {\n      onValueChange(id);\n    }\n  };\n\n  useEffect(() => {\n    if (defaultValue !== undefined) {\n      setActiveId(defaultValue);\n    }\n  }, [defaultValue]);\n\n  return Children.map(children, (child: any, index) => {\n    const id = child.props['data-id'];\n\n    const interactionProps = enableHover\n      ? {\n          onMouseEnter: () => handleSetActiveId(id),\n          onMouseLeave: () => handleSetActiveId(null),\n        }\n      : {\n          onClick: () => handleSetActiveId(id),\n        };\n\n    return cloneElement(\n      child,\n      {\n        key: index,\n        className: cn('relative inline-flex', child.props.className),\n        'data-checked': activeId === id ? 'true' : 'false',\n        ...interactionProps,\n      },\n      <>\n        <AnimatePresence initial={false}>\n          {activeId === id && (\n            <motion.div\n              layoutId={`background-${uniqueId}`}\n              className={cn('absolute inset-0', className)}\n              transition={transition}\n              initial={{ opacity: defaultValue ? 1 : 0 }}\n              animate={{\n                opacity: 1,\n              }}\n              exit={{\n                opacity: 0,\n              }}\n            />\n          )}\n        </AnimatePresence>\n        <div className='z-10'>{child.props.children}</div>\n      </>\n    );\n  });\n}\n",
      "type": "registry:ui"
    }
  ]
}