{
	"$schema": "https://ui.shadcn.com/schema/registry-item.json",
	"name": "MagnetLines-TS-TW",
	"title": "MagnetLines",
	"description": "Animated field lines bend toward the cursor.",
	"type": "registry:component",
	"files": [
		{
			"type": "registry:component",
			"path": "MagnetLines/MagnetLines.tsx",
			"content": "import React, { useRef, useEffect, type CSSProperties } from 'react';\n\ninterface MagnetLinesProps {\n  rows?: number;\n  columns?: number;\n  containerSize?: string;\n  lineColor?: string;\n  lineWidth?: string;\n  lineHeight?: string;\n  baseAngle?: number;\n  className?: string;\n  style?: CSSProperties;\n}\n\nconst MagnetLines: React.FC<MagnetLinesProps> = ({\n  rows = 9,\n  columns = 9,\n  containerSize = '80vmin',\n  lineColor = '#efefef',\n  lineWidth = '1vmin',\n  lineHeight = '6vmin',\n  baseAngle = -10,\n  className = '',\n  style = {}\n}) => {\n  const containerRef = useRef<HTMLDivElement | null>(null);\n\n  useEffect(() => {\n    const container = containerRef.current;\n    if (!container) return;\n\n    const items = container.querySelectorAll<HTMLSpanElement>('span');\n\n    const onPointerMove = (pointer: { x: number; y: number }) => {\n      items.forEach(item => {\n        const rect = item.getBoundingClientRect();\n        const centerX = rect.x + rect.width / 2;\n        const centerY = rect.y + rect.height / 2;\n\n        const b = pointer.x - centerX;\n        const a = pointer.y - centerY;\n        const c = Math.sqrt(a * a + b * b) || 1;\n        const r = ((Math.acos(b / c) * 180) / Math.PI) * (pointer.y > centerY ? 1 : -1);\n\n        item.style.setProperty('--rotate', `${r}deg`);\n      });\n    };\n\n    const handlePointerMove = (e: PointerEvent) => {\n      onPointerMove({ x: e.x, y: e.y });\n    };\n\n    window.addEventListener('pointermove', handlePointerMove);\n\n    if (items.length) {\n      const middleIndex = Math.floor(items.length / 2);\n      const rect = items[middleIndex].getBoundingClientRect();\n      onPointerMove({ x: rect.x, y: rect.y });\n    }\n\n    return () => {\n      window.removeEventListener('pointermove', handlePointerMove);\n    };\n  }, [rows, columns]);\n\n  const total = rows * columns;\n  const spans = Array.from({ length: total }, (_, i) => (\n    <span\n      key={i}\n      className=\"block origin-center\"\n      style={{\n        backgroundColor: lineColor,\n        width: lineWidth,\n        height: lineHeight,\n        //@ts-ignore\n        '--rotate': `${baseAngle}deg`,\n        transform: 'rotate(var(--rotate))',\n        willChange: 'transform'\n      }}\n    />\n  ));\n\n  return (\n    <div\n      ref={containerRef}\n      className={`grid place-items-center ${className}`}\n      style={{\n        gridTemplateColumns: `repeat(${columns}, 1fr)`,\n        gridTemplateRows: `repeat(${rows}, 1fr)`,\n        width: containerSize,\n        height: containerSize,\n        ...style\n      }}\n    >\n      {spans}\n    </div>\n  );\n};\n\nexport default MagnetLines;\n"
		}
	],
	"registryDependencies": [],
	"dependencies": []
}