{"version":3,"sources":["../../src/react/index.tsx"],"names":[],"mappings":";;;;AAmCO,SAAS,WAAA,CAAY,OAAA,GAA8B,EAAC,EAAG;AAC5D,EAAA,MAAM;AAAA,IACJ,OAAA,GAAU,IAAA;AAAA,IACV,MAAA,GAAS,WAAA;AAAA,IACT,MAAA;AAAA,IACA,aAAA;AAAA,IACA,YAAA;AAAA,IACA,OAAA;AAAA,IACA,OAAA;AAAA,IACA;AAAA,GACF,GAAI,OAAA;AACJ,EAAA,MAAM,SAAA,GAAY,OAA8B,IAAI,CAAA;AAGpD,EAAA,MAAM,cAAA,GAAiB,OAAA,CAAQ,MAAM,MAAA,EAAQ,CAAC,MAAA,GAAS,IAAA,CAAK,SAAA,CAAU,MAAM,CAAA,GAAI,MAAS,CAAC,CAAA;AAE1F,EAAA,SAAA,CAAU,MAAM;AAEd,IAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACnC,IAAA,IAAI,CAAC,OAAA,EAAS;AAGd,IAAA,MAAM,oBAAA,GAAuB,MAAA,CAAO,UAAA,CAAW,kCAAkC,CAAA,CAAE,OAAA;AACnF,IAAA,IAAI,oBAAA,EAAsB;AAG1B,IAAA,MAAM,MAAA,GAAS,IAAI,cAAA,EAAe;AAGlC,IAAA,MAAM,aAAA,GAAgB;AAAA,MACpB,GAAI,cAAA,IAAkB,EAAE,MAAA,EAAQ,cAAA,EAAe;AAAA,MAC/C,GAAI,aAAA,KAAkB,MAAA,IAAa,EAAE,aAAA,EAAc;AAAA,MACnD,GAAI,YAAA,KAAiB,MAAA,IAAa,EAAE,YAAA,EAAa;AAAA,MACjD,GAAI,OAAA,KAAY,MAAA,IAAa,EAAE,OAAA,EAAQ;AAAA,MACvC,GAAI,OAAA,KAAY,MAAA,IAAa,EAAE,OAAA,EAAQ;AAAA,MACvC,GAAI,QAAA,KAAa,MAAA,IAAa,EAAE,QAAA;AAAS,KAC3C;AAGA,IAAA,MAAM,cAAA,GACJ,MAAA,KAAW,UAAA,GACP,oBAAA,CAAqB,aAAa,CAAA,GAClC,MAAA,KAAW,SAAA,GACX,mBAAA,CAAoB,aAAa,CAAA,GACjC,MAAA,KAAW,UAAA,GACX,oBAAA,CAAqB,aAAa,CAAA,GAClC,MAAA,KAAW,MAAA,GACX,gBAAA,CAAiB,aAAa,CAAA,GAC9B,MAAA,KAAW,QAAA,GACX,kBAAA,CAAmB,aAAa,CAAA,GAChC,qBAAA,CAAsB,aAAa,CAAA;AAGzC,IAAA,MAAA,CAAO,MAAM,cAAc,CAAA;AAC3B,IAAA,SAAA,CAAU,OAAA,GAAU,MAAA;AAGpB,IAAA,OAAO,MAAM;AACX,MAAA,MAAA,CAAO,OAAA,EAAQ;AACf,MAAA,SAAA,CAAU,OAAA,GAAU,IAAA;AAAA,IACtB,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,OAAA,EAAS,MAAA,EAAQ,cAAA,EAAgB,eAAe,YAAA,EAAc,OAAA,EAAS,OAAA,EAAS,QAAQ,CAAC,CAAA;AAE7F,EAAA,OAAO,SAAA,CAAU,OAAA;AACnB;AAuBO,SAAS,SAAS,KAAA,EAA2B;AAClD,EAAA,WAAA,CAAY,KAAK,CAAA;AACjB,EAAA,OAAO,IAAA;AACT","file":"index.mjs","sourcesContent":["import { useEffect, useRef, useMemo } from 'react';\nimport { CursorFXEngine, createFairyDustEffect, createSparkleEffect, createConfettiEffect, createRetroCRTEffect, createSnowEffect, createBubbleEffect, ImageLoader } from '../core';\n\nexport type CursorEffectType = 'fairyDust' | 'sparkle' | 'confetti' | 'retroCRT' | 'snow' | 'bubble';\n\nexport interface UseCursorFXOptions {\n  effect?: CursorEffectType;\n  colors?: string[];\n  particleCount?: number;\n  particleSize?: number;\n  gravity?: number;\n  maxLife?: number;\n  velocity?: number;\n  enabled?: boolean;\n}\n\n/**\n * React hook for cursor effects.\n * Returns a ref to attach to your canvas element.\n *\n * @param options - Configuration options for the effect\n * @returns Canvas ref to attach to <canvas> element\n *\n * @example\n * ```tsx\n * function App() {\n *   useCursorFX({\n *     colors: ['#FFD700', '#FF69B4'],\n *     particleCount: 5\n *   });\n *\n *   return <div>Your content</div>;\n * }\n * ```\n */\nexport function useCursorFX(options: UseCursorFXOptions = {}) {\n  const {\n    enabled = true,\n    effect = 'fairyDust',\n    colors,\n    particleCount,\n    particleSize,\n    gravity,\n    maxLife,\n    velocity\n  } = options;\n  const engineRef = useRef<CursorFXEngine | null>(null);\n\n  // Memoize colors array to prevent unnecessary re-renders when passed inline\n  const memoizedColors = useMemo(() => colors, [colors ? JSON.stringify(colors) : undefined]);\n\n  useEffect(() => {\n    // SSR safety check\n    if (typeof window === 'undefined') return;\n    if (!enabled) return;\n\n    // Check for prefers-reduced-motion\n    const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n    if (prefersReducedMotion) return;\n\n    // Create engine (automatically creates canvas)\n    const engine = new CursorFXEngine();\n\n    // Build options object, only including user-provided values\n    const effectOptions = {\n      ...(memoizedColors && { colors: memoizedColors }),\n      ...(particleCount !== undefined && { particleCount }),\n      ...(particleSize !== undefined && { particleSize }),\n      ...(gravity !== undefined && { gravity }),\n      ...(maxLife !== undefined && { maxLife }),\n      ...(velocity !== undefined && { velocity }),\n    };\n\n    // Select effect based on type\n    const selectedEffect =\n      effect === 'confetti'\n        ? createConfettiEffect(effectOptions)\n        : effect === 'sparkle'\n        ? createSparkleEffect(effectOptions)\n        : effect === 'retroCRT'\n        ? createRetroCRTEffect(effectOptions)\n        : effect === 'snow'\n        ? createSnowEffect(effectOptions)\n        : effect === 'bubble'\n        ? createBubbleEffect(effectOptions)\n        : createFairyDustEffect(effectOptions);\n\n    // Start the effect\n    engine.start(selectedEffect);\n    engineRef.current = engine;\n\n    // Cleanup on unmount\n    return () => {\n      engine.destroy();\n      engineRef.current = null;\n    };\n  }, [enabled, effect, memoizedColors, particleCount, particleSize, gravity, maxLife, velocity]);\n\n  return engineRef.current;\n}\n\n/**\n * CursorFX component for React.\n * Simple wrapper over useCursorFX hook.\n *\n * @param props - Configuration options for the effect\n *\n * @example\n * ```tsx\n * function App() {\n *   return (\n *     <>\n *       <CursorFX\n *         colors={['#FFD700', '#FF69B4']}\n *         particleCount={5}\n *       />\n *       <YourContent />\n *     </>\n *   );\n * }\n * ```\n */\nexport function CursorFX(props: UseCursorFXOptions) {\n  useCursorFX(props);\n  return null;\n}\n\n// Export types for TypeScript users\nexport type { EffectOptions } from '../core/types';\n\n// Export ImageLoader for preloading bubble and snowflake images\nexport { ImageLoader };\n"]}