{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "confetti",
  "type": "registry:ui",
  "title": "Confetti",
  "description": "Confetti animations are best used to delight your users when something special happens",
  "dependencies": [
    "canvas-confetti",
    "@types/canvas-confetti"
  ],
  "registryDependencies": [
    "button"
  ],
  "files": [
    {
      "path": "registry/magicui/confetti.tsx",
      "content": "\"use client\"\n\nimport type { ReactNode } from \"react\"\nimport React, {\n  createContext,\n  forwardRef,\n  useCallback,\n  useEffect,\n  useImperativeHandle,\n  useMemo,\n  useRef,\n} from \"react\"\nimport type {\n  GlobalOptions as ConfettiGlobalOptions,\n  CreateTypes as ConfettiInstance,\n  Options as ConfettiOptions,\n} from \"canvas-confetti\"\nimport confetti from \"canvas-confetti\"\n\nimport { Button } from \"@/components/ui/button\"\n\ntype Api = {\n  fire: (options?: ConfettiOptions) => void\n}\ntype Props = React.ComponentPropsWithRef(\"canvas\") & {\n  options?: ConfettiOptions\n  globalOptions?: ConfettiGlobalOptions\n  manualstart?: boolean\n  children?: ReactNode\n}\n\nexport type ConfettiRef = Api | null\n\nconst ConfettiContext = createContext({} as Api)\n\n// Define component first\nconst ConfettiComponent = forwardRef((props, ref) => {\n  const {\n    options,\n    globalOptions = { resize: true, useWorker: true },\n    manualstart = false,\n    children,\n    ...rest\n  } = props\n  const instanceRef = useRef(null)\n\n  const canvasRef = useCallback(\n    (node: HTMLCanvasElement) => {\n      if (node !== null) {\n        if (instanceRef.current) return\n        instanceRef.current = confetti.create(node, {\n          ...globalOptions,\n          resize: true,\n        })\n      } else {\n        if (instanceRef.current) {\n          instanceRef.current.reset()\n          instanceRef.current = null\n        }\n      }\n    },\n    [globalOptions]\n  )\n\n  const fire = useCallback(\n    async (opts = {}) => {\n      try {\n        await instanceRef.current?.({ ...options, ...opts })\n      } catch (error) {\n        console.error(\"Confetti error:\", error)\n      }\n    },\n    [options]\n  )\n\n  const api = useMemo(\n    () => ({\n      fire,\n    }),\n    [fire]\n  )\n\n  useImperativeHandle(ref, () => api, [api])\n\n  useEffect(() => {\n    if (!manualstart) {\n      ;(async () => {\n        try {\n          await fire()\n        } catch (error) {\n          console.error(\"Confetti effect error:\", error)\n        }\n      })()\n    }\n  }, [manualstart, fire])\n\n  return (\n    \n      \n      {children}\n    \n  )\n})\n\n// Set display name immediately\nConfettiComponent.displayName = \"Confetti\"\n\n// Export as Confetti\nexport const Confetti = ConfettiComponent\n\ninterface ConfettiButtonProps extends React.ComponentProps(\"button\") {\n  options?: ConfettiOptions &\n    ConfettiGlobalOptions & { canvas?: HTMLCanvasElement }\n}\n\nconst ConfettiButtonComponent = ({\n  options,\n  children,\n  ...props\n}: ConfettiButtonProps) => {\n  const handleClick = async (event: React.MouseEvent) => {\n    try {\n      const rect = event.currentTarget.getBoundingClientRect()\n      const x = rect.left + rect.width / 2\n      const y = rect.top + rect.height / 2\n      await confetti({\n        ...options,\n        origin: {\n          x: x / window.innerWidth,\n          y: y / window.innerHeight,\n        },\n      })\n    } catch (error) {\n      console.error(\"Confetti button error:\", error)\n    }\n  }\n\n  return (\n    \n      {children}\n    \n  )\n}\n\nConfettiButtonComponent.displayName = \"ConfettiButton\"\n\nexport const ConfettiButton = ConfettiButtonComponent\n"
    }
  ]
}
