mail-editor-pancake 0.2.0 → 0.2.2
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/README.md +177 -17
- package/package.json +1 -1
- package/packages/blocks/dist/index.js +168 -154
- package/packages/blocks/dist/index.js.map +1 -1
- package/packages/blocks/src/i18n.ts +31 -1
- package/packages/core/dist/index.d.ts +59 -4
- package/packages/core/dist/index.js +1517 -1470
- package/packages/core/dist/index.js.map +1 -1
- package/packages/core/dist/style.css +1 -1
- package/packages/core/src/editor/Editor.ts +1 -1
- package/packages/core/src/editor/ImageGalleryModal.ts +135 -83
- package/packages/core/src/editor/RightPanel.ts +30 -15
- package/packages/core/src/editor/imageAssets.ts +65 -3
- package/packages/core/src/editor/styles.css +15 -0
- package/packages/core/src/i18n/index.ts +10 -2
- package/packages/core/src/index.ts +4 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineBlock as h, blockButtonWidthCss as
|
|
1
|
+
import { defineBlock as h, blockButtonWidthCss as j, docContentWidthCss as E, htmlContainsMjmlTags as Z, mjRawEmailTableWrap as Q, mjRawCellTypographyFromStyles as ee, normalizeFontWeightStep as k, FONT_WEIGHT_STEP_OPTIONS as L, isRichHtmlEffectivelyEmpty as te, createI18nContext as oe } from "@simple-mail/core";
|
|
2
2
|
const b = {
|
|
3
3
|
html: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none"><rect x="3.5" y="4" width="17" height="16" rx="2" stroke="currentColor" stroke-width="1.5" fill="none"/><path d="M8 8.5l3 3.5-3 3.5M16 8.5l-3 3.5 3 3.5" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/></svg>',
|
|
4
4
|
text: '<svg width="24" height="24" viewBox="0 0 24 24"><path d="M5 6h14M5 10h14M5 14h10M5 18h8" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" fill="none"/></svg>',
|
|
@@ -11,7 +11,7 @@ const b = {
|
|
|
11
11
|
social: '<svg width="24" height="24" viewBox="0 0 24 24"><circle cx="6" cy="12" r="2.5" stroke="currentColor" stroke-width="1.4" fill="none"/><circle cx="12" cy="12" r="2.5" stroke="currentColor" stroke-width="1.4" fill="none"/><circle cx="18" cy="12" r="2.5" stroke="currentColor" stroke-width="1.4" fill="none"/></svg>',
|
|
12
12
|
footer: '<svg width="24" height="24" viewBox="0 0 24 24"><rect x="3.5" y="5" width="17" height="10" rx="1.5" stroke="currentColor" stroke-width="1.4" fill="none"/><path d="M5 18h14" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg>',
|
|
13
13
|
socialGroup: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none"><rect x="3" y="5" width="18" height="14" rx="2" stroke="currentColor" stroke-width="1.5"/><circle cx="8" cy="12" r="2" stroke="currentColor" stroke-width="1.4"/><circle cx="12" cy="12" r="2" stroke="currentColor" stroke-width="1.4"/><circle cx="16" cy="12" r="2" stroke="currentColor" stroke-width="1.4"/></svg>'
|
|
14
|
-
}, x = (e) => e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """),
|
|
14
|
+
}, x = (e) => e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """), le = h({
|
|
15
15
|
type: "button",
|
|
16
16
|
name: "按钮",
|
|
17
17
|
category: "content",
|
|
@@ -69,7 +69,7 @@ const b = {
|
|
|
69
69
|
placeholder: "按钮文字"
|
|
70
70
|
},
|
|
71
71
|
toMjml: (e) => {
|
|
72
|
-
const t = `${e.paddingTop}px ${e.paddingRight}px ${e.paddingBottom}px ${e.paddingLeft}px`, o = `${e.innerPaddingV}px ${e.innerPaddingH}px`, l =
|
|
72
|
+
const t = `${e.paddingTop}px ${e.paddingRight}px ${e.paddingBottom}px ${e.paddingLeft}px`, o = `${e.innerPaddingV}px ${e.innerPaddingH}px`, l = j(e.width), n = l ? ` width="${x(l)}"` : "";
|
|
73
73
|
return `<mj-button href="${x(e.href)}" background-color="${x(
|
|
74
74
|
e.backgroundColor
|
|
75
75
|
)}" color="${x(e.color)}" border-radius="${e.borderRadius}px" font-size="${x(
|
|
@@ -79,12 +79,12 @@ const b = {
|
|
|
79
79
|
)}</mj-button>`;
|
|
80
80
|
},
|
|
81
81
|
renderPreview: (e) => {
|
|
82
|
-
const t =
|
|
82
|
+
const t = j(e.width), o = t ? `width:${t};max-width:100%;box-sizing:border-box;` : "";
|
|
83
83
|
return `<div style="padding:${e.paddingTop}px ${e.paddingRight}px ${e.paddingBottom}px ${e.paddingLeft}px;text-align:${e.align};">
|
|
84
84
|
<a href="${x(e.href)}" style="display:inline-block;background:${e.backgroundColor};border-radius:${e.borderRadius}px;padding:${e.innerPaddingV}px ${e.innerPaddingH}px;text-decoration:none;font-size:${e.fontSize};line-height:1.2;${o}"><span class="sm-button-text" style="color:${e.color}">${x(e.text)}</span></a>
|
|
85
85
|
</div>`;
|
|
86
86
|
}
|
|
87
|
-
}), A = (e) => e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """),
|
|
87
|
+
}), A = (e) => e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """), ne = h({
|
|
88
88
|
type: "divider",
|
|
89
89
|
name: "分隔线",
|
|
90
90
|
category: "content",
|
|
@@ -107,7 +107,7 @@ const b = {
|
|
|
107
107
|
e.width
|
|
108
108
|
)}" padding="${e.paddingTop}px 0px ${e.paddingBottom}px 0px" />`,
|
|
109
109
|
renderPreview: (e) => `<div style="padding:${e.paddingTop}px 0 ${e.paddingBottom}px 0;"><div style="border-top:${e.thickness}px solid ${e.color};width:${e.width};margin:0 auto;"></div></div>`
|
|
110
|
-
}), m = (e) => e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """),
|
|
110
|
+
}), m = (e) => e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """), ie = h({
|
|
111
111
|
type: "custom:footer",
|
|
112
112
|
name: "页脚",
|
|
113
113
|
category: "custom",
|
|
@@ -136,7 +136,7 @@ const b = {
|
|
|
136
136
|
${m(e.address)}<br/>
|
|
137
137
|
<a href="${m(e.unsubscribeHref)}" style="color:${e.textColor};">${m(e.unsubscribeText)}</a>
|
|
138
138
|
</div>`
|
|
139
|
-
}), $ = (e) => e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """),
|
|
139
|
+
}), $ = (e) => e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """), re = h({
|
|
140
140
|
type: "hero",
|
|
141
141
|
name: "Hero 大图",
|
|
142
142
|
category: "content",
|
|
@@ -248,7 +248,7 @@ const b = {
|
|
|
248
248
|
>${e.content}</div>
|
|
249
249
|
</div>`;
|
|
250
250
|
}
|
|
251
|
-
}),
|
|
251
|
+
}), ae = h({
|
|
252
252
|
type: "html",
|
|
253
253
|
name: "HTML",
|
|
254
254
|
category: "content",
|
|
@@ -278,13 +278,13 @@ const b = {
|
|
|
278
278
|
},
|
|
279
279
|
toMjml: (e, t) => {
|
|
280
280
|
const o = `${e.paddingTop}px ${e.paddingRight}px ${e.paddingBottom}px ${e.paddingLeft}px`;
|
|
281
|
-
return
|
|
281
|
+
return Q(o, e.html, ee(t.doc.styles));
|
|
282
282
|
},
|
|
283
283
|
renderPreview: (e) => {
|
|
284
|
-
const t = `${e.paddingTop}px ${e.paddingRight}px ${e.paddingBottom}px ${e.paddingLeft}px`, o =
|
|
284
|
+
const t = `${e.paddingTop}px ${e.paddingRight}px ${e.paddingBottom}px ${e.paddingLeft}px`, o = Z(e.html) ? '<div class="sm-html-mjml-warn">检测到 MJML 标签,此处应只写 HTML,预览可能显示异常。</div>' : "";
|
|
285
285
|
return `<div class="sm-html-content" style="padding:${t};min-height:1em;">${o}${e.html}</div>`;
|
|
286
286
|
}
|
|
287
|
-
}), w = (e) => e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """),
|
|
287
|
+
}), w = (e) => e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """), ce = h({
|
|
288
288
|
type: "image",
|
|
289
289
|
name: "图片",
|
|
290
290
|
category: "content",
|
|
@@ -337,7 +337,7 @@ const b = {
|
|
|
337
337
|
e.src
|
|
338
338
|
)}" alt="${w(e.alt)}" style="display:block;${t}max-width:100%;${l}border:0;outline:none;" /></div>`;
|
|
339
339
|
}
|
|
340
|
-
}), z = (e) => e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """),
|
|
340
|
+
}), z = (e) => e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """), se = h({
|
|
341
341
|
type: "custom:logo",
|
|
342
342
|
name: "公司 Logo",
|
|
343
343
|
category: "custom",
|
|
@@ -372,17 +372,17 @@ const b = {
|
|
|
372
372
|
)}" alt="logo" style="display:block;${t}width:${e.width}px;max-width:100%;height:auto;" /></div>`;
|
|
373
373
|
}
|
|
374
374
|
});
|
|
375
|
-
function
|
|
375
|
+
function O(e) {
|
|
376
376
|
const t = e.trim();
|
|
377
377
|
return t === "ig" ? "instagram" : t === "rabbit" || t === "tiktok" || t === "reddit" ? "web" : t;
|
|
378
378
|
}
|
|
379
|
-
const
|
|
379
|
+
const de = [
|
|
380
380
|
{ label: "X", value: "x" },
|
|
381
381
|
{ label: "Rabbit", value: "rabbit" },
|
|
382
382
|
{ label: "Facebook", value: "facebook" },
|
|
383
383
|
{ label: "TikTok", value: "tiktok" },
|
|
384
384
|
{ label: "Instagram", value: "ig" }
|
|
385
|
-
],
|
|
385
|
+
], ge = [
|
|
386
386
|
{ label: "微信", value: "wechat" },
|
|
387
387
|
{ label: "微博", value: "weibo" },
|
|
388
388
|
{ label: "X", value: "x" },
|
|
@@ -393,7 +393,7 @@ const se = [
|
|
|
393
393
|
{ label: "YouTube", value: "youtube" },
|
|
394
394
|
{ label: "Reddit", value: "reddit" },
|
|
395
395
|
{ label: "网页", value: "web" }
|
|
396
|
-
],
|
|
396
|
+
], pe = {
|
|
397
397
|
wechat: { color: "#1AAD19", preview: "信" },
|
|
398
398
|
weibo: { color: "#E6162D", preview: "微" },
|
|
399
399
|
x: { color: "#000000", preview: "X" },
|
|
@@ -408,11 +408,11 @@ const se = [
|
|
|
408
408
|
rabbit: { color: "#FF2442", preview: "R" },
|
|
409
409
|
website: { color: "#6b7280", preview: "◇" },
|
|
410
410
|
web: { color: "#6b7280", preview: "◇" }
|
|
411
|
-
}, p = (e) => e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """),
|
|
412
|
-
function
|
|
413
|
-
return
|
|
411
|
+
}, p = (e) => e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """), he = (e) => e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
412
|
+
function K(e) {
|
|
413
|
+
return pe[e] ?? { color: "#6b7280", preview: "·" };
|
|
414
414
|
}
|
|
415
|
-
const
|
|
415
|
+
const be = "https://www.mailjet.com/images/theme/v1/icons/ico-social/", me = {
|
|
416
416
|
facebook: "facebook.png",
|
|
417
417
|
twitter: "twitter.png",
|
|
418
418
|
x: "twitter-x.png",
|
|
@@ -431,26 +431,26 @@ const he = "https://www.mailjet.com/images/theme/v1/icons/ico-social/", be = {
|
|
|
431
431
|
soundcloud: "soundcloud.png",
|
|
432
432
|
dribbble: "dribbble.png"
|
|
433
433
|
};
|
|
434
|
-
function
|
|
435
|
-
const t =
|
|
436
|
-
return t ? `${
|
|
434
|
+
function ue(e) {
|
|
435
|
+
const t = me[O(e)];
|
|
436
|
+
return t ? `${be}${t}` : null;
|
|
437
437
|
}
|
|
438
|
-
function
|
|
439
|
-
const { network: t, iconSize: o, iconBorderRadius: l, iconSrc: n, backgroundColor: i } = e,
|
|
440
|
-
return d ? `<span style="display:inline-flex;width:${o}px;height:${o}px;border-radius:${
|
|
438
|
+
function V(e) {
|
|
439
|
+
const { network: t, iconSize: o, iconBorderRadius: l, iconSrc: n, backgroundColor: i } = e, r = fe(o, l), c = K(t), a = (i == null ? void 0 : i.trim()) || c.color, d = (n == null ? void 0 : n.trim()) || ue(t);
|
|
440
|
+
return d ? `<span style="display:inline-flex;width:${o}px;height:${o}px;border-radius:${r};background:${a};overflow:hidden;align-items:center;justify-content:center;flex-shrink:0;line-height:0;"><img src="${p(d)}" alt="" width="${o}" height="${o}" style="display:block;width:${o}px;height:${o}px;border-radius:${r};" /></span>` : `<span style="display:inline-flex;width:${o}px;height:${o}px;border-radius:${r};background:${a};color:#fff;align-items:center;justify-content:center;font-size:${Math.round(
|
|
441
441
|
o / 2
|
|
442
|
-
)}px;font-weight:600;flex-shrink:0;overflow:hidden;">${
|
|
442
|
+
)}px;font-weight:600;flex-shrink:0;overflow:hidden;">${c.preview}</span>`;
|
|
443
443
|
}
|
|
444
444
|
function S(e) {
|
|
445
445
|
return `${e.paddingTop}px ${e.paddingRight}px ${e.paddingBottom}px ${e.paddingLeft}px`;
|
|
446
446
|
}
|
|
447
|
-
function
|
|
447
|
+
function U(e, t) {
|
|
448
448
|
const o = Math.max(1, Number(e) || 28), l = Number(t);
|
|
449
449
|
if (!Number.isFinite(l) || l <= 0) return "0px";
|
|
450
450
|
const n = o / 2;
|
|
451
451
|
return l >= 999 || l >= n ? "999px" : `${Math.min(l, o)}px`;
|
|
452
452
|
}
|
|
453
|
-
function
|
|
453
|
+
function fe(e, t) {
|
|
454
454
|
const o = Math.max(1, Number(e) || 28), l = Number(t);
|
|
455
455
|
if (!Number.isFinite(l) || l <= 0) return "0";
|
|
456
456
|
const n = o / 2;
|
|
@@ -460,29 +460,29 @@ function C(e, t = 10) {
|
|
|
460
460
|
const o = Number(e);
|
|
461
461
|
return !Number.isFinite(o) || o < 0 ? t : Math.min(64, Math.round(o));
|
|
462
462
|
}
|
|
463
|
-
function
|
|
463
|
+
function D(e) {
|
|
464
464
|
return e === "right" ? "flex-end" : e === "left" ? "flex-start" : "center";
|
|
465
465
|
}
|
|
466
|
-
function
|
|
467
|
-
var
|
|
468
|
-
const o = t.labelFontSize > 0 ? t.labelFontSize : 13, l = Math.max(8, Math.min(48, o)), n = k(t.labelFontWeight), i = ((
|
|
469
|
-
return e.map((
|
|
470
|
-
var T,
|
|
471
|
-
const d =
|
|
472
|
-
`name="${p(
|
|
473
|
-
`href="${p(
|
|
474
|
-
`background-color="${p(
|
|
466
|
+
function G(e, t) {
|
|
467
|
+
var c;
|
|
468
|
+
const o = t.labelFontSize > 0 ? t.labelFontSize : 13, l = Math.max(8, Math.min(48, o)), n = k(t.labelFontWeight), i = ((c = t.labelColor) == null ? void 0 : c.trim()) || "#333333", r = p(n);
|
|
469
|
+
return e.map((a) => {
|
|
470
|
+
var T, P, F;
|
|
471
|
+
const d = K(a.network), s = ((T = a.backgroundColor) == null ? void 0 : T.trim()) || d.color, u = [
|
|
472
|
+
`name="${p(O(a.network))}"`,
|
|
473
|
+
`href="${p(a.href)}"`,
|
|
474
|
+
`background-color="${p(s)}"`,
|
|
475
475
|
`color="${p(i)}"`,
|
|
476
476
|
`font-size="${l}px"`,
|
|
477
|
-
`font-weight="${
|
|
478
|
-
].join(" "), y = (
|
|
477
|
+
`font-weight="${r}"`
|
|
478
|
+
].join(" "), y = (P = a.iconSrc) == null ? void 0 : P.trim(), f = y ? `${u} src="${p(y)}"` : u, R = ((F = a.label) == null ? void 0 : F.trim()) ?? "";
|
|
479
479
|
return R ? ` <mj-social-element ${f}>
|
|
480
|
-
${
|
|
480
|
+
${he(R)}
|
|
481
481
|
</mj-social-element>` : ` <mj-social-element ${f} />`;
|
|
482
482
|
}).join(`
|
|
483
483
|
`);
|
|
484
484
|
}
|
|
485
|
-
const
|
|
485
|
+
const J = [
|
|
486
486
|
{ network: "x", href: "https://x.com/" },
|
|
487
487
|
{ network: "rabbit", href: "https://example.com" },
|
|
488
488
|
{ network: "facebook", href: "https://facebook.com/" },
|
|
@@ -496,15 +496,15 @@ function H(e) {
|
|
|
496
496
|
return Array.isArray(t) && t.length ? t.map((l) => ({
|
|
497
497
|
network: String(l.network ?? "web"),
|
|
498
498
|
href: String(l.href ?? "")
|
|
499
|
-
})) :
|
|
499
|
+
})) : J;
|
|
500
500
|
}
|
|
501
|
-
const
|
|
501
|
+
const xe = h({
|
|
502
502
|
type: "custom:social",
|
|
503
503
|
name: "社交链接",
|
|
504
504
|
category: "custom",
|
|
505
505
|
icon: b.social,
|
|
506
506
|
defaultProps: {
|
|
507
|
-
elements:
|
|
507
|
+
elements: J,
|
|
508
508
|
align: "center",
|
|
509
509
|
iconSize: 28,
|
|
510
510
|
iconBorderRadius: 999,
|
|
@@ -522,7 +522,7 @@ const fe = h({
|
|
|
522
522
|
key: "elements",
|
|
523
523
|
label: "社交链接",
|
|
524
524
|
type: "socialLinkList",
|
|
525
|
-
options:
|
|
525
|
+
options: de,
|
|
526
526
|
help: "平台:X、Rabbit、Facebook、TikTok、Instagram (ig)。可填标签、自定义图标 URL。MJML 侧 Rabbit/TikTok 使用 web 占位图标,需要品牌图时请填「图标 URL」。"
|
|
527
527
|
},
|
|
528
528
|
{
|
|
@@ -574,41 +574,41 @@ const fe = h({
|
|
|
574
574
|
{ key: "paddingTop", label: "外边距", type: "spacing" }
|
|
575
575
|
],
|
|
576
576
|
toMjml: (e) => {
|
|
577
|
-
const t = S(e), o =
|
|
577
|
+
const t = S(e), o = U(e.iconSize, e.iconBorderRadius ?? 999), l = C(e.iconSpacing, 10), n = `align="${e.align}" icon-size="${e.iconSize}px" mode="horizontal" border-radius="${o}" inner-padding="${l}px" padding="${t}"`, i = H(e).filter((a) => {
|
|
578
578
|
var d;
|
|
579
|
-
return (d =
|
|
580
|
-
}),
|
|
579
|
+
return (d = a.href) == null ? void 0 : d.trim();
|
|
580
|
+
}), r = {
|
|
581
581
|
labelFontSize: Number(e.labelFontSize ?? 13),
|
|
582
582
|
labelFontWeight: k(String(e.labelFontWeight ?? "400")),
|
|
583
583
|
labelColor: String(e.labelColor ?? "#333333")
|
|
584
|
-
},
|
|
585
|
-
return
|
|
586
|
-
${
|
|
584
|
+
}, c = G(i, r);
|
|
585
|
+
return c.trim() ? `<mj-social ${n}>
|
|
586
|
+
${c}
|
|
587
587
|
</mj-social>` : `<mj-social ${n}></mj-social>`;
|
|
588
588
|
},
|
|
589
589
|
renderPreview: (e) => {
|
|
590
590
|
var d;
|
|
591
|
-
const t = e.labelFontSize != null && e.labelFontSize > 0 ? e.labelFontSize : 13, o = Math.max(8, Math.min(48, t)), l = k(e.labelFontWeight), n = ((d = e.labelColor) == null ? void 0 : d.trim()) || "#333333", i = C(e.iconSpacing, 10),
|
|
591
|
+
const t = e.labelFontSize != null && e.labelFontSize > 0 ? e.labelFontSize : 13, o = Math.max(8, Math.min(48, t)), l = k(e.labelFontWeight), n = ((d = e.labelColor) == null ? void 0 : d.trim()) || "#333333", i = C(e.iconSpacing, 10), r = D(e.align), c = H(e).filter((s) => {
|
|
592
592
|
var g;
|
|
593
|
-
return (g =
|
|
594
|
-
}).map((
|
|
593
|
+
return (g = s.href) == null ? void 0 : g.trim();
|
|
594
|
+
}).map((s) => {
|
|
595
595
|
var f;
|
|
596
|
-
const g = ((f =
|
|
597
|
-
network:
|
|
596
|
+
const g = ((f = s.label) == null ? void 0 : f.trim()) ?? "", u = V({
|
|
597
|
+
network: s.network,
|
|
598
598
|
iconSize: e.iconSize,
|
|
599
599
|
iconBorderRadius: e.iconBorderRadius ?? 999,
|
|
600
|
-
iconSrc:
|
|
601
|
-
backgroundColor:
|
|
600
|
+
iconSrc: s.iconSrc,
|
|
601
|
+
backgroundColor: s.backgroundColor
|
|
602
602
|
}), y = g ? `<span style="font-size:${o}px !important;font-weight:${l};color:${p(
|
|
603
603
|
n
|
|
604
604
|
)} !important;line-height:1.2;">${p(g)}</span>` : "";
|
|
605
605
|
return `<span style="display:inline-flex;align-items:center;gap:6px;"><a href="${p(
|
|
606
|
-
|
|
606
|
+
s.href
|
|
607
607
|
)}" style="display:inline-flex;align-items:center;text-decoration:none;line-height:0;">${u}</a>${y}</span>`;
|
|
608
|
-
}).join(""),
|
|
609
|
-
return `<div style="display:flex;flex-wrap:wrap;justify-content:${
|
|
608
|
+
}).join(""), a = S(e);
|
|
609
|
+
return `<div style="display:flex;flex-wrap:wrap;justify-content:${r};align-items:center;gap:${i}px;padding:${a};">${c || '<span style="color:#9ca3af;font-size:12px;">请填写链接 URL</span>'}</div>`;
|
|
610
610
|
}
|
|
611
|
-
}),
|
|
611
|
+
}), ke = h({
|
|
612
612
|
type: "social-group",
|
|
613
613
|
name: "社交组",
|
|
614
614
|
category: "content",
|
|
@@ -635,7 +635,7 @@ ${a}
|
|
|
635
635
|
key: "elements",
|
|
636
636
|
label: "社交链接",
|
|
637
637
|
type: "socialLinkList",
|
|
638
|
-
options:
|
|
638
|
+
options: ge,
|
|
639
639
|
help: "每行:平台、链接、可选标签文字、自定义图标 URL、图标背景色。标签的字号/字重/颜色在下方统一设置。"
|
|
640
640
|
},
|
|
641
641
|
{
|
|
@@ -687,41 +687,41 @@ ${a}
|
|
|
687
687
|
{ key: "paddingTop", label: "外边距", type: "spacing" }
|
|
688
688
|
],
|
|
689
689
|
toMjml: (e) => {
|
|
690
|
-
const t = S(e), o =
|
|
690
|
+
const t = S(e), o = U(e.iconSize, e.iconBorderRadius ?? 999), l = C(e.iconSpacing, 10), n = `align="${e.align}" icon-size="${e.iconSize}px" mode="horizontal" border-radius="${o}" inner-padding="${l}px" padding="${t}"`, i = e.elements.filter((a) => {
|
|
691
691
|
var d;
|
|
692
|
-
return (d =
|
|
693
|
-
}),
|
|
692
|
+
return (d = a.href) == null ? void 0 : d.trim();
|
|
693
|
+
}), r = {
|
|
694
694
|
labelFontSize: Number(e.labelFontSize ?? 13),
|
|
695
695
|
labelFontWeight: k(String(e.labelFontWeight ?? "400")),
|
|
696
696
|
labelColor: String(e.labelColor ?? "#333333")
|
|
697
|
-
},
|
|
698
|
-
return
|
|
699
|
-
${
|
|
697
|
+
}, c = G(i, r);
|
|
698
|
+
return c.trim() ? `<mj-social ${n}>
|
|
699
|
+
${c}
|
|
700
700
|
</mj-social>` : `<mj-social ${n}></mj-social>`;
|
|
701
701
|
},
|
|
702
702
|
renderPreview: (e) => {
|
|
703
703
|
var d;
|
|
704
|
-
const t = e.labelFontSize != null && e.labelFontSize > 0 ? e.labelFontSize : 13, o = Math.max(8, Math.min(48, t)), l = k(e.labelFontWeight), n = ((d = e.labelColor) == null ? void 0 : d.trim()) || "#333333", i = C(e.iconSpacing, 10),
|
|
704
|
+
const t = e.labelFontSize != null && e.labelFontSize > 0 ? e.labelFontSize : 13, o = Math.max(8, Math.min(48, t)), l = k(e.labelFontWeight), n = ((d = e.labelColor) == null ? void 0 : d.trim()) || "#333333", i = C(e.iconSpacing, 10), r = D(e.align), c = e.elements.filter((s) => {
|
|
705
705
|
var g;
|
|
706
|
-
return (g =
|
|
707
|
-
}).map((
|
|
706
|
+
return (g = s.href) == null ? void 0 : g.trim();
|
|
707
|
+
}).map((s) => {
|
|
708
708
|
var f;
|
|
709
|
-
const g = ((f =
|
|
710
|
-
network:
|
|
709
|
+
const g = ((f = s.label) == null ? void 0 : f.trim()) ?? "", u = V({
|
|
710
|
+
network: s.network,
|
|
711
711
|
iconSize: e.iconSize,
|
|
712
712
|
iconBorderRadius: e.iconBorderRadius ?? 999,
|
|
713
|
-
iconSrc:
|
|
714
|
-
backgroundColor:
|
|
713
|
+
iconSrc: s.iconSrc,
|
|
714
|
+
backgroundColor: s.backgroundColor
|
|
715
715
|
}), y = g ? `<span style="font-size:${o}px !important;font-weight:${l};color:${p(
|
|
716
716
|
n
|
|
717
717
|
)} !important;line-height:1.2;">${p(g)}</span>` : "";
|
|
718
718
|
return `<span style="display:inline-flex;align-items:center;gap:6px;"><a href="${p(
|
|
719
|
-
|
|
719
|
+
s.href
|
|
720
720
|
)}" style="display:inline-flex;align-items:center;text-decoration:none;line-height:0;">${u}</a>${y}</span>`;
|
|
721
|
-
}).join(""),
|
|
722
|
-
return `<div style="display:flex;flex-wrap:wrap;justify-content:${
|
|
721
|
+
}).join(""), a = S(e);
|
|
722
|
+
return `<div style="display:flex;flex-wrap:wrap;justify-content:${r};align-items:center;gap:${i}px;padding:${a};">${c || '<span style="color:#9ca3af;font-size:12px;">请添加社交链接</span>'}</div>`;
|
|
723
723
|
}
|
|
724
|
-
}),
|
|
724
|
+
}), ye = h({
|
|
725
725
|
type: "spacer",
|
|
726
726
|
name: "间距",
|
|
727
727
|
category: "content",
|
|
@@ -730,7 +730,7 @@ ${a}
|
|
|
730
730
|
schema: [{ key: "height", label: "高度 (px)", type: "number", min: 1, max: 200 }],
|
|
731
731
|
toMjml: (e) => `<mj-spacer height="${e.height}px" />`,
|
|
732
732
|
renderPreview: (e) => `<div style="height:${e.height}px;line-height:${e.height}px;"></div>`
|
|
733
|
-
}), v = (e) => e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """), I = "输入文本…",
|
|
733
|
+
}), v = (e) => e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """), I = "输入文本…", $e = h({
|
|
734
734
|
type: "text",
|
|
735
735
|
name: "文本",
|
|
736
736
|
category: "content",
|
|
@@ -807,14 +807,14 @@ ${a}
|
|
|
807
807
|
placeholder: I
|
|
808
808
|
},
|
|
809
809
|
toMjml: (e) => {
|
|
810
|
-
const t = `${e.paddingTop}px ${e.paddingRight}px ${e.paddingBottom}px ${e.paddingLeft}px`, o = e.fontFamily ? ` font-family="${v(e.fontFamily)}"` : "", l = String(e.fontWeight ?? "").trim(), n = l ? ` font-weight="${v(k(l))}"` : "", i = String(e.lineHeight ?? "").trim(),
|
|
811
|
-
return `<mj-text align="${e.align}"${
|
|
810
|
+
const t = `${e.paddingTop}px ${e.paddingRight}px ${e.paddingBottom}px ${e.paddingLeft}px`, o = e.fontFamily ? ` font-family="${v(e.fontFamily)}"` : "", l = String(e.fontWeight ?? "").trim(), n = l ? ` font-weight="${v(k(l))}"` : "", i = String(e.lineHeight ?? "").trim(), r = i ? ` line-height="${v(i)}"` : "", c = String(e.color ?? "").trim(), a = c ? ` color="${v(c)}"` : "", d = String(e.fontSize ?? "").trim(), s = d ? ` font-size="${v(d)}"` : "";
|
|
811
|
+
return `<mj-text align="${e.align}"${a}${s}${r}${o}${n} padding="${t}">${e.content}</mj-text>`;
|
|
812
812
|
},
|
|
813
813
|
renderPreview: (e) => {
|
|
814
|
-
const t = e.fontFamily ? `font-family:${e.fontFamily};` : "", o = String(e.fontWeight ?? "").trim(), l = o ? `font-weight:${k(o)};` : "", n = String(e.lineHeight ?? "").trim(), i = n ? `line-height:${n};` : "line-height:normal;",
|
|
815
|
-
return `<div class="sm-text-content${g}"${u} style="text-align:${e.align};${
|
|
814
|
+
const t = e.fontFamily ? `font-family:${e.fontFamily};` : "", o = String(e.fontWeight ?? "").trim(), l = o ? `font-weight:${k(o)};` : "", n = String(e.lineHeight ?? "").trim(), i = n ? `line-height:${n};` : "line-height:normal;", r = String(e.color ?? "").trim(), c = r ? `color:${r};` : "", a = String(e.fontSize ?? "").trim(), d = a ? `font-size:${a};` : "", s = te(e.content), g = s ? " is-empty" : "", u = s ? ` data-placeholder="${I}"` : "";
|
|
815
|
+
return `<div class="sm-text-content${g}"${u} style="text-align:${e.align};${c}${d}${l}${i}${t}padding:${e.paddingTop}px ${e.paddingRight}px ${e.paddingBottom}px ${e.paddingLeft}px;">${e.content}</div>`;
|
|
816
816
|
}
|
|
817
|
-
}),
|
|
817
|
+
}), we = {
|
|
818
818
|
align: "blocks.field.align",
|
|
819
819
|
textAlign: "blocks.field.textAlign",
|
|
820
820
|
verticalAlign: "blocks.field.verticalAlign",
|
|
@@ -849,7 +849,7 @@ ${a}
|
|
|
849
849
|
address: "blocks.field.address",
|
|
850
850
|
unsubscribeText: "blocks.field.unsubscribeText",
|
|
851
851
|
unsubscribeHref: "blocks.field.unsubscribeLink"
|
|
852
|
-
},
|
|
852
|
+
}, ve = {
|
|
853
853
|
button: {
|
|
854
854
|
backgroundColor: "blocks.field.backgroundColor",
|
|
855
855
|
color: "blocks.field.textColor",
|
|
@@ -909,12 +909,12 @@ ${a}
|
|
|
909
909
|
color: "blocks.field.inheritGlobalPlaceholder",
|
|
910
910
|
fontFamily: "blocks.field.inheritGlobalPlaceholder"
|
|
911
911
|
}
|
|
912
|
-
},
|
|
912
|
+
}, Se = {
|
|
913
913
|
button: "blocks.field.buttonTextPlaceholder",
|
|
914
914
|
hero: "blocks.field.heroPlaceholder",
|
|
915
915
|
html: "blocks.field.htmlPlaceholder",
|
|
916
916
|
text: "blocks.field.textPlaceholder"
|
|
917
|
-
},
|
|
917
|
+
}, Ce = {
|
|
918
918
|
button: { text: "blocks.button.defaultText" },
|
|
919
919
|
hero: { content: "blocks.hero.defaultContent" },
|
|
920
920
|
html: { html: "blocks.html.defaultHtml" },
|
|
@@ -926,111 +926,125 @@ ${a}
|
|
|
926
926
|
}
|
|
927
927
|
};
|
|
928
928
|
function B(e, t) {
|
|
929
|
-
return e.map((o) =>
|
|
929
|
+
return e.map((o) => Be(o, t));
|
|
930
930
|
}
|
|
931
|
-
function
|
|
932
|
-
const o =
|
|
931
|
+
function Be(e, t) {
|
|
932
|
+
const o = q(e.type), l = `blocks.${o}.name`, n = t(l), i = Re(o, e, t);
|
|
933
933
|
return {
|
|
934
934
|
...e,
|
|
935
935
|
name: n === l ? e.name : n,
|
|
936
|
-
defaultProps:
|
|
937
|
-
schema: e.schema.map((
|
|
936
|
+
defaultProps: ze(e, t),
|
|
937
|
+
schema: e.schema.map((r) => Le(o, r, t)),
|
|
938
|
+
renderPreview: Te(e, i),
|
|
938
939
|
inlineEditable: e.inlineEditable ? {
|
|
939
940
|
...e.inlineEditable,
|
|
940
|
-
placeholder:
|
|
941
|
+
placeholder: i
|
|
941
942
|
} : void 0
|
|
942
943
|
};
|
|
943
944
|
}
|
|
944
|
-
function
|
|
945
|
-
const o = { ...e.defaultProps }, l =
|
|
945
|
+
function ze(e, t) {
|
|
946
|
+
const o = { ...e.defaultProps }, l = Ce[q(e.type)] ?? {};
|
|
946
947
|
for (const [n, i] of Object.entries(l))
|
|
947
948
|
o[n] = t(i);
|
|
948
949
|
return o;
|
|
949
950
|
}
|
|
950
|
-
function
|
|
951
|
-
var n, i,
|
|
952
|
-
const l = ((n =
|
|
951
|
+
function Le(e, t, o) {
|
|
952
|
+
var n, i, r, c;
|
|
953
|
+
const l = ((n = ve[e]) == null ? void 0 : n[t.key]) ?? we[t.key];
|
|
953
954
|
return {
|
|
954
955
|
...t,
|
|
955
956
|
label: l ? o(l) : t.label,
|
|
956
957
|
placeholder: (i = W[e]) != null && i[t.key] ? o(W[e][t.key]) : t.placeholder,
|
|
957
|
-
help: (
|
|
958
|
-
options: (
|
|
959
|
-
...
|
|
960
|
-
label:
|
|
958
|
+
help: (r = N[e]) != null && r[t.key] ? o(N[e][t.key]) : t.help,
|
|
959
|
+
options: (c = t.options) == null ? void 0 : c.map((a) => ({
|
|
960
|
+
...a,
|
|
961
|
+
label: Me(a, o)
|
|
961
962
|
}))
|
|
962
963
|
};
|
|
963
964
|
}
|
|
964
|
-
function
|
|
965
|
+
function Me(e, t) {
|
|
965
966
|
return e.value === "left" ? t("common.left") : e.value === "center" ? t("common.center") : e.value === "right" ? t("common.right") : e.value === "top" ? t("blocks.option.top") : e.value === "middle" ? t("blocks.option.middle") : e.value === "bottom" ? t("blocks.option.bottom") : e.value === "" ? t("common.inheritGlobal") : e.label;
|
|
966
967
|
}
|
|
967
|
-
function
|
|
968
|
+
function Re(e, t, o) {
|
|
968
969
|
var n;
|
|
969
|
-
const l =
|
|
970
|
+
const l = Se[e];
|
|
970
971
|
return l ? o(l) : (n = t.inlineEditable) == null ? void 0 : n.placeholder;
|
|
971
972
|
}
|
|
972
|
-
function
|
|
973
|
+
function Te(e, t) {
|
|
974
|
+
var n;
|
|
975
|
+
if (!e.renderPreview || !((n = e.inlineEditable) != null && n.placeholder) || !t)
|
|
976
|
+
return e.renderPreview;
|
|
977
|
+
const o = _(e.inlineEditable.placeholder), l = _(t);
|
|
978
|
+
return (i, r) => e.renderPreview(i, r).replaceAll(
|
|
979
|
+
`data-placeholder="${o}"`,
|
|
980
|
+
`data-placeholder="${l}"`
|
|
981
|
+
);
|
|
982
|
+
}
|
|
983
|
+
function _(e) {
|
|
984
|
+
return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
985
|
+
}
|
|
986
|
+
function q(e) {
|
|
973
987
|
return e.startsWith("custom:") ? e.slice(7) : e;
|
|
974
988
|
}
|
|
975
|
-
const
|
|
976
|
-
|
|
977
|
-
re,
|
|
989
|
+
const Y = [
|
|
990
|
+
$e,
|
|
978
991
|
ae,
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
992
|
+
ce,
|
|
993
|
+
ke,
|
|
994
|
+
re,
|
|
982
995
|
le,
|
|
983
|
-
|
|
984
|
-
|
|
996
|
+
ne,
|
|
997
|
+
ye
|
|
998
|
+
], X = [se, xe, ie];
|
|
985
999
|
function M(e = {}) {
|
|
986
|
-
return e.t ??
|
|
1000
|
+
return e.t ?? oe(e).t;
|
|
987
1001
|
}
|
|
988
|
-
function
|
|
989
|
-
return B(q, M(e));
|
|
990
|
-
}
|
|
991
|
-
function Te(e = {}) {
|
|
1002
|
+
function Pe(e = {}) {
|
|
992
1003
|
return B(Y, M(e));
|
|
993
1004
|
}
|
|
994
1005
|
function Fe(e = {}) {
|
|
1006
|
+
return B(X, M(e));
|
|
1007
|
+
}
|
|
1008
|
+
function je(e = {}) {
|
|
995
1009
|
const t = M(e);
|
|
996
1010
|
return [
|
|
997
|
-
...B(
|
|
998
|
-
...B(
|
|
1011
|
+
...B(Y, t),
|
|
1012
|
+
...B(X, t)
|
|
999
1013
|
];
|
|
1000
1014
|
}
|
|
1001
|
-
const
|
|
1015
|
+
const Ae = Pe(), He = Fe(), Ie = je();
|
|
1002
1016
|
export {
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1017
|
+
ge as SOCIAL_NETWORK_OPTIONS,
|
|
1018
|
+
Ie as allBlocks,
|
|
1019
|
+
Ae as builtinBlocks,
|
|
1020
|
+
le as buttonBlock,
|
|
1021
|
+
je as createAllBlocks,
|
|
1022
|
+
Pe as createBuiltinBlocks,
|
|
1023
|
+
Fe as createExampleCustomBlocks,
|
|
1024
|
+
ne as dividerBlock,
|
|
1011
1025
|
p as escAttr,
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1026
|
+
he as escMjmlText,
|
|
1027
|
+
He as exampleCustomBlocks,
|
|
1028
|
+
D as flexJustifyFromAlign,
|
|
1029
|
+
ie as footerBlock,
|
|
1030
|
+
re as heroBlock,
|
|
1031
|
+
ae as htmlBlock,
|
|
1032
|
+
ce as imageBlock,
|
|
1033
|
+
Be as localizeBlockDefinition,
|
|
1020
1034
|
B as localizeBlockDefinitions,
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1035
|
+
se as logoBlock,
|
|
1036
|
+
ue as mjSocialDefaultIconSrc,
|
|
1037
|
+
O as mjSocialElementName,
|
|
1038
|
+
G as mjSocialElementsLines,
|
|
1025
1039
|
S as paddingQuad,
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1040
|
+
V as renderSocialIconPreviewHtml,
|
|
1041
|
+
xe as socialBlock,
|
|
1042
|
+
ke as socialGroupBlock,
|
|
1043
|
+
fe as socialIconBorderRadiusCss,
|
|
1044
|
+
U as socialIconBorderRadiusMjml,
|
|
1031
1045
|
C as socialIconSpacingPx,
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1046
|
+
K as socialMeta,
|
|
1047
|
+
ye as spacerBlock,
|
|
1048
|
+
$e as textBlock
|
|
1035
1049
|
};
|
|
1036
1050
|
//# sourceMappingURL=index.js.map
|