{
	"$schema": "https://shadcn-svelte.com/schema/registry-item.json",
	"name": "dock",
	"title": "Dock",
	"type": "registry:block",
	"description": "A macOS-style dock component with smooth magnification animation on hover, inspired by the macOS dock.",
	"dependencies": [
		"motion-sv"
	],
	"files": [
		{
			"content": "<script lang=\"ts\" module>\n\timport type { MotionValue } from \"motion-sv\";\n\n\texport interface DockProps {\n\t\tclass?: string;\n\t\ticonSize?: number;\n\t\ticonMagnification?: number;\n\t\tdisableMagnification?: boolean;\n\t\ticonDistance?: number;\n\t\tdirection?: \"top\" | \"middle\" | \"bottom\";\n\t\tchildren: Snippet;\n\t}\n\n\texport interface DockContext {\n\t\tmouseX: MotionValue<number>;\n\t\ticonSize: number;\n\t\ticonMagnification: number;\n\t\tdisableMagnification: boolean;\n\t\ticonDistance: number;\n\t}\n</script>\n\n<script lang=\"ts\">\n\timport { motion, useMotionValue } from \"motion-sv\";\n\timport { cn } from \"$UTILS$\";\n\timport type { Snippet } from \"svelte\";\n\timport { setContext } from \"svelte\";\n\n\tconst DEFAULT_SIZE = 40;\n\tconst DEFAULT_MAGNIFICATION = 60;\n\tconst DEFAULT_DISTANCE = 140;\n\n\tlet {\n\t\tclass: className,\n\t\tchildren,\n\t\ticonSize = DEFAULT_SIZE,\n\t\ticonMagnification = DEFAULT_MAGNIFICATION,\n\t\tdisableMagnification = false,\n\t\ticonDistance = DEFAULT_DISTANCE,\n\t\tdirection = \"middle\",\n\t}: DockProps = $props();\n\n\t// Use MotionValue for mouseX - this enables smooth reactive transforms\n\tconst mouseX = useMotionValue(Infinity);\n\n\t// Provide context to child DockIcon components\n\tsetContext(\"dock\", {\n\t\tmouseX,\n\t\tget iconSize() {\n\t\t\treturn iconSize;\n\t\t},\n\t\tget iconMagnification() {\n\t\t\treturn iconMagnification;\n\t\t},\n\t\tget disableMagnification() {\n\t\t\treturn disableMagnification;\n\t\t},\n\t\tget iconDistance() {\n\t\t\treturn iconDistance;\n\t\t},\n\t});\n</script>\n\n<motion.div\n\tonmousemove={(e) => mouseX.set(e.pageX)}\n\tonmouseleave={() => mouseX.set(Infinity)}\n\tclass={cn(\n\t\t\"mx-auto mt-8 flex h-14 w-max items-center justify-center gap-2 rounded-2xl border p-2 backdrop-blur-md supports-backdrop-blur:bg-white/10 supports-backdrop-blur:dark:bg-black/10\",\n\t\t{\n\t\t\t\"items-start\": direction === \"top\",\n\t\t\t\"items-center\": direction === \"middle\",\n\t\t\t\"items-end\": direction === \"bottom\",\n\t\t},\n\t\tclassName\n\t)}\n>\n\t{@render children()}\n</motion.div>\n",
			"type": "registry:component",
			"target": "magic/dock/dock.svelte"
		},
		{
			"content": "<script lang=\"ts\" module>\n\texport interface DockIconProps {\n\t\tclass?: string;\n\t\tchildren: Snippet;\n\t}\n</script>\n\n<script lang=\"ts\">\n\timport { motion, useMotionValue, useTransform, useSpring } from \"motion-sv\";\n\timport { cn } from \"$UTILS$\";\n\timport type { Snippet } from \"svelte\";\n\timport { getContext } from \"svelte\";\n\timport type { DockContext } from \"./dock.svelte\";\n\n\tlet { class: className, children }: DockIconProps = $props();\n\n\tconst DEFAULT_SIZE = 40;\n\tconst DEFAULT_MAGNIFICATION = 60;\n\tconst DEFAULT_DISTANCE = 140;\n\n\t// Get context from parent Dock component\n\tconst dockContext = getContext<DockContext>(\"dock\");\n\n\tlet ref: HTMLDivElement | null = $state(null);\n\n\t// Fallback motion value if no context\n\tconst defaultMouseX = useMotionValue(Infinity);\n\tconst mouseX = dockContext?.mouseX ?? defaultMouseX;\n\n\tconst size = $derived(dockContext?.iconSize ?? DEFAULT_SIZE);\n\tconst magnification = $derived(dockContext?.iconMagnification ?? DEFAULT_MAGNIFICATION);\n\tconst disableMagnification = $derived(dockContext?.disableMagnification ?? false);\n\tconst distance = $derived(dockContext?.iconDistance ?? DEFAULT_DISTANCE);\n\tconst padding = $derived(Math.max(6, size * 0.2));\n\n\t// Transform mouseX to distance from this icon's center\n\tconst distanceCalc = useTransform(mouseX, (val: number) => {\n\t\tconst bounds = ref?.getBoundingClientRect() ?? { x: 0, width: 0 };\n\t\treturn val - bounds.x - bounds.width / 2;\n\t});\n\n\t// Transform distance to size - magnify when mouse is close\n\tconst sizeTransform = useTransform(distanceCalc, (dist: number) => {\n\t\tconst targetSize = disableMagnification ? size : magnification;\n\t\t// Clamp distance to range and interpolate\n\t\tif (Math.abs(dist) >= distance) return size;\n\t\t// Linear interpolation based on distance\n\t\tconst progress = 1 - Math.abs(dist) / distance;\n\t\treturn size + (targetSize - size) * progress;\n\t});\n\n\t// Apply spring physics for smooth animation\n\tconst scaleSize = useSpring(sizeTransform, {\n\t\tmass: 0.1,\n\t\tstiffness: 150,\n\t\tdamping: 12,\n\t});\n</script>\n\n<motion.div\n\tbind:ref\n\tstyle={{ width: scaleSize, height: scaleSize, padding: `${padding}px` }}\n\tclass={cn(\n\t\t\"flex aspect-square cursor-pointer items-center justify-center rounded-full\",\n\t\tdisableMagnification && \"hover:bg-muted-foreground transition-colors\",\n\t\tclassName\n\t)}\n>\n\t<div>\n\t\t{@render children()}\n\t</div>\n</motion.div>\n",
			"type": "registry:component",
			"target": "magic/dock/dock-icon.svelte"
		},
		{
			"content": "export { default as Dock } from \"./dock.svelte\";\nexport { default as DockIcon } from \"./dock-icon.svelte\";\nexport type { DockProps, DockContext } from \"./dock.svelte\";\nexport type { DockIconProps } from \"./dock-icon.svelte\";\n",
			"type": "registry:file",
			"target": "magic/dock/index.ts"
		}
	]
}