react-tailwind-email-editor 0.0.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.
@@ -0,0 +1,694 @@
1
+ import React from 'react';
2
+ import { LucideIcon } from 'lucide-react';
3
+ import * as react_jsx_runtime from 'react/jsx-runtime';
4
+ import { SerializedNodes } from '@craftjs/core';
5
+
6
+ interface EditorComponentConfig {
7
+ /** The React component to render in the editor canvas */
8
+ component: React.ComponentType<any>;
9
+ /** Display name in the toolbox */
10
+ label: string;
11
+ /** Short description shown below the label */
12
+ description?: string;
13
+ /** Lucide icon or custom icon component */
14
+ icon?: LucideIcon | React.ComponentType<{
15
+ className?: string;
16
+ }>;
17
+ /** Category grouping in the toolbox */
18
+ category?: string;
19
+ /** Default element to create when dragged (JSX element). If not provided, creates <Component /> */
20
+ createElement?: () => React.ReactElement;
21
+ }
22
+ type ComponentRegistry = Record<string, EditorComponentConfig>;
23
+ interface EditorThemeColors {
24
+ /** Primary accent color */
25
+ primary?: string;
26
+ /** Primary foreground (text on primary) */
27
+ primaryForeground?: string;
28
+ /** Background color of sidebars and panels */
29
+ panelBackground?: string;
30
+ /** Canvas/workspace background */
31
+ canvasBackground?: string;
32
+ /** Border color for panels and components */
33
+ border?: string;
34
+ /** Muted background for inactive elements */
35
+ muted?: string;
36
+ /** Text color for muted/secondary text */
37
+ mutedForeground?: string;
38
+ /** Destructive/delete action color */
39
+ destructive?: string;
40
+ /** Foreground/text color */
41
+ foreground?: string;
42
+ /** Background color */
43
+ background?: string;
44
+ }
45
+ interface EditorTheme {
46
+ /** Custom color overrides */
47
+ colors?: EditorThemeColors;
48
+ /** Border radius for UI elements */
49
+ borderRadius?: number;
50
+ /** Font family for editor UI */
51
+ fontFamily?: string;
52
+ /** Paper/canvas width in pixels */
53
+ paperWidth?: number;
54
+ /** Paper minimum height in pixels */
55
+ paperMinHeight?: number;
56
+ /** Paper default background */
57
+ paperBackground?: string;
58
+ }
59
+ interface EditorSlots {
60
+ /** Custom toolbar component (replaces the entire top bar) */
61
+ toolbar?: React.ComponentType<ToolbarSlotProps>;
62
+ /** Custom toolbox/sidebar component */
63
+ toolbox?: React.ComponentType<ToolboxSlotProps>;
64
+ /** Custom settings panel component */
65
+ settingsPanel?: React.ComponentType<SettingsPanelSlotProps>;
66
+ /** Custom empty state for settings panel when nothing is selected */
67
+ settingsEmptyState?: React.ComponentType;
68
+ /** Custom render node wrapper */
69
+ renderNode?: React.ComponentType<{
70
+ render: React.ReactNode;
71
+ }>;
72
+ /** Custom export dialog content */
73
+ exportDialog?: React.ComponentType<ExportDialogSlotProps>;
74
+ /** Custom preview dialog content */
75
+ previewDialog?: React.ComponentType<PreviewDialogSlotProps>;
76
+ }
77
+ interface ToolbarSlotProps {
78
+ onExport: () => string;
79
+ onPreview: () => string;
80
+ onClear: () => void;
81
+ title?: string;
82
+ logo?: React.ReactNode;
83
+ }
84
+ interface ToolboxSlotProps {
85
+ components: ComponentRegistry;
86
+ categories: string[];
87
+ }
88
+ interface SettingsPanelSlotProps {
89
+ selectedId?: string;
90
+ selectedName?: string;
91
+ selectedSettings?: React.ComponentType;
92
+ onDelete?: () => void;
93
+ onDuplicate?: () => void;
94
+ onMoveUp?: () => void;
95
+ onMoveDown?: () => void;
96
+ }
97
+ interface ExportDialogSlotProps {
98
+ html: string;
99
+ onClose: () => void;
100
+ }
101
+ interface PreviewDialogSlotProps {
102
+ html: string;
103
+ onClose: () => void;
104
+ }
105
+ interface EmailTemplate {
106
+ /** Unique template identifier */
107
+ id: string;
108
+ /** Display name */
109
+ name: string;
110
+ /** Template description */
111
+ description?: string;
112
+ /** Lucide icon */
113
+ icon?: LucideIcon;
114
+ /** Serialized Craft.js JSON state */
115
+ data: string;
116
+ }
117
+ interface EditorCallbacks {
118
+ /** Called when HTML is exported */
119
+ onExport?: (html: string) => void;
120
+ /** Called when the editor state changes */
121
+ onChange?: (serializedState: string) => void;
122
+ /** Called when a template is loaded */
123
+ onTemplateLoad?: (templateId: string) => void;
124
+ /** Called when canvas is cleared */
125
+ onClear?: () => void;
126
+ }
127
+ type HtmlRenderer = (typeName: string, props: Record<string, unknown>, childrenHtml: string, linkedNodes?: Record<string, string>) => string | null;
128
+ interface EmailEditorProps {
129
+ /** Additional components to register (merged with built-ins) */
130
+ components?: ComponentRegistry;
131
+ /** Replace ALL built-in components (use only your own) */
132
+ replaceBuiltins?: boolean;
133
+ /** Theme customization */
134
+ theme?: EditorTheme;
135
+ /** Slot overrides for UI sections */
136
+ slots?: EditorSlots;
137
+ /** Pre-defined templates */
138
+ templates?: EmailTemplate[];
139
+ /** Event callbacks */
140
+ callbacks?: EditorCallbacks;
141
+ /** Initial serialized state to load */
142
+ initialState?: string;
143
+ /** Default content to show (JSX children for the Frame) */
144
+ defaultContent?: React.ReactNode;
145
+ /** Editor title displayed in the toolbar */
146
+ title?: string;
147
+ /** Logo element for the toolbar */
148
+ logo?: React.ReactNode;
149
+ /** Custom HTML renderers for export (keyed by component resolved name) */
150
+ htmlRenderers?: Record<string, HtmlRenderer>;
151
+ /** Whether to show the toolbar */
152
+ showToolbar?: boolean;
153
+ /** Whether to show the left toolbox sidebar */
154
+ showToolbox?: boolean;
155
+ /** Whether to show the right settings panel */
156
+ showSettingsPanel?: boolean;
157
+ /** Custom class name for the editor root */
158
+ className?: string;
159
+ /** Custom inline styles for the editor root */
160
+ style?: React.CSSProperties;
161
+ }
162
+
163
+ declare const EmailEditor: React.FC<EmailEditorProps>;
164
+
165
+ interface EditorContextValue {
166
+ components: ComponentRegistry;
167
+ theme: EditorTheme;
168
+ slots: EditorSlots;
169
+ templates: EmailTemplate[];
170
+ callbacks: EditorCallbacks;
171
+ htmlRenderers: Record<string, HtmlRenderer>;
172
+ title: string;
173
+ logo?: React.ReactNode;
174
+ showToolbar: boolean;
175
+ showToolbox: boolean;
176
+ showSettingsPanel: boolean;
177
+ }
178
+ declare const useEditorConfig: () => EditorContextValue;
179
+ interface EditorProviderProps {
180
+ children: React.ReactNode;
181
+ value: Omit<EditorContextValue, 'theme'> & {
182
+ theme: EditorTheme;
183
+ };
184
+ }
185
+ declare const EditorProvider: React.FC<EditorProviderProps>;
186
+
187
+ interface ContainerProps {
188
+ background?: string;
189
+ padding?: number;
190
+ children?: React.ReactNode;
191
+ }
192
+ declare const Container: {
193
+ ({ background, padding, children }: ContainerProps): react_jsx_runtime.JSX.Element;
194
+ craft: {
195
+ props: {
196
+ background: string;
197
+ padding: number;
198
+ };
199
+ related: {
200
+ settings: () => react_jsx_runtime.JSX.Element;
201
+ };
202
+ };
203
+ };
204
+
205
+ interface EmailHeaderProps {
206
+ logoUrl?: string;
207
+ companyName?: string;
208
+ backgroundColor?: string;
209
+ textColor?: string;
210
+ padding?: number;
211
+ }
212
+ declare const EmailHeader: {
213
+ ({ logoUrl, companyName, backgroundColor, textColor, padding, }: EmailHeaderProps): react_jsx_runtime.JSX.Element;
214
+ craft: {
215
+ props: {
216
+ logoUrl: string;
217
+ companyName: string;
218
+ backgroundColor: string;
219
+ textColor: string;
220
+ padding: number;
221
+ };
222
+ related: {
223
+ settings: () => react_jsx_runtime.JSX.Element;
224
+ };
225
+ };
226
+ };
227
+
228
+ interface EmailFooterProps {
229
+ companyName?: string;
230
+ address?: string;
231
+ email?: string;
232
+ phone?: string;
233
+ backgroundColor?: string;
234
+ textColor?: string;
235
+ padding?: number;
236
+ }
237
+ declare const EmailFooter: {
238
+ ({ companyName, address, email, phone, backgroundColor, textColor, padding, }: EmailFooterProps): react_jsx_runtime.JSX.Element;
239
+ craft: {
240
+ props: {
241
+ companyName: string;
242
+ address: string;
243
+ email: string;
244
+ phone: string;
245
+ backgroundColor: string;
246
+ textColor: string;
247
+ padding: number;
248
+ };
249
+ related: {
250
+ settings: () => react_jsx_runtime.JSX.Element;
251
+ };
252
+ };
253
+ };
254
+
255
+ interface EmailButtonProps {
256
+ text?: string;
257
+ href?: string;
258
+ backgroundColor?: string;
259
+ textColor?: string;
260
+ borderRadius?: number;
261
+ paddingX?: number;
262
+ paddingY?: number;
263
+ fontSize?: number;
264
+ align?: 'left' | 'center' | 'right';
265
+ }
266
+ declare const EmailButton: {
267
+ ({ text, href, backgroundColor, textColor, borderRadius, paddingX, paddingY, fontSize, align, }: EmailButtonProps): react_jsx_runtime.JSX.Element;
268
+ craft: {
269
+ props: {
270
+ text: string;
271
+ href: string;
272
+ backgroundColor: string;
273
+ textColor: string;
274
+ borderRadius: number;
275
+ paddingX: number;
276
+ paddingY: number;
277
+ fontSize: number;
278
+ align: string;
279
+ };
280
+ related: {
281
+ settings: () => react_jsx_runtime.JSX.Element;
282
+ };
283
+ };
284
+ };
285
+
286
+ interface TextBlockProps {
287
+ text?: string;
288
+ fontSize?: number;
289
+ fontWeight?: 'normal' | 'bold';
290
+ color?: string;
291
+ align?: 'left' | 'center' | 'right';
292
+ padding?: number;
293
+ lineHeight?: number;
294
+ }
295
+ declare const TextBlock: {
296
+ ({ text, fontSize, fontWeight, color, align, padding, lineHeight, }: TextBlockProps): react_jsx_runtime.JSX.Element;
297
+ craft: {
298
+ props: {
299
+ text: string;
300
+ fontSize: number;
301
+ fontWeight: string;
302
+ color: string;
303
+ align: string;
304
+ padding: number;
305
+ lineHeight: number;
306
+ };
307
+ related: {
308
+ settings: () => react_jsx_runtime.JSX.Element;
309
+ };
310
+ };
311
+ };
312
+
313
+ interface ImageBlockProps {
314
+ src?: string;
315
+ alt?: string;
316
+ width?: string;
317
+ align?: 'left' | 'center' | 'right';
318
+ padding?: number;
319
+ borderRadius?: number;
320
+ }
321
+ declare const ImageBlock: {
322
+ ({ src, alt, width, align, padding, borderRadius, }: ImageBlockProps): react_jsx_runtime.JSX.Element;
323
+ craft: {
324
+ props: {
325
+ src: string;
326
+ alt: string;
327
+ width: string;
328
+ align: string;
329
+ padding: number;
330
+ borderRadius: number;
331
+ };
332
+ related: {
333
+ settings: () => react_jsx_runtime.JSX.Element;
334
+ };
335
+ };
336
+ };
337
+
338
+ interface DividerProps {
339
+ color?: string;
340
+ thickness?: number;
341
+ margin?: number;
342
+ width?: string;
343
+ }
344
+ declare const Divider: {
345
+ ({ color, thickness, margin, width, }: DividerProps): react_jsx_runtime.JSX.Element;
346
+ craft: {
347
+ props: {
348
+ color: string;
349
+ thickness: number;
350
+ margin: number;
351
+ width: string;
352
+ };
353
+ related: {
354
+ settings: () => react_jsx_runtime.JSX.Element;
355
+ };
356
+ };
357
+ };
358
+
359
+ interface InvoiceItem {
360
+ description: string;
361
+ quantity: number;
362
+ unitPrice: number;
363
+ }
364
+ interface InvoiceTableProps {
365
+ items?: InvoiceItem[];
366
+ headerBg?: string;
367
+ headerColor?: string;
368
+ borderColor?: string;
369
+ showTotal?: boolean;
370
+ currency?: string;
371
+ }
372
+ declare const InvoiceTable: {
373
+ ({ items, headerBg, headerColor, borderColor, showTotal, currency, }: InvoiceTableProps): react_jsx_runtime.JSX.Element;
374
+ craft: {
375
+ props: {
376
+ items: {
377
+ description: string;
378
+ quantity: number;
379
+ unitPrice: number;
380
+ }[];
381
+ headerBg: string;
382
+ headerColor: string;
383
+ borderColor: string;
384
+ showTotal: boolean;
385
+ currency: string;
386
+ };
387
+ related: {
388
+ settings: () => react_jsx_runtime.JSX.Element;
389
+ };
390
+ };
391
+ };
392
+
393
+ interface SpacerProps {
394
+ height?: number;
395
+ }
396
+ declare const Spacer: {
397
+ ({ height }: SpacerProps): react_jsx_runtime.JSX.Element;
398
+ craft: {
399
+ props: {
400
+ height: number;
401
+ };
402
+ related: {
403
+ settings: () => react_jsx_runtime.JSX.Element;
404
+ };
405
+ };
406
+ };
407
+
408
+ interface SocialLink {
409
+ platform: 'facebook' | 'twitter' | 'instagram' | 'linkedin' | 'youtube' | 'tiktok';
410
+ url: string;
411
+ }
412
+ interface SocialLinksProps {
413
+ links?: SocialLink[];
414
+ iconSize?: number;
415
+ iconColor?: string;
416
+ backgroundColor?: string;
417
+ align?: 'left' | 'center' | 'right';
418
+ padding?: number;
419
+ gap?: number;
420
+ }
421
+ declare const SocialLinks: {
422
+ ({ links, iconSize, iconColor, backgroundColor, align, padding, gap, }: SocialLinksProps): react_jsx_runtime.JSX.Element;
423
+ craft: {
424
+ props: {
425
+ links: {
426
+ platform: string;
427
+ url: string;
428
+ }[];
429
+ iconSize: number;
430
+ iconColor: string;
431
+ backgroundColor: string;
432
+ align: string;
433
+ padding: number;
434
+ gap: number;
435
+ };
436
+ related: {
437
+ settings: () => react_jsx_runtime.JSX.Element;
438
+ };
439
+ };
440
+ };
441
+
442
+ interface TwoColumnProps {
443
+ leftWidth?: number;
444
+ gap?: number;
445
+ padding?: number;
446
+ backgroundColor?: string;
447
+ children?: React.ReactNode;
448
+ }
449
+ declare const TwoColumn: {
450
+ ({ leftWidth, gap, padding, backgroundColor, }: TwoColumnProps): react_jsx_runtime.JSX.Element;
451
+ craft: {
452
+ props: {
453
+ leftWidth: number;
454
+ gap: number;
455
+ padding: number;
456
+ backgroundColor: string;
457
+ };
458
+ related: {
459
+ settings: () => react_jsx_runtime.JSX.Element;
460
+ };
461
+ };
462
+ };
463
+
464
+ interface CountdownProps {
465
+ title?: string;
466
+ days?: number;
467
+ hours?: number;
468
+ minutes?: number;
469
+ seconds?: number;
470
+ backgroundColor?: string;
471
+ numberColor?: string;
472
+ labelColor?: string;
473
+ titleColor?: string;
474
+ boxBackground?: string;
475
+ padding?: number;
476
+ }
477
+ declare const Countdown: {
478
+ ({ title, days, hours, minutes, seconds, backgroundColor, numberColor, labelColor, titleColor, boxBackground, padding, }: CountdownProps): react_jsx_runtime.JSX.Element;
479
+ craft: {
480
+ props: {
481
+ title: string;
482
+ days: number;
483
+ hours: number;
484
+ minutes: number;
485
+ seconds: number;
486
+ backgroundColor: string;
487
+ numberColor: string;
488
+ labelColor: string;
489
+ titleColor: string;
490
+ boxBackground: string;
491
+ padding: number;
492
+ };
493
+ related: {
494
+ settings: () => react_jsx_runtime.JSX.Element;
495
+ };
496
+ };
497
+ };
498
+
499
+ interface PromoCodeProps {
500
+ title?: string;
501
+ code?: string;
502
+ description?: string;
503
+ backgroundColor?: string;
504
+ borderColor?: string;
505
+ codeBackground?: string;
506
+ textColor?: string;
507
+ codeColor?: string;
508
+ padding?: number;
509
+ borderStyle?: 'solid' | 'dashed' | 'dotted';
510
+ }
511
+ declare const PromoCode: {
512
+ ({ title, code, description, backgroundColor, borderColor, codeBackground, textColor, codeColor, padding, borderStyle, }: PromoCodeProps): react_jsx_runtime.JSX.Element;
513
+ craft: {
514
+ props: {
515
+ title: string;
516
+ code: string;
517
+ description: string;
518
+ backgroundColor: string;
519
+ borderColor: string;
520
+ codeBackground: string;
521
+ textColor: string;
522
+ codeColor: string;
523
+ padding: number;
524
+ borderStyle: string;
525
+ };
526
+ related: {
527
+ settings: () => react_jsx_runtime.JSX.Element;
528
+ };
529
+ };
530
+ };
531
+
532
+ interface TestimonialProps {
533
+ quote?: string;
534
+ authorName?: string;
535
+ authorTitle?: string;
536
+ authorImage?: string;
537
+ backgroundColor?: string;
538
+ quoteColor?: string;
539
+ authorColor?: string;
540
+ accentColor?: string;
541
+ padding?: number;
542
+ showQuoteIcon?: boolean;
543
+ }
544
+ declare const Testimonial: {
545
+ ({ quote, authorName, authorTitle, authorImage, backgroundColor, quoteColor, authorColor, accentColor, padding, showQuoteIcon, }: TestimonialProps): react_jsx_runtime.JSX.Element;
546
+ craft: {
547
+ props: {
548
+ quote: string;
549
+ authorName: string;
550
+ authorTitle: string;
551
+ authorImage: string;
552
+ backgroundColor: string;
553
+ quoteColor: string;
554
+ authorColor: string;
555
+ accentColor: string;
556
+ padding: number;
557
+ showQuoteIcon: boolean;
558
+ };
559
+ related: {
560
+ settings: () => react_jsx_runtime.JSX.Element;
561
+ };
562
+ };
563
+ };
564
+
565
+ interface VideoPlaceholderProps {
566
+ thumbnailUrl?: string;
567
+ videoUrl?: string;
568
+ width?: string;
569
+ align?: 'left' | 'center' | 'right';
570
+ padding?: number;
571
+ borderRadius?: number;
572
+ playButtonColor?: string;
573
+ overlayOpacity?: number;
574
+ }
575
+ declare const VideoPlaceholder: {
576
+ ({ thumbnailUrl, videoUrl, width, align, padding, borderRadius, playButtonColor, overlayOpacity, }: VideoPlaceholderProps): react_jsx_runtime.JSX.Element;
577
+ craft: {
578
+ props: {
579
+ thumbnailUrl: string;
580
+ videoUrl: string;
581
+ width: string;
582
+ align: string;
583
+ padding: number;
584
+ borderRadius: number;
585
+ playButtonColor: string;
586
+ overlayOpacity: number;
587
+ };
588
+ related: {
589
+ settings: () => react_jsx_runtime.JSX.Element;
590
+ };
591
+ };
592
+ };
593
+
594
+ interface VariableTextProps {
595
+ text?: string;
596
+ fontSize?: number;
597
+ fontWeight?: 'normal' | 'bold';
598
+ color?: string;
599
+ align?: 'left' | 'center' | 'right';
600
+ padding?: number;
601
+ lineHeight?: number;
602
+ }
603
+ declare const AVAILABLE_VARIABLES: {
604
+ key: string;
605
+ label: string;
606
+ preview: string;
607
+ }[];
608
+ declare const VariableText: {
609
+ ({ text, fontSize, fontWeight, color, align, padding, lineHeight, }: VariableTextProps): react_jsx_runtime.JSX.Element;
610
+ craft: {
611
+ props: {
612
+ text: string;
613
+ fontSize: number;
614
+ fontWeight: string;
615
+ color: string;
616
+ align: string;
617
+ padding: number;
618
+ lineHeight: number;
619
+ };
620
+ related: {
621
+ settings: () => react_jsx_runtime.JSX.Element;
622
+ };
623
+ };
624
+ };
625
+
626
+ interface ListItem {
627
+ icon: string;
628
+ text: string;
629
+ }
630
+ interface IconListProps {
631
+ items?: ListItem[];
632
+ iconColor?: string;
633
+ textColor?: string;
634
+ backgroundColor?: string;
635
+ fontSize?: number;
636
+ iconSize?: number;
637
+ gap?: number;
638
+ padding?: number;
639
+ }
640
+ declare const IconList: {
641
+ ({ items, iconColor, textColor, backgroundColor, fontSize, iconSize, gap, padding, }: IconListProps): react_jsx_runtime.JSX.Element;
642
+ craft: {
643
+ props: {
644
+ items: {
645
+ icon: string;
646
+ text: string;
647
+ }[];
648
+ iconColor: string;
649
+ textColor: string;
650
+ backgroundColor: string;
651
+ fontSize: number;
652
+ iconSize: number;
653
+ gap: number;
654
+ padding: number;
655
+ };
656
+ related: {
657
+ settings: () => react_jsx_runtime.JSX.Element;
658
+ };
659
+ };
660
+ };
661
+
662
+ declare const DEFAULT_COMPONENTS: ComponentRegistry;
663
+ /** Helper to get the Craft.js resolver map from a ComponentRegistry */
664
+ declare const buildResolver: (registry: ComponentRegistry) => Record<string, React.ComponentType<any>>;
665
+ /** Helper to get unique sorted categories from a ComponentRegistry */
666
+ declare const getCategories: (registry: ComponentRegistry) => string[];
667
+
668
+ interface PaperProps {
669
+ children?: React.ReactNode;
670
+ background?: string;
671
+ }
672
+ declare const Paper: {
673
+ ({ children, background }: PaperProps): react_jsx_runtime.JSX.Element;
674
+ craft: {
675
+ props: {
676
+ background: string;
677
+ };
678
+ related: {
679
+ settings: () => react_jsx_runtime.JSX.Element;
680
+ };
681
+ };
682
+ };
683
+
684
+ declare const Toolbox: () => react_jsx_runtime.JSX.Element;
685
+
686
+ declare const SettingsPanel: () => react_jsx_runtime.JSX.Element;
687
+
688
+ declare const RenderNode: ({ render }: {
689
+ render: React.ReactNode;
690
+ }) => react_jsx_runtime.JSX.Element;
691
+
692
+ declare const generateEmailHtml: (nodes: SerializedNodes, customRenderers?: Record<string, HtmlRenderer>) => string;
693
+
694
+ export { AVAILABLE_VARIABLES, type ComponentRegistry, Container, Countdown, DEFAULT_COMPONENTS, Divider, type EditorCallbacks, type EditorComponentConfig, EditorProvider, type EditorSlots, type EditorTheme, type EditorThemeColors, EmailButton, EmailEditor, type EmailEditorProps, EmailFooter, EmailHeader, type EmailTemplate, type ExportDialogSlotProps, type HtmlRenderer, IconList, ImageBlock, InvoiceTable, Paper, type PreviewDialogSlotProps, PromoCode, RenderNode, SettingsPanel, type SettingsPanelSlotProps, SocialLinks, Spacer, Testimonial, TextBlock, type ToolbarSlotProps, Toolbox, type ToolboxSlotProps, TwoColumn, VariableText, VideoPlaceholder, buildResolver, generateEmailHtml, getCategories, useEditorConfig };