@varianta/sdk 0.1.5 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"react.cjs.js","sources":["../src/react/Customizer.tsx","../src/react/useCustomizer.ts"],"sourcesContent":["/**\n * React wrapper for Customizer Editor\n * @packageDocumentation\n */\n\nimport {\n useRef,\n useEffect,\n useImperativeHandle,\n forwardRef,\n type CSSProperties,\n} from 'react';\nimport { initCustomizer } from '../vanilla';\nimport type {\n CustomizerOptions,\n CustomizerInstance,\n DesignJSON,\n FinalizeResult,\n CustomizerError,\n} from '../types';\n\n/**\n * Props for the Customizer React component\n */\nexport interface CustomizerProps {\n /**\n * Template ID to load. Required unless productId is provided.\n */\n templateId?: string;\n\n /**\n * Product ID to load (fetches all views/templates for the product).\n * Alternative to templateId. Exactly one of templateId or productId must be provided.\n */\n productId?: string;\n\n /**\n * API base URL for fetching templates and finalizing designs\n * @default 'https://api.varianta.io'\n */\n apiUrl?: string;\n\n /**\n * Visual theme\n * @default 'light'\n */\n theme?: 'light' | 'dark';\n\n /**\n * Editor mode\n * @default 'edit'\n */\n mode?: 'edit' | 'preview';\n\n /**\n * Enable debug mode with additional logging\n * @default false\n */\n debug?: boolean;\n\n /**\n * Custom CSS class name\n */\n className?: string;\n\n /**\n * Custom inline styles\n */\n style?: CSSProperties;\n\n /**\n * Initial design data to load\n */\n initialDesign?: DesignJSON;\n\n /**\n * Called when the editor is ready\n */\n onReady?: () => void;\n\n /**\n * Called when the design changes\n */\n onChange?: (design: DesignJSON) => void;\n\n /**\n * Called when a layer is selected\n */\n onLayerSelect?: (layerId: string | null) => void;\n\n /**\n * Called when a layer is added\n */\n onLayerAdd?: (layerId: string) => void;\n\n /**\n * Called when a layer is removed\n */\n onLayerRemove?: (layerId: string) => void;\n\n /**\n * Called when a layer is updated\n */\n onLayerUpdate?: (layerId: string) => void;\n\n /**\n * Called when an error occurs\n */\n onError?: (error: CustomizerError) => void;\n\n /**\n * Called when finalization is complete\n */\n onFinalize?: (result: FinalizeResult) => void;\n\n /**\n * Called when the active view changes (only relevant when using productId)\n */\n onViewChange?: (viewName: string) => void;\n}\n\n/**\n * Handle type exposed via ref\n */\nexport interface CustomizerHandle extends CustomizerInstance {}\n\n/**\n * Customizer React Component\n *\n * @example\n * ```tsx\n * import { Customizer, CustomizerHandle } from '@varianta/sdk/react';\n * import { useRef } from 'react';\n *\n * function App() {\n * const customizerRef = useRef<CustomizerHandle>(null);\n *\n * const handleFinalize = async () => {\n * if (customizerRef.current) {\n * const result = await customizerRef.current.finalize();\n * console.log('Finalized:', result);\n * }\n * };\n *\n * return (\n * <div style={{ width: '100vw', height: '100vh' }}>\n * <Customizer\n * ref={customizerRef}\n * templateId=\"tshirt-001\"\n * theme=\"light\"\n * onChange={(design) => console.log('Design changed:', design)}\n * onReady={() => console.log('Editor ready!')}\n * />\n * <button onClick={handleFinalize}>Finalize Design</button>\n * </div>\n * );\n * }\n * ```\n */\nexport const Customizer = forwardRef<CustomizerHandle, CustomizerProps>(\n (props, ref) => {\n const {\n templateId,\n productId,\n apiUrl,\n theme = 'light',\n mode = 'edit',\n debug = false,\n className,\n style,\n initialDesign,\n onReady,\n onChange,\n onLayerSelect,\n onLayerAdd,\n onLayerRemove,\n onLayerUpdate,\n onError,\n onFinalize,\n onViewChange,\n } = props;\n\n const containerRef = useRef<HTMLDivElement>(null);\n const instanceRef = useRef<CustomizerInstance | null>(null);\n\n // Store latest callbacks in a ref to avoid stale closures\n const callbacksRef = useRef({\n onReady,\n onChange,\n onLayerSelect,\n onLayerAdd,\n onLayerRemove,\n onLayerUpdate,\n onError,\n onFinalize,\n onViewChange,\n });\n\n // Update callbacks ref whenever they change\n useEffect(() => {\n callbacksRef.current = {\n onReady,\n onChange,\n onLayerSelect,\n onLayerAdd,\n onLayerRemove,\n onLayerUpdate,\n onError,\n onFinalize,\n onViewChange,\n };\n }, [onReady, onChange, onLayerSelect, onLayerAdd, onLayerRemove, onLayerUpdate, onError, onFinalize, onViewChange]);\n\n // Initialize the editor\n useEffect(() => {\n if (!containerRef.current) return;\n\n const options: CustomizerOptions = {\n templateId,\n productId,\n apiUrl,\n theme,\n mode,\n debug,\n initialDesign,\n // Use callback refs to always get latest callbacks\n onReady: () => callbacksRef.current.onReady?.(),\n onChange: (design) => callbacksRef.current.onChange?.(design),\n onLayerSelect: (layerId) => callbacksRef.current.onLayerSelect?.(layerId),\n onLayerAdd: (layerId) => callbacksRef.current.onLayerAdd?.(layerId),\n onLayerRemove: (layerId) => callbacksRef.current.onLayerRemove?.(layerId),\n onLayerUpdate: (layerId) => callbacksRef.current.onLayerUpdate?.(layerId),\n onError: (error) => callbacksRef.current.onError?.(error),\n onFinalize: (result) => callbacksRef.current.onFinalize?.(result),\n onViewChange: (viewName) => callbacksRef.current.onViewChange?.(viewName),\n };\n\n try {\n const instance = initCustomizer(containerRef.current, options);\n instanceRef.current = instance;\n } catch (error) {\n console.error('[Customizer React] Failed to initialize:', error);\n callbacksRef.current.onError?.({\n code: 'INIT_ERROR',\n message: error instanceof Error ? error.message : 'Unknown error',\n details: error,\n });\n }\n\n // Cleanup\n return () => {\n if (instanceRef.current) {\n instanceRef.current.destroy();\n instanceRef.current = null;\n }\n };\n }, [templateId, productId, apiUrl, debug, initialDesign]); // Only re-initialize on structural changes\n\n // Update theme when it changes\n useEffect(() => {\n if (instanceRef.current) {\n instanceRef.current.setTheme(theme);\n }\n }, [theme]);\n\n // Update mode when it changes\n useEffect(() => {\n if (instanceRef.current) {\n instanceRef.current.setMode(mode);\n }\n }, [mode]);\n\n // Expose methods via ref\n useImperativeHandle(\n ref,\n () => {\n // Return API that always uses current instanceRef\n return {\n getDesign: () => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n return instanceRef.current.getDesign();\n },\n setDesign: (design: DesignJSON) => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n instanceRef.current.setDesign(design);\n },\n undo: () => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n instanceRef.current.undo();\n },\n redo: () => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n instanceRef.current.redo();\n },\n canUndo: () => {\n if (!instanceRef.current) return false;\n return instanceRef.current.canUndo();\n },\n canRedo: () => {\n if (!instanceRef.current) return false;\n return instanceRef.current.canRedo();\n },\n finalize: async () => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n return instanceRef.current.finalize();\n },\n addTextLayer: (text?: string) => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n instanceRef.current.addTextLayer(text);\n },\n addImageLayer: async (url: string) => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n return instanceRef.current.addImageLayer(url);\n },\n removeLayer: (layerId: string) => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n instanceRef.current.removeLayer(layerId);\n },\n selectLayer: (layerId: string | null) => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n instanceRef.current.selectLayer(layerId);\n },\n getSelectedLayerId: () => {\n if (!instanceRef.current) return null;\n return instanceRef.current.getSelectedLayerId();\n },\n getActiveView: () => {\n if (!instanceRef.current) return null;\n return instanceRef.current.getActiveView();\n },\n getViews: () => {\n if (!instanceRef.current) return [];\n return instanceRef.current.getViews();\n },\n setActiveView: (viewName: string) => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n instanceRef.current.setActiveView(viewName);\n },\n setTheme: (newTheme: 'light' | 'dark') => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n instanceRef.current.setTheme(newTheme);\n },\n setMode: (newMode: 'edit' | 'preview') => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n instanceRef.current.setMode(newMode);\n },\n destroy: () => {\n if (!instanceRef.current) return;\n instanceRef.current.destroy();\n instanceRef.current = null;\n },\n getElement: () => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n return instanceRef.current.getElement();\n },\n };\n },\n [] // Empty deps is OK - we always read from instanceRef.current\n );\n\n return (\n <div\n ref={containerRef}\n className={className}\n style={{\n width: '100%',\n height: '100%',\n ...style,\n }}\n />\n );\n }\n);\n\nCustomizer.displayName = 'Customizer';\n","/**\n * React hook for controlling the customizer editor\n * @packageDocumentation\n */\n\nimport { useRef, useCallback, useState, useEffect } from 'react';\nimport type { CustomizerHandle } from './Customizer';\nimport type { DesignJSON, FinalizeResult } from '../types';\n\n/**\n * Options for the useCustomizer hook\n */\nexport interface UseCustomizerOptions {\n /**\n * Auto-save design to localStorage\n */\n autoSave?: boolean;\n\n /**\n * localStorage key for auto-save\n * @default 'customizer-design'\n */\n autoSaveKey?: string;\n\n /**\n * Debounce time for auto-save in ms\n * @default 1000\n */\n autoSaveDebounce?: number;\n}\n\n/**\n * Return type for useCustomizer hook\n */\nexport interface UseCustomizerReturn {\n /**\n * Ref to attach to the Customizer component\n */\n customizerRef: React.RefObject<CustomizerHandle | null>;\n\n /**\n * Current design state\n */\n design: DesignJSON | null;\n\n /**\n * Whether undo is available\n */\n canUndo: boolean;\n\n /**\n * Whether redo is available\n */\n canRedo: boolean;\n\n /**\n * Selected layer ID\n */\n selectedLayerId: string | null;\n\n /**\n * Whether finalization is in progress\n */\n isFinalizing: boolean;\n\n /**\n * Finalization result\n */\n finalizeResult: FinalizeResult | null;\n\n /**\n * Get the current design\n */\n getDesign: () => DesignJSON | null;\n\n /**\n * Set a new design\n */\n setDesign: (design: DesignJSON) => void;\n\n /**\n * Undo the last action\n */\n undo: () => void;\n\n /**\n * Redo the last undone action\n */\n redo: () => void;\n\n /**\n * Finalize the design\n */\n finalize: () => Promise<FinalizeResult | null>;\n\n /**\n * Add a text layer\n */\n addTextLayer: (text?: string) => void;\n\n /**\n * Add an image layer\n */\n addImageLayer: (url: string) => Promise<void>;\n\n /**\n * Remove a layer\n */\n removeLayer: (layerId: string) => void;\n\n /**\n * Select a layer\n */\n selectLayer: (layerId: string | null) => void;\n}\n\n/**\n * React hook for controlling the customizer editor\n *\n * @example\n * ```tsx\n * import { Customizer } from '@varianta/sdk/react';\n * import { useCustomizer } from '@varianta/sdk/react';\n *\n * function App() {\n * const {\n * customizerRef,\n * design,\n * canUndo,\n * canRedo,\n * undo,\n * redo,\n * finalize,\n * isFinalizing,\n * } = useCustomizer({ autoSave: true });\n *\n * return (\n * <>\n * <Customizer\n * ref={customizerRef}\n * templateId=\"tshirt-001\"\n * onChange={(d) => console.log('Changed:', d)}\n * />\n * <button onClick={undo} disabled={!canUndo}>Undo</button>\n * <button onClick={redo} disabled={!canRedo}>Redo</button>\n * <button onClick={finalize} disabled={isFinalizing}>\n * {isFinalizing ? 'Finalizing...' : 'Finalize'}\n * </button>\n * </>\n * );\n * }\n * ```\n */\nexport function useCustomizer(\n options: UseCustomizerOptions = {}\n): UseCustomizerReturn {\n const {\n autoSave = false,\n autoSaveKey = 'customizer-design',\n autoSaveDebounce = 1000,\n } = options;\n\n const customizerRef = useRef<CustomizerHandle>(null);\n const [design, setDesign] = useState<DesignJSON | null>(null);\n const [canUndo, setCanUndo] = useState(false);\n const [canRedo, setCanRedo] = useState(false);\n const [selectedLayerId, setSelectedLayerId] = useState<string | null>(null);\n const [isFinalizing, setIsFinalizing] = useState(false);\n const [finalizeResult, setFinalizeResult] = useState<FinalizeResult | null>(\n null\n );\n\n const autoSaveTimeoutRef = useRef<NodeJS.Timeout | undefined>(undefined);\n\n // Auto-save to localStorage\n useEffect(() => {\n if (!autoSave || !design) return;\n\n // Clear existing timeout\n if (autoSaveTimeoutRef.current) {\n clearTimeout(autoSaveTimeoutRef.current);\n }\n\n // Set new timeout\n autoSaveTimeoutRef.current = setTimeout(() => {\n try {\n localStorage.setItem(autoSaveKey, JSON.stringify(design));\n } catch (error) {\n console.error('[useCustomizer] Auto-save failed:', error);\n }\n }, autoSaveDebounce);\n\n return () => {\n if (autoSaveTimeoutRef.current) {\n clearTimeout(autoSaveTimeoutRef.current);\n }\n };\n }, [design, autoSave, autoSaveKey, autoSaveDebounce]);\n\n const getDesign = useCallback(() => {\n if (!customizerRef.current) return null;\n try {\n return customizerRef.current.getDesign();\n } catch (error) {\n console.error('[useCustomizer] getDesign failed:', error);\n return null;\n }\n }, []);\n\n const setDesignCallback = useCallback((newDesign: DesignJSON) => {\n if (!customizerRef.current) return;\n try {\n customizerRef.current.setDesign(newDesign);\n setDesign(newDesign);\n } catch (error) {\n console.error('[useCustomizer] setDesign failed:', error);\n }\n }, []);\n\n const undo = useCallback(() => {\n if (!customizerRef.current) return;\n try {\n customizerRef.current.undo();\n setCanUndo(customizerRef.current.canUndo());\n setCanRedo(customizerRef.current.canRedo());\n } catch (error) {\n console.error('[useCustomizer] undo failed:', error);\n }\n }, []);\n\n const redo = useCallback(() => {\n if (!customizerRef.current) return;\n try {\n customizerRef.current.redo();\n setCanUndo(customizerRef.current.canUndo());\n setCanRedo(customizerRef.current.canRedo());\n } catch (error) {\n console.error('[useCustomizer] redo failed:', error);\n }\n }, []);\n\n const finalize = useCallback(async () => {\n if (!customizerRef.current || isFinalizing) return null;\n\n setIsFinalizing(true);\n try {\n const result = await customizerRef.current.finalize();\n setFinalizeResult(result);\n return result;\n } catch (error) {\n console.error('[useCustomizer] finalize failed:', error);\n return null;\n } finally {\n setIsFinalizing(false);\n }\n }, [isFinalizing]);\n\n const addTextLayer = useCallback((text?: string) => {\n if (!customizerRef.current) return;\n try {\n customizerRef.current.addTextLayer(text);\n } catch (error) {\n console.error('[useCustomizer] addTextLayer failed:', error);\n }\n }, []);\n\n const addImageLayer = useCallback(async (url: string) => {\n if (!customizerRef.current) return;\n try {\n await customizerRef.current.addImageLayer(url);\n } catch (error) {\n console.error('[useCustomizer] addImageLayer failed:', error);\n }\n }, []);\n\n const removeLayer = useCallback((layerId: string) => {\n if (!customizerRef.current) return;\n try {\n customizerRef.current.removeLayer(layerId);\n } catch (error) {\n console.error('[useCustomizer] removeLayer failed:', error);\n }\n }, []);\n\n const selectLayer = useCallback((layerId: string | null) => {\n if (!customizerRef.current) return;\n try {\n customizerRef.current.selectLayer(layerId);\n setSelectedLayerId(layerId);\n } catch (error) {\n console.error('[useCustomizer] selectLayer failed:', error);\n }\n }, []);\n\n return {\n customizerRef,\n design,\n canUndo,\n canRedo,\n selectedLayerId,\n isFinalizing,\n finalizeResult,\n getDesign,\n setDesign: setDesignCallback,\n undo,\n redo,\n finalize,\n addTextLayer,\n addImageLayer,\n removeLayer,\n selectLayer,\n };\n}\n"],"names":["Customizer","forwardRef","props","ref","templateId","productId","apiUrl","theme","mode","debug","className","style","initialDesign","onReady","onChange","onLayerSelect","onLayerAdd","onLayerRemove","onLayerUpdate","onError","onFinalize","onViewChange","containerRef","useRef","instanceRef","callbacksRef","useEffect","options","design","layerId","error","result","viewName","instance","initCustomizer","useImperativeHandle","text","url","newTheme","newMode","jsx","useCustomizer","autoSave","autoSaveKey","autoSaveDebounce","customizerRef","setDesign","useState","canUndo","setCanUndo","canRedo","setCanRedo","selectedLayerId","setSelectedLayerId","isFinalizing","setIsFinalizing","finalizeResult","setFinalizeResult","autoSaveTimeoutRef","getDesign","useCallback","setDesignCallback","newDesign","undo","redo","finalize","addTextLayer","addImageLayer","removeLayer","selectLayer"],"mappings":"oKA+JaA,EAAaC,EAAAA,WACxB,CAACC,EAAOC,IAAQ,CACd,KAAM,CACJ,WAAAC,EACA,UAAAC,EACA,OAAAC,EACA,MAAAC,EAAQ,QACR,KAAAC,EAAO,OACP,MAAAC,EAAQ,GACR,UAAAC,EACA,MAAAC,EACA,cAAAC,EACA,QAAAC,EACA,SAAAC,EACA,cAAAC,EACA,WAAAC,EACA,cAAAC,EACA,cAAAC,EACA,QAAAC,EACA,WAAAC,EACA,aAAAC,CAAA,EACEnB,EAEEoB,EAAeC,EAAAA,OAAuB,IAAI,EAC1CC,EAAcD,EAAAA,OAAkC,IAAI,EAGpDE,EAAeF,EAAAA,OAAO,CAC1B,QAAAV,EACA,SAAAC,EACA,cAAAC,EACA,WAAAC,EACA,cAAAC,EACA,cAAAC,EACA,QAAAC,EACA,WAAAC,EACA,aAAAC,CAAA,CACD,EAGDK,OAAAA,EAAAA,UAAU,IAAM,CACdD,EAAa,QAAU,CACrB,QAAAZ,EACA,SAAAC,EACA,cAAAC,EACA,WAAAC,EACA,cAAAC,EACA,cAAAC,EACA,QAAAC,EACA,WAAAC,EACA,aAAAC,CAAA,CAEJ,EAAG,CAACR,EAASC,EAAUC,EAAeC,EAAYC,EAAeC,EAAeC,EAASC,EAAYC,CAAY,CAAC,EAGlHK,EAAAA,UAAU,IAAM,CACd,GAAI,CAACJ,EAAa,QAAS,OAE3B,MAAMK,EAA6B,CACjC,WAAAvB,EACA,UAAAC,EACA,OAAAC,EACA,MAAAC,EACA,KAAAC,EACA,MAAAC,EACA,cAAAG,EAEA,QAAS,IAAMa,EAAa,QAAQ,UAAA,EACpC,SAAWG,GAAWH,EAAa,QAAQ,WAAWG,CAAM,EAC5D,cAAgBC,GAAYJ,EAAa,QAAQ,gBAAgBI,CAAO,EACxE,WAAaA,GAAYJ,EAAa,QAAQ,aAAaI,CAAO,EAClE,cAAgBA,GAAYJ,EAAa,QAAQ,gBAAgBI,CAAO,EACxE,cAAgBA,GAAYJ,EAAa,QAAQ,gBAAgBI,CAAO,EACxE,QAAUC,GAAUL,EAAa,QAAQ,UAAUK,CAAK,EACxD,WAAaC,GAAWN,EAAa,QAAQ,aAAaM,CAAM,EAChE,aAAeC,GAAaP,EAAa,QAAQ,eAAeO,CAAQ,CAAA,EAG1E,GAAI,CACF,MAAMC,EAAWC,EAAAA,eAAeZ,EAAa,QAASK,CAAO,EAC7DH,EAAY,QAAUS,CACxB,OAASH,EAAO,CACd,QAAQ,MAAM,2CAA4CA,CAAK,EAC/DL,EAAa,QAAQ,UAAU,CAC7B,KAAM,aACN,QAASK,aAAiB,MAAQA,EAAM,QAAU,gBAClD,QAASA,CAAA,CACV,CACH,CAGA,MAAO,IAAM,CACPN,EAAY,UACdA,EAAY,QAAQ,QAAA,EACpBA,EAAY,QAAU,KAE1B,CACF,EAAG,CAACpB,EAAYC,EAAWC,EAAQG,EAAOG,CAAa,CAAC,EAGxDc,EAAAA,UAAU,IAAM,CACVF,EAAY,SACdA,EAAY,QAAQ,SAASjB,CAAK,CAEtC,EAAG,CAACA,CAAK,CAAC,EAGVmB,EAAAA,UAAU,IAAM,CACVF,EAAY,SACdA,EAAY,QAAQ,QAAQhB,CAAI,CAEpC,EAAG,CAACA,CAAI,CAAC,EAGT2B,EAAAA,oBACEhC,EACA,KAES,CACP,UAAW,IAAM,CACf,GAAI,CAACqB,EAAY,QACf,MAAM,IAAI,MAAM,wBAAwB,EAE1C,OAAOA,EAAY,QAAQ,UAAA,CAC7B,EACA,UAAYI,GAAuB,CACjC,GAAI,CAACJ,EAAY,QACf,MAAM,IAAI,MAAM,wBAAwB,EAE1CA,EAAY,QAAQ,UAAUI,CAAM,CACtC,EACA,KAAM,IAAM,CACV,GAAI,CAACJ,EAAY,QACf,MAAM,IAAI,MAAM,wBAAwB,EAE1CA,EAAY,QAAQ,KAAA,CACtB,EACA,KAAM,IAAM,CACV,GAAI,CAACA,EAAY,QACf,MAAM,IAAI,MAAM,wBAAwB,EAE1CA,EAAY,QAAQ,KAAA,CACtB,EACA,QAAS,IACFA,EAAY,QACVA,EAAY,QAAQ,QAAA,EADM,GAGnC,QAAS,IACFA,EAAY,QACVA,EAAY,QAAQ,QAAA,EADM,GAGnC,SAAU,SAAY,CACpB,GAAI,CAACA,EAAY,QACf,MAAM,IAAI,MAAM,wBAAwB,EAE1C,OAAOA,EAAY,QAAQ,SAAA,CAC7B,EACA,aAAeY,GAAkB,CAC/B,GAAI,CAACZ,EAAY,QACf,MAAM,IAAI,MAAM,wBAAwB,EAE1CA,EAAY,QAAQ,aAAaY,CAAI,CACvC,EACA,cAAe,MAAOC,GAAgB,CACpC,GAAI,CAACb,EAAY,QACf,MAAM,IAAI,MAAM,wBAAwB,EAE1C,OAAOA,EAAY,QAAQ,cAAca,CAAG,CAC9C,EACA,YAAcR,GAAoB,CAChC,GAAI,CAACL,EAAY,QACf,MAAM,IAAI,MAAM,wBAAwB,EAE1CA,EAAY,QAAQ,YAAYK,CAAO,CACzC,EACA,YAAcA,GAA2B,CACvC,GAAI,CAACL,EAAY,QACf,MAAM,IAAI,MAAM,wBAAwB,EAE1CA,EAAY,QAAQ,YAAYK,CAAO,CACzC,EACA,mBAAoB,IACbL,EAAY,QACVA,EAAY,QAAQ,mBAAA,EADM,KAGnC,cAAe,IACRA,EAAY,QACVA,EAAY,QAAQ,cAAA,EADM,KAGnC,SAAU,IACHA,EAAY,QACVA,EAAY,QAAQ,SAAA,EADM,CAAA,EAGnC,cAAgBQ,GAAqB,CACnC,GAAI,CAACR,EAAY,QACf,MAAM,IAAI,MAAM,wBAAwB,EAE1CA,EAAY,QAAQ,cAAcQ,CAAQ,CAC5C,EACA,SAAWM,GAA+B,CACxC,GAAI,CAACd,EAAY,QACf,MAAM,IAAI,MAAM,wBAAwB,EAE1CA,EAAY,QAAQ,SAASc,CAAQ,CACvC,EACA,QAAUC,GAAgC,CACxC,GAAI,CAACf,EAAY,QACf,MAAM,IAAI,MAAM,wBAAwB,EAE1CA,EAAY,QAAQ,QAAQe,CAAO,CACrC,EACA,QAAS,IAAM,CACRf,EAAY,UACjBA,EAAY,QAAQ,QAAA,EACpBA,EAAY,QAAU,KACxB,EACA,WAAY,IAAM,CAChB,GAAI,CAACA,EAAY,QACf,MAAM,IAAI,MAAM,wBAAwB,EAE1C,OAAOA,EAAY,QAAQ,WAAA,CAC7B,CAAA,GAGF,CAAA,CAAC,EAIDgB,EAAAA,IAAC,MAAA,CACC,IAAKlB,EACL,UAAAZ,EACA,MAAO,CACL,MAAO,OACP,OAAQ,OACR,GAAGC,CAAA,CACL,CAAA,CAGN,CACF,EAEAX,EAAW,YAAc,aCvPlB,SAASyC,EACdd,EAAgC,GACX,CACrB,KAAM,CACJ,SAAAe,EAAW,GACX,YAAAC,EAAc,oBACd,iBAAAC,EAAmB,GAAA,EACjBjB,EAEEkB,EAAgBtB,EAAAA,OAAyB,IAAI,EAC7C,CAACK,EAAQkB,CAAS,EAAIC,EAAAA,SAA4B,IAAI,EACtD,CAACC,EAASC,CAAU,EAAIF,EAAAA,SAAS,EAAK,EACtC,CAACG,EAASC,CAAU,EAAIJ,EAAAA,SAAS,EAAK,EACtC,CAACK,EAAiBC,CAAkB,EAAIN,EAAAA,SAAwB,IAAI,EACpE,CAACO,EAAcC,CAAe,EAAIR,EAAAA,SAAS,EAAK,EAChD,CAACS,EAAgBC,CAAiB,EAAIV,EAAAA,SAC1C,IAAA,EAGIW,EAAqBnC,EAAAA,OAAmC,MAAS,EAGvEG,EAAAA,UAAU,IAAM,CACd,GAAI,GAACgB,GAAY,CAACd,GAGlB,OAAI8B,EAAmB,SACrB,aAAaA,EAAmB,OAAO,EAIzCA,EAAmB,QAAU,WAAW,IAAM,CAC5C,GAAI,CACF,aAAa,QAAQf,EAAa,KAAK,UAAUf,CAAM,CAAC,CAC1D,OAASE,EAAO,CACd,QAAQ,MAAM,oCAAqCA,CAAK,CAC1D,CACF,EAAGc,CAAgB,EAEZ,IAAM,CACPc,EAAmB,SACrB,aAAaA,EAAmB,OAAO,CAE3C,CACF,EAAG,CAAC9B,EAAQc,EAAUC,EAAaC,CAAgB,CAAC,EAEpD,MAAMe,EAAYC,EAAAA,YAAY,IAAM,CAClC,GAAI,CAACf,EAAc,QAAS,OAAO,KACnC,GAAI,CACF,OAAOA,EAAc,QAAQ,UAAA,CAC/B,OAASf,EAAO,CACd,eAAQ,MAAM,oCAAqCA,CAAK,EACjD,IACT,CACF,EAAG,CAAA,CAAE,EAEC+B,EAAoBD,cAAaE,GAA0B,CAC/D,GAAKjB,EAAc,QACnB,GAAI,CACFA,EAAc,QAAQ,UAAUiB,CAAS,EACzChB,EAAUgB,CAAS,CACrB,OAAShC,EAAO,CACd,QAAQ,MAAM,oCAAqCA,CAAK,CAC1D,CACF,EAAG,CAAA,CAAE,EAECiC,EAAOH,EAAAA,YAAY,IAAM,CAC7B,GAAKf,EAAc,QACnB,GAAI,CACFA,EAAc,QAAQ,KAAA,EACtBI,EAAWJ,EAAc,QAAQ,SAAS,EAC1CM,EAAWN,EAAc,QAAQ,SAAS,CAC5C,OAASf,EAAO,CACd,QAAQ,MAAM,+BAAgCA,CAAK,CACrD,CACF,EAAG,CAAA,CAAE,EAECkC,EAAOJ,EAAAA,YAAY,IAAM,CAC7B,GAAKf,EAAc,QACnB,GAAI,CACFA,EAAc,QAAQ,KAAA,EACtBI,EAAWJ,EAAc,QAAQ,SAAS,EAC1CM,EAAWN,EAAc,QAAQ,SAAS,CAC5C,OAASf,EAAO,CACd,QAAQ,MAAM,+BAAgCA,CAAK,CACrD,CACF,EAAG,CAAA,CAAE,EAECmC,EAAWL,EAAAA,YAAY,SAAY,CACvC,GAAI,CAACf,EAAc,SAAWS,EAAc,OAAO,KAEnDC,EAAgB,EAAI,EACpB,GAAI,CACF,MAAMxB,EAAS,MAAMc,EAAc,QAAQ,SAAA,EAC3C,OAAAY,EAAkB1B,CAAM,EACjBA,CACT,OAASD,EAAO,CACd,eAAQ,MAAM,mCAAoCA,CAAK,EAChD,IACT,QAAA,CACEyB,EAAgB,EAAK,CACvB,CACF,EAAG,CAACD,CAAY,CAAC,EAEXY,EAAeN,cAAaxB,GAAkB,CAClD,GAAKS,EAAc,QACnB,GAAI,CACFA,EAAc,QAAQ,aAAaT,CAAI,CACzC,OAASN,EAAO,CACd,QAAQ,MAAM,uCAAwCA,CAAK,CAC7D,CACF,EAAG,CAAA,CAAE,EAECqC,EAAgBP,cAAY,MAAOvB,GAAgB,CACvD,GAAKQ,EAAc,QACnB,GAAI,CACF,MAAMA,EAAc,QAAQ,cAAcR,CAAG,CAC/C,OAASP,EAAO,CACd,QAAQ,MAAM,wCAAyCA,CAAK,CAC9D,CACF,EAAG,CAAA,CAAE,EAECsC,EAAcR,cAAa/B,GAAoB,CACnD,GAAKgB,EAAc,QACnB,GAAI,CACFA,EAAc,QAAQ,YAAYhB,CAAO,CAC3C,OAASC,EAAO,CACd,QAAQ,MAAM,sCAAuCA,CAAK,CAC5D,CACF,EAAG,CAAA,CAAE,EAECuC,EAAcT,cAAa/B,GAA2B,CAC1D,GAAKgB,EAAc,QACnB,GAAI,CACFA,EAAc,QAAQ,YAAYhB,CAAO,EACzCwB,EAAmBxB,CAAO,CAC5B,OAASC,EAAO,CACd,QAAQ,MAAM,sCAAuCA,CAAK,CAC5D,CACF,EAAG,CAAA,CAAE,EAEL,MAAO,CACL,cAAAe,EACA,OAAAjB,EACA,QAAAoB,EACA,QAAAE,EACA,gBAAAE,EACA,aAAAE,EACA,eAAAE,EACA,UAAAG,EACA,UAAWE,EACX,KAAAE,EACA,KAAAC,EACA,SAAAC,EACA,aAAAC,EACA,cAAAC,EACA,YAAAC,EACA,YAAAC,CAAA,CAEJ"}
1
+ {"version":3,"file":"react.cjs.js","sources":["../src/react/Customizer.tsx","../src/react/useCustomizer.ts"],"sourcesContent":["/**\n * React wrapper for Customizer Editor\n * @packageDocumentation\n */\n\nimport {\n useRef,\n useEffect,\n useImperativeHandle,\n forwardRef,\n type CSSProperties,\n} from 'react';\nimport { initCustomizer } from '../vanilla';\nimport type {\n CustomizerOptions,\n CustomizerInstance,\n DesignJSON,\n FinalizeResult,\n CustomizerError,\n} from '../types';\n\n/**\n * Props for the Customizer React component\n */\nexport interface CustomizerProps {\n /**\n * Template ID to load. Required unless productId is provided.\n */\n templateId?: string;\n\n /**\n * Product ID to load (fetches all views/templates for the product).\n * Alternative to templateId. Exactly one of templateId or productId must be provided.\n */\n productId?: string;\n\n /**\n * API base URL for fetching templates and finalizing designs\n * @default 'https://api.varianta.io'\n */\n apiUrl?: string;\n\n /**\n * Visual theme\n * @default 'light'\n */\n theme?: 'light' | 'dark';\n\n /**\n * Editor mode\n * @default 'edit'\n */\n mode?: 'edit' | 'preview';\n\n /**\n * Enable debug mode with additional logging\n * @default false\n */\n debug?: boolean;\n\n /**\n * Custom CSS class name\n */\n className?: string;\n\n /**\n * Custom inline styles\n */\n style?: CSSProperties;\n\n /**\n * Initial design data to load\n */\n initialDesign?: DesignJSON;\n\n /**\n * Called when the editor is ready\n */\n onReady?: () => void;\n\n /**\n * Called when the design changes\n */\n onChange?: (design: DesignJSON) => void;\n\n /**\n * Called when a layer is selected\n */\n onLayerSelect?: (layerId: string | null) => void;\n\n /**\n * Called when a layer is added\n */\n onLayerAdd?: (layerId: string) => void;\n\n /**\n * Called when a layer is removed\n */\n onLayerRemove?: (layerId: string) => void;\n\n /**\n * Called when a layer is updated\n */\n onLayerUpdate?: (layerId: string) => void;\n\n /**\n * Called when an error occurs\n */\n onError?: (error: CustomizerError) => void;\n\n /**\n * Called when finalization is complete\n */\n onFinalize?: (result: FinalizeResult) => void;\n\n /**\n * Called when the active view changes (only relevant when using productId)\n */\n onViewChange?: (viewName: string) => void;\n\n /**\n * Show the Close button in the toolbar\n * @default true\n */\n showCloseButton?: boolean;\n\n /**\n * Show the Save Customization button in the toolbar.\n * When false, the button never appears even when the design is dirty.\n * @default true\n */\n showSaveButton?: boolean;\n\n /**\n * Called when the Close button is clicked\n */\n onClose?: () => void;\n\n /**\n * Called when the Save button is clicked and finalization completes successfully\n */\n onSave?: (result: FinalizeResult) => void;\n}\n\n/**\n * Handle type exposed via ref\n */\nexport type CustomizerHandle = CustomizerInstance;\n\n/**\n * Customizer React Component\n *\n * @example\n * ```tsx\n * import { Customizer, CustomizerHandle } from '@varianta/sdk/react';\n * import { useRef } from 'react';\n *\n * function App() {\n * const customizerRef = useRef<CustomizerHandle>(null);\n *\n * const handleFinalize = async () => {\n * if (customizerRef.current) {\n * const result = await customizerRef.current.finalize();\n * console.log('Finalized:', result);\n * }\n * };\n *\n * return (\n * <div style={{ width: '100vw', height: '100vh' }}>\n * <Customizer\n * ref={customizerRef}\n * templateId=\"tshirt-001\"\n * theme=\"light\"\n * onChange={(design) => console.log('Design changed:', design)}\n * onReady={() => console.log('Editor ready!')}\n * />\n * <button onClick={handleFinalize}>Finalize Design</button>\n * </div>\n * );\n * }\n * ```\n */\nexport const Customizer = forwardRef<CustomizerHandle, CustomizerProps>(\n (props, ref) => {\n const {\n templateId,\n productId,\n apiUrl,\n theme = 'light',\n mode = 'edit',\n debug = false,\n className,\n style,\n initialDesign,\n showCloseButton,\n showSaveButton,\n onReady,\n onChange,\n onLayerSelect,\n onLayerAdd,\n onLayerRemove,\n onLayerUpdate,\n onError,\n onFinalize,\n onViewChange,\n onClose,\n onSave,\n } = props;\n\n const containerRef = useRef<HTMLDivElement>(null);\n const instanceRef = useRef<CustomizerInstance | null>(null);\n\n // Store latest callbacks in a ref to avoid stale closures\n const callbacksRef = useRef({\n onReady,\n onChange,\n onLayerSelect,\n onLayerAdd,\n onLayerRemove,\n onLayerUpdate,\n onError,\n onFinalize,\n onViewChange,\n onClose,\n onSave,\n });\n\n // Update callbacks ref whenever they change\n useEffect(() => {\n callbacksRef.current = {\n onReady,\n onChange,\n onLayerSelect,\n onLayerAdd,\n onLayerRemove,\n onLayerUpdate,\n onError,\n onFinalize,\n onViewChange,\n onClose,\n onSave,\n };\n }, [onReady, onChange, onLayerSelect, onLayerAdd, onLayerRemove, onLayerUpdate, onError, onFinalize, onViewChange, onClose, onSave]);\n\n // Initialize the editor\n useEffect(() => {\n if (!containerRef.current) return;\n\n const options: CustomizerOptions = {\n templateId,\n productId,\n apiUrl,\n theme,\n mode,\n debug,\n initialDesign,\n showCloseButton,\n showSaveButton,\n // Use callback refs to always get latest callbacks\n onReady: () => callbacksRef.current.onReady?.(),\n onChange: (design) => callbacksRef.current.onChange?.(design),\n onLayerSelect: (layerId) => callbacksRef.current.onLayerSelect?.(layerId),\n onLayerAdd: (layerId) => callbacksRef.current.onLayerAdd?.(layerId),\n onLayerRemove: (layerId) => callbacksRef.current.onLayerRemove?.(layerId),\n onLayerUpdate: (layerId) => callbacksRef.current.onLayerUpdate?.(layerId),\n onError: (error) => callbacksRef.current.onError?.(error),\n onFinalize: (result) => callbacksRef.current.onFinalize?.(result),\n onViewChange: (viewName) => callbacksRef.current.onViewChange?.(viewName),\n onClose: () => callbacksRef.current.onClose?.(),\n onSave: (result) => callbacksRef.current.onSave?.(result),\n };\n\n try {\n const instance = initCustomizer(containerRef.current, options);\n instanceRef.current = instance;\n } catch (error) {\n console.error('[Customizer React] Failed to initialize:', error);\n callbacksRef.current.onError?.({\n code: 'INIT_ERROR',\n message: error instanceof Error ? error.message : 'Unknown error',\n details: error,\n });\n }\n\n // Cleanup\n return () => {\n if (instanceRef.current) {\n instanceRef.current.destroy();\n instanceRef.current = null;\n }\n };\n }, [templateId, productId, apiUrl, debug, initialDesign, showCloseButton, showSaveButton]); // Only re-initialize on structural changes\n\n // Update theme when it changes\n useEffect(() => {\n if (instanceRef.current) {\n instanceRef.current.setTheme(theme);\n }\n }, [theme]);\n\n // Update mode when it changes\n useEffect(() => {\n if (instanceRef.current) {\n instanceRef.current.setMode(mode);\n }\n }, [mode]);\n\n // Expose methods via ref\n useImperativeHandle(\n ref,\n () => {\n // Return API that always uses current instanceRef\n return {\n getDesign: () => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n return instanceRef.current.getDesign();\n },\n setDesign: (design: DesignJSON) => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n instanceRef.current.setDesign(design);\n },\n undo: () => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n instanceRef.current.undo();\n },\n redo: () => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n instanceRef.current.redo();\n },\n canUndo: () => {\n if (!instanceRef.current) return false;\n return instanceRef.current.canUndo();\n },\n canRedo: () => {\n if (!instanceRef.current) return false;\n return instanceRef.current.canRedo();\n },\n finalize: async () => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n return instanceRef.current.finalize();\n },\n addTextLayer: (text?: string) => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n instanceRef.current.addTextLayer(text);\n },\n addImageLayer: async (url: string) => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n return instanceRef.current.addImageLayer(url);\n },\n removeLayer: (layerId: string) => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n instanceRef.current.removeLayer(layerId);\n },\n selectLayer: (layerId: string | null) => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n instanceRef.current.selectLayer(layerId);\n },\n getSelectedLayerId: () => {\n if (!instanceRef.current) return null;\n return instanceRef.current.getSelectedLayerId();\n },\n getActiveView: () => {\n if (!instanceRef.current) return null;\n return instanceRef.current.getActiveView();\n },\n getViews: () => {\n if (!instanceRef.current) return [];\n return instanceRef.current.getViews();\n },\n setActiveView: (viewName: string) => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n instanceRef.current.setActiveView(viewName);\n },\n setTheme: (newTheme: 'light' | 'dark') => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n instanceRef.current.setTheme(newTheme);\n },\n setMode: (newMode: 'edit' | 'preview') => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n instanceRef.current.setMode(newMode);\n },\n destroy: () => {\n if (!instanceRef.current) return;\n instanceRef.current.destroy();\n instanceRef.current = null;\n },\n getElement: () => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n return instanceRef.current.getElement();\n },\n };\n },\n [] // Empty deps is OK - we always read from instanceRef.current\n );\n\n return (\n <div\n ref={containerRef}\n className={className}\n style={{\n width: '100%',\n height: '100%',\n ...style,\n }}\n />\n );\n }\n);\n\nCustomizer.displayName = 'Customizer';\n","/**\n * React hook for controlling the customizer editor\n * @packageDocumentation\n */\n\nimport { useRef, useCallback, useState, useEffect } from 'react';\nimport type { CustomizerHandle } from './Customizer';\nimport type { DesignJSON, FinalizeResult } from '../types';\n\n/**\n * Options for the useCustomizer hook\n */\nexport interface UseCustomizerOptions {\n /**\n * Auto-save design to localStorage\n */\n autoSave?: boolean;\n\n /**\n * localStorage key for auto-save\n * @default 'customizer-design'\n */\n autoSaveKey?: string;\n\n /**\n * Debounce time for auto-save in ms\n * @default 1000\n */\n autoSaveDebounce?: number;\n}\n\n/**\n * Return type for useCustomizer hook\n */\nexport interface UseCustomizerReturn {\n /**\n * Ref to attach to the Customizer component\n */\n customizerRef: React.RefObject<CustomizerHandle | null>;\n\n /**\n * Current design state\n */\n design: DesignJSON | null;\n\n /**\n * Whether undo is available\n */\n canUndo: boolean;\n\n /**\n * Whether redo is available\n */\n canRedo: boolean;\n\n /**\n * Selected layer ID\n */\n selectedLayerId: string | null;\n\n /**\n * Whether finalization is in progress\n */\n isFinalizing: boolean;\n\n /**\n * Finalization result\n */\n finalizeResult: FinalizeResult | null;\n\n /**\n * Get the current design\n */\n getDesign: () => DesignJSON | null;\n\n /**\n * Set a new design\n */\n setDesign: (design: DesignJSON) => void;\n\n /**\n * Undo the last action\n */\n undo: () => void;\n\n /**\n * Redo the last undone action\n */\n redo: () => void;\n\n /**\n * Finalize the design\n */\n finalize: () => Promise<FinalizeResult | null>;\n\n /**\n * Add a text layer\n */\n addTextLayer: (text?: string) => void;\n\n /**\n * Add an image layer\n */\n addImageLayer: (url: string) => Promise<void>;\n\n /**\n * Remove a layer\n */\n removeLayer: (layerId: string) => void;\n\n /**\n * Select a layer\n */\n selectLayer: (layerId: string | null) => void;\n}\n\n/**\n * React hook for controlling the customizer editor\n *\n * @example\n * ```tsx\n * import { Customizer } from '@varianta/sdk/react';\n * import { useCustomizer } from '@varianta/sdk/react';\n *\n * function App() {\n * const {\n * customizerRef,\n * design,\n * canUndo,\n * canRedo,\n * undo,\n * redo,\n * finalize,\n * isFinalizing,\n * } = useCustomizer({ autoSave: true });\n *\n * return (\n * <>\n * <Customizer\n * ref={customizerRef}\n * templateId=\"tshirt-001\"\n * onChange={(d) => console.log('Changed:', d)}\n * />\n * <button onClick={undo} disabled={!canUndo}>Undo</button>\n * <button onClick={redo} disabled={!canRedo}>Redo</button>\n * <button onClick={finalize} disabled={isFinalizing}>\n * {isFinalizing ? 'Finalizing...' : 'Finalize'}\n * </button>\n * </>\n * );\n * }\n * ```\n */\nexport function useCustomizer(\n options: UseCustomizerOptions = {}\n): UseCustomizerReturn {\n const {\n autoSave = false,\n autoSaveKey = 'customizer-design',\n autoSaveDebounce = 1000,\n } = options;\n\n const customizerRef = useRef<CustomizerHandle>(null);\n const [design, setDesign] = useState<DesignJSON | null>(null);\n const [canUndo, setCanUndo] = useState(false);\n const [canRedo, setCanRedo] = useState(false);\n const [selectedLayerId, setSelectedLayerId] = useState<string | null>(null);\n const [isFinalizing, setIsFinalizing] = useState(false);\n const [finalizeResult, setFinalizeResult] = useState<FinalizeResult | null>(\n null\n );\n\n const autoSaveTimeoutRef = useRef<NodeJS.Timeout | undefined>(undefined);\n\n // Auto-save to localStorage\n useEffect(() => {\n if (!autoSave || !design) return;\n\n // Clear existing timeout\n if (autoSaveTimeoutRef.current) {\n clearTimeout(autoSaveTimeoutRef.current);\n }\n\n // Set new timeout\n autoSaveTimeoutRef.current = setTimeout(() => {\n try {\n localStorage.setItem(autoSaveKey, JSON.stringify(design));\n } catch (error) {\n console.error('[useCustomizer] Auto-save failed:', error);\n }\n }, autoSaveDebounce);\n\n return () => {\n if (autoSaveTimeoutRef.current) {\n clearTimeout(autoSaveTimeoutRef.current);\n }\n };\n }, [design, autoSave, autoSaveKey, autoSaveDebounce]);\n\n const getDesign = useCallback(() => {\n if (!customizerRef.current) return null;\n try {\n return customizerRef.current.getDesign();\n } catch (error) {\n console.error('[useCustomizer] getDesign failed:', error);\n return null;\n }\n }, []);\n\n const setDesignCallback = useCallback((newDesign: DesignJSON) => {\n if (!customizerRef.current) return;\n try {\n customizerRef.current.setDesign(newDesign);\n setDesign(newDesign);\n } catch (error) {\n console.error('[useCustomizer] setDesign failed:', error);\n }\n }, []);\n\n const undo = useCallback(() => {\n if (!customizerRef.current) return;\n try {\n customizerRef.current.undo();\n setCanUndo(customizerRef.current.canUndo());\n setCanRedo(customizerRef.current.canRedo());\n } catch (error) {\n console.error('[useCustomizer] undo failed:', error);\n }\n }, []);\n\n const redo = useCallback(() => {\n if (!customizerRef.current) return;\n try {\n customizerRef.current.redo();\n setCanUndo(customizerRef.current.canUndo());\n setCanRedo(customizerRef.current.canRedo());\n } catch (error) {\n console.error('[useCustomizer] redo failed:', error);\n }\n }, []);\n\n const finalize = useCallback(async () => {\n if (!customizerRef.current || isFinalizing) return null;\n\n setIsFinalizing(true);\n try {\n const result = await customizerRef.current.finalize();\n setFinalizeResult(result);\n return result;\n } catch (error) {\n console.error('[useCustomizer] finalize failed:', error);\n return null;\n } finally {\n setIsFinalizing(false);\n }\n }, [isFinalizing]);\n\n const addTextLayer = useCallback((text?: string) => {\n if (!customizerRef.current) return;\n try {\n customizerRef.current.addTextLayer(text);\n } catch (error) {\n console.error('[useCustomizer] addTextLayer failed:', error);\n }\n }, []);\n\n const addImageLayer = useCallback(async (url: string) => {\n if (!customizerRef.current) return;\n try {\n await customizerRef.current.addImageLayer(url);\n } catch (error) {\n console.error('[useCustomizer] addImageLayer failed:', error);\n }\n }, []);\n\n const removeLayer = useCallback((layerId: string) => {\n if (!customizerRef.current) return;\n try {\n customizerRef.current.removeLayer(layerId);\n } catch (error) {\n console.error('[useCustomizer] removeLayer failed:', error);\n }\n }, []);\n\n const selectLayer = useCallback((layerId: string | null) => {\n if (!customizerRef.current) return;\n try {\n customizerRef.current.selectLayer(layerId);\n setSelectedLayerId(layerId);\n } catch (error) {\n console.error('[useCustomizer] selectLayer failed:', error);\n }\n }, []);\n\n return {\n customizerRef,\n design,\n canUndo,\n canRedo,\n selectedLayerId,\n isFinalizing,\n finalizeResult,\n getDesign,\n setDesign: setDesignCallback,\n undo,\n redo,\n finalize,\n addTextLayer,\n addImageLayer,\n removeLayer,\n selectLayer,\n };\n}\n"],"names":["Customizer","forwardRef","props","ref","templateId","productId","apiUrl","theme","mode","debug","className","style","initialDesign","showCloseButton","showSaveButton","onReady","onChange","onLayerSelect","onLayerAdd","onLayerRemove","onLayerUpdate","onError","onFinalize","onViewChange","onClose","onSave","containerRef","useRef","instanceRef","callbacksRef","useEffect","options","design","layerId","error","result","viewName","instance","initCustomizer","useImperativeHandle","text","url","newTheme","newMode","jsx","useCustomizer","autoSave","autoSaveKey","autoSaveDebounce","customizerRef","setDesign","useState","canUndo","setCanUndo","canRedo","setCanRedo","selectedLayerId","setSelectedLayerId","isFinalizing","setIsFinalizing","finalizeResult","setFinalizeResult","autoSaveTimeoutRef","getDesign","useCallback","setDesignCallback","newDesign","undo","redo","finalize","addTextLayer","addImageLayer","removeLayer","selectLayer"],"mappings":"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"}
package/dist/react.esm.js CHANGED
@@ -1,76 +1,88 @@
1
1
  import { jsx as F } from "react/jsx-runtime";
2
- import { forwardRef as b, useRef as p, useEffect as I, useImperativeHandle as k, useState as f, useCallback as a } from "react";
2
+ import { forwardRef as b, useRef as I, useEffect as S, useImperativeHandle as k, useState as l, useCallback as c } from "react";
3
3
  import { initCustomizer as N } from "./index.esm.js";
4
4
  const M = b(
5
- (U, D) => {
5
+ (A, p) => {
6
6
  const {
7
- templateId: y,
8
- productId: m,
9
- apiUrl: r,
10
- theme: s = "light",
11
- mode: g = "edit",
12
- debug: S = !1,
7
+ templateId: d,
8
+ productId: f,
9
+ apiUrl: n,
10
+ theme: u = "light",
11
+ mode: y = "edit",
12
+ debug: D = !1,
13
13
  className: T,
14
- style: V,
15
- initialDesign: z,
16
- onReady: w,
17
- onChange: h,
18
- onLayerSelect: l,
19
- onLayerAdd: d,
20
- onLayerRemove: L,
21
- onLayerUpdate: E,
22
- onError: c,
23
- onFinalize: C,
24
- onViewChange: R
25
- } = U, v = p(null), e = p(null), i = p({
26
- onReady: w,
27
- onChange: h,
28
- onLayerSelect: l,
29
- onLayerAdd: d,
30
- onLayerRemove: L,
31
- onLayerUpdate: E,
32
- onError: c,
33
- onFinalize: C,
34
- onViewChange: R
14
+ style: x,
15
+ initialDesign: m,
16
+ showCloseButton: U,
17
+ showSaveButton: V,
18
+ onReady: a,
19
+ onChange: s,
20
+ onLayerSelect: g,
21
+ onLayerAdd: z,
22
+ onLayerRemove: i,
23
+ onLayerUpdate: w,
24
+ onError: h,
25
+ onFinalize: L,
26
+ onViewChange: E,
27
+ onClose: C,
28
+ onSave: R
29
+ } = A, v = I(null), e = I(null), o = I({
30
+ onReady: a,
31
+ onChange: s,
32
+ onLayerSelect: g,
33
+ onLayerAdd: z,
34
+ onLayerRemove: i,
35
+ onLayerUpdate: w,
36
+ onError: h,
37
+ onFinalize: L,
38
+ onViewChange: E,
39
+ onClose: C,
40
+ onSave: R
35
41
  });
36
- return I(() => {
37
- i.current = {
38
- onReady: w,
39
- onChange: h,
40
- onLayerSelect: l,
41
- onLayerAdd: d,
42
- onLayerRemove: L,
43
- onLayerUpdate: E,
44
- onError: c,
45
- onFinalize: C,
46
- onViewChange: R
42
+ return S(() => {
43
+ o.current = {
44
+ onReady: a,
45
+ onChange: s,
46
+ onLayerSelect: g,
47
+ onLayerAdd: z,
48
+ onLayerRemove: i,
49
+ onLayerUpdate: w,
50
+ onError: h,
51
+ onFinalize: L,
52
+ onViewChange: E,
53
+ onClose: C,
54
+ onSave: R
47
55
  };
48
- }, [w, h, l, d, L, E, c, C, R]), I(() => {
56
+ }, [a, s, g, z, i, w, h, L, E, C, R]), S(() => {
49
57
  if (!v.current) return;
50
- const o = {
51
- templateId: y,
52
- productId: m,
53
- apiUrl: r,
54
- theme: s,
55
- mode: g,
56
- debug: S,
57
- initialDesign: z,
58
+ const r = {
59
+ templateId: d,
60
+ productId: f,
61
+ apiUrl: n,
62
+ theme: u,
63
+ mode: y,
64
+ debug: D,
65
+ initialDesign: m,
66
+ showCloseButton: U,
67
+ showSaveButton: V,
58
68
  // Use callback refs to always get latest callbacks
59
- onReady: () => i.current.onReady?.(),
60
- onChange: (t) => i.current.onChange?.(t),
61
- onLayerSelect: (t) => i.current.onLayerSelect?.(t),
62
- onLayerAdd: (t) => i.current.onLayerAdd?.(t),
63
- onLayerRemove: (t) => i.current.onLayerRemove?.(t),
64
- onLayerUpdate: (t) => i.current.onLayerUpdate?.(t),
65
- onError: (t) => i.current.onError?.(t),
66
- onFinalize: (t) => i.current.onFinalize?.(t),
67
- onViewChange: (t) => i.current.onViewChange?.(t)
69
+ onReady: () => o.current.onReady?.(),
70
+ onChange: (t) => o.current.onChange?.(t),
71
+ onLayerSelect: (t) => o.current.onLayerSelect?.(t),
72
+ onLayerAdd: (t) => o.current.onLayerAdd?.(t),
73
+ onLayerRemove: (t) => o.current.onLayerRemove?.(t),
74
+ onLayerUpdate: (t) => o.current.onLayerUpdate?.(t),
75
+ onError: (t) => o.current.onError?.(t),
76
+ onFinalize: (t) => o.current.onFinalize?.(t),
77
+ onViewChange: (t) => o.current.onViewChange?.(t),
78
+ onClose: () => o.current.onClose?.(),
79
+ onSave: (t) => o.current.onSave?.(t)
68
80
  };
69
81
  try {
70
- const t = N(v.current, o);
82
+ const t = N(v.current, r);
71
83
  e.current = t;
72
84
  } catch (t) {
73
- console.error("[Customizer React] Failed to initialize:", t), i.current.onError?.({
85
+ console.error("[Customizer React] Failed to initialize:", t), o.current.onError?.({
74
86
  code: "INIT_ERROR",
75
87
  message: t instanceof Error ? t.message : "Unknown error",
76
88
  details: t
@@ -79,22 +91,22 @@ const M = b(
79
91
  return () => {
80
92
  e.current && (e.current.destroy(), e.current = null);
81
93
  };
82
- }, [y, m, r, S, z]), I(() => {
83
- e.current && e.current.setTheme(s);
84
- }, [s]), I(() => {
85
- e.current && e.current.setMode(g);
86
- }, [g]), k(
87
- D,
94
+ }, [d, f, n, D, m, U, V]), S(() => {
95
+ e.current && e.current.setTheme(u);
96
+ }, [u]), S(() => {
97
+ e.current && e.current.setMode(y);
98
+ }, [y]), k(
99
+ p,
88
100
  () => ({
89
101
  getDesign: () => {
90
102
  if (!e.current)
91
103
  throw new Error("Editor not initialized");
92
104
  return e.current.getDesign();
93
105
  },
94
- setDesign: (o) => {
106
+ setDesign: (r) => {
95
107
  if (!e.current)
96
108
  throw new Error("Editor not initialized");
97
- e.current.setDesign(o);
109
+ e.current.setDesign(r);
98
110
  },
99
111
  undo: () => {
100
112
  if (!e.current)
@@ -113,43 +125,43 @@ const M = b(
113
125
  throw new Error("Editor not initialized");
114
126
  return e.current.finalize();
115
127
  },
116
- addTextLayer: (o) => {
128
+ addTextLayer: (r) => {
117
129
  if (!e.current)
118
130
  throw new Error("Editor not initialized");
119
- e.current.addTextLayer(o);
131
+ e.current.addTextLayer(r);
120
132
  },
121
- addImageLayer: async (o) => {
133
+ addImageLayer: async (r) => {
122
134
  if (!e.current)
123
135
  throw new Error("Editor not initialized");
124
- return e.current.addImageLayer(o);
136
+ return e.current.addImageLayer(r);
125
137
  },
126
- removeLayer: (o) => {
138
+ removeLayer: (r) => {
127
139
  if (!e.current)
128
140
  throw new Error("Editor not initialized");
129
- e.current.removeLayer(o);
141
+ e.current.removeLayer(r);
130
142
  },
131
- selectLayer: (o) => {
143
+ selectLayer: (r) => {
132
144
  if (!e.current)
133
145
  throw new Error("Editor not initialized");
134
- e.current.selectLayer(o);
146
+ e.current.selectLayer(r);
135
147
  },
136
148
  getSelectedLayerId: () => e.current ? e.current.getSelectedLayerId() : null,
137
149
  getActiveView: () => e.current ? e.current.getActiveView() : null,
138
150
  getViews: () => e.current ? e.current.getViews() : [],
139
- setActiveView: (o) => {
151
+ setActiveView: (r) => {
140
152
  if (!e.current)
141
153
  throw new Error("Editor not initialized");
142
- e.current.setActiveView(o);
154
+ e.current.setActiveView(r);
143
155
  },
144
- setTheme: (o) => {
156
+ setTheme: (r) => {
145
157
  if (!e.current)
146
158
  throw new Error("Editor not initialized");
147
- e.current.setTheme(o);
159
+ e.current.setTheme(r);
148
160
  },
149
- setMode: (o) => {
161
+ setMode: (r) => {
150
162
  if (!e.current)
151
163
  throw new Error("Editor not initialized");
152
- e.current.setMode(o);
164
+ e.current.setMode(r);
153
165
  },
154
166
  destroy: () => {
155
167
  e.current && (e.current.destroy(), e.current = null);
@@ -170,122 +182,122 @@ const M = b(
170
182
  style: {
171
183
  width: "100%",
172
184
  height: "100%",
173
- ...V
185
+ ...x
174
186
  }
175
187
  }
176
188
  );
177
189
  }
178
190
  );
179
191
  M.displayName = "Customizer";
180
- function J(U = {}) {
192
+ function H(A = {}) {
181
193
  const {
182
- autoSave: D = !1,
183
- autoSaveKey: y = "customizer-design",
184
- autoSaveDebounce: m = 1e3
185
- } = U, r = p(null), [s, g] = f(null), [S, T] = f(!1), [V, z] = f(!1), [w, h] = f(null), [l, d] = f(!1), [L, E] = f(
194
+ autoSave: p = !1,
195
+ autoSaveKey: d = "customizer-design",
196
+ autoSaveDebounce: f = 1e3
197
+ } = A, n = I(null), [u, y] = l(null), [D, T] = l(!1), [x, m] = l(!1), [U, V] = l(null), [a, s] = l(!1), [g, z] = l(
186
198
  null
187
- ), c = p(void 0);
188
- I(() => {
189
- if (!(!D || !s))
190
- return c.current && clearTimeout(c.current), c.current = setTimeout(() => {
199
+ ), i = I(void 0);
200
+ S(() => {
201
+ if (!(!p || !u))
202
+ return i.current && clearTimeout(i.current), i.current = setTimeout(() => {
191
203
  try {
192
- localStorage.setItem(y, JSON.stringify(s));
193
- } catch (n) {
194
- console.error("[useCustomizer] Auto-save failed:", n);
204
+ localStorage.setItem(d, JSON.stringify(u));
205
+ } catch (r) {
206
+ console.error("[useCustomizer] Auto-save failed:", r);
195
207
  }
196
- }, m), () => {
197
- c.current && clearTimeout(c.current);
208
+ }, f), () => {
209
+ i.current && clearTimeout(i.current);
198
210
  };
199
- }, [s, D, y, m]);
200
- const C = a(() => {
201
- if (!r.current) return null;
211
+ }, [u, p, d, f]);
212
+ const w = c(() => {
213
+ if (!n.current) return null;
202
214
  try {
203
- return r.current.getDesign();
204
- } catch (n) {
205
- return console.error("[useCustomizer] getDesign failed:", n), null;
215
+ return n.current.getDesign();
216
+ } catch (r) {
217
+ return console.error("[useCustomizer] getDesign failed:", r), null;
206
218
  }
207
- }, []), R = a((n) => {
208
- if (r.current)
219
+ }, []), h = c((r) => {
220
+ if (n.current)
209
221
  try {
210
- r.current.setDesign(n), g(n);
211
- } catch (u) {
212
- console.error("[useCustomizer] setDesign failed:", u);
222
+ n.current.setDesign(r), y(r);
223
+ } catch (t) {
224
+ console.error("[useCustomizer] setDesign failed:", t);
213
225
  }
214
- }, []), v = a(() => {
215
- if (r.current)
226
+ }, []), L = c(() => {
227
+ if (n.current)
216
228
  try {
217
- r.current.undo(), T(r.current.canUndo()), z(r.current.canRedo());
218
- } catch (n) {
219
- console.error("[useCustomizer] undo failed:", n);
229
+ n.current.undo(), T(n.current.canUndo()), m(n.current.canRedo());
230
+ } catch (r) {
231
+ console.error("[useCustomizer] undo failed:", r);
220
232
  }
221
- }, []), e = a(() => {
222
- if (r.current)
233
+ }, []), E = c(() => {
234
+ if (n.current)
223
235
  try {
224
- r.current.redo(), T(r.current.canUndo()), z(r.current.canRedo());
225
- } catch (n) {
226
- console.error("[useCustomizer] redo failed:", n);
236
+ n.current.redo(), T(n.current.canUndo()), m(n.current.canRedo());
237
+ } catch (r) {
238
+ console.error("[useCustomizer] redo failed:", r);
227
239
  }
228
- }, []), i = a(async () => {
229
- if (!r.current || l) return null;
230
- d(!0);
240
+ }, []), C = c(async () => {
241
+ if (!n.current || a) return null;
242
+ s(!0);
231
243
  try {
232
- const n = await r.current.finalize();
233
- return E(n), n;
234
- } catch (n) {
235
- return console.error("[useCustomizer] finalize failed:", n), null;
244
+ const r = await n.current.finalize();
245
+ return z(r), r;
246
+ } catch (r) {
247
+ return console.error("[useCustomizer] finalize failed:", r), null;
236
248
  } finally {
237
- d(!1);
249
+ s(!1);
238
250
  }
239
- }, [l]), o = a((n) => {
240
- if (r.current)
251
+ }, [a]), R = c((r) => {
252
+ if (n.current)
241
253
  try {
242
- r.current.addTextLayer(n);
243
- } catch (u) {
244
- console.error("[useCustomizer] addTextLayer failed:", u);
254
+ n.current.addTextLayer(r);
255
+ } catch (t) {
256
+ console.error("[useCustomizer] addTextLayer failed:", t);
245
257
  }
246
- }, []), t = a(async (n) => {
247
- if (r.current)
258
+ }, []), v = c(async (r) => {
259
+ if (n.current)
248
260
  try {
249
- await r.current.addImageLayer(n);
250
- } catch (u) {
251
- console.error("[useCustomizer] addImageLayer failed:", u);
261
+ await n.current.addImageLayer(r);
262
+ } catch (t) {
263
+ console.error("[useCustomizer] addImageLayer failed:", t);
252
264
  }
253
- }, []), A = a((n) => {
254
- if (r.current)
265
+ }, []), e = c((r) => {
266
+ if (n.current)
255
267
  try {
256
- r.current.removeLayer(n);
257
- } catch (u) {
258
- console.error("[useCustomizer] removeLayer failed:", u);
268
+ n.current.removeLayer(r);
269
+ } catch (t) {
270
+ console.error("[useCustomizer] removeLayer failed:", t);
259
271
  }
260
- }, []), x = a((n) => {
261
- if (r.current)
272
+ }, []), o = c((r) => {
273
+ if (n.current)
262
274
  try {
263
- r.current.selectLayer(n), h(n);
264
- } catch (u) {
265
- console.error("[useCustomizer] selectLayer failed:", u);
275
+ n.current.selectLayer(r), V(r);
276
+ } catch (t) {
277
+ console.error("[useCustomizer] selectLayer failed:", t);
266
278
  }
267
279
  }, []);
268
280
  return {
269
- customizerRef: r,
270
- design: s,
271
- canUndo: S,
272
- canRedo: V,
273
- selectedLayerId: w,
274
- isFinalizing: l,
275
- finalizeResult: L,
276
- getDesign: C,
277
- setDesign: R,
278
- undo: v,
279
- redo: e,
280
- finalize: i,
281
- addTextLayer: o,
282
- addImageLayer: t,
283
- removeLayer: A,
284
- selectLayer: x
281
+ customizerRef: n,
282
+ design: u,
283
+ canUndo: D,
284
+ canRedo: x,
285
+ selectedLayerId: U,
286
+ isFinalizing: a,
287
+ finalizeResult: g,
288
+ getDesign: w,
289
+ setDesign: h,
290
+ undo: L,
291
+ redo: E,
292
+ finalize: C,
293
+ addTextLayer: R,
294
+ addImageLayer: v,
295
+ removeLayer: e,
296
+ selectLayer: o
285
297
  };
286
298
  }
287
299
  export {
288
300
  M as Customizer,
289
- J as useCustomizer
301
+ H as useCustomizer
290
302
  };
291
303
  //# sourceMappingURL=react.esm.js.map