@savvycal/mjml-editor 0.0.3 → 0.2.0
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/components/editor/EditorCanvas.d.ts +2 -1
- package/dist/components/editor/EditorCanvas.d.ts.map +1 -1
- package/dist/components/editor/EditorCanvas.js +28 -27
- package/dist/components/editor/InteractivePreview.d.ts.map +1 -1
- package/dist/components/editor/InteractivePreview.js +39 -32
- package/dist/components/editor/MjmlEditor.d.ts +16 -1
- package/dist/components/editor/MjmlEditor.d.ts.map +1 -1
- package/dist/components/editor/MjmlEditor.js +104 -87
- package/dist/components/editor/OutlineTree.d.ts.map +1 -1
- package/dist/components/editor/OutlineTree.js +1 -0
- package/dist/components/editor/SourcePreview.d.ts.map +1 -1
- package/dist/components/editor/SourcePreview.js +39 -32
- package/dist/components/editor/VisualEditor.d.ts.map +1 -1
- package/dist/components/editor/VisualEditor.js +54 -27
- package/dist/hooks/useFontLoader.d.ts +1 -0
- package/dist/hooks/useFontLoader.d.ts.map +1 -1
- package/dist/hooks/useFontLoader.js +19 -16
- package/dist/lib/mjml/renderer.js +14 -14
- package/package.json +1 -1
|
@@ -5,7 +5,8 @@ interface EditorCanvasProps {
|
|
|
5
5
|
onTabChange: (tab: EditorTabType) => void;
|
|
6
6
|
leftPanelOpen?: boolean;
|
|
7
7
|
rightPanelOpen?: boolean;
|
|
8
|
+
showThemeToggle?: boolean;
|
|
8
9
|
}
|
|
9
|
-
export declare function EditorCanvas({ activeTab, onTabChange, leftPanelOpen, rightPanelOpen, }: EditorCanvasProps): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export declare function EditorCanvas({ activeTab, onTabChange, leftPanelOpen, rightPanelOpen, showThemeToggle, }: EditorCanvasProps): import("react/jsx-runtime").JSX.Element;
|
|
10
11
|
export {};
|
|
11
12
|
//# sourceMappingURL=EditorCanvas.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EditorCanvas.d.ts","sourceRoot":"","sources":["../../../src/components/editor/EditorCanvas.tsx"],"names":[],"mappings":"AAWA,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE/C,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE1D,UAAU,iBAAiB;IACzB,SAAS,EAAE,aAAa,CAAC;IACzB,WAAW,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,IAAI,CAAC;IAC1C,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,cAAc,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"EditorCanvas.d.ts","sourceRoot":"","sources":["../../../src/components/editor/EditorCanvas.tsx"],"names":[],"mappings":"AAWA,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE/C,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE1D,UAAU,iBAAiB;IACzB,SAAS,EAAE,aAAa,CAAC;IACzB,WAAW,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,IAAI,CAAC;IAC1C,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,wBAAgB,YAAY,CAAC,EAC3B,SAAS,EACT,WAAW,EACX,aAAa,EACb,cAAc,EACd,eAAsB,GACvB,EAAE,iBAAiB,2CA0GnB"}
|
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
import { jsxs as r, jsx as e } from "react/jsx-runtime";
|
|
2
|
-
import { useState as
|
|
3
|
-
import { Monitor as
|
|
4
|
-
import { VisualEditor as
|
|
5
|
-
import { InteractivePreview as
|
|
6
|
-
import { SourceEditor as
|
|
7
|
-
import { useEditor as
|
|
2
|
+
import { useState as x } from "react";
|
|
3
|
+
import { Monitor as v, Smartphone as N, Undo2 as b, Redo2 as w } from "lucide-react";
|
|
4
|
+
import { VisualEditor as k } from "./VisualEditor.js";
|
|
5
|
+
import { InteractivePreview as C } from "./InteractivePreview.js";
|
|
6
|
+
import { SourceEditor as y } from "./SourceEditor.js";
|
|
7
|
+
import { useEditor as E } from "../../context/EditorContext.js";
|
|
8
8
|
import { Button as i } from "../ui/button.js";
|
|
9
|
-
import { Tabs as
|
|
10
|
-
import { ThemeToggle as
|
|
9
|
+
import { Tabs as S, TabsList as M, TabsTrigger as s } from "../ui/tabs.js";
|
|
10
|
+
import { ThemeToggle as P } from "../ui/theme-toggle.js";
|
|
11
11
|
import { cn as d } from "../../lib/utils.js";
|
|
12
|
-
function
|
|
12
|
+
function q({
|
|
13
13
|
activeTab: o,
|
|
14
14
|
onTabChange: t,
|
|
15
15
|
leftPanelOpen: a,
|
|
16
|
-
rightPanelOpen: l
|
|
16
|
+
rightPanelOpen: l,
|
|
17
|
+
showThemeToggle: c = !0
|
|
17
18
|
}) {
|
|
18
|
-
const { undo:
|
|
19
|
+
const { undo: m, redo: u, canUndo: h, canRedo: f } = E(), [n, p] = x("desktop");
|
|
19
20
|
return /* @__PURE__ */ r("div", { className: "flex flex-col h-full", children: [
|
|
20
21
|
/* @__PURE__ */ r("div", { className: "h-11 px-4 flex items-center gap-1 border-b border-border bg-background relative", children: [
|
|
21
22
|
/* @__PURE__ */ e(
|
|
@@ -52,18 +53,18 @@ function L({
|
|
|
52
53
|
}
|
|
53
54
|
),
|
|
54
55
|
o === "preview" && /* @__PURE__ */ e(
|
|
55
|
-
|
|
56
|
+
S,
|
|
56
57
|
{
|
|
57
58
|
value: n,
|
|
58
|
-
onValueChange: (
|
|
59
|
+
onValueChange: (g) => p(g),
|
|
59
60
|
className: "absolute left-1/2 -translate-x-1/2",
|
|
60
|
-
children: /* @__PURE__ */ r(
|
|
61
|
+
children: /* @__PURE__ */ r(M, { className: "h-8", children: [
|
|
61
62
|
/* @__PURE__ */ r(s, { value: "desktop", className: "h-7 px-2 gap-1.5", children: [
|
|
62
|
-
/* @__PURE__ */ e(
|
|
63
|
+
/* @__PURE__ */ e(v, { className: "h-3.5 w-3.5" }),
|
|
63
64
|
/* @__PURE__ */ e("span", { className: "hidden md:inline", children: "Desktop" })
|
|
64
65
|
] }),
|
|
65
66
|
/* @__PURE__ */ r(s, { value: "mobile", className: "h-7 px-2 gap-1.5", children: [
|
|
66
|
-
/* @__PURE__ */ e(
|
|
67
|
+
/* @__PURE__ */ e(N, { className: "h-3.5 w-3.5" }),
|
|
67
68
|
/* @__PURE__ */ e("span", { className: "hidden md:inline", children: "Mobile" })
|
|
68
69
|
] })
|
|
69
70
|
] })
|
|
@@ -76,11 +77,11 @@ function L({
|
|
|
76
77
|
{
|
|
77
78
|
variant: "ghost",
|
|
78
79
|
size: "icon-sm",
|
|
79
|
-
onClick:
|
|
80
|
-
disabled: !
|
|
80
|
+
onClick: m,
|
|
81
|
+
disabled: !h,
|
|
81
82
|
className: "h-7 w-7 rounded-md text-foreground-muted hover:text-foreground hover:bg-accent disabled:opacity-40",
|
|
82
83
|
title: "Undo (Cmd+Z)",
|
|
83
|
-
children: /* @__PURE__ */ e(
|
|
84
|
+
children: /* @__PURE__ */ e(b, { className: "h-4 w-4" })
|
|
84
85
|
}
|
|
85
86
|
),
|
|
86
87
|
/* @__PURE__ */ e(
|
|
@@ -88,29 +89,29 @@ function L({
|
|
|
88
89
|
{
|
|
89
90
|
variant: "ghost",
|
|
90
91
|
size: "icon-sm",
|
|
91
|
-
onClick:
|
|
92
|
-
disabled: !
|
|
92
|
+
onClick: u,
|
|
93
|
+
disabled: !f,
|
|
93
94
|
className: "h-7 w-7 rounded-md text-foreground-muted hover:text-foreground hover:bg-accent disabled:opacity-40",
|
|
94
95
|
title: "Redo (Cmd+Shift+Z)",
|
|
95
|
-
children: /* @__PURE__ */ e(
|
|
96
|
+
children: /* @__PURE__ */ e(w, { className: "h-4 w-4" })
|
|
96
97
|
}
|
|
97
98
|
),
|
|
98
|
-
/* @__PURE__ */ e(
|
|
99
|
+
c && /* @__PURE__ */ e(P, {})
|
|
99
100
|
] })
|
|
100
101
|
] }),
|
|
101
102
|
/* @__PURE__ */ r("div", { className: "flex-1 min-h-0 overflow-hidden", children: [
|
|
102
103
|
o === "edit" && /* @__PURE__ */ e(
|
|
103
|
-
|
|
104
|
+
k,
|
|
104
105
|
{
|
|
105
106
|
leftPanelOpen: a,
|
|
106
107
|
rightPanelOpen: l
|
|
107
108
|
}
|
|
108
109
|
),
|
|
109
|
-
o === "preview" && /* @__PURE__ */ e(
|
|
110
|
-
o === "source" && /* @__PURE__ */ e(
|
|
110
|
+
o === "preview" && /* @__PURE__ */ e(C, { showHeader: !1, previewMode: n }),
|
|
111
|
+
o === "source" && /* @__PURE__ */ e(y, {})
|
|
111
112
|
] })
|
|
112
113
|
] });
|
|
113
114
|
}
|
|
114
115
|
export {
|
|
115
|
-
|
|
116
|
+
q as EditorCanvas
|
|
116
117
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InteractivePreview.d.ts","sourceRoot":"","sources":["../../../src/components/editor/InteractivePreview.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,UAAU,uBAAuB;IAC/B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAID,wBAAgB,kBAAkB,CAAC,EACjC,UAAiB,EACjB,WAAuB,GACxB,EAAE,uBAAuB,
|
|
1
|
+
{"version":3,"file":"InteractivePreview.d.ts","sourceRoot":"","sources":["../../../src/components/editor/InteractivePreview.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,UAAU,uBAAuB;IAC/B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAID,wBAAgB,kBAAkB,CAAC,EACjC,UAAiB,EACjB,WAAuB,GACxB,EAAE,uBAAuB,2CAqLzB"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { jsxs as
|
|
2
|
-
import { useRef as w, useState as
|
|
1
|
+
import { jsxs as n, jsx as s } from "react/jsx-runtime";
|
|
2
|
+
import { useRef as w, useState as h, useEffect as a, useCallback as E } from "react";
|
|
3
3
|
import { useEditor as y } from "../../context/EditorContext.js";
|
|
4
4
|
import { renderMjmlInteractive as C } from "../../lib/mjml/renderer.js";
|
|
5
5
|
const I = 375;
|
|
@@ -7,31 +7,31 @@ function S({
|
|
|
7
7
|
showHeader: p = !0,
|
|
8
8
|
previewMode: g = "desktop"
|
|
9
9
|
}) {
|
|
10
|
-
const { state:
|
|
10
|
+
const { state: r, selectBlock: d } = y(), o = w(null), [m, x] = h(r.document), [k, v] = h({
|
|
11
11
|
html: "",
|
|
12
12
|
errors: []
|
|
13
13
|
});
|
|
14
|
-
|
|
14
|
+
a(() => {
|
|
15
15
|
const e = setTimeout(() => {
|
|
16
|
-
x(
|
|
16
|
+
x(r.document);
|
|
17
17
|
}, 300);
|
|
18
18
|
return () => clearTimeout(e);
|
|
19
|
-
}, [
|
|
19
|
+
}, [r.document]), a(() => {
|
|
20
20
|
let e = !1;
|
|
21
21
|
return C(m).then((t) => {
|
|
22
|
-
e ||
|
|
22
|
+
e || v(t);
|
|
23
23
|
}), () => {
|
|
24
24
|
e = !0;
|
|
25
25
|
};
|
|
26
26
|
}, [m]);
|
|
27
|
-
const { html: u, errors: l } =
|
|
27
|
+
const { html: u, errors: l } = k, i = E(
|
|
28
28
|
(e) => {
|
|
29
29
|
e.data?.type === "BLOCK_SELECTED" && d(e.data.blockId);
|
|
30
30
|
},
|
|
31
31
|
[d]
|
|
32
32
|
);
|
|
33
|
-
|
|
34
|
-
const
|
|
33
|
+
a(() => (window.addEventListener("message", i), () => window.removeEventListener("message", i)), [i]);
|
|
34
|
+
const c = r.selectedBlockId ? `.block-${r.selectedBlockId} { outline: 2px solid #6366f1 !important; outline-offset: -2px; position: relative; }` : "", b = `
|
|
35
35
|
(function() {
|
|
36
36
|
document.addEventListener('click', function(e) {
|
|
37
37
|
e.preventDefault();
|
|
@@ -60,15 +60,15 @@ function S({
|
|
|
60
60
|
}, true);
|
|
61
61
|
})();
|
|
62
62
|
`;
|
|
63
|
-
return
|
|
63
|
+
return a(() => {
|
|
64
64
|
if (o.current) {
|
|
65
65
|
const e = o.current.contentDocument;
|
|
66
66
|
if (e) {
|
|
67
67
|
e.open(), e.write(u), e.close();
|
|
68
68
|
const t = e.createElement("script");
|
|
69
|
-
t.textContent =
|
|
70
|
-
const
|
|
71
|
-
|
|
69
|
+
t.textContent = b, e.body.appendChild(t);
|
|
70
|
+
const f = e.createElement("style");
|
|
71
|
+
f.textContent = `
|
|
72
72
|
[class*="block-"] {
|
|
73
73
|
cursor: pointer;
|
|
74
74
|
transition: outline 0.15s ease;
|
|
@@ -77,22 +77,22 @@ function S({
|
|
|
77
77
|
outline: 1px dashed #94a3b8 !important;
|
|
78
78
|
outline-offset: -1px;
|
|
79
79
|
}
|
|
80
|
-
${
|
|
81
|
-
`, e.head.appendChild(
|
|
80
|
+
${c}
|
|
81
|
+
`, e.head.appendChild(f);
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
|
-
}, [u,
|
|
84
|
+
}, [u, c, b]), a(() => {
|
|
85
85
|
if (o.current) {
|
|
86
86
|
const e = o.current.contentDocument;
|
|
87
87
|
if (e) {
|
|
88
88
|
let t = e.getElementById("selection-highlight");
|
|
89
|
-
t || (t = e.createElement("style"), t.id = "selection-highlight", e.head.appendChild(t)), t.textContent =
|
|
89
|
+
t || (t = e.createElement("style"), t.id = "selection-highlight", e.head.appendChild(t)), t.textContent = c;
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
|
-
}, [
|
|
93
|
-
p && /* @__PURE__ */
|
|
92
|
+
}, [r.selectedBlockId, c]), /* @__PURE__ */ n("div", { className: "flex flex-col h-full", children: [
|
|
93
|
+
p && /* @__PURE__ */ n("div", { className: "h-11 px-4 flex items-center justify-between border-b border-border bg-background", children: [
|
|
94
94
|
/* @__PURE__ */ s("span", { className: "text-sm font-semibold text-foreground", children: "Preview" }),
|
|
95
|
-
l.length > 0 && /* @__PURE__ */
|
|
95
|
+
l.length > 0 && /* @__PURE__ */ n("span", { className: "text-xs font-medium text-amber-600 dark:text-amber-400 bg-amber-50 dark:bg-amber-900/30 px-2 py-0.5 rounded-md", children: [
|
|
96
96
|
l.length,
|
|
97
97
|
" warning",
|
|
98
98
|
l.length !== 1 ? "s" : ""
|
|
@@ -111,17 +111,24 @@ function S({
|
|
|
111
111
|
sandbox: "allow-same-origin allow-scripts"
|
|
112
112
|
}
|
|
113
113
|
) }),
|
|
114
|
-
l.length > 0 && /* @__PURE__ */
|
|
115
|
-
/* @__PURE__ */ s("div", { className: "text-xs font-semibold text-amber-700 mb-2", children: "Warnings" }),
|
|
116
|
-
/* @__PURE__ */ s("div", { className: "space-y-1", children: l.map((e, t) => /* @__PURE__ */
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
114
|
+
l.length > 0 && /* @__PURE__ */ n("div", { className: "max-h-28 overflow-auto border-t border-border bg-amber-50/50 dark:bg-amber-900/20 p-3", children: [
|
|
115
|
+
/* @__PURE__ */ s("div", { className: "text-xs font-semibold text-amber-700 dark:text-amber-300 mb-2", children: "Warnings" }),
|
|
116
|
+
/* @__PURE__ */ s("div", { className: "space-y-1", children: l.map((e, t) => /* @__PURE__ */ n(
|
|
117
|
+
"div",
|
|
118
|
+
{
|
|
119
|
+
className: "text-xs text-amber-600 dark:text-amber-400",
|
|
120
|
+
children: [
|
|
121
|
+
/* @__PURE__ */ n("span", { className: "font-mono", children: [
|
|
122
|
+
"Line ",
|
|
123
|
+
e.line,
|
|
124
|
+
":"
|
|
125
|
+
] }),
|
|
126
|
+
" ",
|
|
127
|
+
e.message
|
|
128
|
+
]
|
|
129
|
+
},
|
|
130
|
+
t
|
|
131
|
+
)) })
|
|
125
132
|
] })
|
|
126
133
|
] });
|
|
127
134
|
}
|
|
@@ -16,7 +16,22 @@ interface MjmlEditorProps {
|
|
|
16
16
|
* @default true
|
|
17
17
|
*/
|
|
18
18
|
applyThemeToDocument?: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Whether to show the theme toggle in the toolbar.
|
|
21
|
+
* @default true
|
|
22
|
+
*/
|
|
23
|
+
showThemeToggle?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Whether the tree panel (left) is open by default.
|
|
26
|
+
* @default true
|
|
27
|
+
*/
|
|
28
|
+
defaultLeftPanelOpen?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Whether the inspector panel (right) is open by default.
|
|
31
|
+
* @default false
|
|
32
|
+
*/
|
|
33
|
+
defaultRightPanelOpen?: boolean;
|
|
19
34
|
}
|
|
20
|
-
export declare function MjmlEditor({ value, onChange, className, defaultTheme, liquidSchema, applyThemeToDocument, }: MjmlEditorProps): import("react/jsx-runtime").JSX.Element;
|
|
35
|
+
export declare function MjmlEditor({ value, onChange, className, defaultTheme, liquidSchema, applyThemeToDocument, showThemeToggle, defaultLeftPanelOpen, defaultRightPanelOpen, }: MjmlEditorProps): import("react/jsx-runtime").JSX.Element;
|
|
21
36
|
export {};
|
|
22
37
|
//# sourceMappingURL=MjmlEditor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MjmlEditor.d.ts","sourceRoot":"","sources":["../../../src/components/editor/MjmlEditor.tsx"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAcnD,UAAU,eAAe;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC;IAC3C,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B;;;;;;;;;OASG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"MjmlEditor.d.ts","sourceRoot":"","sources":["../../../src/components/editor/MjmlEditor.tsx"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAcnD,UAAU,eAAe;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC;IAC3C,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B;;;;;;;;;OASG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;OAGG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;OAGG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC;AAoKD,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,QAAQ,EACR,SAAS,EACT,YAAuB,EACvB,YAAY,EACZ,oBAA2B,EAC3B,eAAsB,EACtB,oBAA2B,EAC3B,qBAA6B,GAC9B,EAAE,eAAe,2CA4CjB"}
|
|
@@ -1,137 +1,154 @@
|
|
|
1
|
-
import { jsx as
|
|
2
|
-
import { useState as
|
|
3
|
-
import { EditorProvider as
|
|
4
|
-
import { ThemeProvider as
|
|
5
|
-
import { LiquidSchemaProvider as
|
|
6
|
-
import { OutlineTree as
|
|
7
|
-
import { EditorCanvas as
|
|
8
|
-
import { BlockInspector as
|
|
9
|
-
import { GlobalStylesPanel as
|
|
10
|
-
import { FloatingPanel as
|
|
11
|
-
import { createEmptyDocument as
|
|
12
|
-
function
|
|
1
|
+
import { jsx as e, jsxs as w, Fragment as L } from "react/jsx-runtime";
|
|
2
|
+
import { useState as c, useEffect as a, useCallback as D, useRef as M } from "react";
|
|
3
|
+
import { EditorProvider as O, useEditor as j } from "../../context/EditorContext.js";
|
|
4
|
+
import { ThemeProvider as x, useTheme as C } from "../../context/ThemeContext.js";
|
|
5
|
+
import { LiquidSchemaProvider as S } from "../../context/LiquidSchemaContext.js";
|
|
6
|
+
import { OutlineTree as K, GLOBAL_STYLES_ID as B } from "./OutlineTree.js";
|
|
7
|
+
import { EditorCanvas as R } from "./EditorCanvas.js";
|
|
8
|
+
import { BlockInspector as A } from "./BlockInspector.js";
|
|
9
|
+
import { GlobalStylesPanel as F } from "./GlobalStylesPanel.js";
|
|
10
|
+
import { FloatingPanel as I } from "../ui/floating-panel.js";
|
|
11
|
+
import { createEmptyDocument as b, parseMjml as N, serializeMjml as $ } from "../../lib/mjml/parser.js";
|
|
12
|
+
function z(n) {
|
|
13
13
|
if (!n || n.trim() === "")
|
|
14
|
-
return
|
|
14
|
+
return b();
|
|
15
15
|
try {
|
|
16
|
-
return
|
|
17
|
-
} catch (
|
|
18
|
-
return console.error("Failed to parse MJML:",
|
|
16
|
+
return N(n);
|
|
17
|
+
} catch (o) {
|
|
18
|
+
return console.error("Failed to parse MJML:", o), b();
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
|
-
function
|
|
21
|
+
function G({
|
|
22
22
|
className: n,
|
|
23
|
-
children:
|
|
23
|
+
children: o
|
|
24
24
|
}) {
|
|
25
|
-
const { resolvedTheme:
|
|
26
|
-
return /* @__PURE__ */
|
|
25
|
+
const { resolvedTheme: l } = C();
|
|
26
|
+
return /* @__PURE__ */ e(
|
|
27
27
|
"div",
|
|
28
28
|
{
|
|
29
|
-
className: `mjml-editor ${
|
|
30
|
-
children:
|
|
29
|
+
className: `mjml-editor ${l} relative h-full w-full overflow-hidden bg-background text-foreground antialiased ${n || ""}`,
|
|
30
|
+
children: o
|
|
31
31
|
}
|
|
32
32
|
);
|
|
33
33
|
}
|
|
34
|
-
function
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
}, [
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}, [
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
34
|
+
function H({
|
|
35
|
+
onChange: n,
|
|
36
|
+
showThemeToggle: o = !0,
|
|
37
|
+
defaultLeftPanelOpen: l = !0,
|
|
38
|
+
defaultRightPanelOpen: T = !1
|
|
39
|
+
}) {
|
|
40
|
+
const { state: r, undo: d, redo: u, canUndo: f, canRedo: m, deleteBlock: p, selectBlock: h } = j(), [i, g] = c(l), [s, k] = c(T), [y, P] = c("edit"), E = M(n);
|
|
41
|
+
return a(() => {
|
|
42
|
+
E.current = n;
|
|
43
|
+
}, [n]), a(() => {
|
|
44
|
+
r.selectedBlockId && k(!0);
|
|
45
|
+
}, [r.selectedBlockId]), a(() => {
|
|
46
|
+
const v = $(r.document);
|
|
47
|
+
E.current(v);
|
|
48
|
+
}, [r.document]), a(() => {
|
|
49
|
+
const v = (t) => {
|
|
50
|
+
if (!(t.target instanceof HTMLInputElement || t.target instanceof HTMLTextAreaElement || t.target?.isContentEditable)) {
|
|
51
|
+
if ((t.metaKey || t.ctrlKey) && t.key === "z") {
|
|
52
|
+
t.preventDefault(), t.shiftKey ? m && u() : f && d();
|
|
48
53
|
return;
|
|
49
54
|
}
|
|
50
|
-
if ((
|
|
51
|
-
|
|
55
|
+
if ((t.key === "Delete" || t.key === "Backspace") && r.selectedBlockId && r.selectedBlockId !== B) {
|
|
56
|
+
t.preventDefault(), p(r.selectedBlockId);
|
|
52
57
|
return;
|
|
53
58
|
}
|
|
54
|
-
if (
|
|
55
|
-
|
|
59
|
+
if (t.key === "Escape" && r.selectedBlockId) {
|
|
60
|
+
t.preventDefault(), h(null);
|
|
56
61
|
return;
|
|
57
62
|
}
|
|
58
63
|
}
|
|
59
64
|
};
|
|
60
|
-
return window.addEventListener("keydown",
|
|
65
|
+
return window.addEventListener("keydown", v), () => window.removeEventListener("keydown", v);
|
|
61
66
|
}, [
|
|
62
|
-
|
|
63
|
-
s,
|
|
64
|
-
a,
|
|
67
|
+
d,
|
|
65
68
|
u,
|
|
66
|
-
m,
|
|
67
69
|
f,
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
70
|
+
m,
|
|
71
|
+
p,
|
|
72
|
+
h,
|
|
73
|
+
r.selectedBlockId
|
|
74
|
+
]), /* @__PURE__ */ w("div", { className: "relative h-full overflow-hidden", children: [
|
|
75
|
+
/* @__PURE__ */ e("div", { className: "absolute inset-0 bg-canvas", children: /* @__PURE__ */ e(
|
|
76
|
+
R,
|
|
72
77
|
{
|
|
73
|
-
activeTab:
|
|
74
|
-
onTabChange:
|
|
75
|
-
leftPanelOpen:
|
|
76
|
-
rightPanelOpen:
|
|
78
|
+
activeTab: y,
|
|
79
|
+
onTabChange: P,
|
|
80
|
+
leftPanelOpen: i,
|
|
81
|
+
rightPanelOpen: s,
|
|
82
|
+
showThemeToggle: o
|
|
77
83
|
}
|
|
78
84
|
) }),
|
|
79
|
-
|
|
80
|
-
/* @__PURE__ */
|
|
81
|
-
|
|
85
|
+
y === "edit" && /* @__PURE__ */ w(L, { children: [
|
|
86
|
+
/* @__PURE__ */ e(
|
|
87
|
+
I,
|
|
82
88
|
{
|
|
83
89
|
side: "left",
|
|
84
|
-
isOpen:
|
|
85
|
-
onToggle: () =>
|
|
90
|
+
isOpen: i,
|
|
91
|
+
onToggle: () => g(!i),
|
|
86
92
|
width: 256,
|
|
87
|
-
children: /* @__PURE__ */
|
|
93
|
+
children: /* @__PURE__ */ e(K, { onTogglePanel: () => g(!1) })
|
|
88
94
|
}
|
|
89
95
|
),
|
|
90
|
-
/* @__PURE__ */
|
|
91
|
-
|
|
96
|
+
/* @__PURE__ */ e(
|
|
97
|
+
I,
|
|
92
98
|
{
|
|
93
99
|
side: "right",
|
|
94
|
-
isOpen:
|
|
95
|
-
onToggle: () =>
|
|
100
|
+
isOpen: s,
|
|
101
|
+
onToggle: () => k(!s),
|
|
96
102
|
width: 300,
|
|
97
|
-
children:
|
|
98
|
-
|
|
103
|
+
children: r.selectedBlockId === B ? /* @__PURE__ */ e(
|
|
104
|
+
F,
|
|
99
105
|
{
|
|
100
|
-
onTogglePanel: () =>
|
|
106
|
+
onTogglePanel: () => k(!1)
|
|
101
107
|
}
|
|
102
|
-
) : /* @__PURE__ */
|
|
108
|
+
) : /* @__PURE__ */ e(A, { onTogglePanel: () => k(!1) })
|
|
103
109
|
}
|
|
104
110
|
)
|
|
105
111
|
] })
|
|
106
112
|
] });
|
|
107
113
|
}
|
|
108
|
-
function
|
|
114
|
+
function te({
|
|
109
115
|
value: n,
|
|
110
|
-
onChange:
|
|
111
|
-
className:
|
|
112
|
-
defaultTheme:
|
|
113
|
-
liquidSchema:
|
|
114
|
-
applyThemeToDocument:
|
|
116
|
+
onChange: o,
|
|
117
|
+
className: l,
|
|
118
|
+
defaultTheme: T = "system",
|
|
119
|
+
liquidSchema: r,
|
|
120
|
+
applyThemeToDocument: d = !0,
|
|
121
|
+
showThemeToggle: u = !0,
|
|
122
|
+
defaultLeftPanelOpen: f = !0,
|
|
123
|
+
defaultRightPanelOpen: m = !1
|
|
115
124
|
}) {
|
|
116
|
-
const [
|
|
117
|
-
|
|
118
|
-
|
|
125
|
+
const [p, h] = c(!1);
|
|
126
|
+
a(() => {
|
|
127
|
+
h(!0);
|
|
119
128
|
}, []);
|
|
120
|
-
const [
|
|
121
|
-
(
|
|
122
|
-
|
|
129
|
+
const [i] = c(() => z(n)), g = D(
|
|
130
|
+
(s) => {
|
|
131
|
+
o(s);
|
|
123
132
|
},
|
|
124
|
-
[
|
|
133
|
+
[o]
|
|
125
134
|
);
|
|
126
|
-
return
|
|
127
|
-
|
|
135
|
+
return p ? /* @__PURE__ */ e(
|
|
136
|
+
x,
|
|
128
137
|
{
|
|
129
|
-
defaultTheme:
|
|
130
|
-
applyToDocument:
|
|
131
|
-
children: /* @__PURE__ */
|
|
138
|
+
defaultTheme: T,
|
|
139
|
+
applyToDocument: d,
|
|
140
|
+
children: /* @__PURE__ */ e(S, { schema: r, children: /* @__PURE__ */ e(G, { className: l, children: /* @__PURE__ */ e(O, { initialDocument: i, children: /* @__PURE__ */ e(
|
|
141
|
+
H,
|
|
142
|
+
{
|
|
143
|
+
onChange: g,
|
|
144
|
+
showThemeToggle: u,
|
|
145
|
+
defaultLeftPanelOpen: f,
|
|
146
|
+
defaultRightPanelOpen: m
|
|
147
|
+
}
|
|
148
|
+
) }) }) })
|
|
132
149
|
}
|
|
133
|
-
) : /* @__PURE__ */
|
|
150
|
+
) : /* @__PURE__ */ e("div", { className: `h-full w-full bg-background ${l || ""}` });
|
|
134
151
|
}
|
|
135
152
|
export {
|
|
136
|
-
|
|
153
|
+
te as MjmlEditor
|
|
137
154
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OutlineTree.d.ts","sourceRoot":"","sources":["../../../src/components/editor/OutlineTree.tsx"],"names":[],"mappings":"AA8BA,eAAO,MAAM,gBAAgB,sBAAsB,CAAC;AA+NpD,UAAU,gBAAgB;IACxB,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;CAC5B;AAED,wBAAgB,WAAW,CAAC,EAAE,aAAa,EAAE,EAAE,gBAAgB,
|
|
1
|
+
{"version":3,"file":"OutlineTree.d.ts","sourceRoot":"","sources":["../../../src/components/editor/OutlineTree.tsx"],"names":[],"mappings":"AA8BA,eAAO,MAAM,gBAAgB,sBAAsB,CAAC;AA+NpD,UAAU,gBAAgB;IACxB,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;CAC5B;AAED,wBAAgB,WAAW,CAAC,EAAE,aAAa,EAAE,EAAE,gBAAgB,2CAkI9D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SourcePreview.d.ts","sourceRoot":"","sources":["../../../src/components/editor/SourcePreview.tsx"],"names":[],"mappings":"AAGA,UAAU,kBAAkB;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,aAAa,CAAC,EAC5B,UAAU,EACV,UAAgB,GACjB,EAAE,kBAAkB,
|
|
1
|
+
{"version":3,"file":"SourcePreview.d.ts","sourceRoot":"","sources":["../../../src/components/editor/SourcePreview.tsx"],"names":[],"mappings":"AAGA,UAAU,kBAAkB;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,aAAa,CAAC,EAC5B,UAAU,EACV,UAAgB,GACjB,EAAE,kBAAkB,2CAqFpB"}
|
|
@@ -1,41 +1,41 @@
|
|
|
1
1
|
import { jsxs as r, jsx as n } from "react/jsx-runtime";
|
|
2
|
-
import { useRef as
|
|
3
|
-
import { renderMjmlString as
|
|
2
|
+
import { useRef as x, useState as b, useEffect as i } from "react";
|
|
3
|
+
import { renderMjmlString as h } from "../../lib/mjml/renderer.js";
|
|
4
4
|
function w({
|
|
5
5
|
mjmlSource: s,
|
|
6
|
-
debounceMs:
|
|
6
|
+
debounceMs: m = 300
|
|
7
7
|
}) {
|
|
8
|
-
const
|
|
8
|
+
const a = x(null), [l, f] = b(s), [u, d] = b({
|
|
9
9
|
html: "",
|
|
10
10
|
errors: []
|
|
11
11
|
});
|
|
12
|
-
|
|
12
|
+
i(() => {
|
|
13
13
|
const e = setTimeout(() => {
|
|
14
|
-
|
|
15
|
-
},
|
|
14
|
+
f(s);
|
|
15
|
+
}, m);
|
|
16
16
|
return () => clearTimeout(e);
|
|
17
|
-
}, [s,
|
|
18
|
-
if (!
|
|
19
|
-
|
|
17
|
+
}, [s, m]), i(() => {
|
|
18
|
+
if (!l.trim()) {
|
|
19
|
+
d({ html: "", errors: [] });
|
|
20
20
|
return;
|
|
21
21
|
}
|
|
22
22
|
let e = !1;
|
|
23
|
-
return
|
|
24
|
-
e ||
|
|
23
|
+
return h(l).then((o) => {
|
|
24
|
+
e || d(o);
|
|
25
25
|
}), () => {
|
|
26
26
|
e = !0;
|
|
27
27
|
};
|
|
28
|
-
}, [
|
|
29
|
-
const { html:
|
|
30
|
-
return
|
|
31
|
-
if (
|
|
32
|
-
const e =
|
|
33
|
-
e && (e.open(), e.write(
|
|
28
|
+
}, [l]);
|
|
29
|
+
const { html: c, errors: t } = u;
|
|
30
|
+
return i(() => {
|
|
31
|
+
if (a.current) {
|
|
32
|
+
const e = a.current.contentDocument;
|
|
33
|
+
e && (e.open(), e.write(c), e.close());
|
|
34
34
|
}
|
|
35
|
-
}, [
|
|
35
|
+
}, [c]), /* @__PURE__ */ r("div", { className: "flex flex-col h-full", children: [
|
|
36
36
|
/* @__PURE__ */ r("div", { className: "h-11 px-4 flex items-center justify-between border-b border-border bg-background", children: [
|
|
37
37
|
/* @__PURE__ */ n("span", { className: "text-sm font-semibold text-foreground", children: "Preview" }),
|
|
38
|
-
t.length > 0 && /* @__PURE__ */ r("span", { className: "text-xs font-medium text-amber-600 bg-amber-50 px-2 py-0.5 rounded-md", children: [
|
|
38
|
+
t.length > 0 && /* @__PURE__ */ r("span", { className: "text-xs font-medium text-amber-600 dark:text-amber-400 bg-amber-50 dark:bg-amber-900/30 px-2 py-0.5 rounded-md", children: [
|
|
39
39
|
t.length,
|
|
40
40
|
" warning",
|
|
41
41
|
t.length !== 1 ? "s" : ""
|
|
@@ -44,23 +44,30 @@ function w({
|
|
|
44
44
|
/* @__PURE__ */ n("div", { className: "flex-1 overflow-auto bg-muted", children: /* @__PURE__ */ n(
|
|
45
45
|
"iframe",
|
|
46
46
|
{
|
|
47
|
-
ref:
|
|
47
|
+
ref: a,
|
|
48
48
|
title: "Source Preview",
|
|
49
49
|
className: "w-full h-full border-0 bg-white",
|
|
50
50
|
sandbox: "allow-same-origin"
|
|
51
51
|
}
|
|
52
52
|
) }),
|
|
53
|
-
t.length > 0 && /* @__PURE__ */ r("div", { className: "max-h-28 overflow-auto border-t border-border bg-amber-50/50 p-3", children: [
|
|
54
|
-
/* @__PURE__ */ n("div", { className: "text-xs font-semibold text-amber-700 mb-2", children: "Warnings" }),
|
|
55
|
-
/* @__PURE__ */ n("div", { className: "space-y-1", children: t.map((e,
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
53
|
+
t.length > 0 && /* @__PURE__ */ r("div", { className: "max-h-28 overflow-auto border-t border-border bg-amber-50/50 dark:bg-amber-900/20 p-3", children: [
|
|
54
|
+
/* @__PURE__ */ n("div", { className: "text-xs font-semibold text-amber-700 dark:text-amber-300 mb-2", children: "Warnings" }),
|
|
55
|
+
/* @__PURE__ */ n("div", { className: "space-y-1", children: t.map((e, o) => /* @__PURE__ */ r(
|
|
56
|
+
"div",
|
|
57
|
+
{
|
|
58
|
+
className: "text-xs text-amber-600 dark:text-amber-400",
|
|
59
|
+
children: [
|
|
60
|
+
/* @__PURE__ */ r("span", { className: "font-mono", children: [
|
|
61
|
+
"Line ",
|
|
62
|
+
e.line,
|
|
63
|
+
":"
|
|
64
|
+
] }),
|
|
65
|
+
" ",
|
|
66
|
+
e.message
|
|
67
|
+
]
|
|
68
|
+
},
|
|
69
|
+
o
|
|
70
|
+
)) })
|
|
64
71
|
] })
|
|
65
72
|
] });
|
|
66
73
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VisualEditor.d.ts","sourceRoot":"","sources":["../../../src/components/editor/VisualEditor.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"VisualEditor.d.ts","sourceRoot":"","sources":["../../../src/components/editor/VisualEditor.tsx"],"names":[],"mappings":"AAyBA,UAAU,iBAAiB;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,wBAAgB,YAAY,CAAC,EAC3B,aAAa,EACb,cAAc,GACf,EAAE,iBAAiB,2CAuGnB"}
|
|
@@ -1,43 +1,70 @@
|
|
|
1
|
-
import { jsx as
|
|
2
|
-
import { useEditor as
|
|
3
|
-
import { ScrollArea as
|
|
4
|
-
import { VisualSection as
|
|
5
|
-
import { useFontLoader as
|
|
6
|
-
import { useStyleLoader as
|
|
7
|
-
|
|
1
|
+
import { jsx as e, jsxs as s } from "react/jsx-runtime";
|
|
2
|
+
import { useEditor as x } from "../../context/EditorContext.js";
|
|
3
|
+
import { ScrollArea as a } from "../ui/scroll-area.js";
|
|
4
|
+
import { VisualSection as y } from "./visual-blocks/VisualSection.js";
|
|
5
|
+
import { useFontLoader as k } from "../../hooks/useFontLoader.js";
|
|
6
|
+
import { useStyleLoader as E, VISUAL_EDITOR_SCOPE_CLASS as L } from "../../hooks/useStyleLoader.js";
|
|
7
|
+
import { createEmptyDocument as S } from "../../lib/mjml/parser.js";
|
|
8
|
+
function _(o) {
|
|
9
|
+
return o.tagName !== "mjml" ? !1 : o.children?.some((n) => n.tagName === "mj-body") ?? !1;
|
|
10
|
+
}
|
|
11
|
+
const v = 256, A = 300, m = 12, u = 24;
|
|
8
12
|
function G({
|
|
9
|
-
leftPanelOpen:
|
|
10
|
-
rightPanelOpen:
|
|
13
|
+
leftPanelOpen: o,
|
|
14
|
+
rightPanelOpen: n
|
|
11
15
|
}) {
|
|
12
|
-
const { state:
|
|
13
|
-
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
const { state: d, selectBlock: h, setDocument: f } = x();
|
|
17
|
+
k(), E();
|
|
18
|
+
const b = () => {
|
|
19
|
+
f(S());
|
|
20
|
+
};
|
|
21
|
+
if (!_(d.document))
|
|
22
|
+
return /* @__PURE__ */ e(
|
|
23
|
+
a,
|
|
24
|
+
{
|
|
25
|
+
className: "h-full",
|
|
26
|
+
viewportStyle: { backgroundColor: "#ffffff" },
|
|
27
|
+
children: /* @__PURE__ */ e("div", { className: "flex items-center justify-center p-8 min-h-[400px]", children: /* @__PURE__ */ s("div", { className: "bg-red-50 border border-red-200 rounded-lg p-6 max-w-md text-center", children: [
|
|
28
|
+
/* @__PURE__ */ e("p", { className: "text-red-700 font-medium mb-2", children: "Invalid MJML structure" }),
|
|
29
|
+
/* @__PURE__ */ e("p", { className: "text-red-600 text-sm mb-4", children: "The document is missing required elements like mj-body. Reset to a blank template to continue editing." }),
|
|
30
|
+
/* @__PURE__ */ e(
|
|
31
|
+
"button",
|
|
32
|
+
{
|
|
33
|
+
onClick: b,
|
|
34
|
+
className: "px-4 py-2 bg-red-600 text-white text-sm font-medium rounded-md hover:bg-red-700 transition-colors",
|
|
35
|
+
children: "Reset to blank template"
|
|
36
|
+
}
|
|
37
|
+
)
|
|
38
|
+
] }) })
|
|
39
|
+
}
|
|
40
|
+
);
|
|
41
|
+
const r = d.document.children?.find((t) => t.tagName === "mj-body"), i = r?.attributes.width || "600px", p = r?.attributes["background-color"], g = (t) => {
|
|
42
|
+
t.target === t.currentTarget && h(null);
|
|
43
|
+
}, c = o ? v + m + u : 16, l = n ? A + m + u : 16, N = (parseInt(i, 10) || 600) + c + l;
|
|
44
|
+
return /* @__PURE__ */ e(
|
|
45
|
+
a,
|
|
19
46
|
{
|
|
20
47
|
className: "h-full",
|
|
21
48
|
orientation: "both",
|
|
22
|
-
viewportStyle: { backgroundColor:
|
|
23
|
-
children: /* @__PURE__ */
|
|
49
|
+
viewportStyle: { backgroundColor: p || "#ffffff" },
|
|
50
|
+
children: /* @__PURE__ */ e(
|
|
24
51
|
"div",
|
|
25
52
|
{
|
|
26
53
|
className: "py-8",
|
|
27
54
|
style: {
|
|
28
|
-
paddingLeft:
|
|
29
|
-
paddingRight:
|
|
30
|
-
minWidth:
|
|
55
|
+
paddingLeft: c,
|
|
56
|
+
paddingRight: l,
|
|
57
|
+
minWidth: N
|
|
31
58
|
},
|
|
32
|
-
onClick:
|
|
33
|
-
children: /* @__PURE__ */
|
|
59
|
+
onClick: g,
|
|
60
|
+
children: /* @__PURE__ */ s(
|
|
34
61
|
"div",
|
|
35
62
|
{
|
|
36
|
-
className: `light mx-auto w-full ${
|
|
37
|
-
style: { maxWidth:
|
|
63
|
+
className: `light mx-auto w-full ${L}`,
|
|
64
|
+
style: { maxWidth: i },
|
|
38
65
|
children: [
|
|
39
|
-
|
|
40
|
-
(!
|
|
66
|
+
r?.children?.map((t) => /* @__PURE__ */ e(y, { node: t }, t._id)),
|
|
67
|
+
(!r?.children || r.children.length === 0) && /* @__PURE__ */ e("div", { className: "bg-zinc-100 rounded-lg border-2 border-dashed border-zinc-300 p-12 text-center", children: /* @__PURE__ */ e("p", { className: "text-zinc-500", children: "Add a section to get started" }) })
|
|
41
68
|
]
|
|
42
69
|
}
|
|
43
70
|
)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useFontLoader.d.ts","sourceRoot":"","sources":["../../src/hooks/useFontLoader.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useFontLoader.d.ts","sourceRoot":"","sources":["../../src/hooks/useFontLoader.ts"],"names":[],"mappings":"AAWA;;;;GAIG;AACH,wBAAgB,aAAa,SAgD5B"}
|
|
@@ -1,21 +1,24 @@
|
|
|
1
|
-
import { useEffect as
|
|
2
|
-
import { useEditor as
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
import { useMemo as m, useEffect as s } from "react";
|
|
2
|
+
import { useEditor as a } from "../context/EditorContext.js";
|
|
3
|
+
const o = "mjml-editor-font-", i = {
|
|
4
|
+
name: "Ubuntu",
|
|
5
|
+
href: "https://fonts.googleapis.com/css?family=Ubuntu:300,400,500,700"
|
|
6
|
+
};
|
|
7
|
+
function u() {
|
|
8
|
+
const { fonts: c } = a(), n = m(() => [i, ...c], [c]);
|
|
9
|
+
s(() => (document.querySelectorAll(`link[id^="${o}"]`).forEach((e) => {
|
|
10
|
+
const r = e.id.replace(o, "").replace(/-/g, " ");
|
|
11
|
+
n.some(
|
|
12
|
+
(l) => l.name === r || l.name.replace(/\s+/g, "-") === e.id.replace(o, "")
|
|
10
13
|
) || e.remove();
|
|
11
|
-
}),
|
|
12
|
-
const
|
|
13
|
-
let
|
|
14
|
-
|
|
14
|
+
}), n.forEach((e) => {
|
|
15
|
+
const r = `${o}${e.name.replace(/\s+/g, "-")}`;
|
|
16
|
+
let t = document.getElementById(r);
|
|
17
|
+
t ? t.href !== e.href && (t.href = e.href) : (t = document.createElement("link"), t.id = r, t.rel = "stylesheet", t.href = e.href, document.head.appendChild(t));
|
|
15
18
|
}), () => {
|
|
16
|
-
document.querySelectorAll(`link[id^="${
|
|
17
|
-
}), [
|
|
19
|
+
document.querySelectorAll(`link[id^="${o}"]`).forEach((e) => e.remove());
|
|
20
|
+
}), [n]);
|
|
18
21
|
}
|
|
19
22
|
export {
|
|
20
|
-
|
|
23
|
+
u as useFontLoader
|
|
21
24
|
};
|
|
@@ -9,24 +9,24 @@ function m(r) {
|
|
|
9
9
|
...r,
|
|
10
10
|
children: r.children?.map(m)
|
|
11
11
|
};
|
|
12
|
-
const t = r.attributes["mj-class"] || "", e = `block-${r._id}`,
|
|
12
|
+
const t = r.attributes["mj-class"] || "", e = `block-${r._id}`, n = t ? `${t} ${e}` : e;
|
|
13
13
|
return {
|
|
14
14
|
...r,
|
|
15
|
-
attributes: { ...r.attributes, "mj-class":
|
|
15
|
+
attributes: { ...r.attributes, "mj-class": n },
|
|
16
16
|
children: r.children?.map(m)
|
|
17
17
|
};
|
|
18
18
|
}
|
|
19
|
-
function
|
|
20
|
-
return
|
|
19
|
+
function p(r) {
|
|
20
|
+
return g(r);
|
|
21
21
|
}
|
|
22
|
-
function
|
|
23
|
-
const e = " ".repeat(t),
|
|
24
|
-
([a,
|
|
25
|
-
).map(([a,
|
|
22
|
+
function g(r, t = 0) {
|
|
23
|
+
const e = " ".repeat(t), n = r.tagName, l = Object.entries(r.attributes || {}).filter(
|
|
24
|
+
([a, s]) => a !== "_id" && s !== "" && s !== void 0
|
|
25
|
+
).map(([a, s]) => `${a}="${h(s)}"`).join(" "), i = l ? `<${n} ${l}>` : `<${n}>`, c = `</${n}>`;
|
|
26
26
|
if (r.content !== void 0)
|
|
27
27
|
return `${e}${i}${r.content}${c}`;
|
|
28
28
|
if (r.children && r.children.length > 0) {
|
|
29
|
-
const a = r.children.map((
|
|
29
|
+
const a = r.children.map((s) => g(s, t + 1)).join(`
|
|
30
30
|
`);
|
|
31
31
|
return `${e}${i}
|
|
32
32
|
${a}
|
|
@@ -48,23 +48,23 @@ async function $(r) {
|
|
|
48
48
|
};
|
|
49
49
|
} catch (t) {
|
|
50
50
|
return console.error("MJML render error:", t), {
|
|
51
|
-
html: '<p style="color:
|
|
51
|
+
html: '<p style="color: #dc2626; padding: 20px; background: white; margin: 0;">Error rendering email preview</p>',
|
|
52
52
|
errors: [{ line: 0, message: String(t), tagName: "mjml" }]
|
|
53
53
|
};
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
async function d(r) {
|
|
57
57
|
try {
|
|
58
|
-
const t = await u(), e = m(r),
|
|
58
|
+
const t = await u(), e = m(r), n = p(e), l = t(n, {
|
|
59
59
|
validationLevel: "soft"
|
|
60
60
|
});
|
|
61
61
|
return {
|
|
62
|
-
html:
|
|
63
|
-
errors:
|
|
62
|
+
html: l.html,
|
|
63
|
+
errors: l.errors || []
|
|
64
64
|
};
|
|
65
65
|
} catch (t) {
|
|
66
66
|
return console.error("MJML render error:", t), {
|
|
67
|
-
html: '<p style="color:
|
|
67
|
+
html: '<p style="color: #dc2626; padding: 20px; background: white; margin: 0;">Error rendering email preview</p>',
|
|
68
68
|
errors: [{ line: 0, message: String(t), tagName: "mjml" }]
|
|
69
69
|
};
|
|
70
70
|
}
|