@standhigher/react-email-editor 0.3.0 → 0.4.3

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.
@@ -0,0 +1,84 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="1440" height="1300" viewBox="0 0 1440 1300" role="img" aria-labelledby="title description" xml:lang="en"><title id="title">Project module architecture</title><desc id="description">8 connected modules: choose content → edit → preview → save or export. Content block library, Drag-and-drop canvas, Block &amp; body settings, Subject &amp; personalization, Desktop / mobile preview, Custom blocks &amp; resources, Document &amp; editing state, Email rendering &amp; validation.</desc><defs><marker id="arrow" markerWidth="9" markerHeight="9" refX="7" refY="4.5" orient="auto"><path d="M1 1 L7 4.5 L1 8" fill="none" stroke="#91a2b8" stroke-width="1.6"/></marker></defs><g font-family="'PingFang SC','Helvetica Neue',Arial,sans-serif">
2
+ <rect x="0" y="0" width="1440" height="1300" rx="0" fill="#ffffff" stroke="#ffffff"/>
3
+ <text x="48" y="59" font-size="38" font-weight="700" fill="#152033">Project module architecture</text>
4
+ <text x="48" y="101" font-size="23" font-weight="400" fill="#64748b">8 connected modules: choose content → edit → preview → save or export</text>
5
+ <rect x="48" y="135" width="1344" height="88" rx="16" fill="#eff4fb" stroke="#d8e1ed"/>
6
+ <text x="72" y="173" font-size="26" font-weight="650" fill="#152033">Embed in your application</text>
7
+ <text x="72" y="205" font-size="22" font-weight="400" fill="#475569">Add email editing to your website, admin app or business system</text>
8
+ <path d="M720 223 V250" fill="none" stroke="#91a2b8" stroke-width="2.5" stroke-linejoin="round" marker-end="url(#arrow)"/>
9
+ <rect x="48" y="262" width="1344" height="514" rx="20" fill="#f8fafc" stroke="#ccd7e5"/>
10
+ <text x="72" y="305" font-size="27" font-weight="700" fill="#152033">Modules people interact with</text>
11
+ <text x="560" y="304" font-size="21" font-weight="400" fill="#64748b">Six core capabilities for creating an email</text>
12
+ <rect x="72" y="332" width="416" height="188" rx="16" fill="#ffffff" stroke="#d8e1ed"/>
13
+ <rect x="90" y="350" width="38" height="34" rx="9" fill="#efeaff" stroke="#efeaff"/>
14
+ <text x="97" y="375" font-size="18" font-weight="700" fill="#6653c1">01</text>
15
+ <text x="142" y="376" font-size="23" font-weight="650" fill="#152033">Content block library</text>
16
+ <text x="92" y="420" font-size="20" font-weight="400" fill="#475569">Heading, text, button and image</text>
17
+ <text x="92" y="453" font-size="20" font-weight="400" fill="#475569">Divider, spacer and custom HTML</text>
18
+ <text x="92" y="486" font-size="20" font-weight="400" fill="#475569">Drag the content into your email</text>
19
+ <rect x="512" y="332" width="416" height="188" rx="16" fill="#ffffff" stroke="#d8e1ed"/>
20
+ <rect x="530" y="350" width="38" height="34" rx="9" fill="#e7f1ff" stroke="#e7f1ff"/>
21
+ <text x="537" y="375" font-size="18" font-weight="700" fill="#266ab5">02</text>
22
+ <text x="582" y="376" font-size="23" font-weight="650" fill="#152033">Drag-and-drop canvas</text>
23
+ <text x="532" y="420" font-size="20" font-weight="400" fill="#475569">Reorder, duplicate and delete blocks</text>
24
+ <text x="532" y="453" font-size="20" font-weight="400" fill="#475569">Edit text and rich text directly</text>
25
+ <text x="532" y="486" font-size="20" font-weight="400" fill="#475569">See the layout while you edit</text>
26
+ <rect x="952" y="332" width="416" height="188" rx="16" fill="#ffffff" stroke="#d8e1ed"/>
27
+ <rect x="970" y="350" width="38" height="34" rx="9" fill="#fff1e1" stroke="#fff1e1"/>
28
+ <text x="977" y="375" font-size="18" font-weight="700" fill="#a3652d">03</text>
29
+ <text x="1022" y="376" font-size="23" font-weight="650" fill="#152033">Block &amp; body settings</text>
30
+ <text x="972" y="420" font-size="20" font-weight="400" fill="#475569">Change content, colors and borders</text>
31
+ <text x="972" y="453" font-size="20" font-weight="400" fill="#475569">Adjust width, padding and spacing</text>
32
+ <text x="972" y="486" font-size="20" font-weight="400" fill="#475569">Set email-wide fonts and background</text>
33
+ <rect x="72" y="545" width="416" height="188" rx="16" fill="#ffffff" stroke="#d8e1ed"/>
34
+ <rect x="90" y="563" width="38" height="34" rx="9" fill="#e7f6ef" stroke="#e7f6ef"/>
35
+ <text x="97" y="588" font-size="18" font-weight="700" fill="#268163">04</text>
36
+ <text x="142" y="589" font-size="23" font-weight="650" fill="#152033">Subject &amp; personalization</text>
37
+ <text x="92" y="633" font-size="20" font-weight="400" fill="#475569">Set the email subject</text>
38
+ <text x="92" y="666" font-size="20" font-weight="400" fill="#475569">Insert customer or store variables</text>
39
+ <text x="92" y="699" font-size="20" font-weight="400" fill="#475569">See replacements with sample data</text>
40
+ <rect x="512" y="545" width="416" height="188" rx="16" fill="#ffffff" stroke="#d8e1ed"/>
41
+ <rect x="530" y="563" width="38" height="34" rx="9" fill="#e7f1ff" stroke="#e7f1ff"/>
42
+ <text x="537" y="588" font-size="18" font-weight="700" fill="#266ab5">05</text>
43
+ <text x="582" y="589" font-size="23" font-weight="650" fill="#152033">Desktop / mobile preview</text>
44
+ <text x="532" y="633" font-size="20" font-weight="400" fill="#475569">Switch between desktop and mobile</text>
45
+ <text x="532" y="666" font-size="20" font-weight="400" fill="#475569">Preview resolved template variables</text>
46
+ <text x="532" y="699" font-size="20" font-weight="400" fill="#475569">Review content and layout before sending</text>
47
+ <rect x="952" y="545" width="416" height="188" rx="16" fill="#ffffff" stroke="#d8e1ed"/>
48
+ <rect x="970" y="563" width="38" height="34" rx="9" fill="#efeaff" stroke="#efeaff"/>
49
+ <text x="977" y="588" font-size="18" font-weight="700" fill="#6653c1">06</text>
50
+ <text x="1022" y="589" font-size="23" font-weight="650" fill="#152033">Custom blocks &amp; resources</text>
51
+ <text x="972" y="633" font-size="20" font-weight="400" fill="#475569">Add business blocks, e.g. product cards</text>
52
+ <text x="972" y="666" font-size="20" font-weight="400" fill="#475569">Customize editing UI and controls</text>
53
+ <text x="972" y="699" font-size="20" font-weight="400" fill="#475569">Connect your image resource picker</text>
54
+ <path d="M494 426 H504" fill="none" stroke="#91a2b8" stroke-width="2.5" stroke-linejoin="round" marker-end="url(#arrow)"/>
55
+ <path d="M944 426 H934" fill="none" stroke="#91a2b8" stroke-width="2.5" stroke-linejoin="round" marker-end="url(#arrow)"/>
56
+ <path d="M720 776 V812" fill="none" stroke="#91a2b8" stroke-width="2.5" stroke-linejoin="round" />
57
+ <text x="48" y="826" font-size="24" font-weight="650" fill="#475569">Shared capabilities supporting all editing modules</text>
58
+ <path d="M720 845 V856 H386 V876" fill="none" stroke="#91a2b8" stroke-width="2.5" stroke-linejoin="round" marker-end="url(#arrow)"/>
59
+ <path d="M720 856 H1054 V876" fill="none" stroke="#91a2b8" stroke-width="2.5" stroke-linejoin="round" marker-end="url(#arrow)"/>
60
+ <rect x="48" y="889" width="642" height="153" rx="16" fill="#f3efff" stroke="#dcd1f5"/>
61
+ <rect x="70" y="909" width="38" height="34" rx="9" fill="#e7defb" stroke="#e7defb"/>
62
+ <text x="77" y="934" font-size="18" font-weight="700" fill="#6653c1">07</text>
63
+ <text x="122" y="936" font-size="26" font-weight="650" fill="#40347a">Document &amp; editing state</text>
64
+ <text x="72" y="976" font-size="21" font-weight="400" fill="#475569">Keep content, block order, styles and subject together</text>
65
+ <text x="72" y="1010" font-size="21" font-weight="400" fill="#475569">Load, replace and reset; editor instances stay isolated</text>
66
+ <rect x="750" y="889" width="642" height="153" rx="16" fill="#eef5ff" stroke="#cddff7"/>
67
+ <rect x="772" y="909" width="38" height="34" rx="9" fill="#dfeaff" stroke="#dfeaff"/>
68
+ <text x="779" y="934" font-size="18" font-weight="700" fill="#266ab5">08</text>
69
+ <text x="824" y="936" font-size="26" font-weight="650" fill="#225897">Email rendering &amp; validation</text>
70
+ <text x="774" y="976" font-size="21" font-weight="400" fill="#475569">Validate controls and blocks; generate email HTML</text>
71
+ <text x="774" y="1010" font-size="21" font-weight="400" fill="#475569">Keep templates for delivery or resolve data for preview</text>
72
+ <path d="M690 965 H738" fill="none" stroke="#91a2b8" stroke-width="2.5" stroke-linejoin="round" marker-end="url(#arrow)"/>
73
+ <path d="M369 1042 V1081" fill="none" stroke="#91a2b8" stroke-width="2.5" stroke-linejoin="round" marker-end="url(#arrow)"/>
74
+ <path d="M1071 1042 V1081" fill="none" stroke="#91a2b8" stroke-width="2.5" stroke-linejoin="round" marker-end="url(#arrow)"/>
75
+ <rect x="48" y="1094" width="642" height="137" rx="16" fill="#edf8f1" stroke="#cce4d5"/>
76
+ <text x="72" y="1134" font-size="27" font-weight="700" fill="#286844">JSON document</text>
77
+ <text x="72" y="1170" font-size="23" font-weight="400" fill="#475569">Your app saves the draft</text>
78
+ <text x="72" y="1202" font-size="23" font-weight="400" fill="#475569">Load it later and continue editing</text>
79
+ <rect x="750" y="1094" width="642" height="137" rx="16" fill="#edf5ff" stroke="#cddff7"/>
80
+ <text x="774" y="1134" font-size="27" font-weight="700" fill="#225897">Email HTML</text>
81
+ <text x="774" y="1170" font-size="23" font-weight="400" fill="#475569">Export templates or preview output</text>
82
+ <text x="774" y="1202" font-size="23" font-weight="400" fill="#475569">Pass it to your email delivery system</text>
83
+ <text x="48" y="1272" font-size="21" font-weight="400" fill="#64748b">This project builds, previews and exports emails. Your app handles storage, uploads and delivery.</text>
84
+ </g></svg>
@@ -0,0 +1,84 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="1440" height="1300" viewBox="0 0 1440 1300" role="img" aria-labelledby="title description" xml:lang="zh-CN"><title id="title">项目模块架构图</title><desc id="description">8 个模块协同:选内容 → 编邮件 → 看预览 → 保存或导出. 内容区块库, 拖拽编辑画布, 属性与主体设置, 主题与个性化, 桌面 / 移动预览, 自定义区块与资源, 文档与编辑状态, 邮件渲染与校验.</desc><defs><marker id="arrow" markerWidth="9" markerHeight="9" refX="7" refY="4.5" orient="auto"><path d="M1 1 L7 4.5 L1 8" fill="none" stroke="#91a2b8" stroke-width="1.6"/></marker></defs><g font-family="'PingFang SC','Helvetica Neue',Arial,sans-serif">
2
+ <rect x="0" y="0" width="1440" height="1300" rx="0" fill="#ffffff" stroke="#ffffff"/>
3
+ <text x="48" y="59" font-size="38" font-weight="700" fill="#152033">项目模块架构图</text>
4
+ <text x="48" y="101" font-size="23" font-weight="400" fill="#64748b">8 个模块协同:选内容 → 编邮件 → 看预览 → 保存或导出</text>
5
+ <rect x="48" y="135" width="1344" height="88" rx="16" fill="#eff4fb" stroke="#d8e1ed"/>
6
+ <text x="72" y="173" font-size="26" font-weight="650" fill="#152033">接入你的应用</text>
7
+ <text x="72" y="205" font-size="22" font-weight="400" fill="#475569">网站、运营后台或业务系统,把邮件编辑能力嵌入现有页面</text>
8
+ <path d="M720 223 V250" fill="none" stroke="#91a2b8" stroke-width="2.5" stroke-linejoin="round" marker-end="url(#arrow)"/>
9
+ <rect x="48" y="262" width="1344" height="514" rx="20" fill="#f8fafc" stroke="#ccd7e5"/>
10
+ <text x="72" y="305" font-size="27" font-weight="700" fill="#152033">用户直接操作的模块</text>
11
+ <text x="560" y="304" font-size="21" font-weight="400" fill="#64748b">制作一封邮件时使用的 6 项核心能力</text>
12
+ <rect x="72" y="332" width="416" height="188" rx="16" fill="#ffffff" stroke="#d8e1ed"/>
13
+ <rect x="90" y="350" width="38" height="34" rx="9" fill="#efeaff" stroke="#efeaff"/>
14
+ <text x="97" y="375" font-size="18" font-weight="700" fill="#6653c1">01</text>
15
+ <text x="142" y="376" font-size="25" font-weight="650" fill="#152033">内容区块库</text>
16
+ <text x="92" y="420" font-size="23" font-weight="400" fill="#475569">标题、正文、按钮、图片</text>
17
+ <text x="92" y="453" font-size="23" font-weight="400" fill="#475569">分割线、留白、自定义 HTML</text>
18
+ <text x="92" y="486" font-size="23" font-weight="400" fill="#475569">把需要的内容拖入邮件</text>
19
+ <rect x="512" y="332" width="416" height="188" rx="16" fill="#ffffff" stroke="#d8e1ed"/>
20
+ <rect x="530" y="350" width="38" height="34" rx="9" fill="#e7f1ff" stroke="#e7f1ff"/>
21
+ <text x="537" y="375" font-size="18" font-weight="700" fill="#266ab5">02</text>
22
+ <text x="582" y="376" font-size="25" font-weight="650" fill="#152033">拖拽编辑画布</text>
23
+ <text x="532" y="420" font-size="23" font-weight="400" fill="#475569">排列、复制、删除内容区块</text>
24
+ <text x="532" y="453" font-size="23" font-weight="400" fill="#475569">直接编辑文字与富文本</text>
25
+ <text x="532" y="486" font-size="23" font-weight="400" fill="#475569">边编辑边查看邮件布局</text>
26
+ <rect x="952" y="332" width="416" height="188" rx="16" fill="#ffffff" stroke="#d8e1ed"/>
27
+ <rect x="970" y="350" width="38" height="34" rx="9" fill="#fff1e1" stroke="#fff1e1"/>
28
+ <text x="977" y="375" font-size="18" font-weight="700" fill="#a3652d">03</text>
29
+ <text x="1022" y="376" font-size="25" font-weight="650" fill="#152033">属性与主体设置</text>
30
+ <text x="972" y="420" font-size="23" font-weight="400" fill="#475569">修改区块内容、颜色与边框</text>
31
+ <text x="972" y="453" font-size="23" font-weight="400" fill="#475569">调整宽度、内边距与间距</text>
32
+ <text x="972" y="486" font-size="23" font-weight="400" fill="#475569">统一设置邮件字体与背景</text>
33
+ <rect x="72" y="545" width="416" height="188" rx="16" fill="#ffffff" stroke="#d8e1ed"/>
34
+ <rect x="90" y="563" width="38" height="34" rx="9" fill="#e7f6ef" stroke="#e7f6ef"/>
35
+ <text x="97" y="588" font-size="18" font-weight="700" fill="#268163">04</text>
36
+ <text x="142" y="589" font-size="25" font-weight="650" fill="#152033">主题与个性化</text>
37
+ <text x="92" y="633" font-size="23" font-weight="400" fill="#475569">设置邮件主题</text>
38
+ <text x="92" y="666" font-size="23" font-weight="400" fill="#475569">插入姓名、店铺等模板变量</text>
39
+ <text x="92" y="699" font-size="23" font-weight="400" fill="#475569">使用示例数据查看替换结果</text>
40
+ <rect x="512" y="545" width="416" height="188" rx="16" fill="#ffffff" stroke="#d8e1ed"/>
41
+ <rect x="530" y="563" width="38" height="34" rx="9" fill="#e7f1ff" stroke="#e7f1ff"/>
42
+ <text x="537" y="588" font-size="18" font-weight="700" fill="#266ab5">05</text>
43
+ <text x="582" y="589" font-size="25" font-weight="650" fill="#152033">桌面 / 移动预览</text>
44
+ <text x="532" y="633" font-size="23" font-weight="400" fill="#475569">切换桌面与手机显示效果</text>
45
+ <text x="532" y="666" font-size="23" font-weight="400" fill="#475569">预览模板变量替换后的内容</text>
46
+ <text x="532" y="699" font-size="23" font-weight="400" fill="#475569">发送前检查邮件内容与版式</text>
47
+ <rect x="952" y="545" width="416" height="188" rx="16" fill="#ffffff" stroke="#d8e1ed"/>
48
+ <rect x="970" y="563" width="38" height="34" rx="9" fill="#efeaff" stroke="#efeaff"/>
49
+ <text x="977" y="588" font-size="18" font-weight="700" fill="#6653c1">06</text>
50
+ <text x="1022" y="589" font-size="25" font-weight="650" fill="#152033">自定义区块与资源</text>
51
+ <text x="972" y="633" font-size="23" font-weight="400" fill="#475569">增加商品卡片等业务区块</text>
52
+ <text x="972" y="666" font-size="23" font-weight="400" fill="#475569">定制编辑画布和属性控件</text>
53
+ <text x="972" y="699" font-size="23" font-weight="400" fill="#475569">接入已有图片资源选择器</text>
54
+ <path d="M494 426 H504" fill="none" stroke="#91a2b8" stroke-width="2.5" stroke-linejoin="round" marker-end="url(#arrow)"/>
55
+ <path d="M944 426 H934" fill="none" stroke="#91a2b8" stroke-width="2.5" stroke-linejoin="round" marker-end="url(#arrow)"/>
56
+ <path d="M720 776 V812" fill="none" stroke="#91a2b8" stroke-width="2.5" stroke-linejoin="round" />
57
+ <text x="48" y="826" font-size="24" font-weight="650" fill="#475569">支撑所有编辑模块的共享能力</text>
58
+ <path d="M720 845 V856 H386 V876" fill="none" stroke="#91a2b8" stroke-width="2.5" stroke-linejoin="round" marker-end="url(#arrow)"/>
59
+ <path d="M720 856 H1054 V876" fill="none" stroke="#91a2b8" stroke-width="2.5" stroke-linejoin="round" marker-end="url(#arrow)"/>
60
+ <rect x="48" y="889" width="642" height="153" rx="16" fill="#f3efff" stroke="#dcd1f5"/>
61
+ <rect x="70" y="909" width="38" height="34" rx="9" fill="#e7defb" stroke="#e7defb"/>
62
+ <text x="77" y="934" font-size="18" font-weight="700" fill="#6653c1">07</text>
63
+ <text x="122" y="936" font-size="26" font-weight="650" fill="#40347a">文档与编辑状态</text>
64
+ <text x="72" y="976" font-size="23" font-weight="400" fill="#475569">统一记录邮件内容、顺序、样式与主题</text>
65
+ <text x="72" y="1010" font-size="23" font-weight="400" fill="#475569">支持载入、替换、重置;多个编辑器互不干扰</text>
66
+ <rect x="750" y="889" width="642" height="153" rx="16" fill="#eef5ff" stroke="#cddff7"/>
67
+ <rect x="772" y="909" width="38" height="34" rx="9" fill="#dfeaff" stroke="#dfeaff"/>
68
+ <text x="779" y="934" font-size="18" font-weight="700" fill="#266ab5">08</text>
69
+ <text x="824" y="936" font-size="26" font-weight="650" fill="#225897">邮件渲染与校验</text>
70
+ <text x="774" y="976" font-size="23" font-weight="400" fill="#475569">检查控件值与区块配置,生成邮件 HTML</text>
71
+ <text x="774" y="1010" font-size="23" font-weight="400" fill="#475569">保留模板供发送使用,或解析示例数据用于预览</text>
72
+ <path d="M690 965 H738" fill="none" stroke="#91a2b8" stroke-width="2.5" stroke-linejoin="round" marker-end="url(#arrow)"/>
73
+ <path d="M369 1042 V1081" fill="none" stroke="#91a2b8" stroke-width="2.5" stroke-linejoin="round" marker-end="url(#arrow)"/>
74
+ <path d="M1071 1042 V1081" fill="none" stroke="#91a2b8" stroke-width="2.5" stroke-linejoin="round" marker-end="url(#arrow)"/>
75
+ <rect x="48" y="1094" width="642" height="137" rx="16" fill="#edf8f1" stroke="#cce4d5"/>
76
+ <text x="72" y="1134" font-size="27" font-weight="700" fill="#286844">JSON 文档</text>
77
+ <text x="72" y="1170" font-size="23" font-weight="400" fill="#475569">交给应用保存草稿</text>
78
+ <text x="72" y="1202" font-size="23" font-weight="400" fill="#475569">下次载入,继续编辑</text>
79
+ <rect x="750" y="1094" width="642" height="137" rx="16" fill="#edf5ff" stroke="#cddff7"/>
80
+ <text x="774" y="1134" font-size="27" font-weight="700" fill="#225897">邮件 HTML</text>
81
+ <text x="774" y="1170" font-size="23" font-weight="400" fill="#475569">导出邮件模板或预览结果</text>
82
+ <text x="774" y="1202" font-size="23" font-weight="400" fill="#475569">交给应用的邮件发送系统</text>
83
+ <text x="48" y="1272" font-size="22" font-weight="400" fill="#64748b">本项目负责邮件制作、预览与导出;数据存储、文件上传、实际发信由接入应用完成。</text>
84
+ </g></svg>
@@ -0,0 +1,113 @@
1
+ # Basic examples
2
+
3
+ [简体中文](./basic-examples.zh-CN.md) | [API reference](./api.md) | [Advanced examples](./advanced-examples.md)
4
+
5
+ Import `@standhigher/react-email-editor/styles.css` once from your global stylesheet entry. Each component example can live in its own `.tsx` file. Add `"use client"` with Next.js App Router.
6
+
7
+ ## 1. Empty editor and JSON saving
8
+
9
+ ```tsx
10
+ import { useState } from "react";
11
+ import { EmailEditor, useEmailEditor } from "@standhigher/react-email-editor";
12
+
13
+ export function EmailComposer() {
14
+ const editor = useEmailEditor();
15
+ const [savedJson, setSavedJson] = useState("");
16
+
17
+ return (
18
+ <>
19
+ <EmailEditor editor={editor} height={720} />
20
+ <button type="button" onClick={() => setSavedJson(editor.getJson())}>Save JSON</button>
21
+ <output>{savedJson ? "Saved in page state" : "Not saved yet"}</output>
22
+ </>
23
+ );
24
+ }
25
+ ```
26
+
27
+ This example saves to React state, which does not survive a page reload. Your app implements database or file persistence. getDocument() returns a detached JSON object, getJson() a formatted string, and getHtml() template HTML for a sending system.
28
+
29
+ ## 2. Initial content, document switching and reset
30
+
31
+ ```tsx
32
+ import {
33
+ BLOCK_TYPES, createBlockNode, createEmailDocument,
34
+ EmailEditor, useEmailEditor, type EmailDocument,
35
+ } from "@standhigher/react-email-editor";
36
+
37
+ const heading = createBlockNode(BLOCK_TYPES.heading);
38
+ if (heading) heading.controls.html = "<h1>Welcome to our newsletter</h1>";
39
+ const initialDocument = createEmailDocument(heading ? [heading] : []);
40
+
41
+ interface RestorableEditorProps {
42
+ savedDocument: EmailDocument;
43
+ }
44
+
45
+ export function RestorableEditor({ savedDocument }: RestorableEditorProps) {
46
+ const editor = useEmailEditor({ initialDocument });
47
+ return (
48
+ <>
49
+ <EmailEditor editor={editor} height={640} />
50
+ <button type="button" onClick={() => editor.setDocument(savedDocument)}>Load saved document</button>
51
+ <button type="button" onClick={() => editor.reset()}>Restore initial content</button>
52
+ </>
53
+ );
54
+ }
55
+ ```
56
+
57
+ Your app loads and validates savedDocument as a current v4 document. TypeScript types do not replace runtime JSON validation. initialDocument is read once; use setDocument() for later replacements. reset() restores the first initialized content, not the most recently loaded document.
58
+
59
+ ## 3. Body styles, variables and preview export
60
+
61
+ ```tsx
62
+ import { useState } from "react";
63
+ import {
64
+ BLOCK_TYPES, createBlockNode, createEmailDocument, EmailEditor, useEmailEditor,
65
+ } from "@standhigher/react-email-editor";
66
+
67
+ const text = createBlockNode(BLOCK_TYPES.text);
68
+ if (text) text.controls.html = "<p>Hello, {{ customer_name }}, welcome to {{ store_name }}</p>";
69
+ const initialDocument = createEmailDocument(text ? [text] : []);
70
+
71
+ export function PersonalizedEditor() {
72
+ const [html, setHtml] = useState("");
73
+ const editor = useEmailEditor({
74
+ initialDocument,
75
+ body: { contentWidth: 640, contentPadding: "24px", backgroundColor: "#f7f7f7" },
76
+ variables: [
77
+ { name: "{{ store_name }}", description: "Store name", value: "Example Store" },
78
+ { name: "{{ customer_name }}", value: "Sam" },
79
+ ],
80
+ });
81
+ return (
82
+ <>
83
+ <EmailEditor editor={editor} height={720} />
84
+ <button type="button" onClick={() => setHtml(editor.getHtml())}>Read template HTML</button>
85
+ <button type="button" onClick={() => setHtml(editor.getRenderedHtml())}>Read preview HTML</button>
86
+ <pre>{html}</pre>
87
+ </>
88
+ );
89
+ }
90
+ ```
91
+
92
+ Template export preserves variables and dots listed tokens: {{ store_name }} becomes {{ .store_name }}. Preview export substitutes Example Store and other values. The editor includes desktop and mobile preview. This example displays source in a pre element; your app can download or upload it. See [validated saving](./advanced-examples.md#1-validate-before-async-saving) for export error handling.
93
+
94
+ ## 4. Export without mounting the editor
95
+
96
+ ```ts
97
+ import {
98
+ BLOCK_TYPES, createBlockNode, createEmailDocument, documentToHtml,
99
+ } from "@standhigher/react-email-editor";
100
+
101
+ const block = createBlockNode(BLOCK_TYPES.html);
102
+ if (!block) throw new Error("HTML block is not registered");
103
+ block.controls.html = "<p>Hello, {{.customer.name}}</p>";
104
+ const document = createEmailDocument([block]);
105
+
106
+ export const templateHtml = documentToHtml(document);
107
+ export const previewHtml = documentToHtml(document, undefined, {
108
+ resolveHtmlTemplates: true,
109
+ templateData: { customer: { name: "Sam" } },
110
+ });
111
+ ```
112
+
113
+ Each export contains one doctype, html, head and body. Custom blocks need a shared registry; see [advanced examples](./advanced-examples.md#3-business-block-with-multiple-rich-text-regions-and-a-list).
@@ -0,0 +1,113 @@
1
+ # 基础场景示例
2
+
3
+ [English](./basic-examples.md) | [API 参考](./api.zh-CN.md) | [复杂场景](./advanced-examples.zh-CN.md)
4
+
5
+ 在应用全局样式入口引入一次 `@standhigher/react-email-editor/styles.css`。以下每段组件示例可以独立放入一个 `.tsx` 文件;Next.js App Router 中添加 `"use client"`。
6
+
7
+ ## 1. 空编辑器与保存 JSON
8
+
9
+ ```tsx
10
+ import { useState } from "react";
11
+ import { EmailEditor, useEmailEditor } from "@standhigher/react-email-editor";
12
+
13
+ export function EmailComposer() {
14
+ const editor = useEmailEditor();
15
+ const [savedJson, setSavedJson] = useState("");
16
+
17
+ return (
18
+ <>
19
+ <EmailEditor editor={editor} height={720} />
20
+ <button type="button" onClick={() => setSavedJson(editor.getJson())}>保存 JSON</button>
21
+ <output>{savedJson ? "已保存到当前页面状态" : "尚未保存"}</output>
22
+ </>
23
+ );
24
+ }
25
+ ```
26
+
27
+ 该示例保存到 React 状态,刷新后不会保留;数据库或文件持久化由应用实现。`getDocument()` 返回 JSON 对象快照,`getJson()` 返回格式化字符串,`getHtml()` 返回可交给发送系统的模板 HTML。
28
+
29
+ ## 2. 初始内容、切换文档与重置
30
+
31
+ ```tsx
32
+ import {
33
+ BLOCK_TYPES, createBlockNode, createEmailDocument,
34
+ EmailEditor, useEmailEditor, type EmailDocument,
35
+ } from "@standhigher/react-email-editor";
36
+
37
+ const heading = createBlockNode(BLOCK_TYPES.heading);
38
+ if (heading) heading.controls.html = "<h1>欢迎订阅</h1>";
39
+ const initialDocument = createEmailDocument(heading ? [heading] : []);
40
+
41
+ interface RestorableEditorProps {
42
+ savedDocument: EmailDocument;
43
+ }
44
+
45
+ export function RestorableEditor({ savedDocument }: RestorableEditorProps) {
46
+ const editor = useEmailEditor({ initialDocument });
47
+ return (
48
+ <>
49
+ <EmailEditor editor={editor} height={640} />
50
+ <button type="button" onClick={() => editor.setDocument(savedDocument)}>载入已保存文档</button>
51
+ <button type="button" onClick={() => editor.reset()}>恢复初始内容</button>
52
+ </>
53
+ );
54
+ }
55
+ ```
56
+
57
+ `savedDocument` 应由应用读取并校验为当前 v4 文档;TypeScript 类型不替代运行时 JSON 校验。`initialDocument` 只读取一次;后续切换用 `setDocument()`。`reset()` 恢复首次初始化内容,不是最近载入的文档。
58
+
59
+ ## 3. 主体样式、变量与预览导出
60
+
61
+ ```tsx
62
+ import { useState } from "react";
63
+ import {
64
+ BLOCK_TYPES, createBlockNode, createEmailDocument, EmailEditor, useEmailEditor,
65
+ } from "@standhigher/react-email-editor";
66
+
67
+ const text = createBlockNode(BLOCK_TYPES.text);
68
+ if (text) text.controls.html = "<p>你好,{{ customer_name }},欢迎来到 {{ store_name }}</p>";
69
+ const initialDocument = createEmailDocument(text ? [text] : []);
70
+
71
+ export function PersonalizedEditor() {
72
+ const [html, setHtml] = useState("");
73
+ const editor = useEmailEditor({
74
+ initialDocument,
75
+ body: { contentWidth: 640, contentPadding: "24px", backgroundColor: "#f7f7f7" },
76
+ variables: [
77
+ { name: "{{ store_name }}", description: "店铺名称", value: "示例店铺" },
78
+ { name: "{{ customer_name }}", value: "李小明" },
79
+ ],
80
+ });
81
+ return (
82
+ <>
83
+ <EmailEditor editor={editor} height={720} />
84
+ <button type="button" onClick={() => setHtml(editor.getHtml())}>读取模板 HTML</button>
85
+ <button type="button" onClick={() => setHtml(editor.getRenderedHtml())}>读取预览 HTML</button>
86
+ <pre>{html}</pre>
87
+ </>
88
+ );
89
+ }
90
+ ```
91
+
92
+ 模板导出保留变量,并把列出的 `{{ store_name }}` 补成 `{{ .store_name }}`;预览导出替换为示例店铺等文本。编辑器自带桌面与移动端预览。这里用 `<pre>` 展示导出源码;应用可自行下载或上传。生产导出错误处理见[校验后保存](./advanced-examples.zh-CN.md#1-校验后异步保存)。
93
+
94
+ ## 4. 不挂载编辑器直接导出
95
+
96
+ ```ts
97
+ import {
98
+ BLOCK_TYPES, createBlockNode, createEmailDocument, documentToHtml,
99
+ } from "@standhigher/react-email-editor";
100
+
101
+ const block = createBlockNode(BLOCK_TYPES.html);
102
+ if (!block) throw new Error("HTML 区块未注册");
103
+ block.controls.html = "<p>你好,{{.customer.name}}</p>";
104
+ const document = createEmailDocument([block]);
105
+
106
+ export const templateHtml = documentToHtml(document);
107
+ export const previewHtml = documentToHtml(document, undefined, {
108
+ resolveHtmlTemplates: true,
109
+ templateData: { customer: { name: "李小明" } },
110
+ });
111
+ ```
112
+
113
+ 每份导出只有一套 doctype、html、head 和 body。自定义区块需共享注册表,见[复杂场景](./advanced-examples.zh-CN.md#3-业务区块多区域富文本与列表)。
@@ -0,0 +1,125 @@
1
+ # Changelog
2
+
3
+ English | [简体中文](./changelog.zh-CN.md)
4
+
5
+ ## 0.4.3 — 2026-10-28
6
+
7
+ ### Fixes and improvements
8
+
9
+ - Reuse the same Personalization menu in the subject header and configuration panel, with consistent variable colors, width, border radius, shadows and hover styles.
10
+ - Move variable triggers for text, multiline text and link controls to an input suffix on the right, reserving space for content; restore input focus and cursor position after inserting a variable.
11
+ - Open menus to the left or above according to available viewport space, using native popovers to avoid scroll clipping and positioning offsets in embedded containers with `transform`.
12
+ - Complete focus handling when opening from the keyboard, Tab/Shift+Tab exit, Escape dismissal and outside-click dismissal; preserve the selected block on close and clean up observers and event listeners.
13
+ - Keep the public API, email export and `version: 4` document format unchanged.
14
+
15
+ ### Validation
16
+
17
+ - `pnpm check` passed, including type checking, Oxlint, build and all 103 Node tests; add regression coverage for menu positioning, focus, dismissal and lifecycle.
18
+ - Reuse the existing development server for browser interaction checks, covering suffix clicks, cursor insertion, keyboard navigation and positioning inside containers with `transform`.
19
+
20
+ ## 0.4.2 — 2026-10-28
21
+
22
+ ### npm publishing and documentation
23
+
24
+ - Add the MIT license, repository, homepage and issue tracker, pin the public npm registry and pnpm 10.16.1, and recommend Node 24 LTS through `.nvmrc`.
25
+ - Add `pnpm test`, `pnpm check` and complete validation before publishing; preserve CSS through `sideEffects` and verify that consumers can remove unused JavaScript imports.
26
+ - Fix broken npm README images by using fixed absolute CDN URLs for images and viewing links from the published 0.4.1 package; newer packages retain Markdown and SVG documentation without shipping PNG originals again.
27
+ - Use absolute GitHub URLs for language switches, API references, examples, release guides, changelogs and section navigation in both READMEs, and verify target documents and anchors; remote documents must be pushed with the commit.
28
+ - Add English and Chinese release guides, package-content checks and consumer CSS validation; keep the React 18 peer range, existing public API and document format unchanged.
29
+
30
+ ## 0.4.1 — 2026-10-28
31
+
32
+ ### Documentation and type hints
33
+
34
+ - Simplify both READMEs, add module architecture diagrams, and move detailed integration instructions into separate API reference, basic example and advanced example documents.
35
+ - Add examples for saving and restoring documents, body settings and variables, multiple-instance subscriptions, custom blocks, multiple rich-text regions, image resource pickers and individual block template previews; update navigation in the custom block guides.
36
+ - Add English JSDoc for editor instances, document models, plugins and controls, email rendering helpers, rich text and basic UI components, shipped with TypeScript declarations for IDE hover details on parameters, defaults and behavior boundaries.
37
+ - Update only documentation, type comments and the package version, without changing runtime behavior, the public API or the persisted document version; documents remain at `version: 4`.
38
+
39
+ ### Validation
40
+
41
+ - Type checking, Oxlint, build and all 96 Node tests passed.
42
+ - All 34 TypeScript/TSX example files from both READMEs, API references and scenario documents passed type checking; all local documentation link targets exist.
43
+
44
+ ## 0.4.0 — 2026-10-28
45
+
46
+ ### Features and improvements
47
+
48
+ - Standardize React integration on `useEmailEditorConfig()`, `useEmailEditor()` and `<EmailEditor editor={editor}>`; add `useEmailEditorState(editor)` for on-demand subscriptions to cached, read-only document snapshots.
49
+ - Keep editor instance references stable and isolated, allowing reading, validation and export without mounting the UI; add `setDocument()` and `reset()`, clearing selection, focus and control state from the previous document on replacement or reset.
50
+ - Preserve the current document when configuration or variables change; merge external body input when its value changes, avoid initialization callbacks, and keep document reads and callback arguments as independent snapshots.
51
+ - Add export, new-document, reset and subscription examples to the playground, and update English and Chinese integration documentation.
52
+
53
+ ### Fixes and validation
54
+
55
+ - Synchronize configuration, variables, body settings and callbacks during commit so child layout effects can read new values; defer subscription notifications and body callbacks to the layout phase, keeping interrupted concurrent renders from changing existing instances.
56
+ - Use instance-specific IDs for subject inputs so labels, inputs and character-count hints remain independently associated across multiple editors.
57
+ - Add coverage for configuration update timing, concurrent interruption, subject associations across multiple instances, negative type contracts for removed APIs and checks for compatibility entry points in source.
58
+
59
+ ### Breaking changes
60
+
61
+ - Remove public `createEmailEditorConfig`, `EmailEditorConfigOptions`, `EmailEditorHandle`, component refs and previous state Props, without aliases or compatibility layers. Pass configuration and state to `useEmailEditor()`; the component accepts only `editor` and `height`.
62
+ - The fourth argument of `blockToHtml()` and `renderBlockContent()` accepts only a `BlockRenderOptions` object; remove boolean adaptation and explicitly reject booleans passed from JavaScript. Template previews use `{ resolveHtmlTemplate: true }`.
63
+ - Persisted documents remain at `version: 4`, without migration of older versions; this package version change affects only the package API and behavior.
64
+
65
+ ## 0.3.0 — 2026-10-28
66
+
67
+ ### Features and improvements
68
+
69
+ - Add `defineBlock()`, `EmailControls` and `createEmailEditorConfig()`, sharing plugin configuration between the editor and standalone email export; support filtering, sorting and explicit overrides in the built-in block library.
70
+ - Support custom control components, React Canvas/Inspector components, multiple `EditableRichText` regions, `ControlEditor`, declarative nested lists, image resource pickers and shared email HTML helpers in block plugins.
71
+ - Add `config.validate()` to collect issues with numeric ranges, options, URL/image protocols, list counts and business validation; support updating several related controls at once through `setControls()`.
72
+ - Add English and Chinese custom block API documentation, coupon and product card examples, and component regression tests.
73
+
74
+ ### Fixes
75
+
76
+ - Preserve explicit colors and underlines when changing link URLs or opening behavior, and restore BODY inheritance on reset.
77
+ - Use the same base typography for the canvas body, preview and email export, fixing differences in calculations for `em` padding, borders and other dimensions.
78
+ - Fix asynchronous list updates overwriting subsequent edits or sorting; merge the latest values by stable row identifiers, ignore stale results after deletion or unmount, and avoid reusing deleted row identifiers for new rows.
79
+ - Give custom controls independent snapshots of values, body settings and variables to prevent parameter mutations from affecting the host; isolate variable synchronization for custom Canvas/Inspector components as well.
80
+ - Show an empty option in optional selects and support clearing them; associate control labels correctly with selects.
81
+ - Make inspector rich text inherit body settings and enabled block typography, paragraph, list and link styles, updating when body configuration changes.
82
+ - Report missing plugins and email export failures explicitly; isolate canvas and inspector errors per block and preserve original node data.
83
+
84
+ ### Breaking changes
85
+
86
+ - Switch custom blocks to `defineBlock` + `EmailControls` + `createEmailEditorConfig`, with the component receiving `config`; remove the old `blocks` Prop, public `BlockDefinition/FieldConfig/FieldType` and `resolveBlockStyleFields`, without an adaptation layer. Control factories use `EmailControls.text(...)`, and blocks and lists declare controls through `controls` (without `field` / `fields` aliases); runtime and persisted nodes use `controls`, style declarations use `styleControls`, and update methods use `setControl/setControls`, with corresponding renames for types, `ControlEditor` and `controlPath`. Content defaults come from control declarations, rendering uses `renderEmail`, and the document format advances to v4, without compatibility or automatic migration for old data.
87
+ - Standardize email body settings on `body`: documents use `EmailDocument.body`, the component uses `body` / `onBodyChange`, and types and helpers use `EmailBodySettings`, `DEFAULT_EMAIL_BODY` and `resolveEmailBody`; block rendering contexts and `BlockRenderOptions` also use `body`. Remove the previous Global API without aliases or migration code.
88
+ - Advance the document version to `4`, without support for older versions. BODY General provides text color, link color, font, font weight and a link underline toggle; Content provides a single body Background, content width, Padding and block spacing, with border color, width and style grouped under Advanced: Border, collapsed by default. Apply configuration consistently to canvas, preview and export while preserving explicit content formatting. Keep only `contentPadding`, removing `outerPadding`, body alignment, outer background and border radius; center the body and keep the outer area white.
89
+
90
+ ## 0.2.0 — 2026-10-27
91
+
92
+ ### Breaking changes
93
+
94
+ - Advance the document format from `version: 1` to `version: 2`, rejecting older versions without automatic migration. Use `createEmailDocument()` to create current-version documents; upgrading existing data requires updating block fields and styles as well as the version number.
95
+ - Store text formatting for Heading, Text and Button in `fields.html`; Button no longer reads `fields.label` or typography from `style.element`. `EmailElementStyle` no longer extends `EmailTypographyStyle`.
96
+ - Make built-in blocks declare `styleFields` according to their capabilities and ignore disabled styles; remove `dimension.height` and block-level `typography` from built-in blocks. Custom blocks can still enable these fields explicitly, with `exactStyleFields` constraining defaults, canvas and email output.
97
+ - Preserve paragraphs, lists, links and explicit styles inside HTML block source without injecting body typography; undeclared properties can still inherit global styles.
98
+
99
+ ### Features and improvements
100
+
101
+ - Support inline rich-text editing for Button with a single paragraph, joining multiple pasted paragraphs with spaces; preserve basic inline formatting in email output and generate only one outer button link.
102
+ - Add `BlockInspectorSection`, `inspectorSections`, `RichTextProfile` and `inlineEditProfile` for custom inspector groups and rich-text capabilities; standalone `RichText` supports `profile`.
103
+ - Unify color panels, HEX input and color reset; use a centered dialog for link editing, with color, underline and opening behavior options.
104
+ - Improve block action bars, drag feedback, the three-column layout, toolbar wrapping and preview height; let previews follow document content.
105
+ - Change the default button fill to black and default button/image links to empty, with no navigation for blank links; default global content, block, button and image borders to transparent.
106
+ - Simplify both READMEs, add npm keywords, and include the Chinese README and changelog in the published package.
107
+
108
+ ### Fixes and validation
109
+
110
+ - Fix cursor, selection and formatting preservation after rich-text formatting operations, and preserve spacing and indentation when switching lists.
111
+ - Fix button export handling of quotes, comparison operators, comments and spaces inside template expressions.
112
+ - Add Oxlint and regression tests for block configuration, rich text, lists, buttons and color conversion.
113
+
114
+ ## 0.1.0 — 2026-10-27
115
+
116
+ First official release (commit `48011d9`).
117
+
118
+ - Provide a React 18 editor, draggable blocks, rich-text editing, an inspector and desktop/mobile previews.
119
+ - Support JSON documents, global and block styles, HTML source editing, custom blocks and Go template previews.
120
+ - Provide data access through component refs, standalone HTML rendering, ESM, TypeScript declarations and a separate CSS entry point.
121
+ - Provide a Vite playground, build tooling and a local linking workflow.
122
+
123
+ ## 0.0.0-stage — 2026-10-27
124
+
125
+ - Package distribution verification version before the first release.
@@ -1,5 +1,67 @@
1
1
  # 更新日志
2
2
 
3
+ [English](./changelog.md) | 简体中文
4
+
5
+ ## 0.4.3 — 2026-10-28
6
+
7
+ ### 修复与改进
8
+
9
+ - 主题 header 与配置区复用同一个 Personalization 菜单,统一变量颜色、宽度、圆角、阴影和 hover 样式。
10
+ - 将配置区文本、多行文本与链接字段的变量入口移至输入框右侧后缀,预留内容空间;插入变量后恢复输入焦点和光标位置。
11
+ - 菜单按视口空间向左或向上展开,使用原生 popover 避免滚动裁切及带 `transform` 的嵌入容器引起的定位偏移。
12
+ - 补齐键盘打开时的焦点、Tab/Shift+Tab 退出、Escape 关闭与外部点击关闭;关闭菜单时保留当前区块选择,并清理观察器及事件监听器。
13
+ - 保持公开 API、邮件导出和 `version: 4` 文档格式不变。
14
+
15
+ ### 验证
16
+
17
+ - `pnpm check` 通过,包含类型检查、Oxlint、构建及全部 103 项 Node 测试;新增菜单定位、焦点、关闭与生命周期回归测试。
18
+ - 复用现有开发服务完成浏览器交互验收,覆盖后缀点击、光标插入、键盘导航及带 `transform` 容器中的定位。
19
+
20
+ ## 0.4.2 — 2026-10-28
21
+
22
+ ### npm 发布与文档
23
+
24
+ - 补齐 MIT 许可证、仓库、主页和 Issue 地址,固定公开 npm registry 与 pnpm 10.16.1,并通过 `.nvmrc` 推荐 Node 24 LTS。
25
+ - 新增 `pnpm test`、`pnpm check` 和发布前完整校验;通过 `sideEffects` 保留 CSS,并验证消费方可以移除未使用的 JavaScript 导入。
26
+ - 修复 npm README 图片失效:中英文图片与查看链接改用已发布 0.4.1 资源的固定绝对 CDN 地址;新版包不重复携带 PNG 原图,保留 Markdown 和 SVG 文档。
27
+ - 中英文 README 的语言切换、API、示例、发布指南、更新日志及章节导航统一使用 GitHub 绝对地址,并验证目标文档和锚点存在;远端文档需随提交一并推送。
28
+ - 补充中英文发布指南、发布文件范围与 CSS 消费验证;保持 React 18 peer 范围及现有公开 API、文档格式不变。
29
+
30
+ ## 0.4.1 — 2026-10-28
31
+
32
+ ### 文档与类型提示
33
+
34
+ - 精简中英文 README,增加模块架构图,并将完整接入说明整理为独立的 API 参考、基础场景和复杂场景文档。
35
+ - 补充保存恢复、主体与变量、多实例订阅、自定义区块、多区域富文本、图片资源选择器及单区块模板预览示例,同步更新自定义区块指南的文档导航。
36
+ - 为编辑器实例、文档模型、插件与控件、邮件渲染工具、富文本及基础 UI 组件补充英文 JSDoc,随 TypeScript 声明发布,便于 IDE 悬停查看参数、默认值及行为边界。
37
+ - 本次仅更新文档、类型注释和包版本,不改变运行时行为、公开 API 或持久化文档版本;文档仍为 `version: 4`。
38
+
39
+ ### 验证
40
+
41
+ - 类型检查、Oxlint、构建和全部 96 项 Node 测试通过。
42
+ - 中英文 README、API 参考及场景文档的 34 个 TypeScript/TSX 示例文件通过类型检查,文档本地链接目标均存在。
43
+
44
+ ## 0.4.0 — 2026-10-28
45
+
46
+ ### 新增与改进
47
+
48
+ - React 接入统一使用 `useEmailEditorConfig()`、`useEmailEditor()` 和 `<EmailEditor editor={editor}>`;新增 `useEmailEditorState(editor)` 按需订阅缓存的只读文档快照。
49
+ - 编辑器实例引用稳定且互相隔离,无需挂载界面即可读取、校验及导出;提供 `setDocument()` 和 `reset()`,替换或重置时清空旧文档的选择、焦点与控件状态。
50
+ - 配置与变量更新保留当前文档;外部主体输入按值变化合并,初始化不触发回调,文档读取及回调参数保持独立快照。
51
+ - playground 增加导出、新建、重置与订阅示例,中英文接入文档同步更新。
52
+
53
+ ### 修复与验证
54
+
55
+ - 配置、变量、主体及回调在提交阶段同步,子组件的 layout effect 可读取新值;订阅通知及主体回调延后到 layout 阶段,被中断的并发 render 不改变现有实例。
56
+ - 主题输入框使用实例级 ID,多个编辑器的标签、输入框和字数提示独立关联。
57
+ - 补齐配置更新时序、并发中断、多实例主题关联、旧 API 负向类型契约和源码兼容入口检查。
58
+
59
+ ### 不兼容变更
60
+
61
+ - 移除公开 `createEmailEditorConfig`、`EmailEditorConfigOptions`、`EmailEditorHandle`、组件 ref 和旧状态 Props,不提供别名或兼容层。配置与状态改为传给 `useEmailEditor()`,组件只接收 `editor` 和 `height`。
62
+ - `blockToHtml()` 和 `renderBlockContent()` 的第四个参数仅接受 `BlockRenderOptions` 对象;移除 boolean 参数适配,JavaScript 传入 boolean 时明确报错。模板预览改用 `{ resolveHtmlTemplate: true }`。
63
+ - 持久化文档继续使用 `version: 4`,不迁移旧版本;本次版本号变化仅涉及包 API 与行为。
64
+
3
65
  ## 0.3.0 — 2026-10-28
4
66
 
5
67
  ### 新增与改进