@actovision/kaptha-email-editor
Version:
React wrapper for Kaptha Email Editor - A powerful drag-and-drop email editor with framework-agnostic API
1 lines • 12.3 kB
Source Map (JSON)
{"version":3,"sources":["../src/index.tsx"],"names":["KapthaEmailEditor"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * @actovision/kaptha-email-editor - React Wrapper for Kaptha Email Editor\n * \n * This package provides a React component wrapper that loads Kaptha Email Editor\n * from CDN as a self-contained bundle and provides a React interface.\n * \n * The CDN bundle is framework-agnostic and includes its own React instance,\n * eliminating React version conflicts.\n * \n * @example\n * ```tsx\n * import KapthaEmailEditor from '@actovision/kaptha-email-editor';\n * \n * function App() {\n * return (\n * <KapthaEmailEditor\n * apiKey=\"kpt_dev_ws001_demo12345678\"\n * minHeight=\"600px\"\n * onReady={() => console.log('Editor ready!')}\n * />\n * );\n * }\n * ```\n */\n\nimport * as React from 'react';\nimport { useEffect, useRef, useState, useImperativeHandle, forwardRef } from 'react';\n\n// CDN Configuration\nconst CDN_BASE_URL = 'https://code.kaptha.dev/core/embed';\nconst CACHE_VERSION = new Date().toISOString().split('T')[0]; // Format: YYYY-MM-DD\nconst CDN_JS_URL = `${CDN_BASE_URL}/editor.js?v=${CACHE_VERSION}`;\nconst CDN_CSS_URL = `${CDN_BASE_URL}/editor.css?v=${CACHE_VERSION}`;\n\nexport interface EmailDesign {\n components: any[];\n}\n\nexport interface EditorMethods {\n loadDesign: (design: EmailDesign) => void;\n saveDesign: () => EmailDesign;\n exportHtml: () => Promise<{ html: string; mjml: string }>;\n exportMjml: () => string;\n exportJson: () => EmailDesign;\n destroy: () => void;\n}\n\nexport interface CustomBlock {\n id: string;\n name: string;\n category?: string;\n thumbnail?: string;\n components: any[];\n}\n\ninterface KapthaEmailEditorProps {\n /**\n * API key (required)\n * Get your free key at: hello@kaptha.com\n */\n apiKey: string;\n \n /**\n * Minimum height of the editor\n * @default '600px'\n */\n minHeight?: string;\n \n /**\n * Custom blocks to add to the editor\n */\n customBlocks?: CustomBlock[];\n \n /**\n * Initial design to load\n */\n initialDesign?: EmailDesign;\n \n /**\n * Callback when editor is ready\n */\n onReady?: () => void;\n \n /**\n * Callback when design changes\n */\n onDesignChange?: (design: EmailDesign) => void;\n \n /**\n * Callback when editor loads\n */\n onLoad?: () => void;\n}\n\n// Script loader utility with API wait\n// Declare global type\ndeclare global {\n interface Window {\n KapthaEmailEditor?: any;\n }\n}\n\nfunction loadScript(src: string): Promise<void> {\n return new Promise((resolve, reject) => {\n // Wait for API to be available (handles both new loads and cached scripts)\n const waitForAPI = () => {\n const checkAPI = () => {\n if (typeof (window as any).KapthaEmailEditor !== 'undefined') {\n resolve();\n } else {\n setTimeout(checkAPI, 50);\n }\n };\n checkAPI();\n };\n\n // Check if script is already loaded\n const existingScript = document.querySelector(`script[src=\"${src}\"]`);\n if (existingScript) {\n // Script exists, just wait for API\n waitForAPI();\n return;\n }\n\n // Create and load new script\n const script = document.createElement('script');\n script.src = src;\n script.async = true;\n script.onload = waitForAPI;\n script.onerror = () => reject(new Error(`Failed to load script: ${src}`));\n document.head.appendChild(script);\n });\n}\n\n// CSS loader utility\nfunction loadCSS(href: string): void {\n if (document.querySelector(`link[href=\"${href}\"]`)) {\n return;\n }\n\n const link = document.createElement('link');\n link.rel = 'stylesheet';\n link.href = href;\n document.head.appendChild(link);\n}\n\n/**\n * Kaptha Email Editor React Component\n * \n * Loads the editor from CDN and provides a React interface\n */\nconst KapthaEmailEditor = forwardRef<EditorMethods, KapthaEmailEditorProps>((props, ref) => {\n const {\n apiKey,\n minHeight = '600px',\n customBlocks,\n initialDesign,\n onReady,\n onDesignChange,\n onLoad,\n } = props;\n\n const containerRef = useRef<HTMLDivElement>(null);\n const editorInstanceRef = useRef<any>(null);\n const [isLoaded, setIsLoaded] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n // Expose editor methods to parent via ref\n useImperativeHandle(ref, () => ({\n loadDesign: (design: EmailDesign) => {\n editorInstanceRef.current?.loadDesign(design);\n },\n saveDesign: () => {\n return editorInstanceRef.current?.saveDesign() || { components: [] };\n },\n exportHtml: async () => {\n return editorInstanceRef.current?.exportHtml() || { html: '', mjml: '' };\n },\n exportMjml: () => {\n return editorInstanceRef.current?.exportMjml() || '';\n },\n exportJson: () => {\n return editorInstanceRef.current?.exportJson() || { components: [] };\n },\n destroy: () => {\n editorInstanceRef.current?.destroy();\n editorInstanceRef.current = null;\n },\n }));\n\n // Load CDN resources\n useEffect(() => {\n let mounted = true;\n\n const loadResources = async () => {\n try {\n // Load CSS\n loadCSS(CDN_CSS_URL);\n \n // Load JS\n await loadScript(CDN_JS_URL);\n \n if (mounted) {\n setIsLoaded(true);\n if (onLoad) {\n onLoad();\n }\n }\n } catch (err: any) {\n if (mounted) {\n setError(err.message);\n }\n }\n };\n\n loadResources();\n\n return () => {\n mounted = false;\n };\n }, []);\n\n // Initialize editor once loaded\n useEffect(() => {\n if (!isLoaded || !containerRef.current) return;\n\n // Check if API is available\n const KapthaEmailEditor = (window as any).KapthaEmailEditor;\n if (!KapthaEmailEditor) {\n setError('Kaptha Email Editor API not found');\n return;\n }\n\n try {\n // Create editor instance using CDN API\n editorInstanceRef.current = KapthaEmailEditor.createEditor({\n container: containerRef.current,\n apiKey,\n minHeight,\n customBlocks,\n initialDesign,\n onReady: () => {\n if (onReady) {\n onReady();\n }\n },\n onChange: (design: EmailDesign) => {\n if (onDesignChange) {\n onDesignChange(design);\n }\n },\n });\n } catch (err: any) {\n setError(err.message);\n }\n\n // Cleanup on unmount\n return () => {\n if (editorInstanceRef.current) {\n editorInstanceRef.current.destroy();\n editorInstanceRef.current = null;\n }\n };\n }, [isLoaded, apiKey, minHeight, customBlocks, initialDesign]);\n\n if (error) {\n return (\n <div style={{ \n padding: '20px', \n color: '#e53e3e', \n border: '1px solid #fc8181', \n borderRadius: '6px', \n backgroundColor: '#fff5f5' \n }}>\n <strong>Error loading Kaptha Email Editor:</strong> {error}\n </div>\n );\n }\n\n if (!isLoaded) {\n return (\n <div style={{ \n padding: '20px', \n textAlign: 'center', \n color: '#666' \n }}>\n Loading Kaptha Email Editor...\n </div>\n );\n }\n\n return (\n <div \n ref={containerRef} \n style={{ \n minHeight,\n width: '100%',\n position: 'relative'\n }} \n />\n );\n});\n\nKapthaEmailEditor.displayName = 'KapthaEmailEditor';\n\nexport default KapthaEmailEditor;\n"]}