@pexelize/react-editor 1.0.5 → 2.0.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/README.md CHANGED
@@ -1,127 +1,637 @@
1
1
  # @pexelize/react-editor
2
2
 
3
- React wrapper component for the **Pexelize Email Editor**.
3
+ React wrapper for the [Pexelize Editor](https://pexelize.com) - a drag-and-drop email and page builder.
4
4
 
5
- ## 🚀 Installation
5
+ ## Installation
6
6
 
7
7
  ```bash
8
8
  npm install @pexelize/react-editor
9
9
  ```
10
10
 
11
- ## 📖 Usage
11
+ ## Quick Start
12
12
 
13
13
  ```tsx
14
- import { PexelizeEditor, PexelizeEditorRef } from '@pexelize/react-editor';
15
- import { useRef } from 'react';
14
+ import { useRef, useState } from "react";
15
+ import {
16
+ PexelizeEditor,
17
+ PexelizeEditorRef,
18
+ DesignJson,
19
+ } from "@pexelize/react-editor";
16
20
 
17
21
  function EmailBuilder() {
18
22
  const editorRef = useRef<PexelizeEditorRef>(null);
23
+ const [lastSaved, setLastSaved] = useState<Date | null>(null);
19
24
 
20
- const handleSave = () => {
21
- editorRef.current?.saveDesign((design) => {
22
- console.log('Saved:', design);
25
+ const handleExport = async () => {
26
+ const editor = editorRef.current?.editor;
27
+ if (!editor) return;
28
+
29
+ const { html, design } = await editor.exportHtmlAsync();
30
+ console.log("HTML:", html);
31
+ };
32
+
33
+ const handleSave = async () => {
34
+ const editor = editorRef.current?.editor;
35
+ if (!editor) return;
36
+
37
+ const design = await editor.getDesign();
38
+ await saveToBackend(design);
39
+ setLastSaved(new Date());
40
+ };
41
+
42
+ return (
43
+ <div style={{ height: "100vh", display: "flex", flexDirection: "column" }}>
44
+ <div style={{ padding: 16, borderBottom: "1px solid #eee" }}>
45
+ <button onClick={handleExport}>Export HTML</button>
46
+ <button onClick={handleSave}>Save</button>
47
+ {lastSaved && <span>Last saved: {lastSaved.toLocaleTimeString()}</span>}
48
+ </div>
49
+ <PexelizeEditor
50
+ ref={editorRef}
51
+ editorId={123}
52
+ apiKey="your-api-key"
53
+ height="100%"
54
+ options={{ editorMode: "email" }}
55
+ onReady={(editor) => {
56
+ console.log("Editor ready!");
57
+ // Load initial design if available
58
+ // editor.loadDesign(savedDesign);
59
+ }}
60
+ onLoad={() => console.log("Design loaded")}
61
+ onChange={(data) => {
62
+ console.log("Design changed:", data.type);
63
+ // Auto-save or mark as dirty
64
+ }}
65
+ onError={(error) => console.error("Editor error:", error)}
66
+ />
67
+ </div>
68
+ );
69
+ }
70
+ ```
71
+
72
+ ## Complete Example with All Features
73
+
74
+ ```tsx
75
+ import { useRef, useState, useCallback } from "react";
76
+ import {
77
+ PexelizeEditor,
78
+ PexelizeEditorRef,
79
+ DesignJson,
80
+ MergeTag,
81
+ } from "@pexelize/react-editor";
82
+
83
+ function AdvancedEmailBuilder() {
84
+ const editorRef = useRef<PexelizeEditorRef>(null);
85
+ const [isDirty, setIsDirty] = useState(false);
86
+
87
+ // Merge tags for personalization
88
+ const mergeTags: MergeTag[] = [
89
+ { name: "First Name", value: "{{first_name}}" },
90
+ { name: "Last Name", value: "{{last_name}}" },
91
+ { name: "Company", value: "{{company}}" },
92
+ ];
93
+
94
+ const handleReady = useCallback((editor) => {
95
+ console.log("Editor initialized");
96
+
97
+ // Set merge tags
98
+ editor.setMergeTags(mergeTags);
99
+
100
+ // Set custom fonts
101
+ editor.setFonts({
102
+ showDefaultFonts: true,
103
+ customFonts: [{ label: "Brand Font", value: "BrandFont, sans-serif" }],
23
104
  });
105
+
106
+ // Load saved design or start blank
107
+ const savedDesign = localStorage.getItem("email-design");
108
+ if (savedDesign) {
109
+ editor.loadDesign(JSON.parse(savedDesign));
110
+ }
111
+ }, []);
112
+
113
+ const handleChange = useCallback(
114
+ (data: { design: DesignJson; type: string }) => {
115
+ setIsDirty(true);
116
+ // Auto-save to localStorage
117
+ localStorage.setItem("email-design", JSON.stringify(data.design));
118
+ },
119
+ [],
120
+ );
121
+
122
+ const handleExportHtml = async () => {
123
+ const editor = editorRef.current?.editor;
124
+ if (!editor) return;
125
+
126
+ const { html, design } = await editor.exportHtmlAsync();
127
+
128
+ // Download HTML file
129
+ const blob = new Blob([html], { type: "text/html" });
130
+ const url = URL.createObjectURL(blob);
131
+ const a = document.createElement("a");
132
+ a.href = url;
133
+ a.download = "email.html";
134
+ a.click();
24
135
  };
25
136
 
26
- const handleExport = () => {
27
- editorRef.current?.exportHtml((data) => {
28
- console.log('HTML:', data.html);
137
+ const handleExportImage = () => {
138
+ const editor = editorRef.current?.editor;
139
+ if (!editor) return;
140
+
141
+ editor.exportImage((data) => {
142
+ window.open(data.url, "_blank");
29
143
  });
30
144
  };
31
145
 
146
+ const handlePreview = () => {
147
+ const editor = editorRef.current?.editor;
148
+ editor?.showPreview("desktop");
149
+ };
150
+
151
+ const handleUndo = () => editorRef.current?.editor?.undo();
152
+ const handleRedo = () => editorRef.current?.editor?.redo();
153
+
32
154
  return (
33
- <div>
34
- <div style={{ marginBottom: '10px' }}>
35
- <button onClick={handleSave}>Save</button>
36
- <button onClick={handleExport}>Export HTML</button>
155
+ <div style={{ height: "100vh", display: "flex", flexDirection: "column" }}>
156
+ {/* Toolbar */}
157
+ <div
158
+ style={{
159
+ padding: 12,
160
+ borderBottom: "1px solid #ddd",
161
+ display: "flex",
162
+ gap: 8,
163
+ }}
164
+ >
165
+ <button onClick={handleUndo}>Undo</button>
166
+ <button onClick={handleRedo}>Redo</button>
167
+ <button onClick={handlePreview}>Preview</button>
168
+ <button onClick={handleExportHtml}>Export HTML</button>
169
+ <button onClick={handleExportImage}>Export Image</button>
170
+ {isDirty && <span style={{ color: "orange" }}>● Unsaved changes</span>}
37
171
  </div>
38
172
 
173
+ {/* Editor */}
39
174
  <PexelizeEditor
40
175
  ref={editorRef}
41
- editorMode='email'
42
- height='600px'
43
- onReady={() => console.log('Editor ready!')}
44
- onChange={({ design }) => console.log('Changed:', design)}
176
+ editorId={123}
177
+ apiKey="your-api-key"
178
+ height="100%"
179
+ editorMode="email"
180
+ options={{
181
+ appearance: { theme: "light" },
182
+ features: {
183
+ preview: true,
184
+ undoRedo: true,
185
+ imageEditor: true,
186
+ },
187
+ }}
188
+ onReady={handleReady}
189
+ onChange={handleChange}
190
+ onError={(error) => alert(`Error: ${error.message}`)}
45
191
  />
46
192
  </div>
47
193
  );
48
194
  }
195
+
196
+ export default AdvancedEmailBuilder;
197
+ ```
198
+
199
+ ## Props
200
+
201
+ | Prop | Type | Required | Description |
202
+ | ------------- | ------------------- | -------- | -------------------------------------------------------- |
203
+ | `editorId` | `number \| string` | ✅ | Editor ID from your Pexelize dashboard |
204
+ | `apiKey` | `string` | ✅ | API key from your Pexelize dashboard |
205
+ | `templateId` | `string` | ❌ | Template ID for AI Copilot history |
206
+ | `design` | `DesignJson` | ❌ | Initial design to load |
207
+ | `editorMode` | `EditorMode` | ❌ | `'email'` \| `'web'` \| `'popup'` |
208
+ | `contentType` | `EditorContentType` | ❌ | `'page'` \| `'module'` |
209
+ | `ai` | `AIConfig` | ❌ | AI features configuration |
210
+ | `height` | `string \| number` | ❌ | Editor height (default: `'600px'`) |
211
+ | `options` | `PexelizeConfig` | ❌ | SDK configuration options |
212
+ | `className` | `string` | ❌ | CSS class for the container |
213
+ | `style` | `CSSProperties` | ❌ | Inline styles for the container |
214
+ | `onReady` | `(editor) => void` | ❌ | Called when editor is ready |
215
+ | `onLoad` | `() => void` | ❌ | Called when design is loaded |
216
+ | `onChange` | `(data) => void` | ❌ | Called when design changes (receives `{ design, type }`) |
217
+ | `onError` | `(error) => void` | ❌ | Called on initialization error |
218
+
219
+ ## SDK Methods Reference
220
+
221
+ Access the SDK via `editorRef.current?.editor`:
222
+
223
+ ### Design Methods
224
+
225
+ ```tsx
226
+ // Load/save design
227
+ editor.loadDesign(design);
228
+ editor.loadDesign(design, { preserveHistory: false });
229
+ await editor.loadDesignAsync(design);
230
+ editor.loadBlank();
231
+ editor.saveDesign((design) => console.log(design));
232
+ const design = await editor.getDesign();
233
+ ```
234
+
235
+ ### Export Methods
236
+
237
+ ```tsx
238
+ // HTML export
239
+ editor.exportHtml((data) => console.log(data.html, data.design));
240
+ const { html, design, chunks } = await editor.exportHtmlAsync();
241
+
242
+ // Plain text export
243
+ editor.exportPlainText((data) => console.log(data.text));
244
+ const { text, design } = await editor.exportPlainTextAsync();
245
+
246
+ // Image export
247
+ editor.exportImage((data) => console.log(data.url), { format: "png" });
248
+
249
+ // PDF export
250
+ editor.exportPdf((data) => console.log(data.url), { format: "A4" });
251
+
252
+ // ZIP export
253
+ editor.exportZip((data) => console.log(data.url));
254
+ ```
255
+
256
+ ### Merge Tags
257
+
258
+ ```tsx
259
+ editor.setMergeTags([
260
+ { name: "First Name", value: "{{first_name}}" },
261
+ { name: "Company", value: "{{company}}" },
262
+ ]);
263
+ const tags = await editor.getMergeTags();
264
+ ```
265
+
266
+ ### Design Tags
267
+
268
+ ```tsx
269
+ editor.setDesignTags({ brand_color: "#007bff" });
270
+ const tags = await editor.getDesignTags();
271
+ ```
272
+
273
+ ### Special Links
274
+
275
+ ```tsx
276
+ editor.setSpecialLinks([{ name: "Unsubscribe", href: "{{unsubscribe_url}}" }]);
277
+ const links = await editor.getSpecialLinks();
278
+ ```
279
+
280
+ ### Modules
281
+
282
+ ```tsx
283
+ editor.setModules(modules);
284
+ const modules = await editor.getModules();
285
+ await editor.addModule(module);
286
+ await editor.removeModule(moduleId);
287
+ editor.updateModule(moduleId, rowData);
288
+ const syncedIds = await editor.getSyncedModulesInDesign();
289
+ await editor.unlinkSyncedModule(rowId);
290
+ ```
291
+
292
+ ### Fonts
293
+
294
+ ```tsx
295
+ editor.setFonts({
296
+ showDefaultFonts: true,
297
+ customFonts: [{ label: "Custom Font", value: "CustomFont" }],
298
+ });
299
+ const fonts = await editor.getFonts();
300
+ ```
301
+
302
+ ### Body Values
303
+
304
+ ```tsx
305
+ editor.setBodyValues({
306
+ backgroundColor: "#f5f5f5",
307
+ contentWidth: "600px",
308
+ });
309
+ const values = await editor.getBodyValues();
310
+ ```
311
+
312
+ ### Editor Options
313
+
314
+ ```tsx
315
+ editor.setOptions({
316
+ display: { backgroundColor: "#f5f5f5", contentWidth: 600 },
317
+ links: { color: "#0066cc", underline: true },
318
+ buttonDefaults: { backgroundColor: "#3AAEE0" },
319
+ appearance: { theme: "auto", accentColor: "indigo" },
320
+ });
321
+ ```
322
+
323
+ ### Tools Configuration
324
+
325
+ ```tsx
326
+ editor.setToolsConfig({
327
+ heading: { enabled: true },
328
+ button: { properties: { colors: { value: { backgroundColor: "#007bff" } } } },
329
+ });
330
+ ```
331
+
332
+ ### Tabs Management
333
+
334
+ ```tsx
335
+ editor.updateTabs({
336
+ myCustomTab: { enabled: true, position: 1, icon: "star", active: true },
337
+ });
338
+ ```
339
+
340
+ ### Editor Mode & Config
341
+
342
+ ```tsx
343
+ editor.setEditorMode("email"); // 'email' | 'web' | 'popup' | 'document'
344
+ editor.setEditorConfig({
345
+ minRows: 1,
346
+ maxRows: 1,
347
+ contentType: "module",
348
+ autoSelectOnDrop: true,
349
+ });
350
+ const config = await editor.getEditorConfig();
351
+ ```
352
+
353
+ ### Locale & Language
354
+
355
+ ```tsx
356
+ editor.setLocale("en-US");
357
+ editor.setCurrentLanguage("es-ES");
358
+ editor.setLanguages([
359
+ { label: "English", value: "en-US", default: true },
360
+ { label: "Español", value: "es-ES" },
361
+ ]);
362
+ const lang = await editor.getCurrentLanguage();
363
+ editor.setTextDirection("rtl");
364
+ ```
365
+
366
+ ### Appearance
367
+
368
+ ```tsx
369
+ editor.setAppearance({
370
+ theme: "dark",
371
+ panels: { tools: { position: "left" } },
372
+ });
373
+ ```
374
+
375
+ ### Custom CSS/JS
376
+
377
+ ```tsx
378
+ editor.setCustomCSS(["https://example.com/styles.css"]);
379
+ editor.setCustomJS(["https://example.com/script.js"]);
380
+ ```
381
+
382
+ ### Preview
383
+
384
+ ```tsx
385
+ editor.showPreview("desktop"); // 'desktop' | 'tablet' | 'mobile'
386
+ editor.hidePreview();
387
+ ```
388
+
389
+ ### Undo/Redo
390
+
391
+ ```tsx
392
+ editor.undo();
393
+ editor.redo();
394
+ const canUndo = await editor.canUndo();
395
+ const canRedo = await editor.canRedo();
396
+ ```
397
+
398
+ ### Save
399
+
400
+ ```tsx
401
+ editor.save(); // Triggers save callback
402
+ ```
403
+
404
+ ### Element Manipulation
405
+
406
+ ```tsx
407
+ editor.execCommand({
408
+ action: "highlight",
409
+ target: { type: "row", id: "row-123" },
410
+ });
411
+ editor.selectElement({ type: "row", id: "row-123" });
412
+ editor.highlightElement({ type: "content", id: "content-789" });
413
+ editor.highlightElement(null); // Clear highlight
414
+ editor.scrollToElement({ type: "row", id: "row-123" });
415
+ ```
416
+
417
+ ### Events
418
+
419
+ ```tsx
420
+ const unsubscribe = editor.addEventListener("design:updated", (data) => {
421
+ console.log("Design changed:", data);
422
+ });
423
+ editor.removeEventListener("design:updated", callback);
49
424
  ```
50
425
 
51
- ## 🔧 Props
426
+ **Available Events:**
52
427
 
53
- | Prop | Type | Default | Description |
54
- | ------------ | ----------------------------- | --------- | ------------------------------ |
55
- | `editorMode` | `'email' \| 'web' \| 'popup'` | `'email'` | Editor mode |
56
- | `height` | `string \| number` | `'600px'` | Editor height |
57
- | `design` | `DesignJson` | - | Initial design to load |
58
- | `mergeTags` | `MergeTag[]` | - | Merge tags for personalization |
59
- | `appearance` | `AppearanceConfig` | - | Visual customization |
60
- | `onReady` | `() => void` | - | Called when editor is ready |
61
- | `onChange` | `(data) => void` | - | Called when design changes |
62
- | `onLoad` | `(data) => void` | - | Called when design is loaded |
63
- | `onImage` | `ImageUploadCallback` | - | Image upload handler |
64
- | `onSave` | `SaveCallback` | - | Save handler |
428
+ - `editor:ready` - Editor initialized
429
+ - `design:loaded` - Design loaded
430
+ - `design:updated` - Design changed
431
+ - `element:selected` - Element selected
432
+ - `save` - Save triggered
433
+ - `preview:shown` / `preview:hidden` - Preview toggled
434
+ - `image:uploaded` / `image:error` - Image upload events
65
435
 
66
- ## 📚 Ref Methods
436
+ ### Callbacks
67
437
 
68
- Access editor methods via ref:
438
+ ```tsx
439
+ editor.registerCallback("image", (file, done) => {
440
+ uploadToMyServer(file).then((url) => done({ url }));
441
+ });
442
+ editor.registerCallback("save", (data, done) => {
443
+ saveToBackend(data).then(() => done({ success: true }));
444
+ });
445
+ editor.registerCallback("linkClick", (data, done) => {
446
+ done({ url: data.url, target: "_blank" });
447
+ });
448
+ editor.unregisterCallback("image");
449
+
450
+ // Shorthand methods
451
+ editor.onSave(callback);
452
+ editor.offSave();
453
+ editor.onChange(callback);
454
+ editor.onLoad(callback);
455
+ editor.onModuleSave(callback);
456
+ editor.onSyncedModuleUpdate(callback);
457
+ ```
458
+
459
+ ### Tool Registration
69
460
 
70
461
  ```tsx
71
- const editorRef = useRef<PexelizeEditorRef>(null);
462
+ await editor.registerTool({
463
+ id: "myCustomTool",
464
+ label: "My Tool",
465
+ baseToolType: "text",
466
+ icon: "star",
467
+ properties: { ... },
468
+ });
469
+ await editor.unregisterTool("myCustomTool");
470
+ const tools = await editor.getTools();
471
+ ```
72
472
 
73
- // Load a design
74
- editorRef.current?.loadDesign(myDesign);
473
+ ### State
75
474
 
76
- // Load blank
77
- editorRef.current?.loadBlank();
475
+ ```tsx
476
+ const state = await editor.getState();
477
+ ```
478
+
479
+ ### Collaboration
480
+
481
+ ```tsx
482
+ editor.setCollaborationConfig({
483
+ enabled: true,
484
+ threadPreview: true,
485
+ user: { id: "user-123", name: "John Doe" },
486
+ });
487
+ ```
78
488
 
79
- // Get design
80
- const design = await editorRef.current?.getDesign();
489
+ ### Utility Methods
81
490
 
82
- // Save design (callback)
83
- editorRef.current?.saveDesign((design) => console.log(design));
491
+ ```tsx
492
+ editor.registerColumns([1, 2, 1]); // 1:2:1 layout
493
+ editor.setColorPickerConfig({
494
+ colors: ["#FF0000", "#00FF00", "#0000FF"],
495
+ recentColors: true,
496
+ });
497
+ editor.setStyleGuide({
498
+ tools: {
499
+ heading: {
500
+ styles: {
501
+ h1: { label: "Heading 1", values: { fontSize: "32px" } },
502
+ },
503
+ },
504
+ },
505
+ });
506
+ ```
84
507
 
85
- // Export HTML
86
- editorRef.current?.exportHtml((data) => console.log(data.html));
508
+ ### Validation & Audit
87
509
 
88
- // Export HTML (async)
89
- const { html, design } = await editorRef.current?.exportHtmlAsync();
510
+ ```tsx
511
+ const result = await editor.validateTemplate(data, { strict: true, detailed: true });
512
+ editor.validateTemplateCallback(data, (result) => console.log(result));
513
+ const toolResult = await editor.validateTool(data, { toolType: "button" });
514
+ const toolTypes = await editor.getToolTypes();
90
515
 
91
- // Undo/Redo
92
- editorRef.current?.undo();
93
- editorRef.current?.redo();
516
+ editor.setValidator((info) => {
517
+ if (!info.html.includes("alt=")) {
518
+ return [{ id: "missing-alt", title: "Missing Alt Text", severity: "WARNING" }];
519
+ }
520
+ return [];
521
+ });
522
+ editor.setToolValidator("image", (info) => { ... });
523
+ editor.clearValidators();
94
524
 
95
- // Check if ready
96
- const ready = editorRef.current?.isReady();
525
+ const auditResult = await editor.audit();
97
526
  ```
98
527
 
99
- ## 🪝 Hook: usePexelizeSDK
528
+ ### Display Conditions
529
+
530
+ ```tsx
531
+ editor.setDisplayConditions({
532
+ enabled: true,
533
+ conditions: [
534
+ {
535
+ type: "Customer Segment",
536
+ label: "VIP Members",
537
+ before: '{% if customer.tier == "VIP" %}',
538
+ after: "{% endif %}",
539
+ },
540
+ ],
541
+ });
542
+ ```
100
543
 
101
- For more control, use the hook directly:
544
+ ### Image Upload
102
545
 
103
546
  ```tsx
104
- import { usePexelizeSDK } from '@pexelize/react-editor';
547
+ const result = await editor.uploadImage(file, {
548
+ folderId: "folder-123",
549
+ altText: "Description",
550
+ onProgress: (progress) => console.log(`${progress.percent}%`),
551
+ });
552
+ ```
105
553
 
106
- function MyComponent() {
107
- const { sdk, isReady, isLoading, error } = usePexelizeSDK({
108
- containerId: 'my-editor',
109
- editorMode: 'email',
110
- });
554
+ ### Asset Management
111
555
 
112
- if (isLoading) return <div>Loading...</div>;
113
- if (error) return <div>Error: {error}</div>;
556
+ ```tsx
557
+ const { assets, total } = await editor.listAssets({
558
+ folderId: "folder-123",
559
+ page: 1,
560
+ });
561
+ const deleteResult = await editor.deleteAsset(assetId);
562
+ const folders = await editor.listAssetFolders(parentId);
563
+ const folder = await editor.createAssetFolder("New Folder", parentId);
564
+ const storageInfo = await editor.getStorageInfo();
565
+ ```
566
+
567
+ ### AI Image
568
+
569
+ ```tsx
570
+ const result = await editor.saveAiImage(base64Data, {
571
+ prompt: "A sunset over mountains",
572
+ style: "realism",
573
+ suggestedFilename: "ai-sunset.png",
574
+ });
575
+ ```
576
+
577
+ ### Storage & AI Utilities
578
+
579
+ ```tsx
580
+ editor.isExternalStorage();
581
+ editor.canSaveAiImages();
582
+ editor.getAssetStorageMode(); // 'pexelize' | 'external'
583
+ editor.isAIDisabled();
584
+ editor.isAIFeatureEnabledCheck("copilot");
585
+ editor.isAIFeatureExternalCheck("imageGeneration");
586
+ editor.getAIFeatureModeCheck("smartHeading"); // 'pexelize' | 'external' | 'disabled'
587
+ editor.getAIMode();
588
+ ```
589
+
590
+ ### Status
591
+
592
+ ```tsx
593
+ editor.isInitialized();
594
+ editor.isReady();
595
+ editor.destroy();
596
+ ```
597
+
598
+ ## Hook API
599
+
600
+ ```tsx
601
+ import { PexelizeEditor, usePexelizeEditor } from "@pexelize/react-editor";
602
+
603
+ function MyEditor() {
604
+ const { ref, editor, isReady, isLoading, error } = usePexelizeEditor();
114
605
 
115
606
  return (
116
607
  <div>
117
- <div id='my-editor' style={{ height: '600px' }} />
118
608
  <button
609
+ onClick={() => editor?.exportHtml(console.log)}
119
610
  disabled={!isReady}
120
- onClick={() => sdk?.exportHtml((d) => console.log(d.html))}
121
611
  >
122
612
  Export
123
613
  </button>
614
+ <PexelizeEditor ref={ref} editorId={123} apiKey="your-api-key" />
124
615
  </div>
125
616
  );
126
617
  }
127
618
  ```
619
+
620
+ ## TypeScript
621
+
622
+ All SDK types are re-exported:
623
+
624
+ ```tsx
625
+ import type {
626
+ PexelizeConfig,
627
+ DesignJson,
628
+ ExportHtmlData,
629
+ MergeTag,
630
+ EditorEventName,
631
+ AIConfig,
632
+ } from "@pexelize/react-editor";
633
+ ```
634
+
635
+ ## License
636
+
637
+ MIT