{
	"$schema": "https://shadcn-svelte.com/schema/registry-item.json",
	"name": "animated-grid-pattern",
	"title": "Animated Grid Pattern",
	"type": "registry:block",
	"description": "An animated grid pattern component that creates a dynamic background with moving squares that fade in and out.",
	"dependencies": [
		"motion-sv"
	],
	"files": [
		{
			"content": "<script lang=\"ts\">\n\timport { onMount } from \"svelte\";\n\timport { motion } from \"motion-sv\";\n\timport { cn } from \"$UTILS$\";\n\timport type { HTMLAttributes } from \"svelte/elements\";\n\n\tinterface AnimatedGridPatternProps extends HTMLAttributes<SVGElement> {\n\t\twidth?: number;\n\t\theight?: number;\n\t\tx?: number;\n\t\ty?: number;\n\t\tstrokeDasharray?: number;\n\t\tnumSquares?: number;\n\t\tmaxOpacity?: number;\n\t\tduration?: number;\n\t\trepeatDelay?: number;\n\t\tclass?: string;\n\t}\n\n\ttype Square = {\n\t\tid: number;\n\t\tpos: [number, number];\n\t\titeration: number;\n\t};\n\n\tlet {\n\t\twidth = 40,\n\t\theight = 40,\n\t\tx = -1,\n\t\ty = -1,\n\t\tstrokeDasharray = 0,\n\t\tnumSquares = 50,\n\t\tclass: className,\n\t\tmaxOpacity = 0.5,\n\t\tduration = 4,\n\t\trepeatDelay = 0.5,\n\t\t...props\n\t}: AnimatedGridPatternProps = $props();\n\n\tconst id = $props.id();\n\tlet containerRef: SVGSVGElement | null = $state(null);\n\tlet dimensions = $state({ width: 0, height: 0 });\n\tlet squares = $state<Array<Square>>([]);\n\n\tconst getPos = (): [number, number] => {\n\t\treturn [\n\t\t\tMath.floor((Math.random() * dimensions.width) / width),\n\t\t\tMath.floor((Math.random() * dimensions.height) / height),\n\t\t];\n\t};\n\n\tconst generateSquares = (count: number): Array<Square> => {\n\t\treturn Array.from({ length: count }, (_, i) => ({\n\t\t\tid: i,\n\t\t\tpos: getPos(),\n\t\t\titeration: 0,\n\t\t}));\n\t};\n\n\tconst updateSquarePosition = (squareId: number) => {\n\t\tconst current = squares[squareId];\n\t\tif (!current || current.id !== squareId) return;\n\n\t\tconst nextSquares = squares.slice();\n\t\tnextSquares[squareId] = {\n\t\t\t...current,\n\t\t\tpos: getPos(),\n\t\t\titeration: current.iteration + 1,\n\t\t};\n\n\t\tsquares = nextSquares;\n\t};\n\n\t$effect(() => {\n\t\tif (dimensions.width && dimensions.height) {\n\t\t\tsquares = generateSquares(numSquares);\n\t\t}\n\t});\n\n\tonMount(() => {\n\t\tconst element = containerRef;\n\t\tif (!element) return;\n\n\t\tconst resizeObserver = new ResizeObserver((entries) => {\n\t\t\tfor (const entry of entries) {\n\t\t\t\tconst nextWidth = entry.contentRect.width;\n\t\t\t\tconst nextHeight = entry.contentRect.height;\n\t\t\t\tif (dimensions.width !== nextWidth || dimensions.height !== nextHeight) {\n\t\t\t\t\tdimensions = { width: nextWidth, height: nextHeight };\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tresizeObserver.observe(element);\n\n\t\treturn () => {\n\t\t\tresizeObserver.disconnect();\n\t\t};\n\t});\n</script>\n\n<svg\n\tbind:this={containerRef}\n\taria-hidden=\"true\"\n\tclass={cn(\n\t\t\"pointer-events-none absolute inset-0 h-full w-full fill-gray-400/30 stroke-gray-400/30\",\n\t\tclassName\n\t)}\n\t{...props}\n>\n\t<defs>\n\t\t<pattern {id} {width} {height} patternUnits=\"userSpaceOnUse\" {x} {y}>\n\t\t\t<path d={`M.5 ${height}V.5H${width}`} fill=\"none\" stroke-dasharray={strokeDasharray} />\n\t\t</pattern>\n\t</defs>\n\t<rect width=\"100%\" height=\"100%\" fill={`url(#${id})`} />\n\t<svg {x} {y} class=\"overflow-visible\">\n\t\t{#each squares as { pos: [squareX, squareY], id: squareId, iteration }, index (squareId + \"-\" + iteration)}\n\t\t\t<motion.rect\n\t\t\t\tinitial={{ opacity: 0 }}\n\t\t\t\tanimate={{ opacity: maxOpacity }}\n\t\t\t\ttransition={{\n\t\t\t\t\tduration,\n\t\t\t\t\trepeat: 1,\n\t\t\t\t\tdelay: index * 0.1,\n\t\t\t\t\trepeatType: \"reverse\",\n\t\t\t\t\trepeatDelay,\n\t\t\t\t}}\n\t\t\t\tonAnimationComplete={() => updateSquarePosition(squareId)}\n\t\t\t\twidth={width - 1}\n\t\t\t\theight={height - 1}\n\t\t\t\tx={squareX * width + 1}\n\t\t\t\ty={squareY * height + 1}\n\t\t\t\tfill=\"currentColor\"\n\t\t\t\tstroke-width=\"0\"\n\t\t\t/>\n\t\t{/each}\n\t</svg>\n</svg>\n",
			"type": "registry:component",
			"target": "magic/animated-grid-pattern/animated-grid-pattern.svelte"
		},
		{
			"content": "import AnimatedGridPattern from \"./animated-grid-pattern.svelte\";\nexport { AnimatedGridPattern };\n",
			"type": "registry:file",
			"target": "magic/animated-grid-pattern/index.ts"
		}
	]
}