{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "dynamic-toolbar",
  "title": "Dynamic Toolbar",
  "description": "A toolbar that adapts its size and layout based on content.",
  "dependencies": [
    "motion",
    "@hugeicons/core-free-icons",
    "@hugeicons/react",
    "clsx",
    "tailwind-merge"
  ],
  "files": [
    {
      "path": "registry/default/example/dynamic-toolbar.tsx",
      "content": "\"use client\";\nimport { delay, motion } from \"motion/react\";\nimport React, { useEffect, useRef, useState } from \"react\";\nimport {\n  InboxIcon,\n  Message01Icon,\n  PaintBoardIcon,\n  Tag01Icon,\n  Image01Icon,\n  Archive02Icon,\n  ArrowReloadHorizontalIcon,\n  Delete02Icon,\n  ArrowRight01Icon,\n  ArrowLeft01Icon,\n} from \"@hugeicons/core-free-icons\";\nimport { HugeiconsIcon } from \"@hugeicons/react\";\nimport useMeasure from \"@/hooks/use-measure\";\n\nconst ICON_SIZE = 24;\n\n// Change Here\nconst primaryTools = [\n  { icon: InboxIcon, label: \"Inbox\" },\n  { icon: Message01Icon, label: \"Messages\" },\n  { icon: PaintBoardIcon, label: \"Paint\" },\n  { icon: Tag01Icon, label: \"Tags\", blur: true },\n];\n\nconst secondaryTools = [\n  { icon: Image01Icon, label: \"Image\", blur: true },\n  { icon: Archive02Icon, label: \"Archive\" },\n  {\n    icon: ArrowReloadHorizontalIcon,\n    label: \"Reload\",\n    className: \"-scale-x-100\",\n  },\n  {\n    icon: ArrowReloadHorizontalIcon,\n    label: \"Reload\",\n    className: \"-scale-x-100\",\n  },\n  { icon: Delete02Icon, label: \"Delete\", className: \"text-red-500\" },\n];\n\nfunction ToolbarButton({\n  icon,\n  size = ICON_SIZE,\n  blur = false,\n  isBlurred = false,\n  className = \"\",\n}: {\n  icon: any;\n  size?: number;\n  blur?: boolean;\n  isBlurred?: boolean;\n  className?: string;\n}) {\n  const iconElement = (\n    <HugeiconsIcon\n      icon={icon}\n      className={`text-foreground ${className}`}\n      width={size}\n      height={size}\n    />\n  );\n\n  if (blur) {\n    return (\n      <button className=\"p-1 rounded-md hover:bg-accent/50 transition-colors hover:cursor-pointer\">\n        <motion.div\n          initial={{ filter: \"blur(0px)\" }}\n          animate={{ filter: isBlurred ? \"blur(1px)\" : \"blur(0px)\" }}\n        >\n          {iconElement}\n        </motion.div>\n      </button>\n    );\n  }\n\n  return (\n    <button className=\"p-1 rounded-md hover:bg-accent/50 transition-colors hover:cursor-pointer \">\n      {iconElement}\n    </button>\n  );\n}\n\nfunction ExtendedToolbar() {\n  const [isExpanded, setIsExpanded] = useState(false);\n  const [isMounted, setIsMounted] = useState(false);\n  const [primaryRef, primaryBounds] = useMeasure();\n  const [secondaryRef, secondaryBounds] = useMeasure();\n\n  useEffect(() => {\n    setIsMounted(true);\n  }, []);\n\n  const currentWidth = isExpanded ? secondaryBounds.width : primaryBounds.width;\n  const hasMeasurements = primaryBounds.width > 0;\n\n  const initialWidth = hasMeasurements ? primaryBounds.width : \"auto\";\n\n  const springTransition = {\n    type: \"spring\" as const,\n    stiffness: 200,\n    damping: 20,\n    mass: 0.8,\n    bounce: 0.9,\n    duration: isExpanded ? 0.4 : 1.2,\n    delay: isExpanded ? 0 : 0.015,\n  };\n\n  return (\n    <motion.div\n      className=\"relative h-14 rounded-full bg-muted border border-border overflow-hidden\"\n      initial={{ width: initialWidth }}\n      animate={\n        hasMeasurements ? { width: currentWidth } : { width: initialWidth }\n      }\n      transition={isMounted ? springTransition : { duration: 0 }}\n    >\n      <motion.div\n        className=\"h-full flex\"\n        initial={false}\n        animate={{ x: isExpanded ? -primaryBounds.width : 0 }}\n        transition={isMounted ? springTransition : { duration: 0 }}\n      >\n        {/* Primary Tools Panel */}\n        <div\n          ref={primaryRef as React.RefObject<HTMLDivElement>}\n          className=\"flex items-center gap-1 p-1.5 pl-3 pr-2 flex-shrink-0\"\n        >\n          {primaryTools.map((item, index) => (\n            <ToolbarButton\n              key={index}\n              icon={item.icon}\n              blur={item.blur}\n              isBlurred={isExpanded}\n            />\n          ))}\n          <motion.button\n            whileTap={{ scale: 0.9 }}\n            onClick={() => setIsExpanded(true)}\n            className=\"h-full aspect-square flex justify-center items-center bg-background rounded-full\"\n          >\n            <HugeiconsIcon\n              icon={ArrowRight01Icon}\n              className=\"text-muted-foreground\"\n              width={24}\n              height={24}\n            />\n          </motion.button>\n        </div>\n\n        {/* Secondary Tools Panel */}\n        <div\n          ref={secondaryRef as React.RefObject<HTMLDivElement>}\n          className=\"flex items-center gap-1 p-1.5 pl-2 pr-3 flex-shrink-0\"\n          style={{\n            position: isExpanded ? \"relative\" : \"absolute\",\n            opacity: isExpanded ? 1 : 0,\n            pointerEvents: isExpanded ? \"auto\" : \"none\",\n          }}\n        >\n          <motion.button\n            whileTap={{ scale: 0.9 }}\n            onClick={() => setIsExpanded(false)}\n            className=\"h-full aspect-square flex justify-center items-center bg-background rounded-full\"\n          >\n            <HugeiconsIcon\n              icon={ArrowLeft01Icon}\n              className=\"text-muted-foreground\"\n              width={24}\n              height={24}\n            />\n          </motion.button>\n          {secondaryTools.map((item, index) => (\n            <ToolbarButton\n              key={index}\n              icon={item.icon}\n              blur={item.blur}\n              isBlurred={!isExpanded}\n              className={item.className}\n            />\n          ))}\n        </div>\n      </motion.div>\n    </motion.div>\n  );\n}\n\nexport default ExtendedToolbar;\n",
      "type": "registry:component"
    },
    {
      "path": "hooks/use-measure.tsx",
      "content": "import { useEffect, useRef, useState } from \"react\";\n\nconst useMeasure = () => {\n  const ref = useRef<HTMLElement>(null);\n  const [bounds, setBounds] = useState({ height: 0, width: 0 });\n\n  useEffect(() => {\n    const observer = new ResizeObserver((entries) => {\n      for (const entry of entries) {\n        const rect = entry.target.getBoundingClientRect();\n\n        setBounds({\n          height: rect.height,\n          width: rect.width,\n        });\n      }\n    });\n\n    if (ref.current) {\n      observer.observe(ref.current);\n    }\n\n    return () => observer.disconnect();\n  }, []);\n\n  return [ref, bounds] as const;\n};\n\nexport default useMeasure;\n",
      "type": "registry:hook"
    }
  ],
  "type": "registry:component"
}