UNPKG

@actovision/kaptha-email-editor

Version:

React wrapper for Kaptha Email Editor - A powerful drag-and-drop email editor with framework-agnostic API

169 lines (167 loc) 4.72 kB
import * as React from 'react'; import { forwardRef, useRef, useState, useImperativeHandle, useEffect } from 'react'; // src/index.tsx var CDN_BASE_URL = "https://code.kaptha.dev/core/embed"; var CACHE_VERSION = (/* @__PURE__ */ new Date()).toISOString().split("T")[0]; var CDN_JS_URL = `${CDN_BASE_URL}/editor.js?v=${CACHE_VERSION}`; var CDN_CSS_URL = `${CDN_BASE_URL}/editor.css?v=${CACHE_VERSION}`; function loadScript(src) { return new Promise((resolve, reject) => { const waitForAPI = () => { const checkAPI = () => { if (typeof window.KapthaEmailEditor !== "undefined") { resolve(); } else { setTimeout(checkAPI, 50); } }; checkAPI(); }; const existingScript = document.querySelector(`script[src="${src}"]`); if (existingScript) { waitForAPI(); return; } const script = document.createElement("script"); script.src = src; script.async = true; script.onload = waitForAPI; script.onerror = () => reject(new Error(`Failed to load script: ${src}`)); document.head.appendChild(script); }); } function loadCSS(href) { if (document.querySelector(`link[href="${href}"]`)) { return; } const link = document.createElement("link"); link.rel = "stylesheet"; link.href = href; document.head.appendChild(link); } var KapthaEmailEditor = forwardRef((props, ref) => { const { apiKey, minHeight = "600px", customBlocks, initialDesign, onReady, onDesignChange, onLoad } = props; const containerRef = useRef(null); const editorInstanceRef = useRef(null); const [isLoaded, setIsLoaded] = useState(false); const [error, setError] = useState(null); useImperativeHandle(ref, () => ({ loadDesign: (design) => { editorInstanceRef.current?.loadDesign(design); }, saveDesign: () => { return editorInstanceRef.current?.saveDesign() || { components: [] }; }, exportHtml: async () => { return editorInstanceRef.current?.exportHtml() || { html: "", mjml: "" }; }, exportMjml: () => { return editorInstanceRef.current?.exportMjml() || ""; }, exportJson: () => { return editorInstanceRef.current?.exportJson() || { components: [] }; }, destroy: () => { editorInstanceRef.current?.destroy(); editorInstanceRef.current = null; } })); useEffect(() => { let mounted = true; const loadResources = async () => { try { loadCSS(CDN_CSS_URL); await loadScript(CDN_JS_URL); if (mounted) { setIsLoaded(true); if (onLoad) { onLoad(); } } } catch (err) { if (mounted) { setError(err.message); } } }; loadResources(); return () => { mounted = false; }; }, []); useEffect(() => { if (!isLoaded || !containerRef.current) return; const KapthaEmailEditor2 = window.KapthaEmailEditor; if (!KapthaEmailEditor2) { setError("Kaptha Email Editor API not found"); return; } try { editorInstanceRef.current = KapthaEmailEditor2.createEditor({ container: containerRef.current, apiKey, minHeight, customBlocks, initialDesign, onReady: () => { if (onReady) { onReady(); } }, onChange: (design) => { if (onDesignChange) { onDesignChange(design); } } }); } catch (err) { setError(err.message); } return () => { if (editorInstanceRef.current) { editorInstanceRef.current.destroy(); editorInstanceRef.current = null; } }; }, [isLoaded, apiKey, minHeight, customBlocks, initialDesign]); if (error) { return /* @__PURE__ */ React.createElement("div", { style: { padding: "20px", color: "#e53e3e", border: "1px solid #fc8181", borderRadius: "6px", backgroundColor: "#fff5f5" } }, /* @__PURE__ */ React.createElement("strong", null, "Error loading Kaptha Email Editor:"), " ", error); } if (!isLoaded) { return /* @__PURE__ */ React.createElement("div", { style: { padding: "20px", textAlign: "center", color: "#666" } }, "Loading Kaptha Email Editor..."); } return /* @__PURE__ */ React.createElement( "div", { ref: containerRef, style: { minHeight, width: "100%", position: "relative" } } ); }); KapthaEmailEditor.displayName = "KapthaEmailEditor"; var index_default = KapthaEmailEditor; export { index_default as default }; //# sourceMappingURL=index.mjs.map //# sourceMappingURL=index.mjs.map