mail-editor-pancake 0.0.7 → 0.0.9

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.
Files changed (33) hide show
  1. package/README.md +174 -3
  2. package/package.json +1 -1
  3. package/packages/blocks/dist/index.d.ts +12 -0
  4. package/packages/blocks/dist/index.js +186 -148
  5. package/packages/blocks/dist/index.js.map +1 -1
  6. package/packages/blocks/src/index.ts +2 -0
  7. package/packages/blocks/src/social.ts +8 -11
  8. package/packages/blocks/src/socialGroup.ts +8 -11
  9. package/packages/blocks/src/socialShared.ts +52 -0
  10. package/packages/blocks/src/text.ts +21 -14
  11. package/packages/core/dist/index.d.ts +99 -5
  12. package/packages/core/dist/index.js +2475 -1480
  13. package/packages/core/dist/index.js.map +1 -1
  14. package/packages/core/dist/style.css +1 -1
  15. package/packages/core/src/editor/Canvas.ts +77 -34
  16. package/packages/core/src/editor/ColorPickerPopover.ts +291 -0
  17. package/packages/core/src/editor/Editor.ts +269 -32
  18. package/packages/core/src/editor/ExportModal.ts +2 -1
  19. package/packages/core/src/editor/FocusBreadcrumb.ts +120 -0
  20. package/packages/core/src/editor/InlineEditor.ts +316 -65
  21. package/packages/core/src/editor/LeftPanel.ts +1 -2
  22. package/packages/core/src/editor/RichTextToolbar.ts +66 -44
  23. package/packages/core/src/editor/RightPanel.ts +491 -74
  24. package/packages/core/src/editor/SourceView.ts +2 -1
  25. package/packages/core/src/editor/Topbar.ts +98 -7
  26. package/packages/core/src/editor/styles.css +427 -33
  27. package/packages/core/src/index.ts +23 -1
  28. package/packages/core/src/store/store.ts +44 -3
  29. package/packages/core/src/types.ts +8 -0
  30. package/packages/core/src/utils/richHtmlInsert.ts +16 -0
  31. package/packages/core/src/utils/richTextCommand.ts +30 -0
  32. package/packages/core/src/utils/sectionLayout.ts +13 -0
  33. package/packages/core/src/variables/index.ts +91 -0
@@ -1,4 +1,4 @@
1
- import { defineBlock as h, blockButtonWidthCss as A, docContentWidthCss as H, mjRawEmailTableWrap as _, mjRawCellTypographyFromStyles as q, normalizeFontWeightStep as k, FONT_WEIGHT_STEP_OPTIONS as L } from "@simple-mail/core";
1
+ import { defineBlock as h, blockButtonWidthCss as F, docContentWidthCss as L, mjRawEmailTableWrap as V, mjRawCellTypographyFromStyles as U, normalizeFontWeightStep as f, FONT_WEIGHT_STEP_OPTIONS as M } from "@simple-mail/core";
2
2
  const m = {
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 m = {
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
- }, y = (e) => e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;"), G = h({
14
+ }, x = (e) => e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;"), G = h({
15
15
  type: "button",
16
16
  name: "按钮",
17
17
  category: "content",
@@ -69,22 +69,22 @@ const m = {
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`, n = A(e.width), i = n ? ` width="${y(n)}"` : "";
73
- return `<mj-button href="${y(e.href)}" background-color="${y(
72
+ const t = `${e.paddingTop}px ${e.paddingRight}px ${e.paddingBottom}px ${e.paddingLeft}px`, o = `${e.innerPaddingV}px ${e.innerPaddingH}px`, n = F(e.width), i = n ? ` width="${x(n)}"` : "";
73
+ return `<mj-button href="${x(e.href)}" background-color="${x(
74
74
  e.backgroundColor
75
- )}" color="${y(e.color)}" border-radius="${e.borderRadius}px" font-size="${y(
75
+ )}" color="${x(e.color)}" border-radius="${e.borderRadius}px" font-size="${x(
76
76
  e.fontSize
77
- )}" align="${e.align}" padding="${t}" inner-padding="${o}"${i}>${y(
77
+ )}" align="${e.align}" padding="${t}" inner-padding="${o}"${i}>${x(
78
78
  e.text
79
79
  )}</mj-button>`;
80
80
  },
81
81
  renderPreview: (e) => {
82
- const t = A(e.width), o = t ? `width:${t};max-width:100%;box-sizing:border-box;` : "";
82
+ const t = F(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
- <a href="${y(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}">${y(e.text)}</span></a>
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
- }), E = (e) => e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;"), K = h({
87
+ }), P = (e) => e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;"), q = h({
88
88
  type: "divider",
89
89
  name: "分隔线",
90
90
  category: "content",
@@ -103,7 +103,7 @@ const m = {
103
103
  { key: "paddingTop", label: "上边距", type: "number", min: 0, max: 80 },
104
104
  { key: "paddingBottom", label: "下边距", type: "number", min: 0, max: 80 }
105
105
  ],
106
- toMjml: (e) => `<mj-divider border-color="${E(e.color)}" border-width="${e.thickness}px" width="${E(
106
+ toMjml: (e) => `<mj-divider border-color="${P(e.color)}" border-width="${e.thickness}px" width="${P(
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>`
@@ -136,7 +136,7 @@ const m = {
136
136
  ${b(e.address)}<br/>
137
137
  <a href="${b(e.unsubscribeHref)}" style="color:${e.textColor};">${b(e.unsubscribeText)}</a>
138
138
  </div>`
139
- }), z = (e) => e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;"), X = h({
139
+ }), k = (e) => e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;"), K = h({
140
140
  type: "hero",
141
141
  name: "Hero 大图",
142
142
  category: "content",
@@ -197,26 +197,26 @@ const m = {
197
197
  placeholder: "编写覆盖在图片上的文案…"
198
198
  },
199
199
  toMjml: (e, t) => {
200
- const o = H(t.doc.meta.width), n = `${e.paddingTop}px ${e.paddingRight}px ${e.paddingBottom}px ${e.paddingLeft}px`, i = `${e.height}px`;
200
+ const o = L(t.doc.meta.width), n = `${e.paddingTop}px ${e.paddingRight}px ${e.paddingBottom}px ${e.paddingLeft}px`, i = `${e.height}px`;
201
201
  return `<mj-hero
202
202
  mode="fixed-height"
203
203
  height="${i}"
204
204
  background-width="${o}"
205
205
  background-height="${i}"
206
- background-url="${z(e.backgroundUrl)}"
207
- background-color="${z(e.backgroundColor)}"
206
+ background-url="${k(e.backgroundUrl)}"
207
+ background-color="${k(e.backgroundColor)}"
208
208
  padding="${n}"
209
209
  vertical-align="${e.verticalAlign}"
210
210
  >
211
211
  <mj-text
212
212
  align="${e.textAlign}"
213
- color="${z(e.textColor)}"
213
+ color="${k(e.textColor)}"
214
214
  padding="0"
215
215
  >${e.content}</mj-text>
216
216
  </mj-hero>`;
217
217
  },
218
218
  renderPreview: (e, t) => {
219
- const o = H(t.doc.meta.width), n = e.verticalAlign === "top" ? "flex-start" : e.verticalAlign === "bottom" ? "flex-end" : "center", i = `${e.paddingTop}px ${e.paddingRight}px ${e.paddingBottom}px ${e.paddingLeft}px`, l = z(e.backgroundUrl);
219
+ const o = L(t.doc.meta.width), n = e.verticalAlign === "top" ? "flex-start" : e.verticalAlign === "bottom" ? "flex-end" : "center", i = `${e.paddingTop}px ${e.paddingRight}px ${e.paddingBottom}px ${e.paddingLeft}px`, a = k(e.backgroundUrl);
220
220
  return `<div
221
221
  style="
222
222
  box-sizing:border-box;
@@ -224,7 +224,7 @@ const m = {
224
224
  max-width:${o};
225
225
  min-height:${e.height}px;
226
226
  margin:0 auto;
227
- background-image:linear-gradient(to bottom,rgba(0,0,0,0.25),rgba(0,0,0,0.35)),url(${l});
227
+ background-image:linear-gradient(to bottom,rgba(0,0,0,0.25),rgba(0,0,0,0.35)),url(${a});
228
228
  background-size:cover;
229
229
  background-position:center;
230
230
  background-color:${e.backgroundColor};
@@ -232,7 +232,7 @@ const m = {
232
232
  align-items:${n};
233
233
  justify-content:${e.textAlign === "right" ? "flex-end" : e.textAlign === "center" ? "center" : "flex-start"};
234
234
  padding:${i};
235
- color:${z(e.textColor)};
235
+ color:${k(e.textColor)};
236
236
  overflow:hidden;
237
237
  border-radius:2px;
238
238
  "
@@ -242,7 +242,7 @@ const m = {
242
242
  style="
243
243
  width:100%;
244
244
  text-align:${e.textAlign};
245
- color:${z(e.textColor)};
245
+ color:${k(e.textColor)};
246
246
  text-shadow:0 1px 2px rgba(0,0,0,0.45);
247
247
  "
248
248
  >${e.content}</div>
@@ -278,10 +278,10 @@ const m = {
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 _(o, e.html, q(t.doc.styles));
281
+ return V(o, e.html, U(t.doc.styles));
282
282
  },
283
283
  renderPreview: (e) => `<div class="sm-html-content" style="padding:${`${e.paddingTop}px ${e.paddingRight}px ${e.paddingBottom}px ${e.paddingLeft}px`};min-height:1em;">${e.html}</div>`
284
- }), M = (e) => e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;"), Y = h({
284
+ }), w = (e) => e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;"), X = h({
285
285
  type: "image",
286
286
  name: "图片",
287
287
  category: "content",
@@ -325,16 +325,16 @@ const m = {
325
325
  { key: "paddingTop", label: "内边距", type: "spacing" }
326
326
  ],
327
327
  toMjml: (e) => {
328
- const t = `${e.paddingTop}px ${e.paddingRight}px ${e.paddingBottom}px ${e.paddingLeft}px`, o = e.href ? ` href="${M(e.href)}"` : "", n = ` alt="${M(e.alt || "")}"`, i = e.height != null && e.height > 0 ? ` height="${e.height}px"` : "";
329
- return `<mj-image src="${M(e.src)}"${n}${o} width="${e.width}px"${i} align="${e.align}" padding="${t}" />`;
328
+ const t = `${e.paddingTop}px ${e.paddingRight}px ${e.paddingBottom}px ${e.paddingLeft}px`, o = e.href ? ` href="${w(e.href)}"` : "", n = ` alt="${w(e.alt || "")}"`, i = e.height != null && e.height > 0 ? ` height="${e.height}px"` : "";
329
+ return `<mj-image src="${w(e.src)}"${n}${o} width="${e.width}px"${i} align="${e.align}" padding="${t}" />`;
330
330
  },
331
331
  renderPreview: (e) => {
332
332
  const t = e.align === "center" ? "margin:0 auto;" : e.align === "right" ? "margin-left:auto;" : "", o = e.height != null && e.height > 0 ? e.height : 0, n = o > 0 ? `width:${e.width}px;height:${o}px;object-fit:cover;object-position:center;` : `width:${e.width}px;height:auto;`;
333
- return `<div style="padding:${e.paddingTop}px ${e.paddingRight}px ${e.paddingBottom}px ${e.paddingLeft}px;text-align:${e.align};"><img src="${M(
333
+ return `<div style="padding:${e.paddingTop}px ${e.paddingRight}px ${e.paddingBottom}px ${e.paddingLeft}px;text-align:${e.align};"><img src="${w(
334
334
  e.src
335
- )}" alt="${M(e.alt)}" style="display:block;${t}max-width:100%;${n}border:0;outline:none;" /></div>`;
335
+ )}" alt="${w(e.alt)}" style="display:block;${t}max-width:100%;${n}border:0;outline:none;" /></div>`;
336
336
  }
337
- }), R = (e) => e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;"), Z = h({
337
+ }), B = (e) => e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;"), Y = h({
338
338
  type: "custom:logo",
339
339
  name: "公司 Logo",
340
340
  category: "custom",
@@ -361,25 +361,25 @@ const m = {
361
361
  ]
362
362
  }
363
363
  ],
364
- toMjml: (e) => `<mj-image src="${R(e.src)}" href="${R(e.href)}" width="${e.width}px" align="${e.align}" alt="logo" padding="8px 0px 8px 0px" />`,
364
+ toMjml: (e) => `<mj-image src="${B(e.src)}" href="${B(e.href)}" width="${e.width}px" align="${e.align}" alt="logo" padding="8px 0px 8px 0px" />`,
365
365
  renderPreview: (e) => {
366
366
  const t = e.align === "center" ? "margin:0 auto;" : e.align === "right" ? "margin-left:auto;" : "";
367
- return `<div style="padding:8px 0;text-align:${e.align};"><img src="${R(
367
+ return `<div style="padding:8px 0;text-align:${e.align};"><img src="${B(
368
368
  e.src
369
369
  )}" alt="logo" style="display:block;${t}width:${e.width}px;max-width:100%;height:auto;" /></div>`;
370
370
  }
371
371
  });
372
- function Q(e) {
372
+ function H(e) {
373
373
  const t = e.trim();
374
374
  return t === "ig" ? "instagram" : t === "rabbit" || t === "tiktok" || t === "reddit" ? "web" : t;
375
375
  }
376
- const ee = [
376
+ const Z = [
377
377
  { label: "X", value: "x" },
378
378
  { label: "Rabbit", value: "rabbit" },
379
379
  { label: "Facebook", value: "facebook" },
380
380
  { label: "TikTok", value: "tiktok" },
381
381
  { label: "Instagram", value: "ig" }
382
- ], te = [
382
+ ], Q = [
383
383
  { label: "微信", value: "wechat" },
384
384
  { label: "微博", value: "weibo" },
385
385
  { label: "X", value: "x" },
@@ -390,7 +390,7 @@ const ee = [
390
390
  { label: "YouTube", value: "youtube" },
391
391
  { label: "Reddit", value: "reddit" },
392
392
  { label: "网页", value: "web" }
393
- ], oe = {
393
+ ], ee = {
394
394
  wechat: { color: "#1AAD19", preview: "信" },
395
395
  weibo: { color: "#E6162D", preview: "微" },
396
396
  x: { color: "#000000", preview: "X" },
@@ -405,11 +405,40 @@ const ee = [
405
405
  rabbit: { color: "#FF2442", preview: "R" },
406
406
  website: { color: "#6b7280", preview: "◇" },
407
407
  web: { color: "#6b7280", preview: "◇" }
408
- }, s = (e) => e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;"), ne = (e) => e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
409
- function P(e) {
410
- return oe[e] ?? { color: "#6b7280", preview: "·" };
408
+ }, g = (e) => e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;"), te = (e) => e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
409
+ function E(e) {
410
+ return ee[e] ?? { color: "#6b7280", preview: "·" };
411
411
  }
412
- function T(e) {
412
+ const oe = "https://www.mailjet.com/images/theme/v1/icons/ico-social/", ne = {
413
+ facebook: "facebook.png",
414
+ twitter: "twitter.png",
415
+ x: "twitter-x.png",
416
+ google: "google-plus.png",
417
+ pinterest: "pinterest.png",
418
+ linkedin: "linkedin.png",
419
+ instagram: "instagram.png",
420
+ web: "web.png",
421
+ snapchat: "snapchat.png",
422
+ youtube: "youtube.png",
423
+ tumblr: "tumblr.png",
424
+ github: "github.png",
425
+ xing: "xing.png",
426
+ vimeo: "vimeo.png",
427
+ medium: "medium.png",
428
+ soundcloud: "soundcloud.png",
429
+ dribbble: "dribbble.png"
430
+ };
431
+ function ie(e) {
432
+ const t = ne[H(e)];
433
+ return t ? `${oe}${t}` : null;
434
+ }
435
+ function N(e) {
436
+ const { network: t, iconSize: o, iconBorderRadius: n, iconSrc: i, backgroundColor: a } = e, d = le(o, n), c = E(t), l = (a == null ? void 0 : a.trim()) || c.color, r = (i == null ? void 0 : i.trim()) || ie(t);
437
+ return r ? `<span style="display:inline-flex;width:${o}px;height:${o}px;border-radius:${d};background:${l};overflow:hidden;align-items:center;justify-content:center;flex-shrink:0;line-height:0;"><img src="${g(r)}" alt="" width="${o}" height="${o}" style="display:block;width:${o}px;height:${o}px;border-radius:${d};" /></span>` : `<span style="display:inline-flex;width:${o}px;height:${o}px;border-radius:${d};background:${l};color:#fff;align-items:center;justify-content:center;font-size:${Math.round(
438
+ o / 2
439
+ )}px;font-weight:600;flex-shrink:0;overflow:hidden;">${c.preview}</span>`;
440
+ }
441
+ function S(e) {
413
442
  return `${e.paddingTop}px ${e.paddingRight}px ${e.paddingBottom}px ${e.paddingLeft}px`;
414
443
  }
415
444
  function W(e, t) {
@@ -418,13 +447,13 @@ function W(e, t) {
418
447
  const i = o / 2;
419
448
  return n >= 999 || n >= i ? "999px" : `${Math.min(n, o)}px`;
420
449
  }
421
- function V(e, t) {
450
+ function le(e, t) {
422
451
  const o = Math.max(1, Number(e) || 28), n = Number(t);
423
452
  if (!Number.isFinite(n) || n <= 0) return "0";
424
453
  const i = o / 2;
425
454
  return n >= 999 || n >= i ? "50%" : `${Math.min(n, o)}px`;
426
455
  }
427
- function F(e, t = 10) {
456
+ function C(e, t = 10) {
428
457
  const o = Number(e);
429
458
  return !Number.isFinite(o) || o < 0 ? t : Math.min(64, Math.round(o));
430
459
  }
@@ -432,47 +461,47 @@ function I(e) {
432
461
  return e === "right" ? "flex-end" : e === "left" ? "flex-start" : "center";
433
462
  }
434
463
  function O(e, t) {
435
- var d;
436
- const o = t.labelFontSize > 0 ? t.labelFontSize : 13, n = Math.max(8, Math.min(48, o)), i = k(t.labelFontWeight), l = ((d = t.labelColor) == null ? void 0 : d.trim()) || "#333333", g = s(i);
437
- return e.map((a) => {
438
- var v, S, f;
439
- const p = P(a.network), $ = ((v = a.backgroundColor) == null ? void 0 : v.trim()) || p.color, c = [
440
- `name="${s(Q(a.network))}"`,
441
- `href="${s(a.href)}"`,
442
- `background-color="${s($)}"`,
443
- `color="${s(l)}"`,
464
+ var c;
465
+ const o = t.labelFontSize > 0 ? t.labelFontSize : 13, n = Math.max(8, Math.min(48, o)), i = f(t.labelFontWeight), a = ((c = t.labelColor) == null ? void 0 : c.trim()) || "#333333", d = g(i);
466
+ return e.map((l) => {
467
+ var j, T, R;
468
+ const r = E(l.network), s = ((j = l.backgroundColor) == null ? void 0 : j.trim()) || r.color, y = [
469
+ `name="${g(H(l.network))}"`,
470
+ `href="${g(l.href)}"`,
471
+ `background-color="${g(s)}"`,
472
+ `color="${g(a)}"`,
444
473
  `font-size="${n}px"`,
445
- `font-weight="${g}"`
446
- ].join(" "), w = (S = a.iconSrc) == null ? void 0 : S.trim(), u = w ? `${c} src="${s(w)}"` : c, x = ((f = a.label) == null ? void 0 : f.trim()) ?? "";
447
- return x ? ` <mj-social-element ${u}>
448
- ${ne(x)}
474
+ `font-weight="${d}"`
475
+ ].join(" "), $ = (T = l.iconSrc) == null ? void 0 : T.trim(), u = $ ? `${y} src="${g($)}"` : y, z = ((R = l.label) == null ? void 0 : R.trim()) ?? "";
476
+ return z ? ` <mj-social-element ${u}>
477
+ ${te(z)}
449
478
  </mj-social-element>` : ` <mj-social-element ${u} />`;
450
479
  }).join(`
451
480
  `);
452
481
  }
453
- const U = [
482
+ const _ = [
454
483
  { network: "x", href: "https://x.com/" },
455
484
  { network: "rabbit", href: "https://example.com" },
456
485
  { network: "facebook", href: "https://facebook.com/" },
457
486
  { network: "tiktok", href: "https://www.tiktok.com/" },
458
487
  { network: "ig", href: "https://instagram.com/" }
459
488
  ];
460
- function N(e) {
489
+ function A(e) {
461
490
  var o;
462
491
  if ((o = e.elements) != null && o.length) return e.elements;
463
492
  const t = e.links;
464
493
  return Array.isArray(t) && t.length ? t.map((n) => ({
465
494
  network: String(n.network ?? "web"),
466
495
  href: String(n.href ?? "")
467
- })) : U;
496
+ })) : _;
468
497
  }
469
- const ie = h({
498
+ const re = h({
470
499
  type: "custom:social",
471
500
  name: "社交链接",
472
501
  category: "custom",
473
502
  icon: m.social,
474
503
  defaultProps: {
475
- elements: U,
504
+ elements: _,
476
505
  align: "center",
477
506
  iconSize: 28,
478
507
  iconBorderRadius: 999,
@@ -490,7 +519,7 @@ const ie = h({
490
519
  key: "elements",
491
520
  label: "社交链接",
492
521
  type: "socialLinkList",
493
- options: ee,
522
+ options: Z,
494
523
  help: "平台:X、Rabbit、Facebook、TikTok、Instagram (ig)。可填标签、自定义图标 URL。MJML 侧 Rabbit/TikTok 使用 web 占位图标,需要品牌图时请填「图标 URL」。"
495
524
  },
496
525
  {
@@ -506,7 +535,7 @@ const ie = h({
506
535
  label: "标签字重",
507
536
  type: "select",
508
537
  selectVariant: "segmented",
509
- options: [...L]
538
+ options: [...M]
510
539
  },
511
540
  { key: "labelColor", label: "标签颜色", type: "color" },
512
541
  {
@@ -542,37 +571,41 @@ const ie = h({
542
571
  { key: "paddingTop", label: "外边距", type: "spacing" }
543
572
  ],
544
573
  toMjml: (e) => {
545
- const t = T(e), o = W(e.iconSize, e.iconBorderRadius ?? 999), n = F(e.iconSpacing, 10), i = `align="${e.align}" icon-size="${e.iconSize}px" mode="horizontal" border-radius="${o}" inner-padding="${n}px" padding="${t}"`, l = N(e).filter((a) => {
546
- var p;
547
- return (p = a.href) == null ? void 0 : p.trim();
548
- }), g = {
574
+ const t = S(e), o = W(e.iconSize, e.iconBorderRadius ?? 999), n = C(e.iconSpacing, 10), i = `align="${e.align}" icon-size="${e.iconSize}px" mode="horizontal" border-radius="${o}" inner-padding="${n}px" padding="${t}"`, a = A(e).filter((l) => {
575
+ var r;
576
+ return (r = l.href) == null ? void 0 : r.trim();
577
+ }), d = {
549
578
  labelFontSize: Number(e.labelFontSize ?? 13),
550
- labelFontWeight: k(String(e.labelFontWeight ?? "400")),
579
+ labelFontWeight: f(String(e.labelFontWeight ?? "400")),
551
580
  labelColor: String(e.labelColor ?? "#333333")
552
- }, d = O(l, g);
553
- return d.trim() ? `<mj-social ${i}>
554
- ${d}
581
+ }, c = O(a, d);
582
+ return c.trim() ? `<mj-social ${i}>
583
+ ${c}
555
584
  </mj-social>` : `<mj-social ${i}></mj-social>`;
556
585
  },
557
586
  renderPreview: (e) => {
558
- var $;
559
- const t = e.labelFontSize != null && e.labelFontSize > 0 ? e.labelFontSize : 13, o = Math.max(8, Math.min(48, t)), n = k(e.labelFontWeight), i = (($ = e.labelColor) == null ? void 0 : $.trim()) || "#333333", l = V(e.iconSize, e.iconBorderRadius ?? 999), g = F(e.iconSpacing, 10), d = I(e.align), a = N(e).filter((r) => {
560
- var c;
561
- return (c = r.href) == null ? void 0 : c.trim();
562
- }).map((r) => {
563
- var f, C, j;
564
- const c = P(r.network), w = ((f = r.backgroundColor) == null ? void 0 : f.trim()) || c.color, u = ((C = r.label) == null ? void 0 : C.trim()) ?? "", x = (j = r.iconSrc) == null ? void 0 : j.trim(), v = x ? `<img src="${s(x)}" alt="" style="width:${e.iconSize}px;height:${e.iconSize}px;object-fit:cover;border-radius:${l};flex-shrink:0;" />` : `<span style="display:inline-flex;width:${e.iconSize}px;height:${e.iconSize}px;border-radius:${l};background:${w};color:#fff;align-items:center;justify-content:center;font-size:${Math.round(
565
- e.iconSize / 2
566
- )}px;font-weight:600;flex-shrink:0;overflow:hidden;">${c.preview}</span>`, S = u ? `<span style="font-size:${o}px !important;font-weight:${n};color:${s(
587
+ var r;
588
+ const t = e.labelFontSize != null && e.labelFontSize > 0 ? e.labelFontSize : 13, o = Math.max(8, Math.min(48, t)), n = f(e.labelFontWeight), i = ((r = e.labelColor) == null ? void 0 : r.trim()) || "#333333", a = C(e.iconSpacing, 10), d = I(e.align), c = A(e).filter((s) => {
589
+ var p;
590
+ return (p = s.href) == null ? void 0 : p.trim();
591
+ }).map((s) => {
592
+ var u;
593
+ const p = ((u = s.label) == null ? void 0 : u.trim()) ?? "", y = N({
594
+ network: s.network,
595
+ iconSize: e.iconSize,
596
+ iconBorderRadius: e.iconBorderRadius ?? 999,
597
+ iconSrc: s.iconSrc,
598
+ backgroundColor: s.backgroundColor
599
+ }), $ = p ? `<span style="font-size:${o}px !important;font-weight:${n};color:${g(
567
600
  i
568
- )} !important;line-height:1.2;">${s(u)}</span>` : "";
569
- return `<span style="display:inline-flex;align-items:center;gap:6px;"><a href="${s(
570
- r.href
571
- )}" style="display:inline-flex;align-items:center;text-decoration:none;line-height:0;">${v}</a>${S}</span>`;
572
- }).join(""), p = T(e);
573
- return `<div style="display:flex;flex-wrap:wrap;justify-content:${d};align-items:center;gap:${g}px;padding:${p};">${a || '<span style="color:#9ca3af;font-size:12px;">请填写链接 URL</span>'}</div>`;
601
+ )} !important;line-height:1.2;">${g(p)}</span>` : "";
602
+ return `<span style="display:inline-flex;align-items:center;gap:6px;"><a href="${g(
603
+ s.href
604
+ )}" style="display:inline-flex;align-items:center;text-decoration:none;line-height:0;">${y}</a>${$}</span>`;
605
+ }).join(""), l = S(e);
606
+ return `<div style="display:flex;flex-wrap:wrap;justify-content:${d};align-items:center;gap:${a}px;padding:${l};">${c || '<span style="color:#9ca3af;font-size:12px;">请填写链接 URL</span>'}</div>`;
574
607
  }
575
- }), le = h({
608
+ }), ae = h({
576
609
  type: "social-group",
577
610
  name: "社交组",
578
611
  category: "content",
@@ -599,7 +632,7 @@ ${d}
599
632
  key: "elements",
600
633
  label: "社交链接",
601
634
  type: "socialLinkList",
602
- options: te,
635
+ options: Q,
603
636
  help: "每行:平台、链接、可选标签文字、自定义图标 URL、图标背景色。标签的字号/字重/颜色在下方统一设置。"
604
637
  },
605
638
  {
@@ -615,7 +648,7 @@ ${d}
615
648
  label: "标签字重",
616
649
  type: "select",
617
650
  selectVariant: "segmented",
618
- options: [...L]
651
+ options: [...M]
619
652
  },
620
653
  { key: "labelColor", label: "标签颜色", type: "color" },
621
654
  {
@@ -651,37 +684,41 @@ ${d}
651
684
  { key: "paddingTop", label: "外边距", type: "spacing" }
652
685
  ],
653
686
  toMjml: (e) => {
654
- const t = T(e), o = W(e.iconSize, e.iconBorderRadius ?? 999), n = F(e.iconSpacing, 10), i = `align="${e.align}" icon-size="${e.iconSize}px" mode="horizontal" border-radius="${o}" inner-padding="${n}px" padding="${t}"`, l = e.elements.filter((a) => {
655
- var p;
656
- return (p = a.href) == null ? void 0 : p.trim();
657
- }), g = {
687
+ const t = S(e), o = W(e.iconSize, e.iconBorderRadius ?? 999), n = C(e.iconSpacing, 10), i = `align="${e.align}" icon-size="${e.iconSize}px" mode="horizontal" border-radius="${o}" inner-padding="${n}px" padding="${t}"`, a = e.elements.filter((l) => {
688
+ var r;
689
+ return (r = l.href) == null ? void 0 : r.trim();
690
+ }), d = {
658
691
  labelFontSize: Number(e.labelFontSize ?? 13),
659
- labelFontWeight: k(String(e.labelFontWeight ?? "400")),
692
+ labelFontWeight: f(String(e.labelFontWeight ?? "400")),
660
693
  labelColor: String(e.labelColor ?? "#333333")
661
- }, d = O(l, g);
662
- return d.trim() ? `<mj-social ${i}>
663
- ${d}
694
+ }, c = O(a, d);
695
+ return c.trim() ? `<mj-social ${i}>
696
+ ${c}
664
697
  </mj-social>` : `<mj-social ${i}></mj-social>`;
665
698
  },
666
699
  renderPreview: (e) => {
667
- var $;
668
- const t = e.labelFontSize != null && e.labelFontSize > 0 ? e.labelFontSize : 13, o = Math.max(8, Math.min(48, t)), n = k(e.labelFontWeight), i = (($ = e.labelColor) == null ? void 0 : $.trim()) || "#333333", l = V(e.iconSize, e.iconBorderRadius ?? 999), g = F(e.iconSpacing, 10), d = I(e.align), a = e.elements.filter((r) => {
669
- var c;
670
- return (c = r.href) == null ? void 0 : c.trim();
671
- }).map((r) => {
672
- var f, C, j;
673
- const c = P(r.network), w = ((f = r.backgroundColor) == null ? void 0 : f.trim()) || c.color, u = ((C = r.label) == null ? void 0 : C.trim()) ?? "", x = (j = r.iconSrc) == null ? void 0 : j.trim(), v = x ? `<img src="${s(x)}" alt="" style="width:${e.iconSize}px;height:${e.iconSize}px;object-fit:cover;border-radius:${l};flex-shrink:0;" />` : `<span style="display:inline-flex;width:${e.iconSize}px;height:${e.iconSize}px;border-radius:${l};background:${w};color:#fff;align-items:center;justify-content:center;font-size:${Math.round(
674
- e.iconSize / 2
675
- )}px;font-weight:600;flex-shrink:0;overflow:hidden;">${c.preview}</span>`, S = u ? `<span style="font-size:${o}px !important;font-weight:${n};color:${s(
700
+ var r;
701
+ const t = e.labelFontSize != null && e.labelFontSize > 0 ? e.labelFontSize : 13, o = Math.max(8, Math.min(48, t)), n = f(e.labelFontWeight), i = ((r = e.labelColor) == null ? void 0 : r.trim()) || "#333333", a = C(e.iconSpacing, 10), d = I(e.align), c = e.elements.filter((s) => {
702
+ var p;
703
+ return (p = s.href) == null ? void 0 : p.trim();
704
+ }).map((s) => {
705
+ var u;
706
+ const p = ((u = s.label) == null ? void 0 : u.trim()) ?? "", y = N({
707
+ network: s.network,
708
+ iconSize: e.iconSize,
709
+ iconBorderRadius: e.iconBorderRadius ?? 999,
710
+ iconSrc: s.iconSrc,
711
+ backgroundColor: s.backgroundColor
712
+ }), $ = p ? `<span style="font-size:${o}px !important;font-weight:${n};color:${g(
676
713
  i
677
- )} !important;line-height:1.2;">${s(u)}</span>` : "";
678
- return `<span style="display:inline-flex;align-items:center;gap:6px;"><a href="${s(
679
- r.href
680
- )}" style="display:inline-flex;align-items:center;text-decoration:none;line-height:0;">${v}</a>${S}</span>`;
681
- }).join(""), p = T(e);
682
- return `<div style="display:flex;flex-wrap:wrap;justify-content:${d};align-items:center;gap:${g}px;padding:${p};">${a || '<span style="color:#9ca3af;font-size:12px;">请添加社交链接</span>'}</div>`;
714
+ )} !important;line-height:1.2;">${g(p)}</span>` : "";
715
+ return `<span style="display:inline-flex;align-items:center;gap:6px;"><a href="${g(
716
+ s.href
717
+ )}" style="display:inline-flex;align-items:center;text-decoration:none;line-height:0;">${y}</a>${$}</span>`;
718
+ }).join(""), l = S(e);
719
+ return `<div style="display:flex;flex-wrap:wrap;justify-content:${d};align-items:center;gap:${a}px;padding:${l};">${c || '<span style="color:#9ca3af;font-size:12px;">请添加社交链接</span>'}</div>`;
683
720
  }
684
- }), re = h({
721
+ }), ce = h({
685
722
  type: "spacer",
686
723
  name: "间距",
687
724
  category: "content",
@@ -690,7 +727,7 @@ ${d}
690
727
  schema: [{ key: "height", label: "高度 (px)", type: "number", min: 1, max: 200 }],
691
728
  toMjml: (e) => `<mj-spacer height="${e.height}px" />`,
692
729
  renderPreview: (e) => `<div style="height:${e.height}px;line-height:${e.height}px;"></div>`
693
- }), B = (e) => e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;"), ae = h({
730
+ }), v = (e) => e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;"), se = h({
694
731
  type: "text",
695
732
  name: "文本",
696
733
  category: "content",
@@ -698,10 +735,10 @@ ${d}
698
735
  defaultProps: {
699
736
  content: '<p style="margin:0;">在此处输入文本。<strong>双击</strong>进入编辑模式,<em>选中文字</em>会出现工具条;支持变量 {{user.name}}</p>',
700
737
  align: "left",
701
- color: "#433f3f",
702
- fontSize: "16px",
738
+ color: "",
739
+ fontSize: "",
703
740
  fontFamily: "",
704
- fontWeight: "400",
741
+ fontWeight: "",
705
742
  lineHeight: "",
706
743
  paddingTop: 8,
707
744
  paddingRight: 0,
@@ -711,7 +748,7 @@ ${d}
711
748
  schema: [
712
749
  {
713
750
  key: "align",
714
- label: "默认对齐",
751
+ label: "对齐",
715
752
  type: "select",
716
753
  selectVariant: "segmented",
717
754
  options: [
@@ -720,15 +757,16 @@ ${d}
720
757
  { label: "右", value: "right" }
721
758
  ]
722
759
  },
723
- { key: "color", label: "默认颜色", type: "color" },
724
- { key: "fontSize", label: "默认字号", type: "text", placeholder: "14px" },
760
+ { key: "color", label: "颜色", type: "color", placeholder: "继承全局" },
761
+ { key: "fontSize", label: "字号", type: "text", inheritGlobal: !0 },
725
762
  { key: "fontFamily", label: "字体", type: "text", placeholder: "继承全局" },
726
763
  {
727
764
  key: "fontWeight",
728
765
  label: "字重",
729
766
  type: "select",
730
767
  selectVariant: "segmented",
731
- options: [...L]
768
+ inheritGlobal: !0,
769
+ options: [...M]
732
770
  },
733
771
  {
734
772
  key: "lineHeight",
@@ -766,50 +804,50 @@ ${d}
766
804
  placeholder: "输入文本…"
767
805
  },
768
806
  toMjml: (e) => {
769
- const t = `${e.paddingTop}px ${e.paddingRight}px ${e.paddingBottom}px ${e.paddingLeft}px`, o = e.fontFamily ? ` font-family="${B(e.fontFamily)}"` : "", n = k(e.fontWeight), i = n !== "400" ? ` font-weight="${B(n)}"` : "", l = String(e.lineHeight ?? "").trim(), g = l ? ` line-height="${B(l)}"` : "";
770
- return `<mj-text align="${e.align}" color="${B(e.color)}" font-size="${B(
771
- e.fontSize
772
- )}"${g}${o}${i} padding="${t}">${e.content}</mj-text>`;
807
+ const t = `${e.paddingTop}px ${e.paddingRight}px ${e.paddingBottom}px ${e.paddingLeft}px`, o = e.fontFamily ? ` font-family="${v(e.fontFamily)}"` : "", n = String(e.fontWeight ?? "").trim(), i = n ? ` font-weight="${v(f(n))}"` : "", a = String(e.lineHeight ?? "").trim(), d = a ? ` line-height="${v(a)}"` : "", c = String(e.color ?? "").trim(), l = c ? ` color="${v(c)}"` : "", r = String(e.fontSize ?? "").trim(), s = r ? ` font-size="${v(r)}"` : "";
808
+ return `<mj-text align="${e.align}"${l}${s}${d}${o}${i} padding="${t}">${e.content}</mj-text>`;
773
809
  },
774
810
  renderPreview: (e) => {
775
- const t = e.fontFamily ? `font-family:${e.fontFamily};` : "", o = k(e.fontWeight), n = o !== "400" ? `font-weight:${o};` : "", i = String(e.lineHeight ?? "").trim(), l = i ? `line-height:${i};` : "line-height:normal;";
776
- return `<div class="sm-text-content" style="text-align:${e.align};color:${e.color};font-size:${e.fontSize};${l}${t}${n}padding:${e.paddingTop}px ${e.paddingRight}px ${e.paddingBottom}px ${e.paddingLeft}px;">${e.content}</div>`;
811
+ const t = e.fontFamily ? `font-family:${e.fontFamily};` : "", o = String(e.fontWeight ?? "").trim(), n = o ? `font-weight:${f(o)};` : "", i = String(e.lineHeight ?? "").trim(), a = i ? `line-height:${i};` : "line-height:normal;", d = String(e.color ?? "").trim(), c = d ? `color:${d};` : "", l = String(e.fontSize ?? "").trim(), r = l ? `font-size:${l};` : "";
812
+ return `<div class="sm-text-content" style="text-align:${e.align};${c}${r}${n}${a}${t}padding:${e.paddingTop}px ${e.paddingRight}px ${e.paddingBottom}px ${e.paddingLeft}px;">${e.content}</div>`;
777
813
  }
778
- }), ce = [
779
- ae,
814
+ }), de = [
815
+ se,
780
816
  D,
781
- Y,
782
- le,
783
817
  X,
784
- G,
818
+ ae,
785
819
  K,
786
- re
787
- ], se = [Z, ie, J], ge = [...ce, ...se];
820
+ G,
821
+ q,
822
+ ce
823
+ ], ge = [Y, re, J], he = [...de, ...ge];
788
824
  export {
789
- te as SOCIAL_NETWORK_OPTIONS,
790
- ge as allBlocks,
791
- ce as builtinBlocks,
825
+ Q as SOCIAL_NETWORK_OPTIONS,
826
+ he as allBlocks,
827
+ de as builtinBlocks,
792
828
  G as buttonBlock,
793
- K as dividerBlock,
794
- s as escAttr,
795
- ne as escMjmlText,
796
- se as exampleCustomBlocks,
829
+ q as dividerBlock,
830
+ g as escAttr,
831
+ te as escMjmlText,
832
+ ge as exampleCustomBlocks,
797
833
  I as flexJustifyFromAlign,
798
834
  J as footerBlock,
799
- X as heroBlock,
835
+ K as heroBlock,
800
836
  D as htmlBlock,
801
- Y as imageBlock,
802
- Z as logoBlock,
803
- Q as mjSocialElementName,
837
+ X as imageBlock,
838
+ Y as logoBlock,
839
+ ie as mjSocialDefaultIconSrc,
840
+ H as mjSocialElementName,
804
841
  O as mjSocialElementsLines,
805
- T as paddingQuad,
806
- ie as socialBlock,
807
- le as socialGroupBlock,
808
- V as socialIconBorderRadiusCss,
842
+ S as paddingQuad,
843
+ N as renderSocialIconPreviewHtml,
844
+ re as socialBlock,
845
+ ae as socialGroupBlock,
846
+ le as socialIconBorderRadiusCss,
809
847
  W as socialIconBorderRadiusMjml,
810
- F as socialIconSpacingPx,
811
- P as socialMeta,
812
- re as spacerBlock,
813
- ae as textBlock
848
+ C as socialIconSpacingPx,
849
+ E as socialMeta,
850
+ ce as spacerBlock,
851
+ se as textBlock
814
852
  };
815
853
  //# sourceMappingURL=index.js.map