{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "direction-aware-tabs",
  "type": "registry:ui",
  "description": "Tab component with direction-aware animations and smooth transitions",
  "dependencies": [
    "motion",
    "react-use-measure"
  ],
  "files": [
    {
      "path": "registry/default/ui/direction-aware-tabs.tsx",
      "content": "\"use client\"\n\nimport { ReactNode, useMemo, useState } from \"react\"\nimport { AnimatePresence, motion, MotionConfig } from \"motion/react\"\nimport useMeasure from \"react-use-measure\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Tab = {\n  id: number\n  label: string\n  content: ReactNode\n}\n\ninterface OgImageSectionProps {\n  tabs: Tab[]\n  className?: string\n  /** Outer container radius (e.g. `rounded-lg`) */\n  rounded?: string\n  /** Inner tab/bubble radius — should be outer radius minus container padding (~3px) */\n  roundedInner?: string\n  onChange?: () => void\n}\n\nfunction DirectionAwareTabs({\n  tabs,\n  className,\n  rounded,\n  roundedInner,\n  onChange,\n}: OgImageSectionProps) {\n  const [activeTab, setActiveTab] = useState(0)\n  const [direction, setDirection] = useState(0)\n  const [isAnimating, setIsAnimating] = useState(false)\n  const [ref, bounds] = useMeasure()\n\n  const content = useMemo(() => {\n    const activeTabContent = tabs.find((tab) => tab.id === activeTab)?.content\n    return activeTabContent || null\n  }, [activeTab, tabs])\n\n  const handleTabClick = (newTabId: number) => {\n    if (newTabId !== activeTab && !isAnimating) {\n      const newDirection = newTabId > activeTab ? 1 : -1\n      setDirection(newDirection)\n      setActiveTab(newTabId)\n      onChange ? onChange() : null\n    }\n  }\n\n  const variants = {\n    initial: (direction: number) => ({\n      x: 300 * direction,\n      opacity: 0,\n      filter: \"blur(4px)\",\n    }),\n    active: {\n      x: 0,\n      opacity: 1,\n      filter: \"blur(0px)\",\n    },\n    exit: (direction: number) => ({\n      x: -300 * direction,\n      opacity: 0,\n      filter: \"blur(4px)\",\n    }),\n  }\n\n  return (\n    <div className=\"flex w-full flex-col items-center\">\n      <div\n        className={cn(\n          \"shadow-inner-shadow flex cursor-pointer space-x-1 rounded-full border border-none bg-neutral-600 px-[3px] py-[3.2px]\",\n          className,\n          rounded\n        )}\n      >\n        {tabs.map((tab) => (\n          <button\n            key={tab.id}\n            onClick={() => handleTabClick(tab.id)}\n            className={cn(\n              \"relative flex items-center gap-2 rounded-full px-3.5 py-1.5 text-xs font-medium text-neutral-200 transition focus-visible:ring-1 focus-visible:outline-1 focus-visible:outline-none sm:text-sm\",\n              activeTab === tab.id\n                ? \"text-white\"\n                : \"text-neutral-200/80 hover:text-neutral-300/60\",\n              rounded ? roundedInner : undefined\n            )}\n            style={{ WebkitTapHighlightColor: \"transparent\" }}\n          >\n            {activeTab === tab.id && (\n              <motion.span\n                layoutId=\"bubble\"\n                className={cn(\n                  \"shadow-inner-shadow absolute inset-0 z-10 border border-white/10 bg-neutral-700 mix-blend-difference\",\n                  rounded ? roundedInner : \"rounded-full\"\n                )}\n                transition={{ type: \"spring\", bounce: 0.19, duration: 0.4 }}\n              />\n            )}\n\n            {tab.label}\n          </button>\n        ))}\n      </div>\n      <MotionConfig transition={{ duration: 0.4, type: \"spring\", bounce: 0.2 }}>\n        <motion.div\n          className=\"relative mx-auto h-full w-full overflow-hidden\"\n          initial={false}\n          animate={{ height: bounds.height }}\n        >\n          <div className=\"p-1\" ref={ref}>\n            <AnimatePresence\n              custom={direction}\n              mode=\"popLayout\"\n              onExitComplete={() => setIsAnimating(false)}\n            >\n              <motion.div\n                key={activeTab}\n                variants={variants}\n                initial=\"initial\"\n                animate=\"active\"\n                exit=\"exit\"\n                custom={direction}\n                onAnimationStart={() => setIsAnimating(true)}\n                onAnimationComplete={() => setIsAnimating(false)}\n              >\n                {content}\n              </motion.div>\n            </AnimatePresence>\n          </div>\n        </motion.div>\n      </MotionConfig>\n    </div>\n  )\n}\nexport { DirectionAwareTabs }\n",
      "type": "registry:ui"
    }
  ]
}