{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "dock",
  "title": "Dock",
  "description": "A macOS-style dock whose items magnify with spring physics as the pointer moves across them.",
  "dependencies": ["framer-motion"],
  "registryDependencies": ["@godui/godui-theme"],
  "files": [
    {
      "path": "packages/components/src/dock/dock.tsx",
      "content": "\"use client\";\n\nimport {\n  AnimatePresence,\n  type MotionValue,\n  motion,\n  useMotionValue,\n  useSpring,\n  useTransform,\n} from \"framer-motion\";\nimport * as React from \"react\";\n\ntype DockContextValue = {\n  mouseX: MotionValue<number>;\n  baseSize: number;\n  magnification: number;\n  distance: number;\n};\n\nconst DockContext = React.createContext<DockContextValue | null>(null);\n\nfunction useDock() {\n  const ctx = React.useContext(DockContext);\n  if (!ctx) {\n    throw new Error(\"DockItem must be used within a <Dock>.\");\n  }\n  return ctx;\n}\n\nexport type DockProps = React.HTMLAttributes<HTMLDivElement> & {\n  /** Resting size of each item in pixels. */\n  baseSize?: number;\n  /** Maximum magnified size in pixels at the pointer. */\n  magnification?: number;\n  /** Pointer distance in pixels over which items are affected. */\n  distance?: number;\n};\n\nexport type DockItemProps = React.HTMLAttributes<HTMLDivElement> & {\n  /** Label shown above the item on hover. */\n  label?: React.ReactNode;\n};\n\nconst PANEL_BASE =\n  \"mx-auto flex h-16 items-end gap-3 rounded-2xl border border-border bg-card/70 px-3 pb-3 shadow-lg backdrop-blur-md\";\n\nconst ITEM_BASE =\n  \"group relative flex aspect-square items-center justify-center rounded-xl bg-muted text-foreground shadow-sm\";\n\nconst Dock = React.forwardRef<HTMLDivElement, DockProps>(\n  (\n    {\n      baseSize = 44,\n      magnification = 72,\n      distance = 140,\n      className,\n      children,\n      onMouseMove,\n      onMouseLeave,\n      ...props\n    },\n    ref,\n  ) => {\n    const mouseX = useMotionValue(Number.POSITIVE_INFINITY);\n\n    return (\n      <DockContext.Provider\n        value={{ mouseX, baseSize, magnification, distance }}\n      >\n        <div\n          ref={ref}\n          data-slot=\"dock\"\n          role=\"toolbar\"\n          aria-label=\"Dock\"\n          className={`${PANEL_BASE} ${className ?? \"\"}`}\n          onMouseMove={(e) => {\n            mouseX.set(e.clientX);\n            onMouseMove?.(e);\n          }}\n          onMouseLeave={(e) => {\n            mouseX.set(Number.POSITIVE_INFINITY);\n            onMouseLeave?.(e);\n          }}\n          {...props}\n        >\n          {children}\n        </div>\n      </DockContext.Provider>\n    );\n  },\n);\nDock.displayName = \"Dock\";\n\nconst DockItem = React.forwardRef<HTMLDivElement, DockItemProps>(\n  ({ label, className, children, ...props }, forwardedRef) => {\n    const { mouseX, baseSize, magnification, distance } = useDock();\n    const ref = React.useRef<HTMLDivElement>(null);\n    React.useImperativeHandle(\n      forwardedRef,\n      () => ref.current as HTMLDivElement,\n    );\n\n    const distanceFromMouse = useTransform(mouseX, (val) => {\n      const bounds = ref.current?.getBoundingClientRect();\n      if (!bounds) return distance + 1;\n      return val - bounds.x - bounds.width / 2;\n    });\n\n    const sizeTarget = useTransform(\n      distanceFromMouse,\n      [-distance, 0, distance],\n      [baseSize, magnification, baseSize],\n    );\n    const size = useSpring(sizeTarget, {\n      mass: 0.1,\n      stiffness: 170,\n      damping: 12,\n    });\n\n    return (\n      <motion.div\n        ref={ref}\n        data-slot=\"dock-item\"\n        style={{ width: size, height: size }}\n        className={`${ITEM_BASE} ${className ?? \"\"}`}\n        {...(props as React.ComponentProps<typeof motion.div>)}\n      >\n        <AnimatePresence>\n          {label ? (\n            <motion.span\n              initial={{ opacity: 0, y: 4 }}\n              animate={{ opacity: 1, y: 0 }}\n              exit={{ opacity: 0, y: 2 }}\n              className=\"pointer-events-none absolute -top-9 left-1/2 hidden -translate-x-1/2 whitespace-nowrap rounded-md bg-foreground px-2 py-1 text-xs font-medium text-background shadow group-hover:block\"\n            >\n              {label}\n            </motion.span>\n          ) : null}\n        </AnimatePresence>\n        {children}\n      </motion.div>\n    );\n  },\n);\nDockItem.displayName = \"DockItem\";\n\nexport { Dock, DockItem };\n",
      "type": "registry:ui",
      "target": "components/godui/dock.tsx"
    }
  ],
  "type": "registry:ui"
}
