{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "reactive-background-grid-shadcnui", "type": "registry:ui", "title": "Reactive Background Grid", "description": "Background pattern that reacts to mouse movement and click ripples", "dependencies": [ "framer-motion", "react" ], "files": [ { "path": "@uitripled/react-shadcn/src/components/motion-core/reactive-background-grid.tsx", "content": "\"use client\";\n\nimport { AnimatePresence, motion } from \"framer-motion\";\nimport { MouseEvent, useState } from \"react\";\n\ntype ReactiveBackgroundGridProps = {\n dots?: boolean;\n density?: number;\n};\n\nexport function ReactiveBackgroundGrid({\n dots = true,\n density = 20,\n}: ReactiveBackgroundGridProps) {\n const [ripples, setRipples] = useState<\n Array<{ id: number; x: number; y: number }>\n >([]);\n const [hoveredDot, setHoveredDot] = useState<{ x: number; y: number } | null>(\n null\n );\n\n const handleClick = (e: MouseEvent) => {\n const rect = e.currentTarget.getBoundingClientRect();\n const x = e.clientX - rect.left;\n const y = e.clientY - rect.top;\n\n const newRipple = {\n id: Date.now(),\n x,\n y,\n };\n\n setRipples((prev) => [...prev, newRipple]);\n setTimeout(() => {\n setRipples((prev) => prev.filter((r) => r.id !== newRipple.id));\n }, 600);\n };\n\n const [containerSize, setContainerSize] = useState({\n width: 400,\n height: 400,\n });\n\n const handleMouseMove = (e: MouseEvent) => {\n const rect = e.currentTarget.getBoundingClientRect();\n const x = e.clientX - rect.left;\n const y = e.clientY - rect.top;\n setHoveredDot({ x, y });\n setContainerSize({ width: rect.width, height: rect.height });\n };\n\n const gridSize = density;\n const dotsArray = Array.from({ length: gridSize * gridSize });\n\n return (\n setHoveredDot(null)}\n className=\"relative h-96 w-full overflow-hidden rounded-2xl border border-border bg-card\"\n >\n \n\n {dots &&\n dotsArray.map((_, index) => {\n const row = Math.floor(index / gridSize);\n const col = index % gridSize;\n const x = (col / gridSize) * 100;\n const y = (row / gridSize) * 100;\n\n const distance = hoveredDot\n ? Math.sqrt(\n Math.pow(x - (hoveredDot.x / containerSize.width) * 100, 2) +\n Math.pow(y - (hoveredDot.y / containerSize.height) * 100, 2)\n )\n : Infinity;\n\n const scale = hoveredDot && distance < 30 ? 1.5 : 1;\n const opacity = hoveredDot && distance < 30 ? 0.6 : 0.2;\n\n return (\n \n );\n })}\n\n \n {ripples.map((ripple) => (\n \n ))}\n \n \n );\n}\n", "type": "registry:ui", "target": "components/uitripled/reactive-background-grid-shadcnui.tsx" } ] }