@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
JavaScript
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