{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "tooltip-navbar",
  "type": "registry:component",
  "title": "Tooltip Navbar",
  "description": "Tooltip design recreated with smooth animations and interactive feedback.",
  "dependencies": [
    "lucide-react",
    "motion"
  ],
  "files": [
    {
      "path": "components/watermelon/tooltip-navbar.tsx",
      "type": "registry:component",
      "content": "'use client';\n\nimport { motion, AnimatePresence } from 'motion/react';\nimport { useRef, useState, type ReactNode } from 'react';\nexport type TooltipItem = {\n  icon: ReactNode;\n  label: string;\n  labelHasKeyword?: (string | ReactNode)[] | false;\n  hasBadge?: boolean;\n};\n\nimport {\n  MessageCircle,\n  Inbox,\n  Circle,\n  Crosshair,\n  Download,\n  Menu,\n  CommandIcon,\n} from 'lucide-react';\n\n\ninterface TooltipNavbarProps {\n  items: TooltipItem[];\n  tooltipDelay?: number;//in ms\n}\n\nconst DEFAULT_ITEMS: TooltipItem[] = [\n  {\n    icon: <MessageCircle className=\"h-full w-full\" />,\n    label: 'Comment',\n    labelHasKeyword: ['C'],\n    hasBadge: false,\n  },\n  {\n    icon: <Inbox className=\"h-full w-full\" />,\n    label: 'Inbox',\n    labelHasKeyword: ['I'],\n    hasBadge: true,\n  },\n  {\n    icon: <Circle className=\"h-full w-full\" />,\n    label: 'Record',\n    labelHasKeyword: ['R'],\n    hasBadge: false,\n  },\n  {\n    icon: <Crosshair className=\"h-full w-full\" />,\n    label: 'Focus Mode',\n    labelHasKeyword: ['F'],\n    hasBadge: false,\n  },\n  {\n    icon: <Download className=\"h-full w-full\" />,\n    label: 'Share',\n    labelHasKeyword: ['S'],\n    hasBadge: false,\n  },\n  {\n    icon: <Menu className=\"h-full w-full\" />,\n    label: 'Menu',\n    labelHasKeyword: ['M'],\n    hasBadge: false,\n  },\n];\nexport const TooltipNavbar = ({ items = DEFAULT_ITEMS, tooltipDelay = 300 }: TooltipNavbarProps) => {\n  const [activeIndex, setActiveIndex] = useState<number | null>(null);\n  const [coords, setCoords] = useState({ clipPath: '', translateX: 0 });\n\n  const measureRefs = useRef<(HTMLDivElement | null)[]>([]);\n  const buttonRefs = useRef<(HTMLButtonElement | null)[]>([]);\n\n  const [isEntering, setIsEntering] = useState(true);\n  const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n  const calculatePosition = (index: number) => {\n    const activeLabel = measureRefs.current[index];\n    const activeIcon = buttonRefs.current[index];\n\n    if (!activeLabel || !activeIcon) return null;\n\n    const labelLeft = activeLabel.offsetLeft;\n    const labelWidth = activeLabel.offsetWidth;\n    const labelCenter = labelLeft + labelWidth / 2;\n\n    const iconLeft = activeIcon.offsetLeft;\n    const iconWidth = activeIcon.offsetWidth;\n    const iconCenter = iconLeft + iconWidth / 2;\n\n    const totalWidth = measureRefs.current.reduce(\n      (acc, el) => acc + (el?.offsetWidth || 0),\n      0,\n    );\n\n    const cLeft = (labelLeft / totalWidth) * 100;\n    const cRight = 100 - ((labelLeft + labelWidth) / totalWidth) * 100;\n\n    return {\n      clipPath: `inset(0 ${cRight}% 0 ${cLeft}% round 8px)`,\n      translateX: iconCenter - labelCenter,\n    };\n  };\n\n  const handleMouseEnter = (index: number) => {\n    const newCoords = calculatePosition(index);\n    if (!newCoords) return;\n\n    if (activeIndex === null) {\n      if (timeoutRef.current) clearTimeout(timeoutRef.current);\n      setIsEntering(true);\n\n      timeoutRef.current = setTimeout(() => {\n        setCoords(newCoords);\n        setActiveIndex(index);\n      }, tooltipDelay);\n    } else {\n      setCoords(newCoords);\n      setActiveIndex(index);\n    }\n  };\n\n  const handleMouseLeave = () => {\n    if (timeoutRef.current) clearTimeout(timeoutRef.current);\n    setActiveIndex(null);\n    setCoords({ clipPath: '', translateX: 0 });\n    setIsEntering(true);\n  };\n\n  return (\n    <div >\n      <div className=\"flex items-center justify-center\">\n        <div className=\"relative text-white\" onMouseLeave={handleMouseLeave}>\n          <AnimatePresence>\n            {activeIndex !== null && coords.clipPath !== '' && (\n              <motion.div\n                className=\"absolute bottom-16 left-0 \"\n                initial={{ opacity: 0 }}\n                animate={{ opacity: 1 }}\n                exit={{ opacity: 0 }}\n                transition={{ duration: 0.2 }}\n              >\n                <motion.div\n                  className=\"flex bg-black dark:bg-neutral-800\"\n                  animate={{\n                    clipPath: coords.clipPath,\n                    x: coords.translateX,\n                  }}\n                  transition={{\n                    type: 'spring',\n                    bounce: 0,\n\n                    duration: isEntering ? 0 : 0.4,\n                  }}\n                  onUpdate={() => {\n                    if (isEntering) {\n                      setIsEntering(false);\n                    }\n                  }}\n                >\n                  <div className=\"inline-flex h-8 items-center justify-center\">\n                    {items.map((item, index) => (\n                      <div\n                        key={`real-${index}`}\n                        className=\"flex items-center justify-center gap-1 px-2 text-sm font-medium whitespace-nowrap \"\n                      >\n                        <span className=\"text-white\">{item.label}</span>\n                        {item.hasBadge && (\n                          <div className=\"flex items-center gap-0.5 text-white/40\">\n                            <span className=\"flex items-center justify-center rounded-sm border border-white/20 p-1\">\n                              <CommandIcon className=\"size-3 text-neutral-500\" />\n                            </span>\n                          </div>\n                        )}\n                        {item.labelHasKeyword && (\n                          <div className=\"flex items-center gap-0.5 text-white/40\">\n                            {item.labelHasKeyword.map((key, i) => (\n                              <span\n                                key={i}\n                                className=\"flex items-center justify-center rounded-sm border border-white/20 px-1 tabular-nums\"\n                              >\n                                {key}\n                              </span>\n                            ))}\n                          </div>\n                        )}\n                      </div>\n                    ))}\n                  </div>\n                </motion.div>\n              </motion.div>\n            )}\n          </AnimatePresence>\n\n          <div className=\"z-10 inline-flex items-center justify-center rounded-full bg-black/95 p-2 backdrop-blur dark:bg-neutral-800\">\n            {items.map((item, index) => (\n              <button\n                key={index}\n                onMouseEnter={() => handleMouseEnter(index)}\n                ref={(el) => {\n                  buttonRefs.current[index] = el;\n                }}\n                className=\"flex cursor-pointer items-center justify-center rounded-full transition-colors hover:bg-white/10 \"\n              >\n                <div className=\"flex size-10 items-center justify-center p-1.5 dark:text-neutral-200\">\n                  {item.icon}\n                </div>\n                <span className=\"sr-only\">{item.label}</span>\n              </button>\n            ))}\n          </div>\n        </div>\n      </div>\n\n      <div className=\"pointer-events-none absolute bottom-0 left-0 flex h-0 overflow-hidden whitespace-nowrap opacity-0\">\n        {items.map((item, index) => (\n          <div\n            key={`measure-${index}`}\n            ref={(el) => {\n              measureRefs.current[index] = el;\n            }}\n            className=\"flex items-center justify-center gap-1 px-2 text-sm font-medium whitespace-nowrap\"\n          >\n            <span>{item.label}</span>\n            {item.hasBadge && (\n              <div className=\"flex items-center gap-0.5 text-white/40\">\n                <span className=\"flex items-center justify-center rounded-sm border border-white/20 p-1\">\n                  <CommandIcon className=\"size-3 text-neutral-500\" />\n                </span>\n              </div>\n            )}\n            {item.labelHasKeyword && (\n              <div className=\"flex items-center gap-0.5 text-white/40\">\n                {item.labelHasKeyword.map((key, i) => (\n                  <span\n                    key={i}\n                    className=\"flex items-center justify-center rounded-sm border border-white/20 px-1 tabular-nums\"\n                  >\n                    {typeof key === 'string' ? key : '⌘'}\n                  </span>\n                ))}\n              </div>\n            )}\n          </div>\n        ))}\n      </div>\n    </div>\n  );\n};\n"
    }
  ]
}
