{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "burst",
  "title": "Burst",
  "description": "Confetti that sprays from any button on click.",
  "dependencies": [
    "radix-ui"
  ],
  "registryDependencies": [
    "utils",
    "https://ui.cuelark.com/r/theme.json",
    "https://ui.cuelark.com/r/motion.json"
  ],
  "files": [
    {
      "path": "src/registry/cuelark/ui/burst.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\nimport { Slot } from \"radix-ui\";\n\nimport { gsap, motionScale } from \"@/lib/motion\";\n\ntype BurstProps = {\n  children: React.ReactElement;\n  /** Number of particles. */\n  count?: number;\n  /** Particle colors; defaults to signal and ink. */\n  colors?: string[];\n  /** Fire on every click (default) or only when `fire` is called through `ref`-less usage. */\n  disabled?: boolean;\n};\n\n/**\n * Wrap any button: each click throws a small spray of confetti from the click point that arcs, spins and falls\n * (GSAP physics-style timeline). For moments worth celebrating: completed onboarding, a first deploy, a like.\n */\nfunction Burst({ children, count = 18, colors = [\"var(--signal)\", \"var(--foreground)\", \"var(--muted-foreground)\"], disabled }: BurstProps) {\n  const fire = (e: React.MouseEvent<HTMLElement>) => {\n    if (disabled) return;\n    const scale = motionScale(e.currentTarget);\n    if (!scale) return;\n    const r = e.currentTarget.getBoundingClientRect();\n    const x = e.clientX || r.left + r.width / 2;\n    const y = e.clientY || r.top + r.height / 2;\n    for (let i = 0; i < count; i++) {\n      const p = document.createElement(\"span\");\n      const size = 4 + Math.random() * 5;\n      Object.assign(p.style, {\n        position: \"fixed\",\n        left: `${x}px`,\n        top: `${y}px`,\n        width: `${size}px`,\n        height: `${size * (Math.random() > 0.5 ? 1 : 0.45)}px`,\n        background: colors[i % colors.length]!,\n        borderRadius: Math.random() > 0.6 ? \"999px\" : \"1px\",\n        pointerEvents: \"none\",\n        zIndex: \"100\",\n      });\n      document.body.appendChild(p);\n      const angle = -Math.PI / 2 + (Math.random() - 0.5) * Math.PI * 1.1;\n      const v = (70 + Math.random() * 110) * Math.min(scale, 1.5);\n      gsap\n        .timeline({ onComplete: () => p.remove() })\n        .to(p, { x: Math.cos(angle) * v, y: Math.sin(angle) * v, rotate: (Math.random() - 0.5) * 540, duration: 0.5, ease: \"power3.out\" })\n        .to(p, { y: `+=${120 + Math.random() * 80}`, x: `+=${(Math.random() - 0.5) * 60}`, opacity: 0, rotate: \"+=180\", duration: 0.9, ease: \"power1.in\" });\n    }\n  };\n\n  return (\n    <Slot.Root\n      data-slot=\"burst\"\n      onClick={(e: React.MouseEvent<HTMLElement>) => {\n        (children.props as { onClick?: (e: React.MouseEvent<HTMLElement>) => void }).onClick?.(e);\n        fire(e);\n      }}\n    >\n      {children}\n    </Slot.Root>\n  );\n}\n\nexport { Burst };\nexport type { BurstProps };\n",
      "type": "registry:ui"
    }
  ],
  "docs": "Docs and examples: https://ui.cuelark.com/components/burst",
  "categories": [
    "effects"
  ],
  "type": "registry:ui"
}