mail-editor-pancake 0.0.0 → 0.0.8

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 (45) hide show
  1. package/README.md +79 -6
  2. package/package.json +1 -1
  3. package/packages/blocks/dist/index.d.ts +55 -3
  4. package/packages/blocks/dist/index.js +267 -208
  5. package/packages/blocks/dist/index.js.map +1 -1
  6. package/packages/blocks/node_modules/.bin/resolve +21 -0
  7. package/packages/blocks/package.json +1 -0
  8. package/packages/blocks/src/button.ts +1 -0
  9. package/packages/blocks/src/hero.ts +2 -0
  10. package/packages/blocks/src/image.ts +1 -0
  11. package/packages/blocks/src/index.ts +19 -2
  12. package/packages/blocks/src/logo.ts +1 -0
  13. package/packages/blocks/src/social.ts +47 -22
  14. package/packages/blocks/src/socialGroup.ts +49 -22
  15. package/packages/blocks/src/socialShared.ts +39 -2
  16. package/packages/blocks/src/text.ts +25 -19
  17. package/packages/blocks/tsconfig.json +0 -3
  18. package/packages/blocks/vite.config.ts +2 -0
  19. package/packages/core/dist/index.d.ts +90 -7
  20. package/packages/core/dist/index.js +2505 -1462
  21. package/packages/core/dist/index.js.map +1 -1
  22. package/packages/core/dist/style.css +1 -1
  23. package/packages/core/src/editor/Canvas.ts +107 -53
  24. package/packages/core/src/editor/ColorPickerPopover.ts +291 -0
  25. package/packages/core/src/editor/Editor.ts +129 -8
  26. package/packages/core/src/editor/ExportModal.ts +2 -1
  27. package/packages/core/src/editor/FocusBreadcrumb.ts +120 -0
  28. package/packages/core/src/editor/ImageGalleryModal.ts +3 -3
  29. package/packages/core/src/editor/InlineEditor.ts +308 -66
  30. package/packages/core/src/editor/LeftPanel.ts +1 -2
  31. package/packages/core/src/editor/PreviewModal.ts +77 -7
  32. package/packages/core/src/editor/RichTextToolbar.ts +66 -44
  33. package/packages/core/src/editor/RightPanel.ts +773 -171
  34. package/packages/core/src/editor/SourceView.ts +2 -1
  35. package/packages/core/src/editor/Topbar.ts +150 -5
  36. package/packages/core/src/editor/styles.css +644 -81
  37. package/packages/core/src/index.ts +18 -1
  38. package/packages/core/src/renderer/mjml.ts +2 -1
  39. package/packages/core/src/store/store.ts +44 -3
  40. package/packages/core/src/types.ts +34 -3
  41. package/packages/core/src/utils/fontWeightSteps.ts +31 -0
  42. package/packages/core/src/utils/lockedMjml.ts +2 -1
  43. package/packages/core/src/utils/richTextCommand.ts +30 -0
  44. package/packages/core/src/utils/sectionLayout.ts +13 -0
  45. package/playground/vanilla/src/main.ts +1 -1
@@ -44,6 +44,12 @@ export declare interface BlockDefinition<P extends object = Record<string, unkno
44
44
  * 在用户提交时按 `mode` 写回 props(rich:清理后的 innerHTML;html:原始 innerHTML;plain:textContent)。
45
45
  */
46
46
  inlineEditable?: InlineEditableConfig<P>;
47
+ /**
48
+ * 从左栏拖入时在目标列(或自动包裹的单列 Section)中一次性插入多个块,
49
+ * 用于「组合模板」:画布内仅为通用 image/text 等,便于逐项修改。
50
+ * 文档里不会出现本定义的 `type`,仅作左栏入口;若需提供请返回内置块的实例。
51
+ */
52
+ expandPaletteDrop?: (createBlock: (type: string) => Block) => Block[];
47
53
  }
48
54
 
49
55
  export declare interface BlockSchemaField {
@@ -55,12 +61,19 @@ export declare interface BlockSchemaField {
55
61
  label: string;
56
62
  value: string;
57
63
  }[];
64
+ /**
65
+ * select 专用:`segmented` 为横向平铺分段按钮(适合少量互斥选项,如左/中/右对齐)。
66
+ * 默认 `default` 为下拉框。
67
+ */
68
+ selectVariant?: 'default' | 'segmented';
58
69
  /** number 用 */
59
70
  min?: number;
60
71
  max?: number;
61
72
  step?: number;
62
73
  placeholder?: string;
63
74
  help?: string;
75
+ /** 为 true 时右栏显示「继承全局」开关:开=留空跟随邮件全局,关=写入当前全局值为块级固定值 */
76
+ inheritGlobal?: boolean;
64
77
  }
65
78
 
66
79
  export declare interface Column {
@@ -151,6 +164,11 @@ declare interface EditorOptions {
151
164
  imageAssets?: ImageAssetsHandlers;
152
165
  /** 右栏控件形态等可选 UI 偏好。 */
153
166
  ui?: EditorUiOptions;
167
+ /**
168
+ * 顶栏「重置内容」恢复的目标文档(与 `initialDoc` 独立;编辑已保存邮件时仍应指向业务预置模板)。
169
+ * 未传时与构造时的 `initialDoc` 合并结果一致。
170
+ */
171
+ presetDoc?: Partial<EmailDoc>;
154
172
  }
155
173
 
156
174
  /** 编辑器 Chrome 配色:`system` 由 `prefers-color-scheme` 与 `data-sm-theme` 共同决定。邮件画布 `.sm-canvas` 默认仍为白纸以贴近成品。 */
@@ -159,16 +177,34 @@ export declare type EditorTheme = 'light' | 'dark' | 'system';
159
177
  /** MailEditor 可选 UI 行为(不改变文档模型) */
160
178
  export declare interface EditorUiOptions {
161
179
  /**
162
- * 为 true 时:右栏数值、内边距(四行滑块+输入)、全局/组件字号(px 滑块)、字重(分段)、
180
+ * 为 true 时:右栏数值、内边距(四行滑块+输入)、全局/组件字号(px 滑块)、
163
181
  * Section/按钮/分隔线等「宽度」类文本字段(自适应 / px / % + 滑块)使用增强控件。
182
+ * 字重恒为五档平铺(300–700),不受此项影响。
164
183
  * 默认 false。
165
184
  */
166
185
  preferSliderControls?: boolean;
167
186
  /**
168
- * 为 true 时隐藏右栏「主题 / Preheader」及顶栏「邮件设置」入口;仍保留「内容宽度」与「全局样式」。
187
+ * 为 true 时隐藏右栏「主题 / Preheader」;仍保留「内容宽度」与「全局样式」。
188
+ * 顶栏「邮件设置」默认仍会显示,用于回到文档级面板;若需一并隐藏请设 `hideTopbarMailSettings`。
169
189
  * 适合只搭建正文、发件主题由宿主系统管理的场景。
170
190
  */
171
191
  hideMailMeta?: boolean;
192
+ /**
193
+ * 为 true 时隐藏顶栏左侧「Simple Mail Editor」标题(嵌入宿主页面时常用)。
194
+ */
195
+ hideTopbarTitle?: boolean;
196
+ /**
197
+ * 为 true 时隐藏顶栏「邮件设置」按钮。
198
+ */
199
+ hideTopbarMailSettings?: boolean;
200
+ /**
201
+ * 为 true 时隐藏顶栏「全屏」图标按钮(浏览器原生全屏 API,作用于编辑器根节点)。
202
+ */
203
+ hideTopbarFullscreen?: boolean;
204
+ /** 为 true 时隐藏顶栏「清空画布」按钮。 */
205
+ hideTopbarClearCanvas?: boolean;
206
+ /** 为 true 时隐藏顶栏「重置内容」按钮。 */
207
+ hideTopbarResetContent?: boolean;
172
208
  }
173
209
 
174
210
  /**
@@ -203,6 +239,16 @@ export declare function findBlockLocation(doc: EmailDoc, blockId: string): {
203
239
 
204
240
  export declare function findSection(doc: EmailDoc, sectionId: string): Section | undefined;
205
241
 
242
+ export declare const FONT_WEIGHT_STEP_OPTIONS: {
243
+ label: string;
244
+ value: string;
245
+ }[];
246
+
247
+ /** 全局与各组件字重:固定五档,便于右栏平铺或步进滑块 */
248
+ export declare const FONT_WEIGHT_STEP_VALUES: readonly ["300", "400", "500", "600", "700"];
249
+
250
+ export declare type FontWeightStep = (typeof FONT_WEIGHT_STEP_VALUES)[number];
251
+
206
252
  /** 图库列表中的一条资源 */
207
253
  export declare interface GalleryItem {
208
254
  id: string;
@@ -217,7 +263,7 @@ export declare interface GlobalStyles {
217
263
  contentBackgroundColor: string;
218
264
  fontFamily: string;
219
265
  fontSize: string;
220
- /** 全局字重,如 normal / 500 / bold */
266
+ /** 全局字重:数值档 300 | 400 | 500 | 600 | 700(兼容读写 normal / bold 等别名) */
221
267
  fontWeight: string;
222
268
  color: string;
223
269
  linkColor: string;
@@ -300,6 +346,8 @@ declare interface InlineEditableConfig<P extends object = Record<string, unknown
300
346
  placeholder?: string;
301
347
  }
302
348
 
349
+ export declare function isTwoColumnLayout(layout: SectionLayout): layout is TwoColumnLayout;
350
+
303
351
  declare type Listener = (detail?: DocChangedDetail) => void;
304
352
 
305
353
  /**
@@ -331,8 +379,13 @@ export declare class MailEditor {
331
379
  private changeTimer;
332
380
  /** 显式品牌色时覆盖 CSS 变量;未设置则由 styles 按 light/dark 使用默认紫/靛 */
333
381
  private accentColorOverride;
382
+ /** 顶栏开关:是否在画布上始终显示 Section / Block 轻量虚线边框 */
383
+ private showLayoutBorders;
384
+ /** 「重置内容」时恢复的文档快照(与当前画布内容无关) */
385
+ private presetContentDoc;
334
386
  private systemThemeMq;
335
387
  private readonly _onSystemThemeMqChange;
388
+ private readonly _onFullscreenChange;
336
389
  /** design 态 Esc:块 → 父级 Section → 文档级面板(邮件设置或版式/全局样式,取决于 `ui.hideMailMeta`) */
337
390
  private _mailEscHandler;
338
391
  /**
@@ -343,6 +396,15 @@ export declare class MailEditor {
343
396
  constructor(opts: EditorOptions);
344
397
  setValue(doc: EmailDoc): void;
345
398
  getValue(): EmailDoc;
399
+ /**
400
+ * 清空画布:移除所有 Section/Block,保留 meta、styles、variables。
401
+ * 会提交内联编辑并清空选中。
402
+ */
403
+ clearCanvas(): void;
404
+ /** 将画布恢复为构造时 `presetDoc`(或 `initialDoc`)对应的预置内容。 */
405
+ resetToPreset(): void;
406
+ /** 更新「重置内容」的目标(例如宿主异步加载默认模板后)。 */
407
+ setPresetDoc(partial: Partial<EmailDoc>): void;
346
408
  setVariables(vars: Variable[]): void;
347
409
  getVariables(): Variable[];
348
410
  /** 当前界面主题(`system` 不解析为 light/dark)。 */
@@ -374,6 +436,8 @@ export declare class MailEditor {
374
436
  private _blurRightPanelIfFocused;
375
437
  /** 提交内联编辑并清空选中,右栏回到文档级面板 */
376
438
  private _focusMailSettings;
439
+ private _confirmClearCanvas;
440
+ private _confirmResetContent;
377
441
  private _setMode;
378
442
  private _bindKeyboard;
379
443
  private _onChange;
@@ -381,6 +445,10 @@ export declare class MailEditor {
381
445
  private _insertVariable;
382
446
  private _showExport;
383
447
  private _showPreview;
448
+ private _bindFullscreen;
449
+ private _unbindFullscreen;
450
+ private _toggleFullscreen;
451
+ private _toggleLayoutBorders;
384
452
  }
385
453
 
386
454
  export declare function metaWidthInputString(raw: unknown): string;
@@ -407,6 +475,9 @@ export declare function mjRawCellTypographyFromStyles(s: GlobalStyles): MjRawCel
407
475
  */
408
476
  export declare function mjRawEmailTableWrap(paddingCss: string, cellInnerHtml: string, typo: MjRawCellTypography): string;
409
477
 
478
+ /** 将任意历史写法映射到最近一档(normal→400,bold→700 等) */
479
+ export declare function normalizeFontWeightStep(raw: string | undefined | null): FontWeightStep;
480
+
410
481
  /**
411
482
  * 打开内置图库弹层:搜索、分页、选图插入;可选「链接添加」「上传到图库」「删除」由 adapter 决定。
412
483
  */
@@ -426,12 +497,16 @@ export declare function parseMetaWidthFromUserInput(input: string): number | str
426
497
  /** Section 右栏输入;空字符串表示清除宽度 */
427
498
  export declare function parseSectionWidthFromUserInput(input: string): string | number | undefined;
428
499
 
500
+ /** @deprecated 请改用 {@link pruneSectionIfEmpty},避免误删多个空 Section */
501
+ export declare function pruneEmptySections(draft: EmailDoc): void;
502
+
429
503
  /**
430
- * 从文档中移除「每一列都没有任何 Block」的 Section。
431
- * 在内容块被删除或拖走后调用,可与 `autoWrapSection` 搭配,避免唯一块离场后仍残留空壳;
432
- * 不会在用户仅点击「添加 Section」时单独触发,因此未拖入内容的空布局仍会保留在画布上。
504
+ * 若指定 Section 的每一列都没有 Block,则从文档中移除该 Section。
505
+ * 在内容块被删除或拖走后调用,可与 `autoWrapSection` 搭配,避免单列 Section 在唯一块离场后仍残留空壳;
506
+ * 多列 Section 始终保留,便于继续向各列拖入内容。
507
+ * 仅处理刚变空的 Section,不会误删用户事先添加、尚未拖入内容的空布局。
433
508
  */
434
- export declare function pruneEmptySections(draft: EmailDoc): void;
509
+ export declare function pruneSectionIfEmpty(draft: EmailDoc, sectionId: string): void;
435
510
 
436
511
  /**
437
512
  * 组件注册表。所有内置/自定义组件都通过 `defineBlock` 注册进来;
@@ -529,6 +604,9 @@ export { Selection_2 as Selection }
529
604
 
530
605
  declare type SelectionListener = () => void;
531
606
 
607
+ /** 仅更新 layout 字段;两列间切换时列数不变,列内块按列下标保留 */
608
+ export declare function setSectionLayout(section: Section, layout: SectionLayout): void;
609
+
532
610
  /**
533
611
  * 极小的不可变 store + 发布订阅 + history。
534
612
  * 所有变更都通过 `update(fn)` 走结构化克隆,保证:
@@ -565,6 +643,11 @@ export declare class Store {
565
643
  private _notify;
566
644
  }
567
645
 
646
+ /** 两列 Section 的列宽比例(左栏拖入默认 `1-1`,右栏可改为 `1-2` / `2-1`) */
647
+ export declare const TWO_COLUMN_LAYOUTS: readonly ["1-1", "1-2", "2-1"];
648
+
649
+ export declare type TwoColumnLayout = (typeof TWO_COLUMN_LAYOUTS)[number];
650
+
568
651
  export declare interface Variable {
569
652
  /** Mustache 风格变量名,例如 user.name */
570
653
  key: string;