{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "bottom-menu",
  "title": "Bottom Menu",
  "description": "A floating bottom navigation menu with smooth interactions.",
  "dependencies": [
    "motion",
    "react-use-measure",
    "@hugeicons/core-free-icons",
    "@hugeicons/react",
    "clsx",
    "tailwind-merge"
  ],
  "files": [
    {
      "path": "registry/default/example/bottom-menu.tsx",
      "content": "\"use client\";\n\nimport {\n  Notification03Icon,\n  Search01Icon,\n  Sun03Icon,\n  Moon02Icon,\n  ComputerIcon,\n  UserEdit01Icon,\n  PlusSignIcon,\n  Mic01Icon,\n  Camera01Icon,\n  PencilEdit02Icon,\n  FilterHorizontalIcon,\n  AutoConversationsIcon,\n} from \"@hugeicons/core-free-icons\";\nimport { HugeiconsIcon } from \"@hugeicons/react\";\nimport React, { useMemo, useState, useRef, useEffect } from \"react\";\nimport { AnimatePresence, motion } from \"motion/react\";\nimport useMeasure from \"react-use-measure\";\nimport { cn } from \"@/lib/utils\";\n\n// Change Here\nconst MAIN_NAV = [\n  { icon: PlusSignIcon, name: \"home\" },\n  { icon: Search01Icon, name: \"search\" },\n  { icon: Notification03Icon, name: \"notifications\" },\n  { icon: UserEdit01Icon, name: \"profile\" },\n  { icon: Sun03Icon, name: \"theme\" },\n];\n\nconst HOME_ITEMS = [\n  { icon: PencilEdit02Icon, text: \"Note\" },\n  { icon: Mic01Icon, text: \"Voice\" },\n  { icon: Camera01Icon, text: \"Screenshot\" },\n];\n\nconst SEARCH_OPTIONS = [\n  { icon: FilterHorizontalIcon, text: \"Filter\" },\n  { icon: AutoConversationsIcon, text: \"Trending\" },\n];\n\nconst NOTIFICATION_TYPES = [\"Messages\", \"System Alerts\"];\n\nconst PROFILE_LINKS = [\"My Account\", \"Settings\", \"Subscription / Billing\"];\n\nconst THEME_OPTIONS = [\n  { key: \"light\", icon: Sun03Icon, text: \"Light\" },\n  { key: \"dark\", icon: Moon02Icon, text: \"Dark\" },\n  { key: \"system\", icon: ComputerIcon, text: \"System\" },\n];\n\nconst BottomMenu = () => {\n  const containerRef = useRef<HTMLDivElement>(null);\n  const [elementRef] = useMeasure();\n  const [hiddenRef, hiddenBounds] = useMeasure();\n  const [view, setView] = useState<\n    \"default\" | \"home\" | \"search\" | \"notifications\" | \"profile\" | \"theme\"\n  >(\"default\");\n\n  // Track selected theme\n  const [theme, setTheme] = useState<\"light\" | \"dark\" | \"system\">(\"light\");\n  useEffect(() => {\n    const handleClickOutside = (event: MouseEvent) => {\n      if (\n        containerRef.current &&\n        !containerRef.current.contains(event.target as Node)\n      ) {\n        setView(\"default\");\n      }\n    };\n\n    document.addEventListener(\"mousedown\", handleClickOutside);\n    return () => {\n      document.removeEventListener(\"mousedown\", handleClickOutside);\n    };\n  }, []);\n\n  const sharedHover =\n    \"group transition-all duration-75 px-3 py-2 text-[15px] text-muted-foreground w-full text-left rounded-[12px] hover:bg-muted/80 hover:text-foreground\";\n\n  const content = useMemo(() => {\n    switch (view) {\n      case \"default\":\n        return null;\n\n      case \"home\":\n        return (\n          <div className=\"space-y-0.5 min-w-[210px] p-[6px] py-0.5\">\n            {HOME_ITEMS.map(({ icon: Icon, text }) => (\n              <button\n                key={text}\n                className={`${sharedHover} flex items-center gap-3`}\n              >\n                <HugeiconsIcon\n                  icon={Icon}\n                  size={20}\n                  className=\"text-muted-foreground group-hover:text-foreground transition-all duration-75\"\n                />\n                <span className=\"transition-all duration-75\">{text}</span>\n              </button>\n            ))}\n          </div>\n        );\n\n      case \"search\":\n        return (\n          <div className=\"space-y-2 min-w-[270px] p-[8px] py-1\">\n            <div className=\"relative\">\n              <HugeiconsIcon\n                icon={Search01Icon}\n                size={17}\n                className=\"absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground\"\n              />\n              <input\n                type=\"text\"\n                placeholder=\"Search...\"\n                className=\"w-full pl-9 pr-3 py-[6px] text-[14.5px] text-foreground bg-muted/80 border border-border rounded-[12px] focus:outline-none focus:ring-2 focus:ring-ring focus:border-transparent placeholder:text-muted-foreground/50\"\n              />\n            </div>\n            <div className=\"flex gap-1.5\">\n              {SEARCH_OPTIONS.map(({ icon: Icon, text }) => (\n                <button\n                  key={text}\n                  className={`${sharedHover} flex-1 flex items-center justify-center gap-1.5 bg-muted hover:bg-accent`}\n                >\n                  <HugeiconsIcon\n                    icon={Icon}\n                    size={14}\n                    strokeWidth={2}\n                    className=\"text-muted-foreground group-hover:text-foreground transition-all duration-75\"\n                  />\n                  <span className=\"transition-all duration-75\">{text}</span>\n                </button>\n              ))}\n            </div>\n          </div>\n        );\n\n      case \"notifications\":\n        return (\n          <div className=\"space-y-0.5 min-w-[210px] p-[6px] py-0.5\">\n            {NOTIFICATION_TYPES.map((t) => (\n              <button key={t} className={sharedHover}>\n                <span className=\"transition-all duration-75\">{t}</span>\n              </button>\n            ))}\n          </div>\n        );\n\n      case \"profile\":\n        return (\n          <div className=\"space-y-0.5 min-w-[230px] p-[6px] py-0.5\">\n            {PROFILE_LINKS.map((t) => (\n              <button key={t} className={sharedHover}>\n                <span className=\"transition-all duration-75\">{t}</span>\n              </button>\n            ))}\n            <div className=\"border-t border-border my-[2px]\" />\n            <button className=\"px-3 py-2 text-[15px] text-destructive w-full text-left rounded-[12px] hover:bg-destructive/10 transition-all duration-75\">\n              Logout\n            </button>\n          </div>\n        );\n\n      case \"theme\":\n        return (\n          <div className=\"flex items-center justify-between gap-1.5 min-w-[270px] p-[6px] py-0.5\">\n            {THEME_OPTIONS.map(({ key, icon: Icon, text }) => (\n              <button\n                key={key}\n                onClick={() => setTheme(key as \"light\" | \"dark\" | \"system\")}\n                className={`flex items-center justify-center gap-2 rounded-[12px] px-3 py-2 transition-all duration-100 ${\n                  theme === key\n                    ? \"bg-accent text-foreground\"\n                    : \"text-muted-foreground hover:bg-muted\"\n                }`}\n              >\n                <HugeiconsIcon\n                  icon={Icon}\n                  size={18}\n                  className={`transition-all duration-75 ${\n                    theme === key ? \"text-foreground\" : \"text-muted-foreground\"\n                  }`}\n                />\n                <span>{text}</span>\n              </button>\n            ))}\n          </div>\n        );\n\n      default:\n        return null;\n    }\n  }, [view, theme]);\n\n  return (\n    <div\n      ref={containerRef}\n      className={cn(\"relative flex flex-col items-center\")}\n    >\n      {/* Hidden for measurement */}\n      <div\n        ref={hiddenRef}\n        className=\"absolute left-[-9999px] top-[-9999px] invisible pointer-events-none\"\n      >\n        <div className=\"rounded-[18px] bg-background/95 border border-border py-1\">\n          {content}\n        </div>\n      </div>\n\n      {/* Animated submenu */}\n      <AnimatePresence mode=\"wait\">\n        {view !== \"default\" && (\n          <motion.div\n            key=\"submenu\"\n            initial={{\n              opacity: 0,\n              scaleY: 0.9,\n              scaleX: 0.95,\n              height: 0,\n              width: 0,\n              originY: 1,\n              originX: 0.5,\n            }}\n            animate={{\n              opacity: 1,\n              scaleY: 1,\n              scaleX: 1,\n              height: hiddenBounds.height || \"auto\",\n              width: hiddenBounds.width || \"auto\",\n              originY: 1,\n              originX: 0.5,\n            }}\n            exit={{\n              opacity: 0,\n              scaleY: 0.9,\n              scaleX: 0.95,\n              height: 0,\n              width: 0,\n              originY: 1,\n              originX: 0.5,\n            }}\n            transition={{\n              duration: 0.3,\n              ease: [0.45, 0, 0.25, 1],\n            }}\n            style={{\n              transformOrigin: \"bottom center\",\n            }}\n            className=\"absolute bottom-[70px] overflow-hidden\"\n          >\n            <div\n              ref={elementRef}\n              className=\"rounded-[18px] bg-background/95 backdrop-blur-xl border border-border\"\n            >\n              <AnimatePresence initial={false} mode=\"popLayout\">\n                <motion.div\n                  key={view}\n                  initial={{\n                    opacity: 0,\n                    scale: 0.96,\n                    filter: \"blur(10px)\",\n                  }}\n                  animate={{\n                    opacity: 1,\n                    scale: 1,\n                    filter: \"blur(0px)\",\n                  }}\n                  exit={{\n                    opacity: 0,\n                    scale: 0.95,\n                    filter: \"blur(12px)\",\n                  }}\n                  transition={{\n                    duration: 0.25,\n                    ease: [0.42, 0, 0.58, 1],\n                  }}\n                  className=\"py-1\"\n                >\n                  {content}\n                </motion.div>\n              </AnimatePresence>\n            </div>\n          </motion.div>\n        )}\n      </AnimatePresence>\n\n      {/* Toolbar */}\n      <div className=\"flex items-center gap-1 bg-background/95 backdrop-blur-xl border border-border rounded-[18px] p-1 mt-3 z-10\">\n        {MAIN_NAV.map(({ icon: Icon, name }) => (\n          <button\n            key={name}\n            className={`p-3 rounded-[16px] transition-all ${\n              view === name ? \"bg-accent\" : \"hover:bg-muted\"\n            }`}\n            onClick={() => setView(view === name ? \"default\" : (name as any))}\n          >\n            <HugeiconsIcon\n              icon={Icon}\n              size={22}\n              className={`transition-all ${\n                view === name ? \"text-foreground\" : \"text-muted-foreground\"\n              }`}\n            />\n          </button>\n        ))}\n      </div>\n    </div>\n  );\n};\n\nexport default BottomMenu;\n",
      "type": "registry:component"
    }
  ],
  "type": "registry:component"
}