{
  "$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\nexport type ConfettiRef = {\n  fire: (options?: ConfettiOptions) => Promise<void> | void\n}\n\ntype Props = React.ComponentPropsWithRef<\"canvas\"> & {\n  options?: ConfettiOptions\n  globalOptions?: ConfettiGlobalOptions\n  manualstart?: boolean\n  children?: ReactNode\n}\n\nconst ConfettiContext = createContext<ConfettiRef | null>(null)\n\nconst ConfettiComponent = forwardRef<ConfettiRef, Props>((props, ref) => {\n  const {\n    options,\n    globalOptions = { resize: true, useWorker: true },\n    manualstart = false,\n    children,\n    className,\n    ...rest\n  } = props\n\n  const canvasNodeRef = useRef<HTMLCanvasElement | null>(null)\n  const instanceRef = useRef<ConfettiInstance | null>(null)\n  const optionsRef = useRef(options)\n  const globalOptionsRef = useRef(globalOptions)\n\n  useEffect(() => {\n    optionsRef.current = options\n  }, [options])\n\n  useEffect(() => {\n    globalOptionsRef.current = globalOptions\n  }, [globalOptions])\n\n  useEffect(() => {\n    if (canvasNodeRef.current && !instanceRef.current) {\n      instanceRef.current = confetti.create(canvasNodeRef.current, {\n        resize: true,\n        useWorker: true,\n        ...globalOptionsRef.current,\n      })\n    }\n\n    return () => {\n      instanceRef.current?.reset()\n      instanceRef.current = null\n    }\n  }, [])\n\n  const fire = useCallback(async (opts: ConfettiOptions = {}) => {\n    try {\n      await instanceRef.current?.({\n        ...optionsRef.current,\n        ...opts,\n      })\n    } catch (error) {\n      console.error(\"Confetti error:\", error)\n    }\n  }, [])\n\n  const api = useMemo<ConfettiRef>(() => ({ fire }), [fire])\n\n  useImperativeHandle(ref, () => api, [api])\n\n  useEffect(() => {\n    if (!manualstart) {\n      void fire()\n    }\n  }, [manualstart, fire])\n\n  return (\n    <ConfettiContext.Provider value={api}>\n      <canvas ref={canvasNodeRef} className={className} {...rest} />\n      {children}\n    </ConfettiContext.Provider>\n  )\n})\n\nConfettiComponent.displayName = \"Confetti\"\n\nexport const Confetti = ConfettiComponent\n\nexport interface ConfettiButtonProps extends React.ComponentPropsWithoutRef<\n  typeof Button\n> {\n  options?: ConfettiOptions &\n    ConfettiGlobalOptions & { canvas?: HTMLCanvasElement }\n}\n\nexport const ConfettiButton = forwardRef<\n  HTMLButtonElement,\n  ConfettiButtonProps\n>(({ options, children, onClick, ...props }, ref) => {\n  const handleClick: ConfettiButtonProps[\"onClick\"] = async (event) => {\n    try {\n      onClick?.(event)\n      if (event?.defaultPrevented) return\n\n      const target = event?.currentTarget\n      if (target && \"getBoundingClientRect\" in target) {\n        const rect = target.getBoundingClientRect()\n        const origin = {\n          x: (rect.left + rect.width / 2) / window.innerWidth,\n          y: (rect.top + rect.height / 2) / window.innerHeight,\n        }\n\n        await confetti({\n          zIndex: 9999,\n          ...options,\n          origin,\n        })\n      }\n    } catch (error) {\n      console.error(\"Confetti button error:\", error)\n    }\n  }\n\n  return (\n    <Button ref={ref} type=\"button\" onClick={handleClick} {...props}>\n      {children}\n    </Button>\n  )\n})\n\nConfettiButton.displayName = \"ConfettiButton\"\n",
      "type": "registry:ui"
    }
  ]
}