@standhigher/react-email-editor 0.3.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -7,17 +7,20 @@ declare const TEXT_ALIGNS: {
7
7
  readonly right: "right";
8
8
  readonly justify: "justify";
9
9
  };
10
+ /** Text alignment: left, center, right, justify. */
10
11
  type TextAlign = (typeof TEXT_ALIGNS)[keyof typeof TEXT_ALIGNS];
11
12
  declare const HORIZONTAL_ALIGNS: {
12
13
  readonly left: "left";
13
14
  readonly center: "center";
14
15
  readonly right: "right";
15
16
  };
17
+ /** Element alignment: left, center, right. */
16
18
  type HorizontalAlign = (typeof HORIZONTAL_ALIGNS)[keyof typeof HORIZONTAL_ALIGNS];
17
19
  declare const FONT_WEIGHTS: {
18
20
  readonly normal: "normal";
19
21
  readonly bold: "bold";
20
22
  };
23
+ /** Font weight: normal or bold. */
21
24
  type FontWeight = (typeof FONT_WEIGHTS)[keyof typeof FONT_WEIGHTS];
22
25
  declare const BORDER_STYLES: {
23
26
  readonly none: "none";
@@ -25,352 +28,607 @@ declare const BORDER_STYLES: {
25
28
  readonly dashed: "dashed";
26
29
  readonly dotted: "dotted";
27
30
  };
31
+ /** Border style: none, solid, dashed, dotted. */
28
32
  type BorderStyle = (typeof BORDER_STYLES)[keyof typeof BORDER_STYLES];
29
33
  declare const LINK_DECORATIONS: {
30
34
  readonly underline: "underline";
31
35
  readonly none: "none";
32
36
  };
37
+ /** Link decoration: underline or none. */
33
38
  type LinkDecoration = (typeof LINK_DECORATIONS)[keyof typeof LINK_DECORATIONS];
34
39
 
35
40
  declare const DOCUMENT_VERSION: 4;
36
41
  declare const FONT_FAMILIES: readonly ControlOption[];
37
42
  declare const DEFAULT_EMAIL_BODY: EmailBodySettings;
38
43
 
39
- /** 邮件主体布局、外观和可继承的基础文字与链接样式。 */
44
+ /** Email body layout and inherited defaults. */
40
45
  interface EmailBodySettings {
46
+ /** Default text color. */
41
47
  textColor: string;
48
+ /** Centered content background; outer area is white. */
42
49
  backgroundColor: string;
50
+ /** Maximum content width in px, normalized to an integer from 320 to 900. */
43
51
  contentWidth: number;
52
+ /** Default CSS font stack. */
44
53
  fontFamily: string;
54
+ /** Default font weight: normal or bold. */
45
55
  fontWeight: FontWeight;
56
+ /** Color of links without explicit formatting. */
46
57
  linkColor: string;
58
+ /** Default link decoration: underline or none. */
47
59
  linkDecoration: LinkDecoration;
60
+ /** CSS padding inside the content border. */
48
61
  contentPadding: string;
62
+ /** CSS length between adjacent blocks. */
49
63
  blockGap: string;
64
+ /** Content container border width. */
50
65
  borderWidth: string;
66
+ /** Content border style. */
51
67
  borderStyle: BorderStyle;
68
+ /** Content border color. */
52
69
  borderColor: string;
53
70
  }
71
+ /** Persistable email document; only v4 is supported. */
54
72
  interface EmailDocument {
73
+ /** Format version; must be DOCUMENT_VERSION (4). */
55
74
  version: typeof DOCUMENT_VERSION;
75
+ /** Optional subject, separate from exported HTML content. */
56
76
  subject?: string;
77
+ /** Complete body layout and style settings. */
57
78
  body: EmailBodySettings;
79
+ /** Blocks in display and export order. */
58
80
  blocks: EmailBlockNode[];
59
81
  }
82
+ /** Persisted block node without components or render functions. */
60
83
  interface EmailBlockNode {
84
+ /** Unique block identifier within the document. */
61
85
  id: string;
86
+ /** Registered plugin type. */
62
87
  type: string;
88
+ /** Control values keyed by the plugin schema. */
63
89
  controls: Record<string, unknown>;
90
+ /** Enabled block style overrides. */
64
91
  style?: EmailBlockStyle;
92
+ /** Block preview data taking precedence over global data in a shallow merge. */
65
93
  defaultData?: Record<string, unknown>;
66
94
  }
95
+ /** Container or element appearance. */
67
96
  interface EmailDecorationStyle {
97
+ /** Background color. */
68
98
  backgroundColor?: string;
99
+ /** CSS border radius. */
69
100
  borderRadius?: string;
101
+ /** CSS border width. */
70
102
  borderWidth?: string;
103
+ /** Border color. */
71
104
  borderColor?: string;
105
+ /** Border line style. */
72
106
  borderStyle?: BorderStyle;
73
107
  }
108
+ /** Typography explicitly enabled by custom blocks. */
74
109
  interface EmailTypographyStyle {
110
+ /** CSS font stack. */
75
111
  fontFamily?: string;
112
+ /** CSS font size. */
76
113
  fontSize?: string;
114
+ /** Font weight. */
77
115
  fontWeight?: FontWeight;
116
+ /** Line height, including unitless multipliers. */
78
117
  lineHeight?: string;
118
+ /** Text color. */
79
119
  color?: string;
120
+ /** Horizontal text alignment. */
80
121
  textAlign?: TextAlign;
122
+ /** Paragraph spacing. */
81
123
  paragraphSpacing?: string;
124
+ /** List item spacing. */
82
125
  listSpacing?: string;
126
+ /** List indentation. */
83
127
  listIndent?: string;
128
+ /** Default link color. */
84
129
  linkColor?: string;
130
+ /** Default link decoration. */
85
131
  linkDecoration?: LinkDecoration;
86
132
  }
87
- /** 按钮、图片和分割线自身的样式,与区块容器样式独立。 */
133
+ /** Button, image or divider styles, including appearance fields. */
88
134
  interface EmailElementStyle extends EmailDecorationStyle {
135
+ /** Element CSS padding. */
89
136
  padding?: string;
137
+ /** Element CSS width. */
90
138
  width?: string;
139
+ /** Element CSS height. */
91
140
  height?: string;
141
+ /** Element horizontal alignment within its container. */
92
142
  align?: HorizontalAlign;
93
143
  }
144
+ /** Block container dimensions and spacing. */
94
145
  interface EmailSpacingStyle {
146
+ /** Container padding. */
95
147
  padding?: string;
148
+ /** Container outer spacing. */
96
149
  margin?: string;
97
- /** 自定义区块可通过 styleControls 启用;内置区块不支持。只使用 px。 */
150
+ /** Fixed height in px for enabled custom blocks; unsupported by builtins. */
98
151
  height?: string;
99
152
  }
153
+ /** Grouped styles; only plugin-enabled controls are read. */
100
154
  interface EmailBlockStyle {
155
+ /** Container dimensions and spacing. */
101
156
  dimension?: EmailSpacingStyle;
102
- /** 自定义区块可显式启用;内置区块的文字格式存于 controls.html。 */
157
+ /** Optional custom typography; builtin text formatting lives in controls.html. */
103
158
  typography?: EmailTypographyStyle;
159
+ /** Block container appearance. */
104
160
  decorations?: EmailDecorationStyle;
161
+ /** Styles of the button, image or other inner element. */
105
162
  element?: EmailElementStyle;
106
163
  }
107
164
 
165
+ /** Select or alignment control option. */
108
166
  interface ControlOption {
167
+ /** Display label. */
109
168
  label: string;
169
+ /** Persisted option value. */
110
170
  value: string;
111
171
  }
172
+ /** Named runtime control definition. */
112
173
  interface ControlConfig extends ControlDefinition {
174
+ /** Key in the controls object. */
113
175
  name: string;
114
176
  }
177
+ /** Inspector group identifier. */
115
178
  type StyleGroup = "general" | "dimension" | "typography" | "decorations";
179
+ /** Union of style input kinds. */
116
180
  type StyleControlType = "text" | "color" | "alignment" | "select" | "number" | "range" | "spacing" | "corners";
181
+ /** Inspector style control declaration. */
117
182
  interface StyleControlConfig {
118
- /** e.g. "typography.fontSize" — which style slot this reads and writes */
183
+ /** Style path, e.g. dimension.padding. */
119
184
  id: string;
185
+ /** Default inspector group. */
120
186
  group: StyleGroup;
187
+ /** Display label. */
121
188
  label: string;
189
+ /** Style input kind. */
122
190
  control: StyleControlType;
191
+ /** Options for select or alignment. */
123
192
  options?: ControlOption[];
124
- /** Unit suffix for a single-unit slider, e.g. "px". Omit for unitless values. */
193
+ /** Single unit suffix; omit for unitless values. */
125
194
  unit?: string;
126
- /** Email-safe units. A select appears only when more than one is listed. */
195
+ /** Allowed email CSS units; multiple units show a selector. */
127
196
  units?: string[];
197
+ /** Minimum numeric or range value. */
128
198
  min?: number;
199
+ /** Maximum numeric or range value. */
129
200
  max?: number;
201
+ /** Numeric increment. */
130
202
  step?: number;
203
+ /** Default style string; overridden by defaultStyle. */
131
204
  defaultValue?: string;
205
+ /** Empty input hint. */
132
206
  placeholder?: string;
133
207
  }
208
+ /** Canvas or email consumer mode; independent of template resolution. */
134
209
  type RenderMode = "canvas" | "email";
210
+ /** Normalized snapshots used by block renderers. */
135
211
  interface BlockRenderContext {
212
+ /** Block copy with normalized controls and styles. */
136
213
  block: EmailBlockNode;
214
+ /** Values parsed by the plugin readControls. */
137
215
  controls: Record<string, unknown>;
216
+ /** Normalized enabled styles. */
138
217
  style: EmailBlockStyle;
139
- /** canvas/email identify the consumer; HTML template resolution is applied by the shared renderer. */
218
+ /** Canvas or email consumer; templates are processed by the shared renderer. */
140
219
  mode: RenderMode;
220
+ /** Copy of email body settings. */
141
221
  body: EmailBodySettings;
142
222
  }
223
+ /** Rich-text features for text, heading or button. */
143
224
  type RichTextProfile = "text" | "heading" | "button";
144
- /** 显式控制检查器的分组及字段归属,分组按声明顺序展示。 */
225
+ /** Inspector section displayed in declaration order. */
145
226
  interface BlockInspectorSection {
227
+ /** Section title. */
146
228
  title: string;
229
+ /** Content control names in display order. */
147
230
  controlNames?: string[];
231
+ /** Style control IDs in display order. */
148
232
  styleIds?: string[];
233
+ /** Style IDs inside the collapsed advanced section. */
149
234
  advancedStyleIds?: string[];
150
235
  }
236
+ /** Normalized block definition available through plugin values and registry lookups. */
151
237
  interface BlockDefinition {
238
+ /** Unique block type. */
152
239
  type: string;
240
+ /** Library title. */
153
241
  title: string;
242
+ /** Library React icon or string. */
154
243
  icon?: ReactNode | string;
244
+ /** Library description. */
155
245
  description?: string;
246
+ /** Named controls in declaration order. */
156
247
  controls?: ControlConfig[];
248
+ /** Enabled style controls. */
157
249
  styleControls?: StyleControlConfig[];
250
+ /** Custom inspector sections. */
158
251
  inspectorSections?: BlockInspectorSection[];
252
+ /** Parse a raw control object into normalized values. */
159
253
  readControls: (value: Record<string, unknown>) => Record<string, unknown>;
254
+ /** Allow replacing a builtin with the same type. */
160
255
  override?: boolean;
256
+ /** Default styles for new nodes. */
161
257
  defaultStyle?: EmailBlockStyle;
162
- /** Sample data used to render template HTML in the editor and preview. */
258
+ /** Template preview data for new nodes. */
163
259
  defaultData?: Record<string, unknown>;
164
- /** 默认画布直接编辑的 richText 字段;由字段声明解析生成。 */
260
+ /** Rich-text control edited by the default canvas. */
165
261
  inlineControl?: string;
166
- /** Optional React inspector for controls that need domain-specific editing UI. */
262
+ /** Inspector component bound to the editor context. */
167
263
  inspector?: ComponentType<PluginEditorProps>;
168
- /** Optional React canvas for multi-region or interactive editing. */
264
+ /** Canvas component bound to the editor context. */
169
265
  canvas?: ComponentType<PluginEditorProps>;
266
+ /** Render inner HTML from normalized context; email mode validates controls. */
170
267
  renderEmail: (ctx: BlockRenderContext) => string;
171
268
  }
269
+ /** Insertable template variable and preview value. */
172
270
  interface Variable {
173
- /** 下拉展示并插入的变量,例如 `{{ store_name }}`。 */
271
+ /** Exact inserted token, e.g. {{ store_name }}; exact matches receive export dot normalization. */
174
272
  name: string;
175
- /** 下拉选项副文案。空字符串或不传时不渲染。 */
273
+ /** Secondary option text; hidden when absent or empty. */
176
274
  description?: string;
177
- /** 预览时替换该变量的文本。 */
275
+ /** Preview replacement text; omitted values add no preview data. */
178
276
  value?: string;
179
277
  }
180
278
 
279
+ /** Template keys mapped to preview values; nested objects and arrays support paths and loops. */
181
280
  interface TemplateData {
281
+ /** Template key mapped to a scalar, object or array. */
182
282
  [key: string]: unknown;
183
283
  }
184
284
  /** Resolves template HTML for the editor and preview while leaving stored source untouched. */
185
285
  declare function renderTemplatePreview(html: string, defaultData?: TemplateData): string;
186
286
 
287
+ /** Complete document HTML export options. */
187
288
  interface DocumentHtmlOptions {
289
+ /** Resolve templates for preview; default false. */
188
290
  resolveHtmlTemplates?: boolean;
291
+ /** Exact inserted tokens and optional preview values, default []. */
189
292
  variables?: Variable[];
293
+ /** Global template data; shallow precedence below block defaultData and above variables. */
190
294
  templateData?: TemplateData;
191
295
  }
192
296
  declare function documentToHtml(document: EmailDocument, definitions?: readonly BlockDefinition[], options?: DocumentHtmlOptions): string;
193
297
 
194
298
  declare const EMAIL_MARKUP: unique symbol;
299
+ /** Branded email HTML fragment created by email tools. */
195
300
  interface EmailMarkup {
196
301
  readonly [EMAIL_MARKUP]: true;
302
+ /** Fragment HTML content. */
197
303
  readonly html: string;
198
304
  }
305
+ /** email.image options. */
199
306
  interface EmailImageOptions {
307
+ /** Image URL allowing http, https, cid or a template. */
200
308
  src: string;
309
+ /** Alternative text, default empty. */
201
310
  alt?: string;
311
+ /** CSS width, default 100%; invalid values use the default. */
202
312
  width?: string;
203
313
  }
314
+ /** email.button options. */
204
315
  interface EmailButtonOptions {
316
+ /** Link URL; empty or invalid values render non-link text. */
205
317
  href: string;
318
+ /** Button text, automatically escaped. */
206
319
  label: string;
207
320
  }
321
+ /** Email HTML helpers available in plugin renderEmail. */
208
322
  interface EmailTools {
323
+ /** Tagged template strings and values; ordinary values are escaped, markup and arrays compose. */
209
324
  html: (strings: TemplateStringsArray, ...values: unknown[]) => EmailMarkup;
325
+ /** Insert raw HTML without sanitization. */
210
326
  raw: (html: string) => EmailMarkup;
327
+ /** Preserve rich-text formatting and apply body defaults. */
211
328
  richText: (html: string) => EmailMarkup;
329
+ /** Build a presentation table from rows of EmailMarkup cells. */
212
330
  table: (rows: EmailMarkup[][]) => EmailMarkup;
331
+ /** Render an image from URL, alt and width, validating protocols and escaping. */
213
332
  image: (options: EmailImageOptions) => EmailMarkup;
333
+ /** Render an email table button from URL and label. */
214
334
  button: (options: EmailButtonOptions) => EmailMarkup;
335
+ /** Validate a URL; image selects image protocols, default false; invalid URLs return empty. */
215
336
  url: (value: string, image?: boolean) => string;
216
337
  }
217
338
 
339
+ /** Content control kind. */
218
340
  type ControlKind = "text" | "textarea" | "html" | "richText" | "url" | "image" | "number" | "color" | "select" | "boolean" | "list" | "custom";
341
+ /** Custom control props; T is the value type. */
219
342
  interface ControlComponentProps<T = unknown> {
343
+ /** Detached normalized control value. */
220
344
  value: T;
345
+ /** Submit the new control value. */
221
346
  onChange: (value: T) => void;
347
+ /** Declared control label. */
222
348
  label: string;
349
+ /** Current body settings snapshot. */
223
350
  body: EmailBodySettings;
351
+ /** Insertable variable snapshots. */
224
352
  variables: Variable[];
225
353
  }
354
+ /** Control factory options; T is the default/edit value type. */
226
355
  interface ControlOptions<T> {
356
+ /** Required display label. */
227
357
  label: string;
358
+ /** Factory fallback when omitted; persisted undefined receives the default. */
228
359
  defaultValue?: T;
360
+ /** Empty input hint. */
229
361
  placeholder?: string;
362
+ /** Allowed select options. */
230
363
  options?: ControlOption[];
364
+ /** Visible textarea or HTML editor rows. */
231
365
  rows?: number;
366
+ /** Minimum number or list length. */
232
367
  min?: number;
368
+ /** Maximum number or list length. */
233
369
  max?: number;
370
+ /** Number input increment. */
234
371
  step?: number;
372
+ /** Unit label beside a numeric input. */
235
373
  unit?: string;
374
+ /** Rich-text feature profile: text, heading or button. */
236
375
  profile?: RichTextProfile;
237
- /** 由默认画布直接编辑此字段;多区域布局使用 Canvas + EditableRichText。 */
376
+ /** Edit this richText on the default canvas; multiple regions require Canvas. */
238
377
  inline?: boolean;
378
+ /** Custom React control component. */
239
379
  component?: ComponentType<ControlComponentProps<T>>;
380
+ /** Validate a normalized value; return an error message or undefined. */
240
381
  validate?: (value: T) => string | undefined;
241
382
  }
242
- /** 工厂生成的字段,同时负责默认值、运行时窄化和可选自定义控件。 */
383
+ /** Factory-produced control definition; T is its parsed value type. */
243
384
  interface ControlDefinition<T = unknown> extends Omit<ControlOptions<T>, "component" | "validate"> {
385
+ /** Control kind. */
244
386
  kind: ControlKind;
387
+ /** Normalized default value. */
245
388
  defaultValue: T;
389
+ /** Parse an unknown persisted value into T; must be pure. */
246
390
  read: (value: unknown) => T;
247
- /** 只接收已归一化的字段值,不重复调用 read。 */
391
+ /** Validate an already normalized value without re-reading. */
248
392
  validateValue?: (value: unknown) => string | undefined;
249
- /** value 已由宿主归一化。 */
393
+ /** Render React UI from host-normalized control props. */
250
394
  renderControl?: (props: ControlComponentProps) => ReactNode;
395
+ /** Child control schema for each list row. */
251
396
  itemControls?: ControlSchema;
252
397
  }
398
+ /** Map from control names to definitions. */
253
399
  type ControlSchema = Record<string, ControlDefinition>;
400
+ /** Infer values from each Schema control read return type. */
254
401
  type ControlValues<Schema extends ControlSchema> = {
255
402
  [Name in keyof Schema]: ReturnType<Schema[Name]["read"]>;
256
403
  };
404
+ /** Canvas or Inspector props; Controls is the inferred value shape. */
257
405
  interface PluginEditorProps<Controls = Record<string, unknown>> {
406
+ /** Detached block snapshot. */
258
407
  block: EmailBlockNode;
408
+ /** Normalized control value snapshot. */
259
409
  controls: Controls;
410
+ /** Current enabled styles snapshot. */
260
411
  style: EmailBlockStyle;
412
+ /** Body settings snapshot. */
261
413
  body: EmailBodySettings;
414
+ /** Available variable snapshots. */
262
415
  variables: Variable[];
416
+ /** Whether selected; true inside Inspector. */
263
417
  selected: boolean;
418
+ /** Resolved inner HTML in Canvas; empty in Inspector. */
264
419
  renderedHtml: string;
420
+ /** Request selection of this block. */
265
421
  select: () => void;
422
+ /** Update the named control with its typed value. */
266
423
  setControl: <Name extends keyof Controls & string>(name: Name, value: Controls[Name]) => void;
424
+ /** Shallow-merge a patch in one update; replace nested values entirely. */
267
425
  setControls: (patch: Partial<Controls>) => void;
426
+ /** Update a style path with a CSS string. */
268
427
  setStyle: (id: string, value: string) => void;
269
428
  }
429
+ /** Typed email render context; Controls contains inferred values. */
270
430
  interface PluginRenderContext<Controls> extends Omit<BlockRenderContext, "controls"> {
431
+ /** Inferred normalized control values. */
271
432
  controls: Controls;
433
+ /** Escaping and layout helpers for email HTML. */
272
434
  email: EmailTools;
273
435
  }
436
+ /** defineBlock options; Schema infers values and Type preserves the type literal. */
274
437
  interface BlockPluginOptions<Schema extends ControlSchema, Type extends string> {
438
+ /** Nonempty unique type; a business prefix is recommended. */
275
439
  type: Type;
440
+ /** Nonempty library title. */
276
441
  title: string;
442
+ /** Library icon or string. */
277
443
  icon?: ReactNode | string;
444
+ /** Library description. */
278
445
  description?: string;
446
+ /** Must be true to replace a builtin. */
279
447
  override?: boolean;
448
+ /** Control schema, default {}. */
280
449
  controls?: Schema;
281
- /** 默认 spacing + appearance;false 禁用默认容器控件。 */
450
+ /** Container styles enabled by default; false disables all; spacing and appearance select groups. */
282
451
  containerStyles?: boolean | {
452
+ /** Enable default padding and margin controls; default true. */
283
453
  spacing?: boolean;
454
+ /** Enable default background and border controls; default true. */
284
455
  appearance?: boolean;
285
456
  };
457
+ /** Extra style controls; matching IDs replace container controls. */
286
458
  styleControls?: StyleControlConfig[];
459
+ /** Ordered content and style sections. */
287
460
  inspectorSections?: BlockInspectorSection[];
461
+ /** Initial styles, taking precedence over control defaultValue. */
288
462
  defaultStyle?: EmailBlockStyle;
463
+ /** Template preview data for new nodes. */
289
464
  defaultData?: Record<string, unknown>;
465
+ /** Optional React canvas composing multiple editing regions. */
290
466
  Canvas?: ComponentType<PluginEditorProps<ControlValues<Schema>>>;
467
+ /** Optional React inspector replacing the default content editor. */
291
468
  Inspector?: ComponentType<PluginEditorProps<ControlValues<Schema>>>;
469
+ /** Render inner HTML or EmailMarkup from typed context, without editor UI. */
292
470
  renderEmail: (ctx: PluginRenderContext<ControlValues<Schema>>) => string | EmailMarkup;
293
471
  }
294
- /** 只通过 defineBlock 创建;配置同时用于编辑、节点创建和邮件导出。 */
472
+ /** Plugin returned by defineBlock; Schema is its schema and Type its identifier type. */
295
473
  interface BlockPlugin<Schema extends ControlSchema = ControlSchema, Type extends string = string> extends BlockDefinition {
474
+ /** Block type literal. */
296
475
  type: Type;
476
+ /** Detached frozen snapshot of the control schema. */
297
477
  schema: Schema;
298
478
  }
479
+ /** Image resource picker request. */
299
480
  interface ImagePickerContext {
481
+ /** Current image URL. */
300
482
  value: string;
483
+ /** Label of the requesting control. */
301
484
  label: string;
485
+ /** Cancellation signal on unmount or invalidation; pass to resource requests. */
302
486
  signal: AbortSignal;
303
487
  }
488
+ /** Document control validation issue. */
304
489
  interface ValidationIssue {
490
+ /** Invalid block ID. */
305
491
  blockId: string;
492
+ /** Invalid plugin type. */
306
493
  blockType: string;
494
+ /** Control path including list row indexes and child controls. */
307
495
  controlPath: string;
496
+ /** Displayable error description. */
308
497
  message: string;
309
498
  }
310
- interface EmailEditorConfigOptions {
499
+ /** Block registration and image resource adapter options. */
500
+ interface UseEmailEditorConfigOptions {
501
+ /** Plugins created by defineBlock, default []. */
311
502
  plugins?: BlockPlugin[];
312
- /** false 隐藏全部内置区块;数组声明显示顺序。隐藏不影响已有节点渲染。 */
503
+ /** All by default; false hides all; arrays filter/order; hidden nodes still render. */
313
504
  builtins?: false | string[];
505
+ /** Resolve a URL from context, return null to cancel, or throw to show retry. */
314
506
  pickImage?: (context: ImagePickerContext) => Promise<string | null>;
315
507
  }
508
+ /** Shared configuration for editing, creation and standalone export. */
316
509
  interface EmailEditorConfig {
510
+ /** All registered definitions including hidden builtins. */
317
511
  readonly definitions: readonly BlockPlugin[];
512
+ /** Insertable blocks in display order. */
318
513
  readonly library: readonly BlockPlugin[];
319
- readonly pickImage?: EmailEditorConfigOptions["pickImage"];
514
+ /** Optional image resource picker. */
515
+ readonly pickImage?: UseEmailEditorConfigOptions["pickImage"];
516
+ /** Create a detached default node for a registered type; unknown types throw. */
320
517
  createBlock: (type: string) => EmailBlockNode;
518
+ /** Export a v4 document using this configuration and optional template options. */
321
519
  toHtml: (document: EmailDocument, options?: DocumentHtmlOptions) => string;
520
+ /** Return document control issues, including missing plugins. */
322
521
  validate: (document: EmailDocument) => ValidationIssue[];
323
522
  }
324
523
 
524
+ /** Independent export snapshot. */
325
525
  interface EmailEditorData {
526
+ /** Document snapshot for persistence and reloading. */
326
527
  document: EmailDocument;
528
+ /** Pretty-printed document JSON. */
327
529
  json: string;
530
+ /** Complete email HTML preserving templates. */
328
531
  html: string;
532
+ /** Complete HTML resolved with preview data. */
329
533
  renderedHtml: string;
330
534
  }
331
- interface EmailEditorHandle {
535
+ /** Stable editor instance independent of UI mounting. */
536
+ interface EmailEditorInstance {
537
+ /** Read all export formats; rendering errors throw. */
332
538
  getData: () => EmailEditorData;
539
+ /** Read a detached document snapshot. */
333
540
  getDocument: () => EmailDocument;
541
+ /** Read pretty-printed document JSON. */
334
542
  getJson: () => string;
543
+ /** Export complete email HTML preserving templates. */
335
544
  getHtml: () => string;
545
+ /** Export HTML with current preview data. */
336
546
  getRenderedHtml: () => string;
337
- }
547
+ /** Replace with a v4 document, clear interaction state and notify onChange. */
548
+ setDocument: (document: EmailDocument) => void;
549
+ /** Restore initialized document and body, clear interaction state and notify. */
550
+ reset: () => void;
551
+ /** Validate controls and return issues without rendering HTML. */
552
+ validate: () => ValidationIssue[];
553
+ }
554
+ /** Editor UI props. */
338
555
  interface EmailEditorProps {
556
+ /** Required instance created by useEmailEditor. */
557
+ editor: EmailEditorInstance;
558
+ /** Height, default 100%; numbers are px; percentages need a sized parent. */
559
+ height?: number | string;
560
+ }
561
+ type ReadonlyData<T> = T extends object ? {
562
+ readonly [Key in keyof T]: ReadonlyData<T[Key]>;
563
+ } : T;
564
+ /** Cached readonly document subscription snapshot. */
565
+ interface EmailEditorState {
566
+ /** Deeply readonly document; update through instance methods. */
567
+ readonly document: ReadonlyData<EmailDocument>;
568
+ }
569
+ /** Editor initialization and reactive options. */
570
+ interface UseEmailEditorOptions {
571
+ /** Read once; use setDocument for later replacements; defaults to empty. */
339
572
  initialDocument?: EmailDocument;
340
- /** External body settings. Incoming changes are applied to the open document. */
573
+ /** Initial body overrides; later changes merge into the current body. */
341
574
  body?: Partial<EmailBodySettings>;
575
+ /** Block/resource configuration; defaults to all builtins; updates preserve the document. */
342
576
  config?: EmailEditorConfig;
577
+ /** Insertable preview variables, default []; updates affect preview/export. */
343
578
  variables?: Variable[];
344
- height?: number | string;
579
+ /** Detached document after changes, replacements, resets or effective body updates; no initial call. */
345
580
  onChange?: (document: EmailDocument) => void;
581
+ /** Detached body snapshot after body edits inside the editor only. */
346
582
  onBodyChange?: (body: EmailBodySettings) => void;
347
583
  }
348
584
 
349
- declare const EmailEditor: react.ForwardRefExoticComponent<EmailEditorProps & react.RefAttributes<EmailEditorHandle>>;
585
+ declare function EmailEditor(props: EmailEditorProps): react.JSX.Element;
350
586
 
587
+ /** Inherited styles for the low-level rich-text toolbar. */
351
588
  interface RichTextInheritedStyle {
589
+ /** Inherited font stack. */
352
590
  fontFamily: string;
591
+ /** Inherited font size. */
353
592
  fontSize: string;
593
+ /** Inherited text color. */
354
594
  color: string;
595
+ /** Inherited font weight. */
355
596
  fontWeight: FontWeight;
597
+ /** Inherited line height. */
356
598
  lineHeight: string;
599
+ /** Inherited paragraph spacing. */
357
600
  paragraphSpacing: string;
601
+ /** Inherited list item spacing. */
358
602
  listSpacing?: string;
603
+ /** Inherited list indentation. */
359
604
  listIndent?: string;
605
+ /** Inherited link color. */
360
606
  linkColor?: string;
607
+ /** Inherited link decoration. */
361
608
  linkDecoration?: string;
362
609
  }
363
610
 
611
+ /** Low-level rich-text props; prefer EditableRichText in plugins. */
364
612
  interface RichTextProps {
613
+ /** Initial and externally synchronized HTML. */
365
614
  initialHtml: string;
615
+ /** Feature profile, default text. */
366
616
  profile?: RichTextProfile;
617
+ /** Empty hint, default Type something…. */
367
618
  placeholder?: string;
619
+ /** Variables available in the toolbar. */
368
620
  variables: Variable[];
621
+ /** Whether selected and eligible to show the toolbar. */
369
622
  selected: boolean;
623
+ /** Toolbar DOM ID; caller ensures uniqueness. */
370
624
  toolbarId: string;
625
+ /** Whether the toolbar is hidden. */
371
626
  toolbarCollapsed: boolean;
627
+ /** Inherited typography; defaults to internal typography. */
372
628
  inherited?: RichTextInheritedStyle;
629
+ /** Receive complete rich-text HTML after each edit. */
373
630
  onCommit: (html: string) => void;
631
+ /** Request selection on click or focus. */
374
632
  onSelect: () => void;
375
633
  }
376
634
  declare function RichText({ initialHtml, profile, placeholder, variables, selected, toolbarId, toolbarCollapsed, inherited, onCommit, onSelect, }: RichTextProps): react.JSX.Element;
@@ -407,27 +665,34 @@ declare const TYPOGRAPHY_CONTROL_MAP: {
407
665
  linkColor: StyleControlConfig;
408
666
  linkDecoration: StyleControlConfig;
409
667
  };
668
+ /** Dimension names: padding, margin, height. */
410
669
  type DimensionControlName = keyof typeof DIMENSION_CONTROLS;
670
+ /** Appearance control names. */
411
671
  type DecorationControlName = keyof typeof DECORATION_CONTROLS;
672
+ /** Typography control names. */
412
673
  type TypographyControlName = keyof typeof TYPOGRAPHY_CONTROL_MAP;
413
674
  type StyleControlOverrideMap<Name extends string> = Partial<Record<Name, Partial<StyleControlConfig>>>;
414
675
  declare function createDimensionControls(overrides?: StyleControlOverrideMap<DimensionControlName>): Record<DimensionControlName, StyleControlConfig>;
415
676
  declare function createDecorationControls(overrides?: StyleControlOverrideMap<DecorationControlName>): Record<DecorationControlName, StyleControlConfig>;
416
677
  declare function createTypographyControls(overrides?: StyleControlOverrideMap<TypographyControlName>): Record<TypographyControlName, StyleControlConfig>;
417
678
 
679
+ /** Single-block rendering options; must be an object. */
418
680
  interface BlockRenderOptions {
681
+ /** Resolve templates, default false; single-block rendering does not auto-merge variables. */
419
682
  resolveHtmlTemplate?: boolean;
683
+ /** Explicit preview data; defaults to node defaultData. */
420
684
  templateData?: TemplateData;
685
+ /** Exact token dot normalization on export; merge preview data explicitly. */
421
686
  variables?: Variable[];
687
+ /** Body defaults; defaults to DEFAULT_EMAIL_BODY. */
422
688
  body?: EmailBodySettings;
423
689
  }
424
- type BlockRenderOptionsInput = BlockRenderOptions | boolean;
425
- /** 用变量 name 里的字段名作为键,value 作为预览替换值。 */
690
+ /** Convert variable name paths and preview values into template data. */
426
691
  declare function variablesToTemplateData(variables: Variable[]): TemplateData;
427
692
  declare function mergeTemplateData(variables: Variable[], defaultData?: TemplateData): TemplateData | undefined;
428
- declare function renderBlockContent(node: EmailBlockNode, definitions?: readonly BlockDefinition[], mode?: RenderMode, options?: BlockRenderOptionsInput): string;
693
+ declare function renderBlockContent(node: EmailBlockNode, definitions?: readonly BlockDefinition[], mode?: RenderMode, options?: BlockRenderOptions): string;
429
694
  declare function renderBlock(node: EmailBlockNode, definitions?: readonly BlockDefinition[], mode?: RenderMode, body?: EmailBodySettings): string;
430
- declare function blockToHtml(node: EmailBlockNode, definitions?: readonly BlockDefinition[], mode?: RenderMode, options?: BlockRenderOptionsInput): string;
695
+ declare function blockToHtml(node: EmailBlockNode, definitions?: readonly BlockDefinition[], mode?: RenderMode, options?: BlockRenderOptions): string;
431
696
 
432
697
  declare function buildRenderContext(node: EmailBlockNode, mode: RenderMode, body?: EmailBodySettings, definition?: BlockDefinition | undefined): BlockRenderContext;
433
698
 
@@ -435,8 +700,11 @@ declare function getBlockDefinition(type: string, definitions?: readonly BlockDe
435
700
 
436
701
  declare function generateId(prefix?: string): string;
437
702
 
703
+ /** Inspector group option. */
438
704
  interface StyleGroupOption {
705
+ /** Group identifier. */
439
706
  group: StyleGroup;
707
+ /** Display label. */
440
708
  label: string;
441
709
  }
442
710
  declare const STYLE_GROUPS: StyleGroupOption[];
@@ -450,6 +718,7 @@ declare const BLOCK_TYPES: {
450
718
  readonly spacer: "spacer";
451
719
  readonly html: "html";
452
720
  };
721
+ /** Union of builtin block type identifiers. */
453
722
  type BuiltinBlockType = (typeof BLOCK_TYPES)[keyof typeof BLOCK_TYPES];
454
723
 
455
724
  declare function defineBlock<Schema extends ControlSchema, const Type extends string>(input: BlockPluginOptions<Schema, Type>): BlockPlugin<Schema, Type>;
@@ -466,81 +735,130 @@ declare const EmailControls: {
466
735
  boolean: (options: ControlOptions<boolean>) => ControlDefinition<boolean>;
467
736
  number: (options: ControlOptions<number>) => ControlDefinition<number>;
468
737
  list<Schema extends ControlSchema>(options: ControlOptions<ControlValues<Schema>[]> & {
738
+ /** Controls for each list row; Schema infers row values. */
469
739
  controls: Schema;
470
740
  }): ControlDefinition<ControlValues<Schema>[]>;
471
741
  custom<T>(options: ControlOptions<T> & {
742
+ /** Required default value; must be JSON-persistable. */
472
743
  defaultValue: T;
744
+ /** Purely parse an unknown persisted value into T. */
473
745
  read: (value: unknown) => T;
746
+ /** Required editing component receiving ControlComponentProps<T>. */
474
747
  component: NonNullable<ControlOptions<T>["component"]>;
475
748
  }): ControlDefinition<T>;
476
749
  };
477
750
 
478
- declare function createEmailEditorConfig(options?: EmailEditorConfigOptions): EmailEditorConfig;
751
+ declare function useEmailEditorConfig(options?: UseEmailEditorConfigOptions): EmailEditorConfig;
752
+
753
+ declare function useEmailEditor(options?: UseEmailEditorOptions): EmailEditorInstance;
754
+
755
+ declare function useEmailEditorState(editor: EmailEditorInstance): EmailEditorState;
479
756
 
757
+ /** Rich-text region within plugin context. */
480
758
  interface EditableRichTextProps {
759
+ /** Name of a declared richText control. */
481
760
  control: string;
761
+ /** Override the control rich-text feature profile. */
482
762
  profile?: RichTextProfile;
763
+ /** Override the empty editor hint. */
483
764
  placeholder?: string;
484
765
  }
485
766
  declare function EditableRichText({ control, profile, placeholder }: EditableRichTextProps): react.JSX.Element;
486
767
 
768
+ /** Text input props; other attributes follow React input; supports ref. */
487
769
  interface TextInputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "type"> {
770
+ /** Input type, default text; excludes checkbox and other non-text kinds. */
488
771
  type?: "text" | "url" | "email" | "search" | "tel" | "password" | "number";
489
772
  }
490
773
  declare const TextInput: react.ForwardRefExoticComponent<TextInputProps & react.RefAttributes<HTMLInputElement>>;
491
774
 
775
+ /** String select props. */
492
776
  interface SelectControlProps {
777
+ /** Native select DOM ID. */
493
778
  id?: string;
779
+ /** Accessible name. */
494
780
  label?: string;
781
+ /** Current option value. */
495
782
  value: string;
783
+ /** Options in display order. */
496
784
  options: readonly ControlOption[];
785
+ /** Optional empty-option label; no duplicate empty option. */
497
786
  emptyLabel?: string;
787
+ /** Compact size, default false. */
498
788
  compact?: boolean;
789
+ /** Whether disabled. */
499
790
  disabled?: boolean;
791
+ /** Receive the new option value. */
500
792
  onChange: (value: string) => void;
501
793
  }
502
794
  declare function SelectControl({ id, label, value, options, emptyLabel, compact, disabled, onChange }: SelectControlProps): react.JSX.Element;
503
795
 
796
+ /** Checkbox or switch props. */
504
797
  interface CheckboxControlProps {
798
+ /** Visible and accessible label. */
505
799
  label: string;
800
+ /** Current checked state. */
506
801
  checked: boolean;
802
+ /** Whether disabled. */
507
803
  disabled?: boolean;
804
+ /** Additional root CSS class. */
508
805
  className?: string;
806
+ /** Appearance: checkbox by default, or switch. */
509
807
  variant?: "checkbox" | "switch";
808
+ /** Receive the new checked state. */
510
809
  onChange: (checked: boolean) => void;
511
810
  }
512
811
  declare function CheckboxControl({ label, checked, disabled, className, variant, onChange }: CheckboxControlProps): react.JSX.Element;
513
812
 
813
+ /** Color picker props. */
514
814
  interface ColorControlProps {
815
+ /** Current CSS color value. */
515
816
  value: string;
817
+ /** Display fallback for an empty value, default #000000. */
516
818
  fallback?: string;
819
+ /** Button and dialog label, default Color. */
517
820
  label?: string;
821
+ /** Value submitted on reset; defaults to fallback. */
518
822
  resetTo?: string;
823
+ /** Receive the selected or reset color. */
519
824
  onChange: (value: string) => void;
520
825
  }
521
826
  declare function ColorControl({ value, fallback, label, resetTo, onChange }: ColorControlProps): react.JSX.Element;
522
827
 
828
+ /** Numeric range props. */
523
829
  interface RangeControlProps {
830
+ /** Native input DOM ID. */
524
831
  id?: string;
832
+ /** Accessible name. */
525
833
  label?: string;
834
+ /** Current numeric value. */
526
835
  value: number;
836
+ /** Minimum, default 0. */
527
837
  min?: number;
838
+ /** Maximum, default 100. */
528
839
  max?: number;
840
+ /** Increment, default 1. */
529
841
  step?: number;
842
+ /** Receive the updated number. */
530
843
  onChange: (value: number) => void;
531
844
  }
532
845
  declare function RangeControl({ id, label, value, min, max, step, onChange, }: RangeControlProps): react.JSX.Element;
533
846
 
847
+ /** Button props; other attributes follow React button; type defaults to button. */
534
848
  interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
849
+ /** Appearance: default, primary, solid or icon; default is default. */
535
850
  variant?: "default" | "primary" | "solid" | "icon";
851
+ /** Optional tooltip linked through aria-describedby. */
536
852
  tooltip?: string;
537
853
  }
538
854
  declare function Button({ type, variant, className, tooltip, children, "aria-describedby": describedBy, ...props }: ButtonProps): react.JSX.Element;
539
855
 
856
+ /** Declared-control component props within plugin context. */
540
857
  interface ControlEditorProps {
858
+ /** Declared control name; unknown names throw. */
541
859
  control: string;
542
860
  }
543
- /** 自定义 Inspector 复用字段声明、资源选择器、校验和标准控件。 */
861
+ /** Reuse declared controls, image pickers and validation inside a plugin inspector. */
544
862
  declare function ControlEditor({ control }: ControlEditorProps): react.JSX.Element;
545
863
 
546
- export { BLOCK_TYPES, BORDER_STYLES, type BlockInspectorSection, type BlockPlugin, type BlockPluginOptions, type BlockRenderContext, type BlockRenderOptions, type BorderStyle, type BuiltinBlockType, Button, CheckboxControl, ColorControl, type ControlComponentProps, type ControlDefinition, ControlEditor, type ControlEditorProps, type ControlKind, type ControlOption, type ControlOptions, type ControlSchema, type ControlValues, DEFAULT_BLOCKS, DEFAULT_EMAIL_BODY, DOCUMENT_VERSION, type DecorationControlName, type DimensionControlName, type DocumentHtmlOptions, EditableRichText, type EditableRichTextProps, type EmailBlockNode, type EmailBlockStyle, type EmailBodySettings, EmailControls, type EmailDecorationStyle, type EmailDocument, EmailEditor, type EmailEditorConfig, type EmailEditorConfigOptions, type EmailEditorData, type EmailEditorHandle, type EmailEditorProps, type EmailElementStyle, type EmailMarkup, type EmailSpacingStyle, type EmailTools, type EmailTypographyStyle, FONT_FAMILIES, FONT_WEIGHTS, type FontWeight, HORIZONTAL_ALIGNS, type HorizontalAlign, type ImagePickerContext, LINK_DECORATIONS, type LinkDecoration, type PluginEditorProps, type PluginRenderContext, RangeControl, type RenderMode, RichText, type RichTextProfile, STYLE_GROUPS, SelectControl, type StyleControlConfig, type StyleControlType, type StyleGroup, TEXT_ALIGNS, type TemplateData, type TextAlign, TextInput, type TypographyControlName, type ValidationIssue, type Variable, blockToHtml, buildRenderContext, createBlockNode, createDecorationControls, createDimensionControls, createEmailDocument, createEmailEditorConfig, createTypographyControls, defineBlock, documentToHtml, generateId, getBlockDefinition, mergeTemplateData, renderBlock, renderBlockContent, renderTemplatePreview, resolveEmailBody, variablesToTemplateData };
864
+ export { BLOCK_TYPES, BORDER_STYLES, type BlockInspectorSection, type BlockPlugin, type BlockPluginOptions, type BlockRenderContext, type BlockRenderOptions, type BorderStyle, type BuiltinBlockType, Button, CheckboxControl, ColorControl, type ControlComponentProps, type ControlDefinition, ControlEditor, type ControlEditorProps, type ControlKind, type ControlOption, type ControlOptions, type ControlSchema, type ControlValues, DEFAULT_BLOCKS, DEFAULT_EMAIL_BODY, DOCUMENT_VERSION, type DecorationControlName, type DimensionControlName, type DocumentHtmlOptions, EditableRichText, type EditableRichTextProps, type EmailBlockNode, type EmailBlockStyle, type EmailBodySettings, EmailControls, type EmailDecorationStyle, type EmailDocument, EmailEditor, type EmailEditorConfig, type EmailEditorData, type EmailEditorInstance, type EmailEditorProps, type EmailEditorState, type EmailElementStyle, type EmailMarkup, type EmailSpacingStyle, type EmailTools, type EmailTypographyStyle, FONT_FAMILIES, FONT_WEIGHTS, type FontWeight, HORIZONTAL_ALIGNS, type HorizontalAlign, type ImagePickerContext, LINK_DECORATIONS, type LinkDecoration, type PluginEditorProps, type PluginRenderContext, RangeControl, type RenderMode, RichText, type RichTextProfile, STYLE_GROUPS, SelectControl, type StyleControlConfig, type StyleControlType, type StyleGroup, TEXT_ALIGNS, type TemplateData, type TextAlign, TextInput, type TypographyControlName, type UseEmailEditorConfigOptions, type UseEmailEditorOptions, type ValidationIssue, type Variable, blockToHtml, buildRenderContext, createBlockNode, createDecorationControls, createDimensionControls, createEmailDocument, createTypographyControls, defineBlock, documentToHtml, generateId, getBlockDefinition, mergeTemplateData, renderBlock, renderBlockContent, renderTemplatePreview, resolveEmailBody, useEmailEditor, useEmailEditorConfig, useEmailEditorState, variablesToTemplateData };