{
  "name": "infinity-loop-default",
  "type": "registry:ui",
  "tier": "free",
  "dependencies": [
    "framer-motion"
  ],
  "registryDependencies": [
    "https://www.craftui.space/r/craftui-base.json"
  ],
  "files": [
    {
      "path": "components/craftui/loaders/infinity-loop/default.tsx",
      "content": "'use client';\n\nimport { motion } from 'motion/react';\n\ninterface InfinityLoopProps {\n  width?: number;\n  height?: number;\n  color?: string;\n  pathColor?: string;\n  dotSize?: number;\n  showPath?: boolean;\n  isAnimating?: boolean;\n  duration?: number;\n  ease?: any;\n  strokeWidth?: number;\n  strokeLinecap?: 'round' | 'butt' | 'square';\n}\n\nexport function InfinityLoop({\n  width = 80,\n  height = 40,\n  color = \"currentColor\",\n  pathColor = \"#cccccc\",\n  dotSize = 6,\n  showPath = true,\n  isAnimating = true,\n  duration = 2.5,\n  ease = 'linear',\n  strokeWidth = 2,\n  strokeLinecap = 'round',\n}: InfinityLoopProps) {\n  const cx = width / 2;\n  const cy = height / 2;\n  const r = height * 0.35;\n  const dotR = dotSize / 2;\n\n  // Infinity path (lemniscate approximated with bezier curves)\n  const infinityPath = [\n    `M ${cx},${cy}`,\n    `C ${cx + r * 0.5},${cy - r * 1.2} ${cx + r * 2},${cy - r * 1.2} ${cx + r * 2},${cy}`,\n    `C ${cx + r * 2},${cy + r * 1.2} ${cx + r * 0.5},${cy + r * 1.2} ${cx},${cy}`,\n    `C ${cx - r * 0.5},${cy - r * 1.2} ${cx - r * 2},${cy - r * 1.2} ${cx - r * 2},${cy}`,\n    `C ${cx - r * 2},${cy + r * 1.2} ${cx - r * 0.5},${cy + r * 1.2} ${cx},${cy}`,\n  ].join(' ');\n\n  // Sample ~40 points along the infinity path using parametric lemniscate\n  const steps = 60;\n  const xKeyframes: number[] = [];\n  const yKeyframes: number[] = [];\n\n  for (let i = 0; i <= steps; i++) {\n    const t = (2 * Math.PI * i) / steps;\n    const scale = r * 1.8;\n    const denom = 1 + Math.sin(t) * Math.sin(t);\n    const px = cx + (scale * Math.cos(t)) / denom;\n    const py = cy + (scale * Math.sin(t) * Math.cos(t)) / denom;\n    xKeyframes.push(px);\n    yKeyframes.push(py);\n  }\n\n  return (\n    <svg\n      width={width}\n      height={height}\n      viewBox={`0 0 ${width} ${height}`}\n      fill=\"none\"\n      xmlns=\"http://www.w3.org/2000/svg\"\n      aria-label=\"Loading\"\n      role=\"img\"\n    >\n      {showPath && (\n        <path\n          d={infinityPath}\n          stroke={pathColor}\n          strokeWidth={strokeWidth}\n          fill=\"none\"\n          strokeLinecap={strokeLinecap}\n        />\n      )}\n      <motion.circle\n        r={dotR}\n        fill={color}\n        initial={{ cx: xKeyframes[0], cy: yKeyframes[0] }}\n        animate={{\n          cx: xKeyframes,\n          cy: yKeyframes,\n        }}\n        transition={{\n          duration: duration,\n          repeat: isAnimating ? Infinity : 0,\n          ease: ease,\n        }}\n      />\n    </svg>\n  );\n}\n",
      "type": "registry:ui",
      "target": "~/components/craftui/loaders/infinity-loop/default.tsx"
    }
  ],
  "meta": {
    "displayName": "Infinity Loop - Infinity Loop",
    "description": "A dot traces the mathematical lemniscate (infinity symbol) path smoothly and continuously",
    "category": "loaders",
    "tags": [
      "infinity",
      "loop",
      "smooth",
      "continuous",
      "path",
      "minimal",
      "symbol",
      "elegant"
    ],
    "animationType": "loop"
  }
}