{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "morph-navbar",
  "title": "Morph Navbar",
  "description": "A polished navigation bar with a fluid, morphing pill that tracks the active link and hover state.",
  "dependencies": [
    "motion"
  ],
  "registryDependencies": [
    "utils"
  ],
  "files": [
    {
      "path": "registry/react/atlasui/morph-navbar.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport Link from \"next/link\";\n\nimport { motion } from \"motion/react\";\n\nimport { cn } from \"@/lib/utils\";\n\ninterface NavbarContextValue {\n  registerItem: (href: string, el: HTMLDivElement | null) => void;\n  previewItem: (el: HTMLDivElement) => void;\n  clearPreview: () => void;\n  activeHref: string;\n}\n\nexport const MorphNavbarContext =\n  React.createContext<NavbarContextValue | null>(null);\n\nexport function MorphNavbar({\n  children,\n  activeHref,\n}: {\n  children: React.ReactNode;\n  activeHref: string;\n}) {\n  const containerRef = React.useRef<HTMLDivElement>(null);\n\n  // Registry of nav items by href\n  const itemRegistry = React.useRef<Record<string, HTMLDivElement | null>>({});\n\n  const lastActivePosition = React.useRef<{\n    left: string;\n    width: string;\n  } | null>(null);\n\n  const [activePill, setActivePill] = React.useState({\n    left: \"4px\",\n    width: \"0px\",\n  });\n\n  const [hoverPill, setHoverPill] = React.useState({\n    left: \"4px\",\n    width: \"calc(100% - 8px)\",\n  });\n\n  function measureItem(el: HTMLDivElement) {\n    if (!containerRef.current) return null;\n\n    const itemRect = el.getBoundingClientRect();\n    const containerRect = containerRef.current.getBoundingClientRect();\n\n    return {\n      left: `${itemRect.left - containerRect.left}px`,\n      width: `${itemRect.width}px`,\n    };\n  }\n\n  function updateActivePill(next: { left: string; width: string }) {\n    // Avoid unnecessary state updates (prevents render loops)\n    if (\n      lastActivePosition.current &&\n      lastActivePosition.current.left === next.left &&\n      lastActivePosition.current.width === next.width\n    ) {\n      return;\n    }\n\n    lastActivePosition.current = next;\n    setActivePill(next);\n  }\n\n  const contextValue: NavbarContextValue = {\n    registerItem(href, el) {\n      itemRegistry.current[href] = el;\n\n      // Only position the active pill for the active route\n      if (!el || href !== activeHref) return;\n\n      const pos = measureItem(el);\n      if (pos) updateActivePill(pos);\n    },\n\n    previewItem(el) {\n      const pos = measureItem(el);\n      if (pos) setHoverPill(pos);\n    },\n\n    clearPreview() {\n      setHoverPill({\n        left: \"4px\",\n        width: \"calc(100% - 8px)\",\n      });\n    },\n\n    activeHref,\n  };\n\n  return (\n    <MorphNavbarContext.Provider value={contextValue}>\n      <nav\n        aria-label=\"Main Navigation\"\n        className=\"relative mx-auto flex h-14 max-w-fit rounded-full bg-linear-to-b from-neutral-700 to-neutral-800 p-1 text-white shadow-[0_8px_32px_rgba(0,0,0,0.6),0_2px_8px_rgba(0,0,0,0.4),inset_0_1px_0_rgba(255,255,255,0.1),inset_0_-1px_2px_rgba(0,0,0,0.5)] md:h-16\"\n      >\n        <div\n          ref={containerRef}\n          className=\"relative flex h-full w-full gap-x-1 rounded-full bg-linear-to-b from-neutral-800 to-neutral-900 p-1 shadow-[inset_0_2px_4px_rgba(0,0,0,0.8),inset_0_-1px_2px_rgba(255,255,255,0.05)]\"\n        >\n          {/* Active pill */}\n          <motion.span\n            className=\"absolute z-5 h-10 rounded-full bg-linear-to-b from-[#E8E8E8] via-[#C0C0C0] to-[#A0A0A0] shadow-[0_2px_8px_rgba(0,0,0,0.4),0_1px_2px_rgba(0,0,0,0.3),inset_0_2px_0_rgba(255,255,255,0.5),inset_0_-2px_0_rgba(255,255,255,0.3),inset_0_-8px_16px_rgba(255,255,255,0.2),inset_0_0_0_1px_rgba(255,255,255,0.4),inset_0_1px_4px_rgba(0,0,0,0.1)] md:h-12\"\n            style={{ top: \"4px\" }}\n            animate={activePill}\n            transition={{ type: \"spring\", stiffness: 400, damping: 33 }}\n            aria-hidden=\"true\"\n          />\n\n          {/* Hover pill */}\n          <motion.span\n            className=\"absolute h-10 rounded-full bg-linear-to-b from-white/10 to-white/5 shadow-[inset_0_1px_2px_rgba(255,255,255,0.2)] backdrop-blur-sm md:h-12\"\n            style={{ top: \"4px\" }}\n            animate={hoverPill}\n            transition={{ type: \"spring\", stiffness: 400, damping: 33 }}\n            aria-hidden=\"true\"\n          />\n\n          {children}\n        </div>\n      </nav>\n    </MorphNavbarContext.Provider>\n  );\n}\n\ninterface MorphNavbarItemProps {\n  href: string;\n  children: React.ReactNode;\n  className?: string;\n}\n\nexport function MorphNavbarItem({\n  href,\n  children,\n  className,\n}: MorphNavbarItemProps) {\n  const ctx = React.useContext(MorphNavbarContext);\n  const ref = React.useRef<HTMLDivElement>(null);\n\n  React.useEffect(() => {\n    if (!ref.current || !ctx) return;\n    ctx.registerItem(href, ref.current);\n  }, [ctx, href]);\n\n  if (!ctx) return null;\n\n  const isActive = href === ctx.activeHref;\n\n  return (\n    <div\n      ref={ref}\n      onMouseEnter={() => ref.current && ctx.previewItem(ref.current)}\n      onMouseLeave={ctx.clearPreview}\n      className=\"relative z-20 flex items-center justify-center\"\n    >\n      <Link\n        href={href}\n        aria-current={isActive ? \"page\" : undefined}\n        className={cn(\n          \"flex items-center justify-center rounded-full px-4 py-3 font-sans text-xs font-medium transition-colors md:px-7 md:text-base\",\n          isActive ? \"text-neutral-900\" : \"text-white\",\n          className\n        )}\n      >\n        {children}\n      </Link>\n    </div>\n  );\n}\n",
      "type": "registry:component"
    }
  ],
  "type": "registry:component"
}