@standhigher/react-email-editor 0.0.0-stage → 0.1.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.
@@ -0,0 +1,325 @@
1
+ import * as react from 'react';
2
+ import { ReactNode } from 'react';
3
+
4
+ declare const TEXT_ALIGNS: {
5
+ readonly left: "left";
6
+ readonly center: "center";
7
+ readonly right: "right";
8
+ readonly justify: "justify";
9
+ };
10
+ type TextAlign = (typeof TEXT_ALIGNS)[keyof typeof TEXT_ALIGNS];
11
+ declare const HORIZONTAL_ALIGNS: {
12
+ readonly left: "left";
13
+ readonly center: "center";
14
+ readonly right: "right";
15
+ };
16
+ type HorizontalAlign = (typeof HORIZONTAL_ALIGNS)[keyof typeof HORIZONTAL_ALIGNS];
17
+ declare const FONT_WEIGHTS: {
18
+ readonly normal: "normal";
19
+ readonly bold: "bold";
20
+ };
21
+ type FontWeight = (typeof FONT_WEIGHTS)[keyof typeof FONT_WEIGHTS];
22
+ declare const BORDER_STYLES: {
23
+ readonly none: "none";
24
+ readonly solid: "solid";
25
+ readonly dashed: "dashed";
26
+ readonly dotted: "dotted";
27
+ };
28
+ type BorderStyle = (typeof BORDER_STYLES)[keyof typeof BORDER_STYLES];
29
+ declare const LINK_DECORATIONS: {
30
+ readonly underline: "underline";
31
+ readonly none: "none";
32
+ };
33
+ type LinkDecoration = (typeof LINK_DECORATIONS)[keyof typeof LINK_DECORATIONS];
34
+
35
+ declare const DOCUMENT_VERSION: 1;
36
+ declare const FONT_FAMILIES: readonly FieldOption[];
37
+ declare const DEFAULT_EMAIL_GLOBAL: EmailGlobalSettings;
38
+
39
+ interface EmailGlobalSettings {
40
+ textColor: string;
41
+ textAlign: TextAlign;
42
+ backgroundColor: string;
43
+ contentWidth: number;
44
+ contentAlign: HorizontalAlign;
45
+ fontFamily: string;
46
+ 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
+ linkColor: string;
57
+ linkDecoration: LinkDecoration;
58
+ borderWidth: string;
59
+ borderStyle: BorderStyle;
60
+ borderColor: string;
61
+ borderRadius: string;
62
+ }
63
+ interface EmailDocument {
64
+ version: typeof DOCUMENT_VERSION;
65
+ subject?: string;
66
+ global: EmailGlobalSettings;
67
+ blocks: EmailBlockNode[];
68
+ }
69
+ interface EmailBlockNode {
70
+ id: string;
71
+ type: string;
72
+ fields: Record<string, unknown>;
73
+ style?: EmailBlockStyle;
74
+ defaultData?: Record<string, unknown>;
75
+ }
76
+ interface EmailDecorationStyle {
77
+ backgroundColor?: string;
78
+ borderRadius?: string;
79
+ borderWidth?: string;
80
+ borderColor?: string;
81
+ borderStyle?: BorderStyle;
82
+ }
83
+ interface EmailTypographyStyle {
84
+ fontFamily?: string;
85
+ fontSize?: string;
86
+ fontWeight?: FontWeight;
87
+ lineHeight?: string;
88
+ color?: string;
89
+ textAlign?: TextAlign;
90
+ paragraphSpacing?: string;
91
+ listSpacing?: string;
92
+ listIndent?: string;
93
+ linkColor?: string;
94
+ linkDecoration?: LinkDecoration;
95
+ }
96
+ /** 按钮、图片和分割线自身的样式,与区块容器样式独立。 */
97
+ interface EmailElementStyle extends EmailDecorationStyle, EmailTypographyStyle {
98
+ padding?: string;
99
+ width?: string;
100
+ height?: string;
101
+ align?: HorizontalAlign;
102
+ }
103
+ interface EmailSpacingStyle {
104
+ padding?: string;
105
+ margin?: string;
106
+ /** 内层单元格高度,只使用 px。缺省时不输出 height。 */
107
+ height?: string;
108
+ }
109
+ interface EmailBlockStyle {
110
+ dimension?: EmailSpacingStyle;
111
+ typography?: EmailTypographyStyle;
112
+ decorations?: EmailDecorationStyle;
113
+ element?: EmailElementStyle;
114
+ }
115
+
116
+ type FieldType = "text" | "textarea" | "html" | "url" | "number" | "color" | "select";
117
+ interface FieldOption {
118
+ label: string;
119
+ value: string;
120
+ }
121
+ interface FieldConfig {
122
+ type: FieldType;
123
+ 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
+ }
133
+ type StyleGroup = "general" | "dimension" | "typography" | "decorations";
134
+ type StyleControlType = "text" | "color" | "alignment" | "select" | "number" | "range" | "spacing" | "corners";
135
+ interface StyleFieldConfig {
136
+ /** e.g. "typography.fontSize" — which style slot this reads and writes */
137
+ id: string;
138
+ group: StyleGroup;
139
+ label: string;
140
+ control: StyleControlType;
141
+ options?: FieldOption[];
142
+ /** Unit suffix for a single-unit slider, e.g. "px". Omit for unitless values. */
143
+ unit?: string;
144
+ /** Email-safe units. A select appears only when more than one is listed. */
145
+ units?: string[];
146
+ min?: number;
147
+ max?: number;
148
+ step?: number;
149
+ defaultValue?: string;
150
+ placeholder?: string;
151
+ }
152
+ type RenderMode = "canvas" | "email";
153
+ interface BlockRenderContext {
154
+ block: EmailBlockNode;
155
+ fields: Record<string, unknown>;
156
+ style: EmailBlockStyle;
157
+ /** canvas/email identify the consumer; HTML template resolution is applied by the shared renderer. */
158
+ mode: RenderMode;
159
+ global: EmailGlobalSettings;
160
+ }
161
+ interface BlockDefinition {
162
+ type: string;
163
+ title: string;
164
+ icon?: ReactNode | string;
165
+ description?: string;
166
+ fields?: FieldConfig[];
167
+ styleFields?: StyleFieldConfig[];
168
+ /** getBlockDefinition 只保留 styleFields,不补容器间距和装饰。 */
169
+ exactStyleFields?: boolean;
170
+ defaultFields?: Record<string, unknown>;
171
+ defaultStyle?: EmailBlockStyle;
172
+ /** Sample data used to render template HTML in the editor and preview. */
173
+ 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;
177
+ }
178
+ interface Variable {
179
+ /** 下拉展示并插入的变量,例如 `{{ store_name }}`。 */
180
+ name: string;
181
+ /** 下拉选项副文案。空字符串或不传时不渲染。 */
182
+ description?: string;
183
+ /** 预览时替换该变量的文本。 */
184
+ value?: string;
185
+ }
186
+
187
+ interface EmailEditorData {
188
+ document: EmailDocument;
189
+ json: string;
190
+ html: string;
191
+ renderedHtml: string;
192
+ }
193
+ interface EmailEditorHandle {
194
+ getData: () => EmailEditorData;
195
+ getDocument: () => EmailDocument;
196
+ getJson: () => string;
197
+ getHtml: () => string;
198
+ getRenderedHtml: () => string;
199
+ }
200
+ interface EmailEditorProps {
201
+ initialDocument?: EmailDocument;
202
+ /** External global settings. Incoming changes are applied to the open document. */
203
+ global?: Partial<EmailGlobalSettings>;
204
+ blocks?: BlockDefinition[];
205
+ variables?: Variable[];
206
+ height?: number | string;
207
+ onChange?: (document: EmailDocument) => void;
208
+ onGlobalChange?: (global: EmailGlobalSettings) => void;
209
+ }
210
+
211
+ declare const EmailEditor: react.ForwardRefExoticComponent<EmailEditorProps & react.RefAttributes<EmailEditorHandle>>;
212
+
213
+ interface RichTextInheritedStyle {
214
+ fontFamily: string;
215
+ fontSize: string;
216
+ color: string;
217
+ fontWeight: FontWeight;
218
+ lineHeight: string;
219
+ paragraphSpacing: string;
220
+ }
221
+
222
+ interface RichTextProps {
223
+ initialHtml: string;
224
+ placeholder?: string;
225
+ variables: Variable[];
226
+ selected: boolean;
227
+ inherited?: RichTextInheritedStyle;
228
+ onCommit: (html: string) => void;
229
+ onSelect: () => void;
230
+ }
231
+ declare function RichText({ initialHtml, placeholder, variables, selected, inherited, onCommit, onSelect, }: RichTextProps): react.JSX.Element;
232
+
233
+ declare const DEFAULT_BLOCKS: BlockDefinition[];
234
+
235
+ declare function resolveEmailGlobal(global?: Partial<EmailGlobalSettings> | null): EmailGlobalSettings;
236
+ declare function createEmailDocument(blocks?: EmailBlockNode[]): EmailDocument;
237
+
238
+ declare function createBlockNode(type: string, definitions?: BlockDefinition[]): EmailBlockNode | null;
239
+
240
+ declare const DIMENSION_FIELDS: {
241
+ padding: StyleFieldConfig;
242
+ margin: StyleFieldConfig;
243
+ height: StyleFieldConfig;
244
+ };
245
+ declare const DECORATION_FIELDS: {
246
+ backgroundColor: StyleFieldConfig;
247
+ borderWidth: StyleFieldConfig;
248
+ borderStyle: StyleFieldConfig;
249
+ borderColor: StyleFieldConfig;
250
+ borderRadius: StyleFieldConfig;
251
+ };
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;
264
+ };
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;
287
+
288
+ interface BlockRenderOptions {
289
+ resolveHtmlTemplate?: boolean;
290
+ templateData?: TemplateData;
291
+ variables?: Variable[];
292
+ global?: EmailGlobalSettings;
293
+ }
294
+ type BlockRenderOptionsInput = BlockRenderOptions | boolean;
295
+ /** 用变量 name 里的字段名作为键,value 作为预览替换值。 */
296
+ declare function variablesToTemplateData(variables: Variable[]): TemplateData;
297
+ 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;
301
+
302
+ declare function buildRenderContext(node: EmailBlockNode, mode: RenderMode, global?: EmailGlobalSettings): BlockRenderContext;
303
+
304
+ declare function getBlockDefinition(type: string, definitions?: BlockDefinition[]): BlockDefinition | undefined;
305
+
306
+ declare function generateId(prefix?: string): string;
307
+
308
+ interface StyleGroupOption {
309
+ group: StyleGroup;
310
+ label: string;
311
+ }
312
+ declare const STYLE_GROUPS: StyleGroupOption[];
313
+
314
+ declare const BLOCK_TYPES: {
315
+ readonly heading: "heading";
316
+ readonly text: "text";
317
+ readonly button: "button";
318
+ readonly image: "image";
319
+ readonly divider: "divider";
320
+ readonly spacer: "spacer";
321
+ readonly html: "html";
322
+ };
323
+ type BuiltinBlockType = (typeof BLOCK_TYPES)[keyof typeof BLOCK_TYPES];
324
+
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 };