{
	"$schema": "https://ui.shadcn.com/schema/registry-item.json",
	"name": "Dock-JS-TW",
	"title": "Dock",
	"description": "macOS style magnifying dock with proximity scaling of icons.",
	"type": "registry:component",
	"files": [
		{
			"type": "registry:component",
			"path": "Dock/Dock.jsx",
			"content": "'use client';\n\nimport { motion, useMotionValue, useSpring, useTransform, AnimatePresence } from 'motion/react';\nimport { Children, cloneElement, useEffect, useMemo, useRef, useState } from 'react';\n\nfunction DockItem({ children, className = '', onClick, mouseX, spring, distance, magnification, baseItemSize, label }) {\n  const ref = useRef(null);\n  const isHovered = useMotionValue(0);\n\n  const mouseDistance = useTransform(mouseX, val => {\n    const rect = ref.current?.getBoundingClientRect() ?? {\n      x: 0,\n      width: baseItemSize\n    };\n    return val - rect.x - baseItemSize / 2;\n  });\n\n  const targetSize = useTransform(mouseDistance, [-distance, 0, distance], [baseItemSize, magnification, baseItemSize]);\n  const size = useSpring(targetSize, spring);\n\n  const handleKeyDown = e => {\n    if (e.key === 'Enter' || e.key === ' ') {\n      e.preventDefault();\n      onClick?.();\n    }\n  };\n\n  return (\n    <motion.div\n      ref={ref}\n      style={{\n        width: size,\n        height: size\n      }}\n      onHoverStart={() => isHovered.set(1)}\n      onHoverEnd={() => isHovered.set(0)}\n      onFocus={() => isHovered.set(1)}\n      onBlur={() => isHovered.set(0)}\n      onClick={onClick}\n      onKeyDown={handleKeyDown}\n      className={`relative inline-flex items-center justify-center rounded-full bg-[#120F17] border-neutral-700 border-2 shadow-md ${className}`}\n      tabIndex={0}\n      role=\"button\"\n      aria-haspopup=\"true\"\n      aria-label={label}\n    >\n      {Children.map(children, child => cloneElement(child, { isHovered }))}\n    </motion.div>\n  );\n}\n\nfunction DockLabel({ children, className = '', ...rest }) {\n  const { isHovered } = rest;\n  const [isVisible, setIsVisible] = useState(false);\n\n  useEffect(() => {\n    const unsubscribe = isHovered.on('change', latest => {\n      setIsVisible(latest === 1);\n    });\n    return () => unsubscribe();\n  }, [isHovered]);\n\n  return (\n    <AnimatePresence>\n      {isVisible && (\n        <motion.div\n          initial={{ opacity: 0, y: 0 }}\n          animate={{ opacity: 1, y: -10 }}\n          exit={{ opacity: 0, y: 0 }}\n          transition={{ duration: 0.2 }}\n          className={`${className} absolute -top-6 left-1/2 w-fit whitespace-pre rounded-md border border-neutral-700 bg-[#120F17] px-2 py-0.5 text-xs text-white`}\n          role=\"tooltip\"\n          style={{ x: '-50%' }}\n        >\n          {children}\n        </motion.div>\n      )}\n    </AnimatePresence>\n  );\n}\n\nfunction DockIcon({ children, className = '' }) {\n  return <div className={`flex items-center justify-center ${className}`}>{children}</div>;\n}\n\nexport default function Dock({\n  items,\n  className = '',\n  spring = { mass: 0.1, stiffness: 150, damping: 12 },\n  magnification = 70,\n  distance = 200,\n  panelHeight = 64,\n  dockHeight = 256,\n  baseItemSize = 50\n}) {\n  const mouseX = useMotionValue(Infinity);\n  const isHovered = useMotionValue(0);\n\n  const maxHeight = useMemo(\n    () => Math.max(dockHeight, magnification + magnification / 2 + 4),\n    [magnification, dockHeight]\n  );\n  const heightRow = useTransform(isHovered, [0, 1], [panelHeight, maxHeight]);\n  const height = useSpring(heightRow, spring);\n\n  return (\n    <motion.div style={{ height, scrollbarWidth: 'none' }} className=\"mx-2 flex max-w-full items-center\">\n      <motion.div\n        onMouseMove={({ pageX }) => {\n          isHovered.set(1);\n          mouseX.set(pageX);\n        }}\n        onMouseLeave={() => {\n          isHovered.set(0);\n          mouseX.set(Infinity);\n        }}\n        className={`${className} absolute bottom-2 left-1/2 transform -translate-x-1/2 flex items-end w-fit gap-4 rounded-2xl border-neutral-700 border-2 pb-2 px-4`}\n        style={{ height: panelHeight }}\n        role=\"toolbar\"\n        aria-label=\"Application dock\"\n      >\n        {items.map((item, index) => (\n          <DockItem\n            key={index}\n            onClick={item.onClick}\n            className={item.className}\n            mouseX={mouseX}\n            spring={spring}\n            distance={distance}\n            magnification={magnification}\n            baseItemSize={baseItemSize}\n            label={item.label}\n          >\n            <DockIcon>{item.icon}</DockIcon>\n            <DockLabel>{item.label}</DockLabel>\n          </DockItem>\n        ))}\n      </motion.div>\n    </motion.div>\n  );\n}\n"
		}
	],
	"registryDependencies": [],
	"dependencies": [
		"motion@^12.23.12"
	]
}