react-email-studio 3.2.0 → 3.3.1
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.
- package/dist/index.cjs +214 -83
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +13 -1
- package/dist/index.d.ts +13 -1
- package/dist/index.js +212 -83
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -286,6 +286,18 @@ type JsonToHtmlOptions = EmailHtmlOptions;
|
|
|
286
286
|
*/
|
|
287
287
|
declare function jsonToHtml(designInput: unknown, opts?: JsonToHtmlOptions): string;
|
|
288
288
|
|
|
289
|
+
/**
|
|
290
|
+
* Pull usable HTML from a full document (`<!DOCTYPE` / `<html>`) or a fragment string.
|
|
291
|
+
*/
|
|
292
|
+
declare function extractHtmlForDesign(html: string): string;
|
|
293
|
+
/**
|
|
294
|
+
* Wrap HTML (fragment or full email/page document) in a minimal `email_document`
|
|
295
|
+
* with one row, one column, and a single **html** block — suitable for `loadJson`.
|
|
296
|
+
*
|
|
297
|
+
* @returns `null` when there is no non-empty HTML after extraction/normalization.
|
|
298
|
+
*/
|
|
299
|
+
declare function htmlToEmailDesignTemplate(html: string): EmailDocument | null;
|
|
300
|
+
|
|
289
301
|
declare function utf8ToBase64(raw: string): string;
|
|
290
302
|
declare function base64ToUtf8(b64: string): string;
|
|
291
303
|
|
|
@@ -413,4 +425,4 @@ declare const DEVICES: ({
|
|
|
413
425
|
})[];
|
|
414
426
|
declare function PreviewModal({ html, contentWidth, rowCount, blockCount, editorZoom, locale, initialDevice, initialMobileVariant, onClose, C, title, secondaryActionLabel, onSecondaryAction, }: EmailPreviewModalProps): react_jsx_runtime.JSX.Element;
|
|
415
427
|
|
|
416
|
-
export { type BlockBase, type EmailDocument, type EmailDocumentColumn, type EmailDocumentRow, type EmailDocumentSettings, type EmailHtmlOptions, PreviewModal as EmailPreviewModal, type EmailPreviewModalProps, type JsonToHtmlOptions, type MobilePreviewVariant, ReactEmailEditor, type ReactEmailEditorOptions, type ReactEmailEditorProps, type ReactEmailEditorRef, base64ToUtf8, DEVICES as emailPreviewDevices, jsonToHtml, utf8ToBase64 };
|
|
428
|
+
export { type BlockBase, type EmailDocument, type EmailDocumentColumn, type EmailDocumentRow, type EmailDocumentSettings, type EmailHtmlOptions, PreviewModal as EmailPreviewModal, type EmailPreviewModalProps, type JsonToHtmlOptions, type MobilePreviewVariant, ReactEmailEditor, type ReactEmailEditorOptions, type ReactEmailEditorProps, type ReactEmailEditorRef, base64ToUtf8, DEVICES as emailPreviewDevices, extractHtmlForDesign, htmlToEmailDesignTemplate, jsonToHtml, utf8ToBase64 };
|
package/dist/index.d.ts
CHANGED
|
@@ -286,6 +286,18 @@ type JsonToHtmlOptions = EmailHtmlOptions;
|
|
|
286
286
|
*/
|
|
287
287
|
declare function jsonToHtml(designInput: unknown, opts?: JsonToHtmlOptions): string;
|
|
288
288
|
|
|
289
|
+
/**
|
|
290
|
+
* Pull usable HTML from a full document (`<!DOCTYPE` / `<html>`) or a fragment string.
|
|
291
|
+
*/
|
|
292
|
+
declare function extractHtmlForDesign(html: string): string;
|
|
293
|
+
/**
|
|
294
|
+
* Wrap HTML (fragment or full email/page document) in a minimal `email_document`
|
|
295
|
+
* with one row, one column, and a single **html** block — suitable for `loadJson`.
|
|
296
|
+
*
|
|
297
|
+
* @returns `null` when there is no non-empty HTML after extraction/normalization.
|
|
298
|
+
*/
|
|
299
|
+
declare function htmlToEmailDesignTemplate(html: string): EmailDocument | null;
|
|
300
|
+
|
|
289
301
|
declare function utf8ToBase64(raw: string): string;
|
|
290
302
|
declare function base64ToUtf8(b64: string): string;
|
|
291
303
|
|
|
@@ -413,4 +425,4 @@ declare const DEVICES: ({
|
|
|
413
425
|
})[];
|
|
414
426
|
declare function PreviewModal({ html, contentWidth, rowCount, blockCount, editorZoom, locale, initialDevice, initialMobileVariant, onClose, C, title, secondaryActionLabel, onSecondaryAction, }: EmailPreviewModalProps): react_jsx_runtime.JSX.Element;
|
|
415
427
|
|
|
416
|
-
export { type BlockBase, type EmailDocument, type EmailDocumentColumn, type EmailDocumentRow, type EmailDocumentSettings, type EmailHtmlOptions, PreviewModal as EmailPreviewModal, type EmailPreviewModalProps, type JsonToHtmlOptions, type MobilePreviewVariant, ReactEmailEditor, type ReactEmailEditorOptions, type ReactEmailEditorProps, type ReactEmailEditorRef, base64ToUtf8, DEVICES as emailPreviewDevices, jsonToHtml, utf8ToBase64 };
|
|
428
|
+
export { type BlockBase, type EmailDocument, type EmailDocumentColumn, type EmailDocumentRow, type EmailDocumentSettings, type EmailHtmlOptions, PreviewModal as EmailPreviewModal, type EmailPreviewModalProps, type JsonToHtmlOptions, type MobilePreviewVariant, ReactEmailEditor, type ReactEmailEditorOptions, type ReactEmailEditorProps, type ReactEmailEditorRef, base64ToUtf8, DEVICES as emailPreviewDevices, extractHtmlForDesign, htmlToEmailDesignTemplate, jsonToHtml, utf8ToBase64 };
|
package/dist/index.js
CHANGED
|
@@ -136,7 +136,7 @@ var I18N = {
|
|
|
136
136
|
blockPaletteGroupActions: "Buttons & links",
|
|
137
137
|
blockPaletteGroupWidgets: "Widgets",
|
|
138
138
|
closePanel: "Close",
|
|
139
|
-
canvasEmptyHint: "Drag blocks from the library into
|
|
139
|
+
canvasEmptyHint: "Drag row layouts or blocks from the library. Drop blocks into a column or onto the mail preview area.",
|
|
140
140
|
emailContentSettings: "Email content",
|
|
141
141
|
loadingDesign: "Loading design\u2026"
|
|
142
142
|
},
|
|
@@ -1091,7 +1091,7 @@ function rowToHtml(row) {
|
|
|
1091
1091
|
const r = row.ratios[i] ?? 1;
|
|
1092
1092
|
const cs = row.columnStyles && row.columnStyles[i] ? row.columnStyles[i] : {};
|
|
1093
1093
|
const colShell = emailSurfaceBgCss(cs);
|
|
1094
|
-
const
|
|
1094
|
+
const pad3 = cs.padding && typeof cs.padding === "object" && !Array.isArray(cs.padding) ? `padding:${(() => {
|
|
1095
1095
|
const o = cs.padding;
|
|
1096
1096
|
const t = numOr2(o.top, 0);
|
|
1097
1097
|
const rgt = numOr2(o.right, t);
|
|
@@ -1107,7 +1107,7 @@ function rowToHtml(row) {
|
|
|
1107
1107
|
const bl = numOr2(x.bl, tr2);
|
|
1108
1108
|
return `border-radius:${tl}px ${tr2}px ${br}px ${bl}px;`;
|
|
1109
1109
|
})() : typeof cs.borderRadius === "number" && Number.isFinite(cs.borderRadius) ? `border-radius:${cs.borderRadius}px;` : "";
|
|
1110
|
-
return `<div style="flex:${r} 1 0;min-width:0;box-sizing:border-box;${
|
|
1110
|
+
return `<div style="flex:${r} 1 0;min-width:0;box-sizing:border-box;${pad3}${rad}${colShell}">${cell.map(blockToHtml).join("")}</div>`;
|
|
1111
1111
|
}).join("")}</div>`;
|
|
1112
1112
|
const innerTrim = inner.replace(/>\s+</g, "><").trim();
|
|
1113
1113
|
const body = innerTrim || " ";
|
|
@@ -1327,8 +1327,8 @@ function layoutColumnBorderRadiusForDoc(r) {
|
|
|
1327
1327
|
}
|
|
1328
1328
|
return 0;
|
|
1329
1329
|
}
|
|
1330
|
-
function columnPaddingNonZero(
|
|
1331
|
-
return
|
|
1330
|
+
function columnPaddingNonZero(pad3) {
|
|
1331
|
+
return pad3.top !== 0 || pad3.right !== 0 || pad3.bottom !== 0 || pad3.left !== 0;
|
|
1332
1332
|
}
|
|
1333
1333
|
function columnRadiusNonZero(r) {
|
|
1334
1334
|
if (typeof r === "number") return r !== 0;
|
|
@@ -1685,9 +1685,9 @@ function mapBlockToInternal(b, layoutDepth = 0) {
|
|
|
1685
1685
|
if (asNum(s.fontWeight) != null) block.props.fontWeight = s.fontWeight;
|
|
1686
1686
|
if (asNum(s.borderRadius) != null) block.props.borderRadius = s.borderRadius;
|
|
1687
1687
|
if (s.padding && typeof s.padding === "object") {
|
|
1688
|
-
const
|
|
1689
|
-
block.props.paddingV = asNum(
|
|
1690
|
-
block.props.paddingH = asNum(
|
|
1688
|
+
const pad3 = s.padding;
|
|
1689
|
+
block.props.paddingV = asNum(pad3.top) ?? block.props.paddingV;
|
|
1690
|
+
block.props.paddingH = asNum(pad3.right) ?? block.props.paddingH;
|
|
1691
1691
|
}
|
|
1692
1692
|
if (asStr(s.textAlign)) block.props.align = s.textAlign;
|
|
1693
1693
|
break;
|
|
@@ -2202,9 +2202,15 @@ function useLiveCountdown(endDate) {
|
|
|
2202
2202
|
const s = Math.floor(diff % 6e4 / 1e3);
|
|
2203
2203
|
return [d, h, m, s];
|
|
2204
2204
|
}
|
|
2205
|
-
function
|
|
2206
|
-
return {};
|
|
2205
|
+
function layoutSplitChromeBorder(_C, preview) {
|
|
2206
|
+
if (preview) return {};
|
|
2207
|
+
return {
|
|
2208
|
+
border: "1px dotted rgba(148, 163, 184, 0.5)",
|
|
2209
|
+
boxSizing: "border-box"
|
|
2210
|
+
};
|
|
2207
2211
|
}
|
|
2212
|
+
var CONTENT_BLOCK_HOVER_BORDER = "1px dotted rgba(148, 163, 184, 0.5)";
|
|
2213
|
+
var DROP_HERE_HEIGHT_PX = 45;
|
|
2208
2214
|
function blockLinkCaptureHandler(preview, e) {
|
|
2209
2215
|
if (preview) return;
|
|
2210
2216
|
const t = e.target;
|
|
@@ -2236,6 +2242,7 @@ function radiusCssLayout(v) {
|
|
|
2236
2242
|
return "0px";
|
|
2237
2243
|
}
|
|
2238
2244
|
function ContentBlock({ block, selected, onClick, preview, C }) {
|
|
2245
|
+
const [hover, setHover] = useState(false);
|
|
2239
2246
|
const { type, props: p } = block;
|
|
2240
2247
|
const numOr2 = (v, fb) => typeof v === "number" && Number.isFinite(v) ? v : fb;
|
|
2241
2248
|
const boxPx = (v) => {
|
|
@@ -2279,14 +2286,19 @@ function ContentBlock({ block, selected, onClick, preview, C }) {
|
|
|
2279
2286
|
onClick: preview ? void 0 : onClick || void 0,
|
|
2280
2287
|
onClickCapture: (e) => blockLinkCaptureHandler(preview, e),
|
|
2281
2288
|
onAuxClickCapture: (e) => blockLinkCaptureHandler(preview, e),
|
|
2289
|
+
onMouseEnter: preview ? void 0 : () => setHover(true),
|
|
2290
|
+
onMouseLeave: preview ? void 0 : () => setHover(false),
|
|
2282
2291
|
style: {
|
|
2283
2292
|
cursor: preview ? "default" : onClick ? "pointer" : "default",
|
|
2284
2293
|
outline: selected && !preview ? `2px solid ${C.accent}` : "2px solid transparent",
|
|
2285
2294
|
outlineOffset: 1,
|
|
2286
2295
|
borderRadius: 3,
|
|
2287
|
-
transition: "outline .12s",
|
|
2296
|
+
transition: "outline .12s, border-color .12s",
|
|
2288
2297
|
position: "relative",
|
|
2289
|
-
...
|
|
2298
|
+
...preview ? {} : {
|
|
2299
|
+
border: hover ? CONTENT_BLOCK_HOVER_BORDER : "1px solid transparent",
|
|
2300
|
+
boxSizing: "border-box"
|
|
2301
|
+
},
|
|
2290
2302
|
...shellBg,
|
|
2291
2303
|
padding: paddingCss(p.padding),
|
|
2292
2304
|
margin: marginCss(p.margin)
|
|
@@ -2526,7 +2538,7 @@ function NestedRowBlock({
|
|
|
2526
2538
|
outline: rowSelected ? `2px solid ${C.accent}` : "2px solid transparent",
|
|
2527
2539
|
outlineOffset: 1,
|
|
2528
2540
|
transition: "outline .12s",
|
|
2529
|
-
...
|
|
2541
|
+
...layoutSplitChromeBorder(C, preview),
|
|
2530
2542
|
...backgroundLayerStyle({
|
|
2531
2543
|
bgColor: p.bgColor,
|
|
2532
2544
|
bgImage: p.bgImage,
|
|
@@ -2558,7 +2570,10 @@ function NestedRowBlock({
|
|
|
2558
2570
|
style: {
|
|
2559
2571
|
flex: p.ratios?.[ici] ?? 1,
|
|
2560
2572
|
minWidth: 0,
|
|
2561
|
-
|
|
2573
|
+
minHeight: preview ? void 0 : DROP_HERE_HEIGHT_PX,
|
|
2574
|
+
display: "flex",
|
|
2575
|
+
flexDirection: "column",
|
|
2576
|
+
...layoutSplitChromeBorder(C, preview),
|
|
2562
2577
|
...backgroundLayerStyle(cS),
|
|
2563
2578
|
padding: paddingCssLayout(cS.padding),
|
|
2564
2579
|
borderRadius: radiusCssLayout(cS.borderRadius),
|
|
@@ -2775,6 +2790,7 @@ function Cell({
|
|
|
2775
2790
|
/* @__PURE__ */ jsx3("div", { style: { position: "absolute", left: -4, top: "50%", transform: "translateY(-50%)", width: 8, height: 8, borderRadius: "50%", background: C.accent } }),
|
|
2776
2791
|
/* @__PURE__ */ jsx3("div", { style: { position: "absolute", right: -4, top: "50%", transform: "translateY(-50%)", width: 8, height: 8, borderRadius: "50%", background: C.accent } })
|
|
2777
2792
|
] }) : null;
|
|
2793
|
+
const cellEmpty = !preview && blocks.length === 0;
|
|
2778
2794
|
return /* @__PURE__ */ jsxs2(
|
|
2779
2795
|
"div",
|
|
2780
2796
|
{
|
|
@@ -2784,17 +2800,44 @@ function Cell({
|
|
|
2784
2800
|
onDragLeave: handleDragLeave,
|
|
2785
2801
|
onDrop: handleDrop,
|
|
2786
2802
|
style: {
|
|
2787
|
-
|
|
2788
|
-
|
|
2803
|
+
display: "flex",
|
|
2804
|
+
flexDirection: "column",
|
|
2805
|
+
minHeight: preview ? void 0 : cellEmpty ? DROP_HERE_HEIGHT_PX : 44,
|
|
2789
2806
|
borderRadius: 4,
|
|
2790
|
-
...preview ? {} : insertAt !== null ? { border: `1px dotted ${C.accent}`, background: `${C.accent}0a` } :
|
|
2791
|
-
background: insertAt !== null ? `${C.accent}0a` : "transparent",
|
|
2807
|
+
...preview ? {} : insertAt !== null && !cellEmpty ? { border: `1px dotted ${C.accent}`, background: `${C.accent}0a` } : {},
|
|
2808
|
+
background: insertAt !== null && !cellEmpty ? `${C.accent}0a` : "transparent",
|
|
2792
2809
|
transition: "border-color .15s,background .15s",
|
|
2793
2810
|
padding: preview ? 0 : 0,
|
|
2794
2811
|
position: "relative"
|
|
2795
2812
|
},
|
|
2796
2813
|
children: [
|
|
2797
|
-
|
|
2814
|
+
cellEmpty && /* @__PURE__ */ jsx3(
|
|
2815
|
+
"div",
|
|
2816
|
+
{
|
|
2817
|
+
style: {
|
|
2818
|
+
height: DROP_HERE_HEIGHT_PX,
|
|
2819
|
+
minHeight: DROP_HERE_HEIGHT_PX,
|
|
2820
|
+
maxHeight: DROP_HERE_HEIGHT_PX,
|
|
2821
|
+
display: "flex",
|
|
2822
|
+
alignItems: "center",
|
|
2823
|
+
justifyContent: "center",
|
|
2824
|
+
margin: 0,
|
|
2825
|
+
borderRadius: 6,
|
|
2826
|
+
boxSizing: "border-box",
|
|
2827
|
+
textAlign: "center",
|
|
2828
|
+
userSelect: "none",
|
|
2829
|
+
transition: "color .15s, border-color .15s, background .15s, box-shadow .15s",
|
|
2830
|
+
border: insertAt !== null ? `2px dashed ${C.accent}` : `2px dashed ${C.border}`,
|
|
2831
|
+
background: insertAt !== null ? `${C.accent}14` : `${C.canvas}`,
|
|
2832
|
+
boxShadow: insertAt !== null ? `inset 0 0 0 1px ${C.accent}22` : `inset 0 0 0 1px ${C.border}99`,
|
|
2833
|
+
color: insertAt !== null ? C.accent2 : C.muted,
|
|
2834
|
+
fontSize: 10,
|
|
2835
|
+
fontWeight: insertAt !== null ? 700 : 500,
|
|
2836
|
+
letterSpacing: "0.02em"
|
|
2837
|
+
},
|
|
2838
|
+
children: insertAt !== null ? "Release to drop" : "Drop here"
|
|
2839
|
+
}
|
|
2840
|
+
),
|
|
2798
2841
|
/* @__PURE__ */ jsx3(Line, { idx: 0 }),
|
|
2799
2842
|
blocks.map((cb, ci) => /* @__PURE__ */ jsx3(Fragment, { children: /* @__PURE__ */ jsx3(
|
|
2800
2843
|
BlockItem,
|
|
@@ -2845,7 +2888,6 @@ function LayoutRow({
|
|
|
2845
2888
|
transition: "outline .12s",
|
|
2846
2889
|
padding: row.padding,
|
|
2847
2890
|
position: "relative",
|
|
2848
|
-
...editChromeBorder(C, preview),
|
|
2849
2891
|
...backgroundLayerStyle({
|
|
2850
2892
|
bgColor: row.bgColor,
|
|
2851
2893
|
bgImage: row.bgImage,
|
|
@@ -2884,8 +2926,9 @@ function LayoutRow({
|
|
|
2884
2926
|
id: editorId ? `${editorId}-col-${row.id}-${ci}` : void 0,
|
|
2885
2927
|
style: {
|
|
2886
2928
|
flex: row.ratios[ci] ?? 1,
|
|
2887
|
-
minHeight: 50,
|
|
2888
|
-
|
|
2929
|
+
minHeight: preview ? 50 : DROP_HERE_HEIGHT_PX,
|
|
2930
|
+
display: "flex",
|
|
2931
|
+
flexDirection: "column",
|
|
2889
2932
|
...backgroundLayerStyle(cS),
|
|
2890
2933
|
padding: paddingCssLayout(cS.padding),
|
|
2891
2934
|
borderRadius: radiusCssLayout(cS.borderRadius),
|
|
@@ -3100,13 +3143,13 @@ var FONTS = [
|
|
|
3100
3143
|
"Trebuchet MS,sans-serif",
|
|
3101
3144
|
"Impact,sans-serif"
|
|
3102
3145
|
];
|
|
3103
|
-
function paddingToCss(
|
|
3104
|
-
if (typeof
|
|
3105
|
-
if (
|
|
3106
|
-
const t = typeof
|
|
3107
|
-
const r = typeof
|
|
3108
|
-
const b = typeof
|
|
3109
|
-
const l = typeof
|
|
3146
|
+
function paddingToCss(pad3, fallback) {
|
|
3147
|
+
if (typeof pad3 === "number" && Number.isFinite(pad3)) return `${Math.max(0, pad3)}px`;
|
|
3148
|
+
if (pad3 && typeof pad3 === "object" && !Array.isArray(pad3)) {
|
|
3149
|
+
const t = typeof pad3.top === "number" && Number.isFinite(pad3.top) ? pad3.top : fallback;
|
|
3150
|
+
const r = typeof pad3.right === "number" && Number.isFinite(pad3.right) ? pad3.right : t;
|
|
3151
|
+
const b = typeof pad3.bottom === "number" && Number.isFinite(pad3.bottom) ? pad3.bottom : t;
|
|
3152
|
+
const l = typeof pad3.left === "number" && Number.isFinite(pad3.left) ? pad3.left : r;
|
|
3110
3153
|
return `${t}px ${r}px ${b}px ${l}px`;
|
|
3111
3154
|
}
|
|
3112
3155
|
return `${fallback}px`;
|
|
@@ -4902,7 +4945,7 @@ function ContentBlockEditor({ block, onChange, onClose, onUpload, C }) {
|
|
|
4902
4945
|
/* @__PURE__ */ jsx6(NumRangePx, { label: "Letter spacing", value: p.letterSpacing ?? 0, onChange: (n) => set("letterSpacing", n), min: 0, max: 30, step: 0.5, C }),
|
|
4903
4946
|
/* @__PURE__ */ jsx6(PR, { label: "Line height", C, children: /* @__PURE__ */ jsx6("input", { type: "number", style: useIS(C).IS, min: 0.8, max: 4, step: 0.05, value: p.lineHeight ?? 1.2, onChange: (e) => set("lineHeight", +e.target.value) }) }),
|
|
4904
4947
|
/* @__PURE__ */ jsx6(BlockSurfaceBgInspector, { variant: "surface", p, set, C, onUpload, syncKey: block.id }),
|
|
4905
|
-
/* @__PURE__ */ jsx6(PaddingEditor, { value: p.padding, onChange: (
|
|
4948
|
+
/* @__PURE__ */ jsx6(PaddingEditor, { value: p.padding, onChange: (pad3) => set("padding", pad3), C }),
|
|
4906
4949
|
/* @__PURE__ */ jsx6(MarginEditor, { value: p.margin, onChange: (m) => set("margin", m), C })
|
|
4907
4950
|
] });
|
|
4908
4951
|
case "text":
|
|
@@ -4928,7 +4971,7 @@ function ContentBlockEditor({ block, onChange, onClose, onUpload, C }) {
|
|
|
4928
4971
|
/* @__PURE__ */ jsx6(PR, { label: "Line height", C, children: /* @__PURE__ */ jsx6("input", { type: "number", style: useIS(C).IS, min: 1, max: 4, step: 0.05, value: p.lineHeight ?? 1.65, onChange: (e) => set("lineHeight", +e.target.value) }) }),
|
|
4929
4972
|
/* @__PURE__ */ jsx6(NumRangePx, { label: "Letter spacing", value: p.letterSpacing ?? 0, onChange: (n) => set("letterSpacing", n), min: 0, max: 30, step: 0.5, C }),
|
|
4930
4973
|
/* @__PURE__ */ jsx6(BlockSurfaceBgInspector, { variant: "surface", p, set, C, onUpload, syncKey: block.id }),
|
|
4931
|
-
/* @__PURE__ */ jsx6(PaddingEditor, { value: p.padding, onChange: (
|
|
4974
|
+
/* @__PURE__ */ jsx6(PaddingEditor, { value: p.padding, onChange: (pad3) => set("padding", pad3), C }),
|
|
4932
4975
|
/* @__PURE__ */ jsx6(MarginEditor, { value: p.margin, onChange: (m) => set("margin", m), C })
|
|
4933
4976
|
] });
|
|
4934
4977
|
case "html":
|
|
@@ -4953,7 +4996,7 @@ function ContentBlockEditor({ block, onChange, onClose, onUpload, C }) {
|
|
|
4953
4996
|
}
|
|
4954
4997
|
) }, block.id),
|
|
4955
4998
|
/* @__PURE__ */ jsx6(BlockSurfaceBgInspector, { variant: "surface", p, set, C, onUpload, syncKey: block.id }),
|
|
4956
|
-
/* @__PURE__ */ jsx6(PaddingEditor, { value: p.padding, onChange: (
|
|
4999
|
+
/* @__PURE__ */ jsx6(PaddingEditor, { value: p.padding, onChange: (pad3) => set("padding", pad3), C }),
|
|
4957
5000
|
/* @__PURE__ */ jsx6(MarginEditor, { value: p.margin, onChange: (m) => set("margin", m), C })
|
|
4958
5001
|
] });
|
|
4959
5002
|
case "image":
|
|
@@ -4976,7 +5019,7 @@ function ContentBlockEditor({ block, onChange, onClose, onUpload, C }) {
|
|
|
4976
5019
|
/* @__PURE__ */ jsx6(AlignButtons, { value: p.align, onChange: (v) => set("align", v), options: ["left", "center", "right"], C }),
|
|
4977
5020
|
/* @__PURE__ */ jsx6(BorderRadiusEditor, { value: p.borderRadius, onChange: (br) => set("borderRadius", br), C }),
|
|
4978
5021
|
/* @__PURE__ */ jsx6(BlockSurfaceBgInspector, { variant: "surface", p, set, C, onUpload, syncKey: block.id }),
|
|
4979
|
-
/* @__PURE__ */ jsx6(PaddingEditor, { value: p.padding, onChange: (
|
|
5022
|
+
/* @__PURE__ */ jsx6(PaddingEditor, { value: p.padding, onChange: (pad3) => set("padding", pad3), C }),
|
|
4980
5023
|
/* @__PURE__ */ jsx6(MarginEditor, { value: p.margin, onChange: (m) => set("margin", m), C })
|
|
4981
5024
|
] });
|
|
4982
5025
|
case "button":
|
|
@@ -4996,7 +5039,7 @@ function ContentBlockEditor({ block, onChange, onClose, onUpload, C }) {
|
|
|
4996
5039
|
Sel("fontWeight", "Weight", ["400", "500", "600", "700", "800"]),
|
|
4997
5040
|
Tog("fullWidth", "Full Width"),
|
|
4998
5041
|
/* @__PURE__ */ jsx6(BlockSurfaceBgInspector, { variant: "backdrop", p, set, C, onUpload, syncKey: block.id }),
|
|
4999
|
-
/* @__PURE__ */ jsx6(PaddingEditor, { value: p.padding, onChange: (
|
|
5042
|
+
/* @__PURE__ */ jsx6(PaddingEditor, { value: p.padding, onChange: (pad3) => set("padding", pad3), C }),
|
|
5000
5043
|
/* @__PURE__ */ jsx6(MarginEditor, { value: p.margin, onChange: (m) => set("margin", m), C })
|
|
5001
5044
|
] });
|
|
5002
5045
|
case "link":
|
|
@@ -5011,7 +5054,7 @@ function ContentBlockEditor({ block, onChange, onClose, onUpload, C }) {
|
|
|
5011
5054
|
Sel("fontFamily", "Font", FONTS2),
|
|
5012
5055
|
Tog("underline", "Underline"),
|
|
5013
5056
|
/* @__PURE__ */ jsx6(BlockSurfaceBgInspector, { variant: "surface", p, set, C, onUpload, syncKey: block.id }),
|
|
5014
|
-
/* @__PURE__ */ jsx6(PaddingEditor, { value: p.padding, onChange: (
|
|
5057
|
+
/* @__PURE__ */ jsx6(PaddingEditor, { value: p.padding, onChange: (pad3) => set("padding", pad3), C }),
|
|
5015
5058
|
/* @__PURE__ */ jsx6(MarginEditor, { value: p.margin, onChange: (m) => set("margin", m), C })
|
|
5016
5059
|
] });
|
|
5017
5060
|
case "divider":
|
|
@@ -5020,14 +5063,14 @@ function ContentBlockEditor({ block, onChange, onClose, onUpload, C }) {
|
|
|
5020
5063
|
/* @__PURE__ */ jsx6(NumRangePx, { label: "Thickness", value: p.thickness ?? 1, onChange: (n) => set("thickness", n), min: 1, max: 20, step: 1, C }),
|
|
5021
5064
|
/* @__PURE__ */ jsx6(DividerStyleButtons, { value: p.style, onChange: (s) => set("style", s), C }),
|
|
5022
5065
|
/* @__PURE__ */ jsx6(BlockSurfaceBgInspector, { variant: "surface", p, set, C, onUpload, syncKey: block.id }),
|
|
5023
|
-
/* @__PURE__ */ jsx6(PaddingEditor, { value: p.padding, onChange: (
|
|
5066
|
+
/* @__PURE__ */ jsx6(PaddingEditor, { value: p.padding, onChange: (pad3) => set("padding", pad3), C }),
|
|
5024
5067
|
/* @__PURE__ */ jsx6(MarginEditor, { value: p.margin, onChange: (m) => set("margin", m), C })
|
|
5025
5068
|
] });
|
|
5026
5069
|
case "spacer":
|
|
5027
5070
|
return /* @__PURE__ */ jsxs4(Fragment4, { children: [
|
|
5028
5071
|
/* @__PURE__ */ jsx6(NumRangePx, { label: "Height", value: p.height ?? 24, onChange: (n) => set("height", n), min: 4, max: 300, step: 1, C }),
|
|
5029
5072
|
/* @__PURE__ */ jsx6(BlockSurfaceBgInspector, { variant: "surface", p, set, C, onUpload, syncKey: block.id }),
|
|
5030
|
-
/* @__PURE__ */ jsx6(PaddingEditor, { value: p.padding, onChange: (
|
|
5073
|
+
/* @__PURE__ */ jsx6(PaddingEditor, { value: p.padding, onChange: (pad3) => set("padding", pad3), C }),
|
|
5031
5074
|
/* @__PURE__ */ jsx6(MarginEditor, { value: p.margin, onChange: (m) => set("margin", m), C })
|
|
5032
5075
|
] });
|
|
5033
5076
|
case "social":
|
|
@@ -5076,7 +5119,7 @@ function ContentBlockEditor({ block, onChange, onClose, onUpload, C }) {
|
|
|
5076
5119
|
Sel("shape", "Shape", ["circle", "square"]),
|
|
5077
5120
|
/* @__PURE__ */ jsx6(NumRangePx, { label: "Gap", value: p.gap ?? 6, onChange: (n) => set("gap", n), min: 0, max: 40, step: 1, C }),
|
|
5078
5121
|
/* @__PURE__ */ jsx6(BlockSurfaceBgInspector, { variant: "surface", p, set, C, onUpload, syncKey: block.id }),
|
|
5079
|
-
/* @__PURE__ */ jsx6(PaddingEditor, { value: p.padding, onChange: (
|
|
5122
|
+
/* @__PURE__ */ jsx6(PaddingEditor, { value: p.padding, onChange: (pad3) => set("padding", pad3), C }),
|
|
5080
5123
|
/* @__PURE__ */ jsx6(MarginEditor, { value: p.margin, onChange: (m) => set("margin", m), C })
|
|
5081
5124
|
] });
|
|
5082
5125
|
case "video":
|
|
@@ -5136,7 +5179,7 @@ function ContentBlockEditor({ block, onChange, onClose, onUpload, C }) {
|
|
|
5136
5179
|
] }),
|
|
5137
5180
|
/* @__PURE__ */ jsx6(NumRangePx, { label: "Height", value: p.height ?? 280, onChange: (n) => set("height", n), min: 80, max: 720, step: 1, C }),
|
|
5138
5181
|
/* @__PURE__ */ jsx6(BlockSurfaceBgInspector, { variant: "surface", p, set, C, onUpload, syncKey: block.id }),
|
|
5139
|
-
/* @__PURE__ */ jsx6(PaddingEditor, { value: p.padding, onChange: (
|
|
5182
|
+
/* @__PURE__ */ jsx6(PaddingEditor, { value: p.padding, onChange: (pad3) => set("padding", pad3), C }),
|
|
5140
5183
|
/* @__PURE__ */ jsx6(MarginEditor, { value: p.margin, onChange: (m) => set("margin", m), C })
|
|
5141
5184
|
] });
|
|
5142
5185
|
case "menu":
|
|
@@ -5162,7 +5205,7 @@ function ContentBlockEditor({ block, onChange, onClose, onUpload, C }) {
|
|
|
5162
5205
|
/* @__PURE__ */ jsx6(NumRangePx, { label: "Font size", value: p.fontSize ?? 14, onChange: (n) => set("fontSize", n), min: 8, max: 48, step: 1, C }),
|
|
5163
5206
|
/* @__PURE__ */ jsx6(NumRangePx, { label: "Item gap", value: p.gap ?? 20, onChange: (n) => set("gap", n), min: 0, max: 80, step: 1, C }),
|
|
5164
5207
|
/* @__PURE__ */ jsx6(BlockSurfaceBgInspector, { variant: "surface", p, set, C, onUpload, syncKey: block.id }),
|
|
5165
|
-
/* @__PURE__ */ jsx6(PaddingEditor, { value: p.padding, onChange: (
|
|
5208
|
+
/* @__PURE__ */ jsx6(PaddingEditor, { value: p.padding, onChange: (pad3) => set("padding", pad3), C }),
|
|
5166
5209
|
/* @__PURE__ */ jsx6(MarginEditor, { value: p.margin, onChange: (m) => set("margin", m), C })
|
|
5167
5210
|
] });
|
|
5168
5211
|
case "timer": {
|
|
@@ -5202,7 +5245,7 @@ function ContentBlockEditor({ block, onChange, onClose, onUpload, C }) {
|
|
|
5202
5245
|
/* @__PURE__ */ jsx6(AlignButtons, { value: p.align, onChange: (v) => set("align", v), options: ["left", "center", "right"], C }),
|
|
5203
5246
|
Tog("showLabels", "Show Labels"),
|
|
5204
5247
|
/* @__PURE__ */ jsx6(BlockSurfaceBgInspector, { variant: "backdrop", p, set, C, onUpload, syncKey: block.id }),
|
|
5205
|
-
/* @__PURE__ */ jsx6(PaddingEditor, { value: p.padding, onChange: (
|
|
5248
|
+
/* @__PURE__ */ jsx6(PaddingEditor, { value: p.padding, onChange: (pad3) => set("padding", pad3), C }),
|
|
5206
5249
|
/* @__PURE__ */ jsx6(MarginEditor, { value: p.margin, onChange: (m) => set("margin", m), C })
|
|
5207
5250
|
] });
|
|
5208
5251
|
}
|
|
@@ -5299,8 +5342,8 @@ function ContentBlockEditor({ block, onChange, onClose, onUpload, C }) {
|
|
|
5299
5342
|
Tog("striped", "Striped rows"),
|
|
5300
5343
|
/* @__PURE__ */ jsx6(NumRangePx, { label: "Font size", value: p.fontSize ?? 13, onChange: (n) => set("fontSize", n), min: 10, max: 24, step: 1, C }),
|
|
5301
5344
|
/* @__PURE__ */ jsx6(BlockSurfaceBgInspector, { variant: "surface", p, set, C, onUpload, syncKey: block.id }),
|
|
5302
|
-
/* @__PURE__ */ jsx6(PaddingEditor, { value: p.padding, onChange: (
|
|
5303
|
-
/* @__PURE__ */ jsx6(PaddingEditor, { label: "Cell padding", value: p.cellPadding, onChange: (
|
|
5345
|
+
/* @__PURE__ */ jsx6(PaddingEditor, { value: p.padding, onChange: (pad3) => set("padding", pad3), C }),
|
|
5346
|
+
/* @__PURE__ */ jsx6(PaddingEditor, { label: "Cell padding", value: p.cellPadding, onChange: (pad3) => set("cellPadding", pad3), C }),
|
|
5304
5347
|
/* @__PURE__ */ jsx6(MarginEditor, { value: p.margin, onChange: (m) => set("margin", m), C })
|
|
5305
5348
|
] });
|
|
5306
5349
|
case "layout":
|
|
@@ -5693,7 +5736,7 @@ function LayoutRowEditor({
|
|
|
5693
5736
|
}
|
|
5694
5737
|
) })
|
|
5695
5738
|
] }) : null,
|
|
5696
|
-
/* @__PURE__ */ jsx6(PaddingEditor, { label: "Column padding", value: (row.columnStyles || {})[selCol]?.padding, onChange: (
|
|
5739
|
+
/* @__PURE__ */ jsx6(PaddingEditor, { label: "Column padding", value: (row.columnStyles || {})[selCol]?.padding, onChange: (pad3) => updCol(selCol, { padding: pad3 }), C }),
|
|
5697
5740
|
/* @__PURE__ */ jsx6(BorderRadiusEditor, { label: "Column radius", value: (row.columnStyles || {})[selCol]?.borderRadius, onChange: (br) => updCol(selCol, { borderRadius: br }), C })
|
|
5698
5741
|
] })
|
|
5699
5742
|
] })
|
|
@@ -5976,8 +6019,8 @@ function MobilePhoneScaleSlot({ variantKey, children }) {
|
|
|
5976
6019
|
const pw = phone.offsetWidth;
|
|
5977
6020
|
const ph = phone.offsetHeight;
|
|
5978
6021
|
if (cw < 12 || ch < 12 || pw < 12 || ph < 12) return;
|
|
5979
|
-
const
|
|
5980
|
-
const raw = Math.min(1, (cw -
|
|
6022
|
+
const pad3 = 20;
|
|
6023
|
+
const raw = Math.min(1, (cw - pad3) / pw, (ch - pad3) / ph);
|
|
5981
6024
|
const s = Number.isFinite(raw) ? Math.max(0.2, raw) : 1;
|
|
5982
6025
|
setFit({ s, w: pw * s, h: ph * s });
|
|
5983
6026
|
};
|
|
@@ -6847,6 +6890,43 @@ var ReactEmailEditor = forwardRef(
|
|
|
6847
6890
|
}
|
|
6848
6891
|
}
|
|
6849
6892
|
};
|
|
6893
|
+
const insertBlockFromLibrary = (contentType) => {
|
|
6894
|
+
if (!rows.length) return;
|
|
6895
|
+
if (selContentMeta?.inner) {
|
|
6896
|
+
const { rowId, cellIdx, contentIdx, inner } = selContentMeta;
|
|
6897
|
+
dropContent(rowId, cellIdx, {
|
|
6898
|
+
kind: "new",
|
|
6899
|
+
contentType,
|
|
6900
|
+
insertAt: null,
|
|
6901
|
+
nested: { parentBlockIdx: contentIdx, innerCellIdx: inner.cellIdx }
|
|
6902
|
+
});
|
|
6903
|
+
return;
|
|
6904
|
+
}
|
|
6905
|
+
if (selContentMeta?.rowId && typeof selContentMeta.cellIdx === "number" && selContentMeta.cellIdx >= 0) {
|
|
6906
|
+
const r = rows.find((x) => x.id === selContentMeta.rowId);
|
|
6907
|
+
if (r && selContentMeta.cellIdx < r.cells.length) {
|
|
6908
|
+
dropContent(selContentMeta.rowId, selContentMeta.cellIdx, {
|
|
6909
|
+
kind: "new",
|
|
6910
|
+
contentType,
|
|
6911
|
+
insertAt: null
|
|
6912
|
+
});
|
|
6913
|
+
return;
|
|
6914
|
+
}
|
|
6915
|
+
}
|
|
6916
|
+
if (selectedRowId) {
|
|
6917
|
+
const targetRow = rows.find((r) => r.id === selectedRowId);
|
|
6918
|
+
if (targetRow) {
|
|
6919
|
+
dropContent(targetRow.id, 0, {
|
|
6920
|
+
kind: "new",
|
|
6921
|
+
contentType,
|
|
6922
|
+
insertAt: null
|
|
6923
|
+
});
|
|
6924
|
+
return;
|
|
6925
|
+
}
|
|
6926
|
+
}
|
|
6927
|
+
const main = rows[0];
|
|
6928
|
+
dropContent(main.id, 0, { kind: "new", contentType, insertAt: null });
|
|
6929
|
+
};
|
|
6850
6930
|
const deleteContent = (rowId, cellIdx, ci, inner = null) => {
|
|
6851
6931
|
if (!inner) {
|
|
6852
6932
|
mutate((prev) => prev.map((r) => {
|
|
@@ -7443,6 +7523,8 @@ var ReactEmailEditor = forwardRef(
|
|
|
7443
7523
|
if (data.layoutPresetKey) {
|
|
7444
7524
|
const preset = LAYOUT_PRESETS.find((p) => p.key === data.layoutPresetKey);
|
|
7445
7525
|
if (preset) mutate((prev) => [...prev, makeLayoutRow(preset)]);
|
|
7526
|
+
} else if (data.contentType && typeof data.contentType === "string") {
|
|
7527
|
+
insertBlockFromLibrary(data.contentType);
|
|
7446
7528
|
}
|
|
7447
7529
|
} catch {
|
|
7448
7530
|
}
|
|
@@ -7483,6 +7565,21 @@ var ReactEmailEditor = forwardRef(
|
|
|
7483
7565
|
}
|
|
7484
7566
|
return base;
|
|
7485
7567
|
})(),
|
|
7568
|
+
onDragOver: (e) => {
|
|
7569
|
+
e.preventDefault();
|
|
7570
|
+
e.stopPropagation();
|
|
7571
|
+
},
|
|
7572
|
+
onDrop: (e) => {
|
|
7573
|
+
e.preventDefault();
|
|
7574
|
+
e.stopPropagation();
|
|
7575
|
+
try {
|
|
7576
|
+
const data = JSON.parse(e.dataTransfer.getData("application/json") || "{}");
|
|
7577
|
+
if (data.contentType && typeof data.contentType === "string") {
|
|
7578
|
+
insertBlockFromLibrary(data.contentType);
|
|
7579
|
+
}
|
|
7580
|
+
} catch {
|
|
7581
|
+
}
|
|
7582
|
+
},
|
|
7486
7583
|
children: [
|
|
7487
7584
|
rows.length === 0 && /* @__PURE__ */ jsxs9("div", { id: eid("canvas-empty"), style: { padding: "56px 20px", textAlign: "center", color: C.muted, border: `2px dashed ${C.border}`, borderRadius: 7 }, children: [
|
|
7488
7585
|
/* @__PURE__ */ jsx11("div", { style: { fontSize: 30, marginBottom: 10 }, children: "\u2709" }),
|
|
@@ -7694,43 +7791,7 @@ var ReactEmailEditor = forwardRef(
|
|
|
7694
7791
|
onDragStart: (e) => {
|
|
7695
7792
|
e.dataTransfer.setData("application/json", JSON.stringify({ contentType: bt.type }));
|
|
7696
7793
|
},
|
|
7697
|
-
onClick: () =>
|
|
7698
|
-
if (!rows.length) return;
|
|
7699
|
-
if (selContentMeta?.inner) {
|
|
7700
|
-
const { rowId, cellIdx, contentIdx, inner } = selContentMeta;
|
|
7701
|
-
dropContent(rowId, cellIdx, {
|
|
7702
|
-
kind: "new",
|
|
7703
|
-
contentType: bt.type,
|
|
7704
|
-
insertAt: null,
|
|
7705
|
-
nested: { parentBlockIdx: contentIdx, innerCellIdx: inner.cellIdx }
|
|
7706
|
-
});
|
|
7707
|
-
return;
|
|
7708
|
-
}
|
|
7709
|
-
if (selContentMeta?.rowId && typeof selContentMeta.cellIdx === "number" && selContentMeta.cellIdx >= 0) {
|
|
7710
|
-
const r = rows.find((x) => x.id === selContentMeta.rowId);
|
|
7711
|
-
if (r && selContentMeta.cellIdx < r.cells.length) {
|
|
7712
|
-
dropContent(selContentMeta.rowId, selContentMeta.cellIdx, {
|
|
7713
|
-
kind: "new",
|
|
7714
|
-
contentType: bt.type,
|
|
7715
|
-
insertAt: null
|
|
7716
|
-
});
|
|
7717
|
-
return;
|
|
7718
|
-
}
|
|
7719
|
-
}
|
|
7720
|
-
if (selectedRowId) {
|
|
7721
|
-
const targetRow = rows.find((r) => r.id === selectedRowId);
|
|
7722
|
-
if (targetRow) {
|
|
7723
|
-
dropContent(targetRow.id, 0, {
|
|
7724
|
-
kind: "new",
|
|
7725
|
-
contentType: bt.type,
|
|
7726
|
-
insertAt: null
|
|
7727
|
-
});
|
|
7728
|
-
return;
|
|
7729
|
-
}
|
|
7730
|
-
}
|
|
7731
|
-
const main = rows[0];
|
|
7732
|
-
dropContent(main.id, 0, { kind: "new", contentType: bt.type, insertAt: null });
|
|
7733
|
-
},
|
|
7794
|
+
onClick: () => insertBlockFromLibrary(bt.type),
|
|
7734
7795
|
title: selContentMeta?.inner ? "Click to add inside the selected nested column" : selContentMeta?.rowId ? "Click to add in the selected column" : selectedRowId ? "Click to add to column 1 of the selected row" : "Click to add to the first row, first column",
|
|
7735
7796
|
style: {
|
|
7736
7797
|
display: "flex",
|
|
@@ -8101,11 +8162,79 @@ var ReactEmailEditor = forwardRef(
|
|
|
8101
8162
|
);
|
|
8102
8163
|
}
|
|
8103
8164
|
);
|
|
8165
|
+
|
|
8166
|
+
// src/lib/htmlToEmailDesign.ts
|
|
8167
|
+
var pad = (n) => ({ top: n, right: n, bottom: n, left: n });
|
|
8168
|
+
function extractHtmlForDesign(html) {
|
|
8169
|
+
const t = String(html ?? "").trim();
|
|
8170
|
+
if (!t) return "";
|
|
8171
|
+
const head = t.slice(0, 800).toLowerCase();
|
|
8172
|
+
if (!head.includes("<html") && !head.includes("<!doctype")) {
|
|
8173
|
+
return normalizeRichHtmlForStorage(t);
|
|
8174
|
+
}
|
|
8175
|
+
try {
|
|
8176
|
+
const doc = new DOMParser().parseFromString(t, "text/html");
|
|
8177
|
+
const body = doc.body;
|
|
8178
|
+
if (!body) return normalizeRichHtmlForStorage(t);
|
|
8179
|
+
return normalizeRichHtmlForStorage(body.innerHTML);
|
|
8180
|
+
} catch {
|
|
8181
|
+
return normalizeRichHtmlForStorage(t);
|
|
8182
|
+
}
|
|
8183
|
+
}
|
|
8184
|
+
function htmlToEmailDesignTemplate(html) {
|
|
8185
|
+
const inner = extractHtmlForDesign(html);
|
|
8186
|
+
if (!inner) return null;
|
|
8187
|
+
const doc = {
|
|
8188
|
+
type: "email_document",
|
|
8189
|
+
settings: {
|
|
8190
|
+
width: 600,
|
|
8191
|
+
backgroundColor: "#f1f5f9",
|
|
8192
|
+
contentBackgroundColor: "#ffffff",
|
|
8193
|
+
fontFamily: "Arial, Helvetica, sans-serif",
|
|
8194
|
+
lineHeightBase: 1.6,
|
|
8195
|
+
color: "#111827",
|
|
8196
|
+
responsive: true,
|
|
8197
|
+
rtl: false
|
|
8198
|
+
},
|
|
8199
|
+
rows: [
|
|
8200
|
+
{
|
|
8201
|
+
id: "row_html_import",
|
|
8202
|
+
type: "row",
|
|
8203
|
+
layout: { columns: 1, gap: 0, stackOnMobile: true, align: "center" },
|
|
8204
|
+
styles: {
|
|
8205
|
+
backgroundColor: "#ffffff",
|
|
8206
|
+
backgroundRepeat: "no-repeat",
|
|
8207
|
+
backgroundSize: "cover",
|
|
8208
|
+
padding: pad(24),
|
|
8209
|
+
textAlign: "left"
|
|
8210
|
+
},
|
|
8211
|
+
columns: [
|
|
8212
|
+
{
|
|
8213
|
+
id: "col_html_import",
|
|
8214
|
+
layout: { width: "100%", verticalAlign: "top", mobileWidth: "100%" },
|
|
8215
|
+
styles: { padding: pad(0), backgroundColor: "" },
|
|
8216
|
+
blocks: [
|
|
8217
|
+
{
|
|
8218
|
+
id: "block_html_import",
|
|
8219
|
+
type: "html",
|
|
8220
|
+
content: { html: inner },
|
|
8221
|
+
styles: {}
|
|
8222
|
+
}
|
|
8223
|
+
]
|
|
8224
|
+
}
|
|
8225
|
+
]
|
|
8226
|
+
}
|
|
8227
|
+
]
|
|
8228
|
+
};
|
|
8229
|
+
return doc;
|
|
8230
|
+
}
|
|
8104
8231
|
export {
|
|
8105
8232
|
PreviewModal as EmailPreviewModal,
|
|
8106
8233
|
ReactEmailEditor,
|
|
8107
8234
|
base64ToUtf8,
|
|
8108
8235
|
DEVICES as emailPreviewDevices,
|
|
8236
|
+
extractHtmlForDesign,
|
|
8237
|
+
htmlToEmailDesignTemplate,
|
|
8109
8238
|
jsonToHtml,
|
|
8110
8239
|
utf8ToBase64
|
|
8111
8240
|
};
|