{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "loader",
  "title": "Loader",
  "description": "Three loading animations: bouncing dots, equalizer bars and an orbit spinner.",
  "dependencies": [
    "motion"
  ],
  "registryDependencies": [
    "utils"
  ],
  "files": [
    {
      "path": "registry/new-york/loader/loader.tsx",
      "content": "\"use client\"\n\nimport { motion, useReducedMotion } from \"motion/react\"\nimport { cn } from \"@/lib/utils\"\n\nexport type LoaderVariant = \"dots\" | \"bars\" | \"orbit\"\n\nexport interface LoaderProps {\n  /** Animation style. Default: \"dots\" */\n  variant?: LoaderVariant\n  /** Overall size in px. Default: 40 */\n  size?: number\n  /** Color (any CSS color). Default: \"currentColor\" */\n  color?: string\n  /** Seconds per cycle. Lower = faster. Default: 1 */\n  speed?: number\n  /** Number of dots or bars. Default: 3 for dots, 5 for bars */\n  count?: number\n  /** Accessible label. Default: \"Loading\" */\n  label?: string\n  className?: string\n}\n\nexport function Loader({\n  variant = \"dots\",\n  size = 40,\n  color = \"currentColor\",\n  speed = 1,\n  count,\n  label = \"Loading\",\n  className,\n}: LoaderProps) {\n  const reduced = useReducedMotion()\n  const repeat = reduced ? 0 : Infinity\n  const n = count ?? (variant === \"bars\" ? 5 : 3)\n\n  return (\n    <span\n      role=\"status\"\n      aria-label={label}\n      className={cn(\"inline-flex items-center justify-center\", className)}\n      style={{ width: size, height: size, color }}\n    >\n      {variant === \"dots\" && (\n        <span className=\"flex items-center\" style={{ gap: size * 0.12 }}>\n          {Array.from({ length: n }, (_, i) => (\n            <motion.span\n              key={i}\n              className=\"rounded-full bg-current\"\n              style={{ width: size * 0.2, height: size * 0.2 }}\n              animate={{ y: [0, -size * 0.22, 0], opacity: [0.35, 1, 0.35] }}\n              transition={{ duration: speed, repeat, ease: \"easeInOut\", delay: (i / n) * speed * 0.5 }}\n            />\n          ))}\n        </span>\n      )}\n\n      {variant === \"bars\" && (\n        <span className=\"flex h-full items-center\" style={{ gap: size * 0.08 }}>\n          {Array.from({ length: n }, (_, i) => (\n            <motion.span\n              key={i}\n              className=\"rounded-full bg-current\"\n              style={{ width: size * 0.1, height: \"100%\", originY: 0.5 }}\n              animate={{ scaleY: [0.3, 1, 0.3], opacity: [0.5, 1, 0.5] }}\n              transition={{ duration: speed, repeat, ease: \"easeInOut\", delay: (i / n) * speed * 0.6 }}\n            />\n          ))}\n        </span>\n      )}\n\n      {variant === \"orbit\" && (\n        <span className=\"relative size-full\">\n          {/* track */}\n          <span className=\"absolute inset-0 rounded-full border-2 border-current opacity-15\" />\n          {/* sweeping arc */}\n          <motion.span\n            className=\"absolute inset-0 rounded-full border-2 border-transparent border-t-current\"\n            animate={{ rotate: 360 }}\n            transition={{ duration: speed, repeat, ease: \"linear\" }}\n          />\n          {/* two satellites orbiting in opposite directions */}\n          {[1, -1].map((dir) => (\n            <motion.span\n              key={dir}\n              className=\"absolute inset-[22%]\"\n              animate={{ rotate: dir * 360 }}\n              transition={{ duration: speed * 1.6, repeat, ease: \"easeInOut\" }}\n            >\n              <span\n                className=\"absolute left-1/2 top-0 -translate-x-1/2 -translate-y-1/2 rounded-full bg-current\"\n                style={{ width: size * 0.14, height: size * 0.14 }}\n              />\n            </motion.span>\n          ))}\n        </span>\n      )}\n    </span>\n  )\n}\n",
      "type": "registry:component"
    }
  ],
  "docs": "Docs, live playground and every prop: https://trytweenly.vercel.app/docs/components/loader",
  "type": "registry:component"
}