@emabuild/core 0.0.2 → 0.0.4

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.
Files changed (74) hide show
  1. package/README.md +410 -0
  2. package/dist/dnd/drag-manager.d.ts +13 -14
  3. package/dist/dnd/drag-manager.d.ts.map +1 -1
  4. package/dist/dnd/drop-indicator.d.ts +24 -0
  5. package/dist/dnd/drop-indicator.d.ts.map +1 -0
  6. package/dist/dnd/shadow-dom-utils.d.ts +29 -0
  7. package/dist/dnd/shadow-dom-utils.d.ts.map +1 -0
  8. package/dist/index.d.ts +1 -1
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +1 -1
  11. package/dist/{mail-editor-CoB2C5CT.js → mail-editor-D0FbEUZu.js} +677 -870
  12. package/dist/mail-editor-D0FbEUZu.js.map +1 -0
  13. package/dist/mail-editor.d.ts +3 -3
  14. package/dist/mail-editor.d.ts.map +1 -1
  15. package/dist/mail-editor.js +1 -1
  16. package/dist/properties/property-panel.d.ts +4 -9
  17. package/dist/properties/property-panel.d.ts.map +1 -1
  18. package/dist/properties/widgets/alignment-widget.d.ts +4 -0
  19. package/dist/properties/widgets/alignment-widget.d.ts.map +1 -0
  20. package/dist/properties/widgets/color-picker-widget.d.ts +4 -0
  21. package/dist/properties/widgets/color-picker-widget.d.ts.map +1 -0
  22. package/dist/properties/widgets/dropdown-widget.d.ts +4 -0
  23. package/dist/properties/widgets/dropdown-widget.d.ts.map +1 -0
  24. package/dist/properties/widgets/index.d.ts +8 -0
  25. package/dist/properties/widgets/index.d.ts.map +1 -0
  26. package/dist/properties/widgets/padding-widget.d.ts +4 -0
  27. package/dist/properties/widgets/padding-widget.d.ts.map +1 -0
  28. package/dist/properties/widgets/text-input-widget.d.ts +4 -0
  29. package/dist/properties/widgets/text-input-widget.d.ts.map +1 -0
  30. package/dist/properties/widgets/textarea-widget.d.ts +4 -0
  31. package/dist/properties/widgets/textarea-widget.d.ts.map +1 -0
  32. package/dist/properties/widgets/toggle-widget.d.ts +4 -0
  33. package/dist/properties/widgets/toggle-widget.d.ts.map +1 -0
  34. package/dist/sidebar/body-settings.d.ts +15 -0
  35. package/dist/sidebar/body-settings.d.ts.map +1 -0
  36. package/dist/sidebar/editor-sidebar.d.ts +0 -3
  37. package/dist/sidebar/editor-sidebar.d.ts.map +1 -1
  38. package/dist/state/design-factory.d.ts +9 -0
  39. package/dist/state/design-factory.d.ts.map +1 -0
  40. package/dist/state/design-lookup.d.ts +14 -0
  41. package/dist/state/design-lookup.d.ts.map +1 -0
  42. package/dist/state/editor-store.d.ts +27 -10
  43. package/dist/state/editor-store.d.ts.map +1 -1
  44. package/dist/state/history-manager.d.ts +20 -0
  45. package/dist/state/history-manager.d.ts.map +1 -0
  46. package/dist/tools/built-in/button-tool.d.ts.map +1 -1
  47. package/dist/tools/built-in/divider-tool.d.ts.map +1 -1
  48. package/dist/tools/built-in/form-tool.d.ts.map +1 -1
  49. package/dist/tools/built-in/heading-tool.d.ts.map +1 -1
  50. package/dist/tools/built-in/html-tool.d.ts.map +1 -1
  51. package/dist/tools/built-in/image-tool.d.ts.map +1 -1
  52. package/dist/tools/built-in/menu-tool.d.ts.map +1 -1
  53. package/dist/tools/built-in/paragraph-tool.d.ts.map +1 -1
  54. package/dist/tools/built-in/social-tool.d.ts.map +1 -1
  55. package/dist/tools/built-in/table-tool.d.ts.map +1 -1
  56. package/dist/tools/built-in/text-tool.d.ts.map +1 -1
  57. package/dist/tools/built-in/timer-tool.d.ts.map +1 -1
  58. package/dist/tools/built-in/video-tool.d.ts.map +1 -1
  59. package/dist/tools/helpers/email-html.d.ts +55 -0
  60. package/dist/tools/helpers/email-html.d.ts.map +1 -0
  61. package/dist/tools/helpers/index.d.ts +5 -0
  62. package/dist/tools/helpers/index.d.ts.map +1 -0
  63. package/dist/tools/helpers/types.d.ts +36 -0
  64. package/dist/tools/helpers/types.d.ts.map +1 -0
  65. package/dist/tools/helpers/value-extractor.d.ts +31 -0
  66. package/dist/tools/helpers/value-extractor.d.ts.map +1 -0
  67. package/dist/utils/event-emitter.d.ts +32 -4
  68. package/dist/utils/event-emitter.d.ts.map +1 -1
  69. package/dist/utils/id-generator.d.ts +17 -3
  70. package/dist/utils/id-generator.d.ts.map +1 -1
  71. package/package.json +16 -4
  72. package/dist/mail-editor-CoB2C5CT.js.map +0 -1
  73. package/dist/utils/deep-clone.d.ts +0 -2
  74. package/dist/utils/deep-clone.d.ts.map +0 -1
package/README.md ADDED
@@ -0,0 +1,410 @@
1
+ # @emabuild — Drag & Drop Email Editor
2
+
3
+ A fully embeddable drag-and-drop email editor Web Component. Cross-client email HTML export, and 13 built-in content blocks.
4
+
5
+ Built with [Lit 3](https://lit.dev/) — works in Angular, React, Vue, or plain HTML.
6
+
7
+ ## Quick Start
8
+
9
+ ```bash
10
+ npm install @emabuild/core lit
11
+ ```
12
+
13
+ ```html
14
+ <mail-editor id="editor" style="height:100vh;"></mail-editor>
15
+
16
+ <script type="module">
17
+ import '@emabuild/core/mail-editor';
18
+
19
+ const editor = document.getElementById('editor');
20
+
21
+ editor.addEventListener('editor:ready', () => {
22
+ console.log('Editor is ready');
23
+ });
24
+ </script>
25
+ ```
26
+
27
+ ## Packages
28
+
29
+ | Package | Description | Size |
30
+ |---------|-------------|------|
31
+ | [`@emabuild/core`](https://www.npmjs.com/package/@emabuild/core) | `<mail-editor>` Web Component | ~17KB gzip |
32
+ | [`@emabuild/email-renderer`](https://www.npmjs.com/package/@emabuild/email-renderer) | Standalone HTML export engine (works server-side) | ~3KB gzip |
33
+ | [`@emabuild/types`](https://www.npmjs.com/package/@emabuild/types) | TypeScript type definitions | types only |
34
+
35
+ ## Framework Integration
36
+
37
+ ### Angular
38
+
39
+ ```bash
40
+ npm install @emabuild/core lit
41
+ ```
42
+
43
+ ```typescript
44
+ // app.module.ts
45
+ import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
46
+
47
+ @NgModule({
48
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
49
+ })
50
+ export class AppModule {}
51
+ ```
52
+
53
+ ```typescript
54
+ // app.component.ts
55
+ import '@emabuild/core/mail-editor';
56
+
57
+ @Component({
58
+ template: `<mail-editor #editor style="height:100vh;"></mail-editor>
59
+ <button (click)="exportHtml()">Export</button>`,
60
+ })
61
+ export class AppComponent {
62
+ @ViewChild('editor') editor!: ElementRef;
63
+
64
+ exportHtml() {
65
+ this.editor.nativeElement.exportHtml((result) => {
66
+ console.log(result.html);
67
+ });
68
+ }
69
+ }
70
+ ```
71
+
72
+ ### React
73
+
74
+ ```tsx
75
+ import '@emabuild/core/mail-editor';
76
+ import { useRef, useEffect } from 'react';
77
+
78
+ export function EmailEditor() {
79
+ const editorRef = useRef<any>(null);
80
+
81
+ useEffect(() => {
82
+ const el = editorRef.current;
83
+ el?.addEventListener('editor:ready', () => {
84
+ el.loadDesign(myDesign);
85
+ });
86
+ }, []);
87
+
88
+ const handleExport = () => {
89
+ editorRef.current?.exportHtml((result) => {
90
+ console.log(result.html);
91
+ });
92
+ };
93
+
94
+ return (
95
+ <div style={{ height: '100vh' }}>
96
+ <mail-editor ref={editorRef} />
97
+ <button onClick={handleExport}>Export HTML</button>
98
+ </div>
99
+ );
100
+ }
101
+ ```
102
+
103
+ ### Vue
104
+
105
+ ```vue
106
+ <template>
107
+ <mail-editor ref="editor" style="height: 100vh" />
108
+ <button @click="exportHtml">Export</button>
109
+ </template>
110
+
111
+ <script setup>
112
+ import '@emabuild/core/mail-editor';
113
+ import { ref, onMounted } from 'vue';
114
+
115
+ const editor = ref(null);
116
+
117
+ onMounted(() => {
118
+ editor.value.addEventListener('editor:ready', () => {
119
+ editor.value.loadDesign(myDesign);
120
+ });
121
+ });
122
+
123
+ function exportHtml() {
124
+ editor.value.exportHtml((result) => {
125
+ console.log(result.html);
126
+ });
127
+ }
128
+ </script>
129
+ ```
130
+
131
+ ## API Reference
132
+
133
+ ### Methods
134
+
135
+ ```typescript
136
+ // Load a design JSON
137
+ editor.loadDesign(design: EmailDesign): void;
138
+
139
+ // Save the current design as JSON
140
+ editor.saveDesign(callback: (design: EmailDesign) => void): void;
141
+
142
+ // Export email-ready HTML
143
+ editor.exportHtml(callback: (result: ExportResult) => void, options?: ExportOptions): void;
144
+
145
+ // Promise-based export
146
+ const result = await editor.exportHtmlAsync(options?: ExportOptions);
147
+
148
+ // Undo / Redo
149
+ editor.undo(): void;
150
+ editor.redo(): void;
151
+
152
+ // Register a custom tool
153
+ editor.registerTool(definition: ToolDefinition): void;
154
+
155
+ // Register a callback (e.g. for image upload)
156
+ editor.registerCallback(type: string, callback: Function): void;
157
+
158
+ // Update body-level settings
159
+ editor.setBodyValues(values: Partial<BodyValues>): void;
160
+ ```
161
+
162
+ ### Events
163
+
164
+ ```typescript
165
+ editor.addEventListener('editor:ready', () => {
166
+ // Editor is fully initialized
167
+ });
168
+
169
+ editor.addEventListener('design:loaded', (e) => {
170
+ // A design was loaded via loadDesign()
171
+ console.log(e.detail.design);
172
+ });
173
+
174
+ editor.addEventListener('design:updated', (e) => {
175
+ // User made a change
176
+ console.log(e.detail.type); // 'content_updated' | 'row_added' | ...
177
+ });
178
+ ```
179
+
180
+ ### Export Result
181
+
182
+ ```typescript
183
+ editor.exportHtml((result) => {
184
+ result.design; // EmailDesign JSON — save this for future editing
185
+ result.html; // Complete HTML document (<!DOCTYPE> to </html>)
186
+ result.chunks; // { body, css, fonts[], js }
187
+ });
188
+ ```
189
+
190
+ ### Export Options
191
+
192
+ ```typescript
193
+ editor.exportHtml(callback, {
194
+ minify: true, // Minify HTML output
195
+ inlineStyles: true, // Inline CSS into style attributes
196
+ cleanup: true, // Remove unused CSS classes
197
+ mergeTags: { // Replace merge tags with values
198
+ first_name: 'John',
199
+ company: 'Acme',
200
+ },
201
+ });
202
+ ```
203
+
204
+ ## Built-in Content Blocks
205
+
206
+ | Block | Description | Email Safe |
207
+ |-------|-------------|:----------:|
208
+ | Text | Rich text with formatting | Yes |
209
+ | Heading | H1-H4 with size/weight/color | Yes |
210
+ | Paragraph | Block text with line-height | Yes |
211
+ | Image | Responsive image with link | Yes |
212
+ | Button | CTA button (VML Outlook fallback) | Yes |
213
+ | Divider | Horizontal line | Yes |
214
+ | HTML | Raw HTML injection | Yes |
215
+ | Social | Social media icon links | Yes |
216
+ | Menu | Horizontal navigation | Yes |
217
+ | Video | YouTube/Vimeo thumbnail + play | Yes |
218
+ | Timer | Countdown display | Yes |
219
+ | Table | Data table with headers | Yes |
220
+ | Form | Input form (web mode only) | Web only |
221
+
222
+ ## Layout Presets
223
+
224
+ Drag or click to add rows with predefined column layouts:
225
+
226
+ - `100%` — single column
227
+ - `50 / 50` — two equal columns
228
+ - `33 / 33 / 33` — three equal columns
229
+ - `66 / 33` — two-thirds + one-third
230
+ - `33 / 66` — one-third + two-thirds
231
+ - `25 / 25 / 25 / 25` — four equal columns
232
+
233
+ ## Custom Tools
234
+
235
+ Register custom content blocks with their own properties and renderers:
236
+
237
+ ```typescript
238
+ import { html } from 'lit';
239
+
240
+ editor.registerTool({
241
+ name: 'product_card',
242
+ label: 'Product Card',
243
+ icon: '<svg>...</svg>',
244
+ supportedDisplayModes: ['email'],
245
+ options: {
246
+ product: {
247
+ title: 'Product',
248
+ options: {
249
+ name: { label: 'Name', defaultValue: 'Product', widget: 'text' },
250
+ price: { label: 'Price', defaultValue: '$0.00', widget: 'text' },
251
+ image: { label: 'Image URL', defaultValue: '', widget: 'text' },
252
+ bgColor: { label: 'Background', defaultValue: '#ffffff', widget: 'color_picker' },
253
+ },
254
+ },
255
+ },
256
+ defaultValues: {
257
+ name: 'Product', price: '$0.00', image: '', bgColor: '#ffffff',
258
+ },
259
+ renderer: {
260
+ renderEditor(values) {
261
+ return html`
262
+ <div style="background:${values.bgColor};padding:16px;text-align:center;">
263
+ <img src="${values.image}" style="max-width:100%;border-radius:8px;" />
264
+ <h3 style="margin:12px 0 4px;">${values.name}</h3>
265
+ <p style="color:#3b82f6;font-weight:bold;">${values.price}</p>
266
+ </div>
267
+ `;
268
+ },
269
+ renderHtml(values, ctx) {
270
+ return `<table role="presentation" width="100%" cellpadding="0" cellspacing="0" border="0">
271
+ <tr><td style="background-color:${values.bgColor};padding:16px;text-align:center;">
272
+ <img src="${values.image}" width="${ctx.columnWidth}" style="max-width:100%;" />
273
+ <h3 style="margin:12px 0 4px;">${values.name}</h3>
274
+ <p style="color:#3b82f6;font-weight:bold;">${values.price}</p>
275
+ </td></tr>
276
+ </table>`;
277
+ },
278
+ },
279
+ });
280
+ ```
281
+
282
+ ## Design JSON Structure
283
+
284
+ Designs are stored as structured JSON. The format is interoperable with other email editor tools.
285
+
286
+ ```json
287
+ {
288
+ "counters": { "u_row": 1, "u_column": 1, "u_content_text": 1 },
289
+ "body": {
290
+ "id": "u_body",
291
+ "rows": [
292
+ {
293
+ "id": "u_row_1",
294
+ "cells": [1],
295
+ "columns": [
296
+ {
297
+ "id": "u_column_1",
298
+ "contents": [
299
+ {
300
+ "id": "u_content_text_1",
301
+ "type": "text",
302
+ "values": {
303
+ "text": "<p>Hello World</p>",
304
+ "containerPadding": "10px",
305
+ "_meta": { "htmlID": "u_content_text_1", "htmlClassNames": "u_content_text" }
306
+ }
307
+ }
308
+ ],
309
+ "values": { "backgroundColor": "", "padding": "0px", "_meta": { "htmlID": "u_column_1", "htmlClassNames": "u_column" } }
310
+ }
311
+ ],
312
+ "values": { "backgroundColor": "", "columnsBackgroundColor": "#ffffff", "padding": "0px", "_meta": { "htmlID": "u_row_1", "htmlClassNames": "u_row" } }
313
+ }
314
+ ],
315
+ "headers": [],
316
+ "footers": [],
317
+ "values": {
318
+ "backgroundColor": "#e7e7e7",
319
+ "contentWidth": "600px",
320
+ "fontFamily": { "label": "Arial", "value": "arial,helvetica,sans-serif" },
321
+ "textColor": "#000000",
322
+ "preheaderText": "",
323
+ "_meta": { "htmlID": "u_body", "htmlClassNames": "u_body" }
324
+ }
325
+ },
326
+ "schemaVersion": 16
327
+ }
328
+ ```
329
+
330
+ ## Server-Side Rendering
331
+
332
+ Use `@emabuild/email-renderer` to generate HTML from design JSON on the server (Node.js):
333
+
334
+ ```typescript
335
+ import { renderDesignToHtml } from '@emabuild/email-renderer';
336
+
337
+ const toolRenderers = new Map();
338
+ // Register tool HTML renderers...
339
+
340
+ const result = renderDesignToHtml(designJson, toolRenderers, {
341
+ minify: true,
342
+ mergeTags: { first_name: 'John' },
343
+ });
344
+
345
+ console.log(result.html); // Complete email HTML
346
+ ```
347
+
348
+ ## Email Client Support
349
+
350
+ Exported HTML uses fluid hybrid design with MSO conditional comments for maximum compatibility:
351
+
352
+ - Gmail (Web, iOS, Android)
353
+ - Outlook (2016, 2019, 365, Outlook.com)
354
+ - Apple Mail (macOS, iOS)
355
+ - Yahoo Mail
356
+ - Thunderbird
357
+ - Samsung Mail
358
+
359
+ Key techniques used:
360
+ - Table-based layout with `role="presentation"`
361
+ - MSO ghost tables (`<!--[if mso]>`) for Outlook column rendering
362
+ - VML roundrect for Outlook button border-radius
363
+ - Responsive CSS with `@media` queries
364
+ - Fluid hybrid columns (`display:inline-block` + `max-width`)
365
+ - Dark mode support (`prefers-color-scheme`)
366
+ - Preheader text with invisible padding fill
367
+
368
+ ## Keyboard Shortcuts
369
+
370
+ | Shortcut | Action |
371
+ |----------|--------|
372
+ | `Ctrl/Cmd + Z` | Undo |
373
+ | `Ctrl/Cmd + Y` | Redo |
374
+ | `Ctrl/Cmd + Shift + Z` | Redo |
375
+ | `Delete` / `Backspace` | Delete selected element |
376
+ | `Escape` | Deselect |
377
+
378
+ ## Property Widgets
379
+
380
+ Available widget types for tool property definitions:
381
+
382
+ | Widget | Type | Description |
383
+ |--------|------|-------------|
384
+ | `text` | `string` | Single-line text input |
385
+ | `rich_text` | `string` | Multi-line textarea (HTML) |
386
+ | `color_picker` | `string` | Color swatch + hex input |
387
+ | `toggle` | `boolean` | Checkbox toggle |
388
+ | `dropdown` | `string` | Select dropdown (requires `widgetParams.options`) |
389
+ | `alignment` | `string` | Left/center/right visual picker |
390
+ | `padding` | `string` | 4-side padding editor (CSS shorthand) |
391
+
392
+ ## Development
393
+
394
+ ```bash
395
+ # Install dependencies
396
+ pnpm install
397
+
398
+ # Start the demo app
399
+ pnpm --filter @emabuild/demo dev
400
+
401
+ # Build all packages
402
+ pnpm build
403
+
404
+ # Publish to npm
405
+ pnpm -r publish --access public
406
+ ```
407
+
408
+ ## License
409
+
410
+ MIT
@@ -5,26 +5,25 @@ export declare class DragManager {
5
5
  private toolRegistry;
6
6
  private root;
7
7
  private currentDrop;
8
- private indicator;
8
+ private contentIndicator;
9
9
  private rowIndicator;
10
10
  constructor(store: EditorStore, toolRegistry: ToolRegistry, root: ShadowRoot);
11
+ /** Attach all drag event listeners to the shadow root */
11
12
  attach(): void;
12
- private createIndicator;
13
+ /** Remove all event listeners and clean up indicators */
13
14
  detach(): void;
14
- private handleDragStart;
15
- private handleDragOver;
16
- private handleDrop;
17
- private handleDragEnd;
18
- private handleDragLeave;
19
- private findRowDropPosition;
20
- private findContentDropPosition;
15
+ private onDragOver;
16
+ private onDrop;
17
+ private onDragEnd;
18
+ private onDragLeave;
19
+ private handleLayoutDrop;
20
+ private handleToolDrop;
21
+ private handleContentDrop;
22
+ private findRowDropTarget;
23
+ private findContentDropTarget;
21
24
  private showContentIndicator;
22
25
  private showRowIndicator;
23
- private hideIndicator;
24
- private hideRowIndicator;
26
+ private hideAllIndicators;
25
27
  private reset;
26
- private queryShadowAll;
27
- private walkShadowDom;
28
- private findContentElement;
29
28
  }
30
29
  //# sourceMappingURL=drag-manager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"drag-manager.d.ts","sourceRoot":"","sources":["../../src/dnd/drag-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAiB9D,qBAAa,WAAW;IACtB,OAAO,CAAC,KAAK,CAAc;IAC3B,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,IAAI,CAAa;IACzB,OAAO,CAAC,WAAW,CAA2B;IAC9C,OAAO,CAAC,SAAS,CAA4B;IAC7C,OAAO,CAAC,YAAY,CAA4B;gBAEpC,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU;IAM5E,MAAM,IAAI,IAAI;IAad,OAAO,CAAC,eAAe;IAgBvB,MAAM,IAAI,IAAI;IAiBd,OAAO,CAAC,eAAe,CAGrB;IAMF,OAAO,CAAC,cAAc,CAkCpB;IAMF,OAAO,CAAC,UAAU,CA8ChB;IAEF,OAAO,CAAC,aAAa,CAInB;IAEF,OAAO,CAAC,eAAe,CAOrB;IAMF,OAAO,CAAC,mBAAmB;IAgC3B,OAAO,CAAC,uBAAuB;IAwD/B,OAAO,CAAC,oBAAoB;IAiC5B,OAAO,CAAC,gBAAgB;IAmCxB,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,gBAAgB;IAIxB,OAAO,CAAC,KAAK;IAUb,OAAO,CAAC,cAAc;IAQtB,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,kBAAkB;CAc3B"}
1
+ {"version":3,"file":"drag-manager.d.ts","sourceRoot":"","sources":["../../src/dnd/drag-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAe9D,qBAAa,WAAW;IACtB,OAAO,CAAC,KAAK,CAAc;IAC3B,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,IAAI,CAAa;IACzB,OAAO,CAAC,WAAW,CAA2B;IAC9C,OAAO,CAAC,gBAAgB,CAA4B;IACpD,OAAO,CAAC,YAAY,CAA4B;gBAEpC,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU;IAM5E,yDAAyD;IACzD,MAAM,IAAI,IAAI;IASd,yDAAyD;IACzD,MAAM,IAAI,IAAI;IAWd,OAAO,CAAC,UAAU,CAoBhB;IAEF,OAAO,CAAC,MAAM,CAqBZ;IAEF,OAAO,CAAC,SAAS,CAGf;IAEF,OAAO,CAAC,WAAW,CAMjB;IAIF,OAAO,CAAC,gBAAgB;IAMxB,OAAO,CAAC,cAAc;IAiBtB,OAAO,CAAC,iBAAiB;IASzB,OAAO,CAAC,iBAAiB;IAqBzB,OAAO,CAAC,qBAAqB;IAgD7B,OAAO,CAAC,oBAAoB;IAc5B,OAAO,CAAC,gBAAgB;IAcxB,OAAO,CAAC,iBAAiB;IAKzB,OAAO,CAAC,KAAK;CAId"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * @module drop-indicator
3
+ *
4
+ * Reusable drop indicator creation and positioning.
5
+ * Used by DragManager for both content-level (blue) and row-level (purple) indicators.
6
+ */
7
+ /**
8
+ * Create a floating drop indicator element.
9
+ * @param color - CSS color for the indicator line
10
+ * @returns An absolutely-positioned HTMLElement (hidden by default)
11
+ */
12
+ export declare function createDropIndicator(color: string): HTMLElement;
13
+ /**
14
+ * Position an indicator at a specific Y offset within a container.
15
+ * @param indicator - The indicator element
16
+ * @param container - The shadow root or element to append the indicator to
17
+ * @param items - The list of elements to position between
18
+ * @param index - The insertion index (0 = before first, items.length = after last)
19
+ * @param insetX - Horizontal inset from edges (e.g. "4px" for content, "0" for rows)
20
+ */
21
+ export declare function positionIndicator(indicator: HTMLElement, container: ShadowRoot | HTMLElement, items: HTMLElement[], index: number, insetX?: string): void;
22
+ /** Hide a drop indicator */
23
+ export declare function hideIndicator(indicator: HTMLElement | null): void;
24
+ //# sourceMappingURL=drop-indicator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drop-indicator.d.ts","sourceRoot":"","sources":["../../src/dnd/drop-indicator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,CAe9D;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,WAAW,EACtB,SAAS,EAAE,UAAU,GAAG,WAAW,EACnC,KAAK,EAAE,WAAW,EAAE,EACpB,KAAK,EAAE,MAAM,EACb,MAAM,SAAQ,GACb,IAAI,CA2BN;AAED,4BAA4B;AAC5B,wBAAgB,aAAa,CAAC,SAAS,EAAE,WAAW,GAAG,IAAI,GAAG,IAAI,CAEjE"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * @module shadow-dom-utils
3
+ *
4
+ * Utilities for traversing nested shadow DOM trees.
5
+ * Required because the editor uses Lit Web Components with shadow DOM,
6
+ * and standard `querySelectorAll` doesn't cross shadow boundaries.
7
+ */
8
+ /**
9
+ * Recursively walk all elements across shadow DOM boundaries.
10
+ * @param root - Starting point (ShadowRoot or HTMLElement)
11
+ * @param callback - Called for each element encountered
12
+ */
13
+ export declare function walkShadowDom(root: ShadowRoot | HTMLElement, callback: (el: HTMLElement) => void): void;
14
+ /**
15
+ * Query all elements matching a selector across shadow DOM boundaries.
16
+ * @param root - Starting point
17
+ * @param selector - CSS selector to match
18
+ * @returns Array of matching elements
19
+ */
20
+ export declare function queryShadowAll<T extends HTMLElement>(root: ShadowRoot | HTMLElement, selector: string): T[];
21
+ /**
22
+ * Walk up the DOM tree (including shadow DOM boundaries) to find
23
+ * an ancestor with a specific `data-*` attribute.
24
+ * @param el - Starting element
25
+ * @param dataKey - The dataset key to look for (e.g. "contentId" for data-content-id)
26
+ * @returns The matching ancestor element, or null
27
+ */
28
+ export declare function findAncestorWithData(el: HTMLElement | null, dataKey: string): HTMLElement | null;
29
+ //# sourceMappingURL=shadow-dom-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shadow-dom-utils.d.ts","sourceRoot":"","sources":["../../src/dnd/shadow-dom-utils.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,UAAU,GAAG,WAAW,EAAE,QAAQ,EAAE,CAAC,EAAE,EAAE,WAAW,KAAK,IAAI,GAAG,IAAI,CAQvG;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,WAAW,EAAE,IAAI,EAAE,UAAU,GAAG,WAAW,EAAE,QAAQ,EAAE,MAAM,GAAG,CAAC,EAAE,CAM3G;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,WAAW,GAAG,IAAI,EAAE,OAAO,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAYhG"}
package/dist/index.d.ts CHANGED
@@ -2,5 +2,5 @@ export { MailEditorElement } from './mail-editor.js';
2
2
  export { EditorStore } from './state/editor-store.js';
3
3
  export { ToolRegistry } from './tools/tool-registry.js';
4
4
  export type { LitToolDefinition } from './tools/tool-registry.js';
5
- export type { UnlayerDesign, DesignBody, DesignRow, DesignColumn, DesignContent, MailEditorConfig, ExportResult, ExportOptions, ToolDefinition, ToolPropertyGroup, ToolProperty, } from '@emabuild/types';
5
+ export type { EmailDesign, DesignBody, DesignRow, DesignColumn, DesignContent, MailEditorConfig, ExportResult, ExportOptions, ToolDefinition, ToolPropertyGroup, ToolProperty, } from '@emabuild/types';
6
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,YAAY,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAGlE,YAAY,EACV,aAAa,EACb,UAAU,EACV,SAAS,EACT,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,YAAY,GACb,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,YAAY,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAGlE,YAAY,EACV,WAAW,EACX,UAAU,EACV,SAAS,EACT,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,YAAY,GACb,MAAM,iBAAiB,CAAC"}
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { E, M, T } from "./mail-editor-CoB2C5CT.js";
1
+ import { E, M, T } from "./mail-editor-D0FbEUZu.js";
2
2
  export {
3
3
  E as EditorStore,
4
4
  M as MailEditorElement,