@mjml-agent-editor/editor 0.4.3 → 0.5.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/canvas.cjs +69 -16
- package/dist/canvas.cjs.map +1 -1
- package/dist/canvas.js +69 -16
- package/dist/canvas.js.map +1 -1
- package/package.json +1 -1
package/dist/canvas.js
CHANGED
|
@@ -1957,6 +1957,13 @@ var SCHEMA = {
|
|
|
1957
1957
|
{ attr: "direction", label: "reverseColumns", group: "advanced", control: { type: "toggle", on: "rtl" } },
|
|
1958
1958
|
{ attr: "border", label: "border", group: "advanced", control: { type: "text", placeholder: "1px solid #cccccc" } }
|
|
1959
1959
|
],
|
|
1960
|
+
// MJML allows a group these and `width` only: padding or a border fails strict. Its width is
|
|
1961
|
+
// not offered, as the canvas does not draw it: the plugin's group drops MJML's rule for it.
|
|
1962
|
+
"mj-group": [
|
|
1963
|
+
{ attr: "vertical-align", label: "verticalAlign", group: "layout", control: { type: "segmented", options: VERTICAL_ALIGN } },
|
|
1964
|
+
{ attr: "background-color", label: "backgroundColor", group: "style", control: { type: "color" } },
|
|
1965
|
+
{ attr: "direction", label: "reverseColumns", group: "advanced", control: { type: "toggle", on: "rtl" } }
|
|
1966
|
+
],
|
|
1960
1967
|
"mj-column": [
|
|
1961
1968
|
{ attr: "vertical-align", label: "verticalAlign", group: "layout", control: { type: "segmented", options: VERTICAL_ALIGN }, default: "top" },
|
|
1962
1969
|
{ attr: "padding", label: "padding", group: "spacing", control: { type: "box", units: PX_PCT } },
|
|
@@ -2315,8 +2322,12 @@ var COLUMN_RATIOS = {
|
|
|
2315
2322
|
[1, 2, 1]
|
|
2316
2323
|
]
|
|
2317
2324
|
};
|
|
2318
|
-
function columnsOf(
|
|
2319
|
-
|
|
2325
|
+
function columnsOf(container) {
|
|
2326
|
+
let children = container.components().models;
|
|
2327
|
+
const only = children.length === 1 ? children[0] : null;
|
|
2328
|
+
if (tagOf2(container) === "mj-section" && only && tagOf2(only) === "mj-group") {
|
|
2329
|
+
children = only.components().models;
|
|
2330
|
+
}
|
|
2320
2331
|
return children.length > 0 && children.every((c) => tagOf2(c) === "mj-column") ? children : null;
|
|
2321
2332
|
}
|
|
2322
2333
|
function ratioWidths(ratio) {
|
|
@@ -2379,6 +2390,7 @@ function StructureSection({
|
|
|
2379
2390
|
}) {
|
|
2380
2391
|
switch (tagOf3(component)) {
|
|
2381
2392
|
case "mj-section":
|
|
2393
|
+
case "mj-group":
|
|
2382
2394
|
return /* @__PURE__ */ jsx6(ColumnWidths, { component, labels, locked });
|
|
2383
2395
|
case "mj-social":
|
|
2384
2396
|
return /* @__PURE__ */ jsx6(
|
|
@@ -2833,11 +2845,11 @@ function ElementSettings({
|
|
|
2833
2845
|
] }),
|
|
2834
2846
|
/* @__PURE__ */ jsx7(StructureSection, { editor, component, labels, locked }),
|
|
2835
2847
|
GROUPS.map((group) => {
|
|
2836
|
-
const
|
|
2837
|
-
if (
|
|
2848
|
+
const inGroup2 = visible.filter((f) => f.group === group);
|
|
2849
|
+
if (inGroup2.length === 0) return null;
|
|
2838
2850
|
return /* @__PURE__ */ jsxs6("section", { className: "border-b border-panel-border/60 py-2", children: [
|
|
2839
2851
|
/* @__PURE__ */ jsx7("h3", { className: "px-3 pb-1 text-[10px] font-semibold tracking-wider text-panel-muted-fg/80 uppercase", children: groupName(group, labels) }),
|
|
2840
|
-
|
|
2852
|
+
inGroup2.map(row)
|
|
2841
2853
|
] }, group);
|
|
2842
2854
|
}),
|
|
2843
2855
|
advancedCount > 0 && /* @__PURE__ */ jsxs6("section", { className: "py-1", children: [
|
|
@@ -3284,12 +3296,17 @@ function fixPluginTypes(editor) {
|
|
|
3284
3296
|
for (const type of editor.Components.getTypes()) {
|
|
3285
3297
|
if (!type.id.startsWith("mj-") || type.id === "mj-table") continue;
|
|
3286
3298
|
const base = type.model.prototype.getAttrToHTML;
|
|
3299
|
+
const view = type.view.prototype;
|
|
3287
3300
|
editor.Components.addType(type.id, {
|
|
3301
|
+
...type.id === "mj-column" && { view: groupedColumnView(view) },
|
|
3302
|
+
...type.id === "mj-group" && { view: redrawnGroupView(view) },
|
|
3288
3303
|
model: {
|
|
3289
3304
|
defaults: {
|
|
3290
3305
|
"style-default": {},
|
|
3291
3306
|
...type.id === "mj-column" && {
|
|
3292
|
-
droppable: (source) => COLUMN_CHILDREN.has(String(source.get("tagName")))
|
|
3307
|
+
droppable: (source) => COLUMN_CHILDREN.has(String(source.get("tagName"))),
|
|
3308
|
+
// The plugin moves a column only within sections, so a group's could not even swap.
|
|
3309
|
+
draggable: '[data-gjs-type="mj-section"], [data-gjs-type="mj-group"]'
|
|
3293
3310
|
},
|
|
3294
3311
|
// GrapesJS's own is an SVG's markup, which the canvas wrote into `src` and saved.
|
|
3295
3312
|
...type.id === "mj-image" && { src: "" }
|
|
@@ -3306,6 +3323,41 @@ function fixPluginTypes(editor) {
|
|
|
3306
3323
|
});
|
|
3307
3324
|
}
|
|
3308
3325
|
}
|
|
3326
|
+
var inGroup = (column) => column.parent()?.get("type") === "mj-group";
|
|
3327
|
+
function groupedColumnView(base) {
|
|
3328
|
+
return {
|
|
3329
|
+
getMjmlTemplate() {
|
|
3330
|
+
if (!inGroup(this.model)) return base.getMjmlTemplate.call(this);
|
|
3331
|
+
const siblings = "<mj-column></mj-column>".repeat(
|
|
3332
|
+
Math.max((this.model.collection?.length ?? 1) - 1, 0)
|
|
3333
|
+
);
|
|
3334
|
+
const width = (c) => {
|
|
3335
|
+
const value = c?.getAttributes().width;
|
|
3336
|
+
return typeof value === "string" && value ? ` width="${value.replace(/"/g, "")}"` : "";
|
|
3337
|
+
};
|
|
3338
|
+
let body = this.model;
|
|
3339
|
+
while (body && body.get("type") !== "mj-body") body = body.parent();
|
|
3340
|
+
return {
|
|
3341
|
+
start: `<mjml><mj-body${width(body)}><mj-section><mj-group${width(this.model.parent())}>`,
|
|
3342
|
+
end: `${siblings}</mj-group></mj-section></mj-body></mjml>`
|
|
3343
|
+
};
|
|
3344
|
+
},
|
|
3345
|
+
getTemplateFromEl(container) {
|
|
3346
|
+
if (!inGroup(this.model)) return base.getTemplateFromEl.call(this, container);
|
|
3347
|
+
return container.firstChild?.querySelector(
|
|
3348
|
+
"div > table > tbody > tr > td > div > div"
|
|
3349
|
+
) ?? null;
|
|
3350
|
+
}
|
|
3351
|
+
};
|
|
3352
|
+
}
|
|
3353
|
+
function redrawnGroupView(base) {
|
|
3354
|
+
return {
|
|
3355
|
+
init() {
|
|
3356
|
+
base.init.call(this);
|
|
3357
|
+
this.listenTo(this.model.components(), "add remove", this.render);
|
|
3358
|
+
}
|
|
3359
|
+
};
|
|
3360
|
+
}
|
|
3309
3361
|
|
|
3310
3362
|
// src/components/editor/EmailEditor.tsx
|
|
3311
3363
|
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
@@ -3446,9 +3498,10 @@ function EmailEditor({
|
|
|
3446
3498
|
setLocked(false);
|
|
3447
3499
|
};
|
|
3448
3500
|
}, [turn, setLocked]);
|
|
3501
|
+
const inert = readOnly || loading;
|
|
3449
3502
|
const wasLocked = useRef5(false);
|
|
3450
3503
|
useEffect5(() => {
|
|
3451
|
-
if (
|
|
3504
|
+
if (inert) {
|
|
3452
3505
|
wasLocked.current = true;
|
|
3453
3506
|
return;
|
|
3454
3507
|
}
|
|
@@ -3463,7 +3516,7 @@ function EmailEditor({
|
|
|
3463
3516
|
cancelAnimationFrame(frame);
|
|
3464
3517
|
root.style.overflow = overflow;
|
|
3465
3518
|
};
|
|
3466
|
-
}, [
|
|
3519
|
+
}, [inert]);
|
|
3467
3520
|
const [crumbs, setCrumbs] = useState5([]);
|
|
3468
3521
|
const [picker, setPicker] = useState5(
|
|
3469
3522
|
null
|
|
@@ -3565,7 +3618,7 @@ function EmailEditor({
|
|
|
3565
3618
|
fixPluginTypes(editor);
|
|
3566
3619
|
registerBlocks(editor, blocks, labels.blockCategorySections, SECTION_SVG);
|
|
3567
3620
|
setupLayerNames(editor, labels);
|
|
3568
|
-
const STRUCTURE = /* @__PURE__ */ new Set(["mj-wrapper", "mj-section", "mj-column"]);
|
|
3621
|
+
const STRUCTURE = /* @__PURE__ */ new Set(["mj-wrapper", "mj-section", "mj-group", "mj-column"]);
|
|
3569
3622
|
const showBodyInLayers = () => {
|
|
3570
3623
|
const body = findByTag("mj-body");
|
|
3571
3624
|
if (!body) return;
|
|
@@ -3851,9 +3904,14 @@ function EmailEditor({
|
|
|
3851
3904
|
"div",
|
|
3852
3905
|
{
|
|
3853
3906
|
className: "relative flex h-full min-h-0 flex-1",
|
|
3854
|
-
inert
|
|
3907
|
+
inert,
|
|
3855
3908
|
onKeyDown: (e) => onBlockSearchKey(e.nativeEvent),
|
|
3856
3909
|
children: [
|
|
3910
|
+
loading && /* @__PURE__ */ jsxs7("div", { className: "absolute inset-0 z-30 flex items-center justify-center gap-2 bg-white/70 text-sm text-zinc-500", children: [
|
|
3911
|
+
/* @__PURE__ */ jsx8(Spinner, {}),
|
|
3912
|
+
" ",
|
|
3913
|
+
labels.loadingEditor
|
|
3914
|
+
] }),
|
|
3857
3915
|
readOnly && /* @__PURE__ */ jsx8("div", { className: "absolute inset-0 z-30 flex cursor-not-allowed items-start justify-center bg-white/20 pt-3", children: /* @__PURE__ */ jsxs7("span", { className: "flex items-center gap-2 rounded-full bg-panel px-3 py-1 text-xs text-panel-fg shadow", children: [
|
|
3858
3916
|
/* @__PURE__ */ jsx8(Spinner, {}),
|
|
3859
3917
|
" ",
|
|
@@ -3895,12 +3953,7 @@ function EmailEditor({
|
|
|
3895
3953
|
editorRef.current?.AssetManager.close();
|
|
3896
3954
|
}
|
|
3897
3955
|
}
|
|
3898
|
-
)
|
|
3899
|
-
loading && /* @__PURE__ */ jsxs7("div", { className: "absolute inset-0 z-10 flex items-center justify-center gap-2 bg-white/70 text-sm text-zinc-500", children: [
|
|
3900
|
-
/* @__PURE__ */ jsx8(Spinner, {}),
|
|
3901
|
-
" ",
|
|
3902
|
-
labels.loadingEditor
|
|
3903
|
-
] })
|
|
3956
|
+
)
|
|
3904
3957
|
] }),
|
|
3905
3958
|
/* @__PURE__ */ jsx8(Breadcrumb, { crumbs, onSelect: (c) => editorRef.current?.select(c) })
|
|
3906
3959
|
] })
|