@standhigher/react-email-editor 0.1.0 → 0.3.0

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
@@ -1,5 +1,5 @@
1
1
  import * as react from 'react';
2
- import { ReactNode } from 'react';
2
+ import { ReactNode, ComponentType, InputHTMLAttributes, ButtonHTMLAttributes } from 'react';
3
3
 
4
4
  declare const TEXT_ALIGNS: {
5
5
  readonly left: "left";
@@ -32,44 +32,35 @@ declare const LINK_DECORATIONS: {
32
32
  };
33
33
  type LinkDecoration = (typeof LINK_DECORATIONS)[keyof typeof LINK_DECORATIONS];
34
34
 
35
- declare const DOCUMENT_VERSION: 1;
36
- declare const FONT_FAMILIES: readonly FieldOption[];
37
- declare const DEFAULT_EMAIL_GLOBAL: EmailGlobalSettings;
35
+ declare const DOCUMENT_VERSION: 4;
36
+ declare const FONT_FAMILIES: readonly ControlOption[];
37
+ declare const DEFAULT_EMAIL_BODY: EmailBodySettings;
38
38
 
39
- interface EmailGlobalSettings {
39
+ /** 邮件主体布局、外观和可继承的基础文字与链接样式。 */
40
+ interface EmailBodySettings {
40
41
  textColor: string;
41
- textAlign: TextAlign;
42
42
  backgroundColor: string;
43
43
  contentWidth: number;
44
- contentAlign: HorizontalAlign;
45
44
  fontFamily: string;
46
45
  fontWeight: FontWeight;
47
- contentBackgroundColor: string;
48
- contentPadding: string;
49
- outerPadding: string;
50
- blockGap: string;
51
- defaultFontSize: string;
52
- defaultLineHeight: string;
53
- paragraphSpacing: string;
54
- listSpacing: string;
55
- listIndent: string;
56
46
  linkColor: string;
57
47
  linkDecoration: LinkDecoration;
48
+ contentPadding: string;
49
+ blockGap: string;
58
50
  borderWidth: string;
59
51
  borderStyle: BorderStyle;
60
52
  borderColor: string;
61
- borderRadius: string;
62
53
  }
63
54
  interface EmailDocument {
64
55
  version: typeof DOCUMENT_VERSION;
65
56
  subject?: string;
66
- global: EmailGlobalSettings;
57
+ body: EmailBodySettings;
67
58
  blocks: EmailBlockNode[];
68
59
  }
69
60
  interface EmailBlockNode {
70
61
  id: string;
71
62
  type: string;
72
- fields: Record<string, unknown>;
63
+ controls: Record<string, unknown>;
73
64
  style?: EmailBlockStyle;
74
65
  defaultData?: Record<string, unknown>;
75
66
  }
@@ -94,7 +85,7 @@ interface EmailTypographyStyle {
94
85
  linkDecoration?: LinkDecoration;
95
86
  }
96
87
  /** 按钮、图片和分割线自身的样式,与区块容器样式独立。 */
97
- interface EmailElementStyle extends EmailDecorationStyle, EmailTypographyStyle {
88
+ interface EmailElementStyle extends EmailDecorationStyle {
98
89
  padding?: string;
99
90
  width?: string;
100
91
  height?: string;
@@ -103,42 +94,33 @@ interface EmailElementStyle extends EmailDecorationStyle, EmailTypographyStyle {
103
94
  interface EmailSpacingStyle {
104
95
  padding?: string;
105
96
  margin?: string;
106
- /** 内层单元格高度,只使用 px。缺省时不输出 height。 */
97
+ /** 自定义区块可通过 styleControls 启用;内置区块不支持。只使用 px。 */
107
98
  height?: string;
108
99
  }
109
100
  interface EmailBlockStyle {
110
101
  dimension?: EmailSpacingStyle;
102
+ /** 自定义区块可显式启用;内置区块的文字格式存于 controls.html。 */
111
103
  typography?: EmailTypographyStyle;
112
104
  decorations?: EmailDecorationStyle;
113
105
  element?: EmailElementStyle;
114
106
  }
115
107
 
116
- type FieldType = "text" | "textarea" | "html" | "url" | "number" | "color" | "select";
117
- interface FieldOption {
108
+ interface ControlOption {
118
109
  label: string;
119
110
  value: string;
120
111
  }
121
- interface FieldConfig {
122
- type: FieldType;
112
+ interface ControlConfig extends ControlDefinition {
123
113
  name: string;
124
- label: string;
125
- defaultValue?: unknown;
126
- placeholder?: string;
127
- options?: FieldOption[];
128
- rows?: number;
129
- min?: number;
130
- max?: number;
131
- step?: number;
132
114
  }
133
115
  type StyleGroup = "general" | "dimension" | "typography" | "decorations";
134
116
  type StyleControlType = "text" | "color" | "alignment" | "select" | "number" | "range" | "spacing" | "corners";
135
- interface StyleFieldConfig {
117
+ interface StyleControlConfig {
136
118
  /** e.g. "typography.fontSize" — which style slot this reads and writes */
137
119
  id: string;
138
120
  group: StyleGroup;
139
121
  label: string;
140
122
  control: StyleControlType;
141
- options?: FieldOption[];
123
+ options?: ControlOption[];
142
124
  /** Unit suffix for a single-unit slider, e.g. "px". Omit for unitless values. */
143
125
  unit?: string;
144
126
  /** Email-safe units. A select appears only when more than one is listed. */
@@ -152,28 +134,40 @@ interface StyleFieldConfig {
152
134
  type RenderMode = "canvas" | "email";
153
135
  interface BlockRenderContext {
154
136
  block: EmailBlockNode;
155
- fields: Record<string, unknown>;
137
+ controls: Record<string, unknown>;
156
138
  style: EmailBlockStyle;
157
139
  /** canvas/email identify the consumer; HTML template resolution is applied by the shared renderer. */
158
140
  mode: RenderMode;
159
- global: EmailGlobalSettings;
141
+ body: EmailBodySettings;
142
+ }
143
+ type RichTextProfile = "text" | "heading" | "button";
144
+ /** 显式控制检查器的分组及字段归属,分组按声明顺序展示。 */
145
+ interface BlockInspectorSection {
146
+ title: string;
147
+ controlNames?: string[];
148
+ styleIds?: string[];
149
+ advancedStyleIds?: string[];
160
150
  }
161
151
  interface BlockDefinition {
162
152
  type: string;
163
153
  title: string;
164
154
  icon?: ReactNode | string;
165
155
  description?: string;
166
- fields?: FieldConfig[];
167
- styleFields?: StyleFieldConfig[];
168
- /** getBlockDefinition 只保留 styleFields,不补容器间距和装饰。 */
169
- exactStyleFields?: boolean;
170
- defaultFields?: Record<string, unknown>;
156
+ controls?: ControlConfig[];
157
+ styleControls?: StyleControlConfig[];
158
+ inspectorSections?: BlockInspectorSection[];
159
+ readControls: (value: Record<string, unknown>) => Record<string, unknown>;
160
+ override?: boolean;
171
161
  defaultStyle?: EmailBlockStyle;
172
162
  /** Sample data used to render template HTML in the editor and preview. */
173
163
  defaultData?: Record<string, unknown>;
174
- /** Content is edited inline on the canvas and stored in fields.html. */
175
- inlineEdit?: boolean;
176
- render: (ctx: BlockRenderContext) => string;
164
+ /** 默认画布直接编辑的 richText 字段;由字段声明解析生成。 */
165
+ inlineControl?: string;
166
+ /** Optional React inspector for controls that need domain-specific editing UI. */
167
+ inspector?: ComponentType<PluginEditorProps>;
168
+ /** Optional React canvas for multi-region or interactive editing. */
169
+ canvas?: ComponentType<PluginEditorProps>;
170
+ renderEmail: (ctx: BlockRenderContext) => string;
177
171
  }
178
172
  interface Variable {
179
173
  /** 下拉展示并插入的变量,例如 `{{ store_name }}`。 */
@@ -184,6 +178,150 @@ interface Variable {
184
178
  value?: string;
185
179
  }
186
180
 
181
+ interface TemplateData {
182
+ [key: string]: unknown;
183
+ }
184
+ /** Resolves template HTML for the editor and preview while leaving stored source untouched. */
185
+ declare function renderTemplatePreview(html: string, defaultData?: TemplateData): string;
186
+
187
+ interface DocumentHtmlOptions {
188
+ resolveHtmlTemplates?: boolean;
189
+ variables?: Variable[];
190
+ templateData?: TemplateData;
191
+ }
192
+ declare function documentToHtml(document: EmailDocument, definitions?: readonly BlockDefinition[], options?: DocumentHtmlOptions): string;
193
+
194
+ declare const EMAIL_MARKUP: unique symbol;
195
+ interface EmailMarkup {
196
+ readonly [EMAIL_MARKUP]: true;
197
+ readonly html: string;
198
+ }
199
+ interface EmailImageOptions {
200
+ src: string;
201
+ alt?: string;
202
+ width?: string;
203
+ }
204
+ interface EmailButtonOptions {
205
+ href: string;
206
+ label: string;
207
+ }
208
+ interface EmailTools {
209
+ html: (strings: TemplateStringsArray, ...values: unknown[]) => EmailMarkup;
210
+ raw: (html: string) => EmailMarkup;
211
+ richText: (html: string) => EmailMarkup;
212
+ table: (rows: EmailMarkup[][]) => EmailMarkup;
213
+ image: (options: EmailImageOptions) => EmailMarkup;
214
+ button: (options: EmailButtonOptions) => EmailMarkup;
215
+ url: (value: string, image?: boolean) => string;
216
+ }
217
+
218
+ type ControlKind = "text" | "textarea" | "html" | "richText" | "url" | "image" | "number" | "color" | "select" | "boolean" | "list" | "custom";
219
+ interface ControlComponentProps<T = unknown> {
220
+ value: T;
221
+ onChange: (value: T) => void;
222
+ label: string;
223
+ body: EmailBodySettings;
224
+ variables: Variable[];
225
+ }
226
+ interface ControlOptions<T> {
227
+ label: string;
228
+ defaultValue?: T;
229
+ placeholder?: string;
230
+ options?: ControlOption[];
231
+ rows?: number;
232
+ min?: number;
233
+ max?: number;
234
+ step?: number;
235
+ unit?: string;
236
+ profile?: RichTextProfile;
237
+ /** 由默认画布直接编辑此字段;多区域布局使用 Canvas + EditableRichText。 */
238
+ inline?: boolean;
239
+ component?: ComponentType<ControlComponentProps<T>>;
240
+ validate?: (value: T) => string | undefined;
241
+ }
242
+ /** 工厂生成的字段,同时负责默认值、运行时窄化和可选自定义控件。 */
243
+ interface ControlDefinition<T = unknown> extends Omit<ControlOptions<T>, "component" | "validate"> {
244
+ kind: ControlKind;
245
+ defaultValue: T;
246
+ read: (value: unknown) => T;
247
+ /** 只接收已归一化的字段值,不重复调用 read。 */
248
+ validateValue?: (value: unknown) => string | undefined;
249
+ /** value 已由宿主归一化。 */
250
+ renderControl?: (props: ControlComponentProps) => ReactNode;
251
+ itemControls?: ControlSchema;
252
+ }
253
+ type ControlSchema = Record<string, ControlDefinition>;
254
+ type ControlValues<Schema extends ControlSchema> = {
255
+ [Name in keyof Schema]: ReturnType<Schema[Name]["read"]>;
256
+ };
257
+ interface PluginEditorProps<Controls = Record<string, unknown>> {
258
+ block: EmailBlockNode;
259
+ controls: Controls;
260
+ style: EmailBlockStyle;
261
+ body: EmailBodySettings;
262
+ variables: Variable[];
263
+ selected: boolean;
264
+ renderedHtml: string;
265
+ select: () => void;
266
+ setControl: <Name extends keyof Controls & string>(name: Name, value: Controls[Name]) => void;
267
+ setControls: (patch: Partial<Controls>) => void;
268
+ setStyle: (id: string, value: string) => void;
269
+ }
270
+ interface PluginRenderContext<Controls> extends Omit<BlockRenderContext, "controls"> {
271
+ controls: Controls;
272
+ email: EmailTools;
273
+ }
274
+ interface BlockPluginOptions<Schema extends ControlSchema, Type extends string> {
275
+ type: Type;
276
+ title: string;
277
+ icon?: ReactNode | string;
278
+ description?: string;
279
+ override?: boolean;
280
+ controls?: Schema;
281
+ /** 默认 spacing + appearance;false 禁用默认容器控件。 */
282
+ containerStyles?: boolean | {
283
+ spacing?: boolean;
284
+ appearance?: boolean;
285
+ };
286
+ styleControls?: StyleControlConfig[];
287
+ inspectorSections?: BlockInspectorSection[];
288
+ defaultStyle?: EmailBlockStyle;
289
+ defaultData?: Record<string, unknown>;
290
+ Canvas?: ComponentType<PluginEditorProps<ControlValues<Schema>>>;
291
+ Inspector?: ComponentType<PluginEditorProps<ControlValues<Schema>>>;
292
+ renderEmail: (ctx: PluginRenderContext<ControlValues<Schema>>) => string | EmailMarkup;
293
+ }
294
+ /** 只通过 defineBlock 创建;配置同时用于编辑、节点创建和邮件导出。 */
295
+ interface BlockPlugin<Schema extends ControlSchema = ControlSchema, Type extends string = string> extends BlockDefinition {
296
+ type: Type;
297
+ schema: Schema;
298
+ }
299
+ interface ImagePickerContext {
300
+ value: string;
301
+ label: string;
302
+ signal: AbortSignal;
303
+ }
304
+ interface ValidationIssue {
305
+ blockId: string;
306
+ blockType: string;
307
+ controlPath: string;
308
+ message: string;
309
+ }
310
+ interface EmailEditorConfigOptions {
311
+ plugins?: BlockPlugin[];
312
+ /** false 隐藏全部内置区块;数组声明显示顺序。隐藏不影响已有节点渲染。 */
313
+ builtins?: false | string[];
314
+ pickImage?: (context: ImagePickerContext) => Promise<string | null>;
315
+ }
316
+ interface EmailEditorConfig {
317
+ readonly definitions: readonly BlockPlugin[];
318
+ readonly library: readonly BlockPlugin[];
319
+ readonly pickImage?: EmailEditorConfigOptions["pickImage"];
320
+ createBlock: (type: string) => EmailBlockNode;
321
+ toHtml: (document: EmailDocument, options?: DocumentHtmlOptions) => string;
322
+ validate: (document: EmailDocument) => ValidationIssue[];
323
+ }
324
+
187
325
  interface EmailEditorData {
188
326
  document: EmailDocument;
189
327
  json: string;
@@ -199,13 +337,13 @@ interface EmailEditorHandle {
199
337
  }
200
338
  interface EmailEditorProps {
201
339
  initialDocument?: EmailDocument;
202
- /** External global settings. Incoming changes are applied to the open document. */
203
- global?: Partial<EmailGlobalSettings>;
204
- blocks?: BlockDefinition[];
340
+ /** External body settings. Incoming changes are applied to the open document. */
341
+ body?: Partial<EmailBodySettings>;
342
+ config?: EmailEditorConfig;
205
343
  variables?: Variable[];
206
344
  height?: number | string;
207
345
  onChange?: (document: EmailDocument) => void;
208
- onGlobalChange?: (global: EmailGlobalSettings) => void;
346
+ onBodyChange?: (body: EmailBodySettings) => void;
209
347
  }
210
348
 
211
349
  declare const EmailEditor: react.ForwardRefExoticComponent<EmailEditorProps & react.RefAttributes<EmailEditorHandle>>;
@@ -217,91 +355,83 @@ interface RichTextInheritedStyle {
217
355
  fontWeight: FontWeight;
218
356
  lineHeight: string;
219
357
  paragraphSpacing: string;
358
+ listSpacing?: string;
359
+ listIndent?: string;
360
+ linkColor?: string;
361
+ linkDecoration?: string;
220
362
  }
221
363
 
222
364
  interface RichTextProps {
223
365
  initialHtml: string;
366
+ profile?: RichTextProfile;
224
367
  placeholder?: string;
225
368
  variables: Variable[];
226
369
  selected: boolean;
370
+ toolbarId: string;
371
+ toolbarCollapsed: boolean;
227
372
  inherited?: RichTextInheritedStyle;
228
373
  onCommit: (html: string) => void;
229
374
  onSelect: () => void;
230
375
  }
231
- declare function RichText({ initialHtml, placeholder, variables, selected, inherited, onCommit, onSelect, }: RichTextProps): react.JSX.Element;
376
+ declare function RichText({ initialHtml, profile, placeholder, variables, selected, toolbarId, toolbarCollapsed, inherited, onCommit, onSelect, }: RichTextProps): react.JSX.Element;
232
377
 
233
- declare const DEFAULT_BLOCKS: BlockDefinition[];
378
+ declare const DEFAULT_BLOCKS: BlockPlugin[];
234
379
 
235
- declare function resolveEmailGlobal(global?: Partial<EmailGlobalSettings> | null): EmailGlobalSettings;
380
+ declare function resolveEmailBody(body?: Partial<EmailBodySettings> | null): EmailBodySettings;
236
381
  declare function createEmailDocument(blocks?: EmailBlockNode[]): EmailDocument;
237
382
 
238
- declare function createBlockNode(type: string, definitions?: BlockDefinition[]): EmailBlockNode | null;
383
+ declare function createBlockNode(type: string, definitions?: readonly BlockDefinition[]): EmailBlockNode | null;
239
384
 
240
- declare const DIMENSION_FIELDS: {
241
- padding: StyleFieldConfig;
242
- margin: StyleFieldConfig;
243
- height: StyleFieldConfig;
385
+ declare const DIMENSION_CONTROLS: {
386
+ padding: StyleControlConfig;
387
+ margin: StyleControlConfig;
388
+ height: StyleControlConfig;
244
389
  };
245
- declare const DECORATION_FIELDS: {
246
- backgroundColor: StyleFieldConfig;
247
- borderWidth: StyleFieldConfig;
248
- borderStyle: StyleFieldConfig;
249
- borderColor: StyleFieldConfig;
250
- borderRadius: StyleFieldConfig;
390
+ declare const DECORATION_CONTROLS: {
391
+ backgroundColor: StyleControlConfig;
392
+ borderWidth: StyleControlConfig;
393
+ borderStyle: StyleControlConfig;
394
+ borderColor: StyleControlConfig;
395
+ borderRadius: StyleControlConfig;
251
396
  };
252
- declare const TYPOGRAPHY_FIELD_MAP: {
253
- fontFamily: StyleFieldConfig;
254
- fontSize: StyleFieldConfig;
255
- fontWeight: StyleFieldConfig;
256
- lineHeight: StyleFieldConfig;
257
- color: StyleFieldConfig;
258
- textAlign: StyleFieldConfig;
259
- paragraphSpacing: StyleFieldConfig;
260
- listSpacing: StyleFieldConfig;
261
- listIndent: StyleFieldConfig;
262
- linkColor: StyleFieldConfig;
263
- linkDecoration: StyleFieldConfig;
397
+ declare const TYPOGRAPHY_CONTROL_MAP: {
398
+ fontFamily: StyleControlConfig;
399
+ fontSize: StyleControlConfig;
400
+ fontWeight: StyleControlConfig;
401
+ lineHeight: StyleControlConfig;
402
+ color: StyleControlConfig;
403
+ textAlign: StyleControlConfig;
404
+ paragraphSpacing: StyleControlConfig;
405
+ listSpacing: StyleControlConfig;
406
+ listIndent: StyleControlConfig;
407
+ linkColor: StyleControlConfig;
408
+ linkDecoration: StyleControlConfig;
264
409
  };
265
- type DimensionFieldName = keyof typeof DIMENSION_FIELDS;
266
- type DecorationFieldName = keyof typeof DECORATION_FIELDS;
267
- type TypographyFieldName = keyof typeof TYPOGRAPHY_FIELD_MAP;
268
- type StyleFieldOverrideMap<Name extends string> = Partial<Record<Name, Partial<StyleFieldConfig>>>;
269
- declare function createDimensionFields(overrides?: StyleFieldOverrideMap<DimensionFieldName>): Record<DimensionFieldName, StyleFieldConfig>;
270
- declare function createDecorationFields(overrides?: StyleFieldOverrideMap<DecorationFieldName>): Record<DecorationFieldName, StyleFieldConfig>;
271
- declare function createTypographyFields(overrides?: StyleFieldOverrideMap<TypographyFieldName>): Record<TypographyFieldName, StyleFieldConfig>;
272
- /** 容器字段按固定槽位合并。相同 id 使用调用方字段,其余字段按原顺序接在后面。返回值都是副本。 */
273
- declare function resolveBlockStyleFields(fields?: StyleFieldConfig[], exactStyleFields?: boolean): StyleFieldConfig[];
274
-
275
- interface TemplateData {
276
- [key: string]: unknown;
277
- }
278
- /** Resolves template HTML for the editor and preview while leaving stored source untouched. */
279
- declare function renderTemplatePreview(html: string, defaultData?: TemplateData): string;
280
-
281
- interface DocumentHtmlOptions {
282
- resolveHtmlTemplates?: boolean;
283
- variables?: Variable[];
284
- templateData?: TemplateData;
285
- }
286
- declare function documentToHtml(document: EmailDocument, definitions?: BlockDefinition[], options?: DocumentHtmlOptions): string;
410
+ type DimensionControlName = keyof typeof DIMENSION_CONTROLS;
411
+ type DecorationControlName = keyof typeof DECORATION_CONTROLS;
412
+ type TypographyControlName = keyof typeof TYPOGRAPHY_CONTROL_MAP;
413
+ type StyleControlOverrideMap<Name extends string> = Partial<Record<Name, Partial<StyleControlConfig>>>;
414
+ declare function createDimensionControls(overrides?: StyleControlOverrideMap<DimensionControlName>): Record<DimensionControlName, StyleControlConfig>;
415
+ declare function createDecorationControls(overrides?: StyleControlOverrideMap<DecorationControlName>): Record<DecorationControlName, StyleControlConfig>;
416
+ declare function createTypographyControls(overrides?: StyleControlOverrideMap<TypographyControlName>): Record<TypographyControlName, StyleControlConfig>;
287
417
 
288
418
  interface BlockRenderOptions {
289
419
  resolveHtmlTemplate?: boolean;
290
420
  templateData?: TemplateData;
291
421
  variables?: Variable[];
292
- global?: EmailGlobalSettings;
422
+ body?: EmailBodySettings;
293
423
  }
294
424
  type BlockRenderOptionsInput = BlockRenderOptions | boolean;
295
425
  /** 用变量 name 里的字段名作为键,value 作为预览替换值。 */
296
426
  declare function variablesToTemplateData(variables: Variable[]): TemplateData;
297
427
  declare function mergeTemplateData(variables: Variable[], defaultData?: TemplateData): TemplateData | undefined;
298
- declare function renderBlockContent(node: EmailBlockNode, definitions?: BlockDefinition[], mode?: RenderMode, options?: BlockRenderOptionsInput): string;
299
- declare function renderBlock(node: EmailBlockNode, definitions?: BlockDefinition[], mode?: RenderMode, global?: EmailGlobalSettings): string;
300
- declare function blockToHtml(node: EmailBlockNode, definitions?: BlockDefinition[], mode?: RenderMode, options?: BlockRenderOptionsInput): string;
428
+ declare function renderBlockContent(node: EmailBlockNode, definitions?: readonly BlockDefinition[], mode?: RenderMode, options?: BlockRenderOptionsInput): string;
429
+ 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;
301
431
 
302
- declare function buildRenderContext(node: EmailBlockNode, mode: RenderMode, global?: EmailGlobalSettings): BlockRenderContext;
432
+ declare function buildRenderContext(node: EmailBlockNode, mode: RenderMode, body?: EmailBodySettings, definition?: BlockDefinition | undefined): BlockRenderContext;
303
433
 
304
- declare function getBlockDefinition(type: string, definitions?: BlockDefinition[]): BlockDefinition | undefined;
434
+ declare function getBlockDefinition(type: string, definitions?: readonly BlockDefinition[]): BlockDefinition | undefined;
305
435
 
306
436
  declare function generateId(prefix?: string): string;
307
437
 
@@ -322,4 +452,95 @@ declare const BLOCK_TYPES: {
322
452
  };
323
453
  type BuiltinBlockType = (typeof BLOCK_TYPES)[keyof typeof BLOCK_TYPES];
324
454
 
325
- export { BLOCK_TYPES, BORDER_STYLES, type BlockDefinition, type BlockRenderContext, type BlockRenderOptions, type BorderStyle, type BuiltinBlockType, DEFAULT_BLOCKS, DEFAULT_EMAIL_GLOBAL, DOCUMENT_VERSION, type DecorationFieldName, type DimensionFieldName, type DocumentHtmlOptions, type EmailBlockNode, type EmailBlockStyle, type EmailDecorationStyle, type EmailDocument, EmailEditor, type EmailEditorData, type EmailEditorHandle, type EmailEditorProps, type EmailElementStyle, type EmailGlobalSettings, type EmailSpacingStyle, type EmailTypographyStyle, FONT_FAMILIES, FONT_WEIGHTS, type FieldConfig, type FieldType, type FontWeight, HORIZONTAL_ALIGNS, type HorizontalAlign, LINK_DECORATIONS, type LinkDecoration, type RenderMode, RichText, STYLE_GROUPS, type StyleControlType, type StyleFieldConfig, type StyleGroup, TEXT_ALIGNS, type TemplateData, type TextAlign, type TypographyFieldName, type Variable, blockToHtml, buildRenderContext, createBlockNode, createDecorationFields, createDimensionFields, createEmailDocument, createTypographyFields, documentToHtml, generateId, getBlockDefinition, mergeTemplateData, renderBlock, renderBlockContent, renderTemplatePreview, resolveBlockStyleFields, resolveEmailGlobal, variablesToTemplateData };
455
+ declare function defineBlock<Schema extends ControlSchema, const Type extends string>(input: BlockPluginOptions<Schema, Type>): BlockPlugin<Schema, Type>;
456
+
457
+ declare const EmailControls: {
458
+ text: (options: ControlOptions<string>) => ControlDefinition<string>;
459
+ textarea: (options: ControlOptions<string>) => ControlDefinition<string>;
460
+ richText: (options: ControlOptions<string>) => ControlDefinition<string>;
461
+ html: (options: ControlOptions<string>) => ControlDefinition<string>;
462
+ url: (options: ControlOptions<string>) => ControlDefinition<string>;
463
+ image: (options: ControlOptions<string>) => ControlDefinition<string>;
464
+ color: (options: ControlOptions<string>) => ControlDefinition<string>;
465
+ select: (options: ControlOptions<string>) => ControlDefinition<string>;
466
+ boolean: (options: ControlOptions<boolean>) => ControlDefinition<boolean>;
467
+ number: (options: ControlOptions<number>) => ControlDefinition<number>;
468
+ list<Schema extends ControlSchema>(options: ControlOptions<ControlValues<Schema>[]> & {
469
+ controls: Schema;
470
+ }): ControlDefinition<ControlValues<Schema>[]>;
471
+ custom<T>(options: ControlOptions<T> & {
472
+ defaultValue: T;
473
+ read: (value: unknown) => T;
474
+ component: NonNullable<ControlOptions<T>["component"]>;
475
+ }): ControlDefinition<T>;
476
+ };
477
+
478
+ declare function createEmailEditorConfig(options?: EmailEditorConfigOptions): EmailEditorConfig;
479
+
480
+ interface EditableRichTextProps {
481
+ control: string;
482
+ profile?: RichTextProfile;
483
+ placeholder?: string;
484
+ }
485
+ declare function EditableRichText({ control, profile, placeholder }: EditableRichTextProps): react.JSX.Element;
486
+
487
+ interface TextInputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "type"> {
488
+ type?: "text" | "url" | "email" | "search" | "tel" | "password" | "number";
489
+ }
490
+ declare const TextInput: react.ForwardRefExoticComponent<TextInputProps & react.RefAttributes<HTMLInputElement>>;
491
+
492
+ interface SelectControlProps {
493
+ id?: string;
494
+ label?: string;
495
+ value: string;
496
+ options: readonly ControlOption[];
497
+ emptyLabel?: string;
498
+ compact?: boolean;
499
+ disabled?: boolean;
500
+ onChange: (value: string) => void;
501
+ }
502
+ declare function SelectControl({ id, label, value, options, emptyLabel, compact, disabled, onChange }: SelectControlProps): react.JSX.Element;
503
+
504
+ interface CheckboxControlProps {
505
+ label: string;
506
+ checked: boolean;
507
+ disabled?: boolean;
508
+ className?: string;
509
+ variant?: "checkbox" | "switch";
510
+ onChange: (checked: boolean) => void;
511
+ }
512
+ declare function CheckboxControl({ label, checked, disabled, className, variant, onChange }: CheckboxControlProps): react.JSX.Element;
513
+
514
+ interface ColorControlProps {
515
+ value: string;
516
+ fallback?: string;
517
+ label?: string;
518
+ resetTo?: string;
519
+ onChange: (value: string) => void;
520
+ }
521
+ declare function ColorControl({ value, fallback, label, resetTo, onChange }: ColorControlProps): react.JSX.Element;
522
+
523
+ interface RangeControlProps {
524
+ id?: string;
525
+ label?: string;
526
+ value: number;
527
+ min?: number;
528
+ max?: number;
529
+ step?: number;
530
+ onChange: (value: number) => void;
531
+ }
532
+ declare function RangeControl({ id, label, value, min, max, step, onChange, }: RangeControlProps): react.JSX.Element;
533
+
534
+ interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
535
+ variant?: "default" | "primary" | "solid" | "icon";
536
+ tooltip?: string;
537
+ }
538
+ declare function Button({ type, variant, className, tooltip, children, "aria-describedby": describedBy, ...props }: ButtonProps): react.JSX.Element;
539
+
540
+ interface ControlEditorProps {
541
+ control: string;
542
+ }
543
+ /** 自定义 Inspector 复用字段声明、资源选择器、校验和标准控件。 */
544
+ declare function ControlEditor({ control }: ControlEditorProps): react.JSX.Element;
545
+
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 };