{
  "name": "dots-compress-default",
  "type": "registry:ui",
  "tier": "free",
  "dependencies": [
    "framer-motion"
  ],
  "registryDependencies": [
    "https://www.craftui.space/r/craftui-base.json"
  ],
  "files": [
    {
      "path": "components/craftui/loaders/dots-compress/default.tsx",
      "content": "'use client';\n\nimport { motion } from 'motion/react';\n\ninterface DotsCompressProps {\n  width?: number;\n  color?: string;\n  dotSize?: number;\n  isAnimating?: boolean;\n  duration?: number;\n  ease?: any;\n}\n\nexport function DotsCompress({ \n  width = 60,\n  color = \"currentColor\",\n  dotSize = 12,\n  isAnimating = true,\n  duration = 1.0,\n  ease = [0.455, 0.03, 0.515, 0.955],\n}: DotsCompressProps) {\n\n  // Start state: horizontal layout (aspect 4:1)\n  const startHeight = width / 4;\n  const endWidth = 25;\n  const endHeight = 25; // aspect 1:1\n\n  // Dot positions\n  const dots = [\n    { \n      id: 0, \n      startX: 6, \n      startY: startHeight / 2,\n      endX: endWidth / 2,\n      endY: dotSize / 2 + 1\n    },\n    { \n      id: 1, \n      startX: width / 2, \n      startY: startHeight / 2,\n      endX: endWidth / 2,\n      endY: endHeight / 2\n    },\n    { \n      id: 2, \n      startX: width - 6, \n      startY: startHeight / 2,\n      endX: endWidth / 2,\n      endY: endHeight - dotSize / 2 - 1\n    }\n  ];\n\n  return (\n    <motion.svg\n      fill=\"none\"\n      xmlns=\"http://www.w3.org/2000/svg\"\n      initial={{ width, height: startHeight }}\n      animate={{\n        width: [width, endWidth],\n        height: [startHeight, endHeight]\n      }}\n      transition={{\n        duration: duration,\n        repeat: isAnimating ? Infinity : 0,\n        repeatType: \"reverse\",\n        ease: ease\n      }}\n    >\n      <motion.g\n        initial={{ viewBox: `0 0 ${width} ${startHeight}` }}\n        animate={{\n          viewBox: [`0 0 ${width} ${startHeight}`, `0 0 ${endWidth} ${endHeight}`]\n        }}\n        transition={{\n          duration: duration,\n          repeat: isAnimating ? Infinity : 0,\n          repeatType: \"reverse\",\n          ease: ease\n        }}\n      >\n        {dots.map((dot) => (\n          <motion.circle\n            key={dot.id}\n            r={dotSize / 2}\n            fill={color}\n            initial={{ cx: dot.startX, cy: dot.startY }}\n            animate={{\n              cx: [dot.startX, dot.endX],\n              cy: [dot.startY, dot.endY]\n            }}\n            transition={{\n              duration: duration,\n              repeat: isAnimating ? Infinity : 0,\n              repeatType: \"reverse\",\n              ease: ease\n            }}\n          />\n        ))}\n      </motion.g>\n    </motion.svg>\n  );\n}",
      "type": "registry:ui",
      "target": "~/components/craftui/loaders/dots-compress/default.tsx"
    }
  ],
  "meta": {
    "displayName": "Dots Compress - Dots Compress",
    "description": "Three dots alternating between horizontal spread and vertical stack with container morphing",
    "category": "loaders",
    "tags": [
      "dots",
      "loading",
      "compress",
      "squeeze",
      "morph"
    ],
    "animationType": "loop"
  }
}