@emabuild/core 0.0.3 → 0.0.5

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 (57) hide show
  1. package/README.md +425 -0
  2. package/dist/canvas/column-renderer.d.ts +4 -4
  3. package/dist/canvas/column-renderer.d.ts.map +1 -1
  4. package/dist/canvas/content-renderer.d.ts +4 -4
  5. package/dist/canvas/content-renderer.d.ts.map +1 -1
  6. package/dist/canvas/editor-canvas.d.ts +4 -4
  7. package/dist/canvas/editor-canvas.d.ts.map +1 -1
  8. package/dist/canvas/row-renderer.d.ts +4 -4
  9. package/dist/canvas/row-renderer.d.ts.map +1 -1
  10. package/dist/dnd/drag-manager.d.ts.map +1 -1
  11. package/dist/form-tool-BucdYK9Z.js +69 -0
  12. package/dist/form-tool-BucdYK9Z.js.map +1 -0
  13. package/dist/html-tool-CDX3fL-9.js +49 -0
  14. package/dist/html-tool-CDX3fL-9.js.map +1 -0
  15. package/dist/index.d.ts +1 -1
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +4 -4
  18. package/dist/mail-editor-DNPaJKo3.js +1568 -0
  19. package/dist/mail-editor-DNPaJKo3.js.map +1 -0
  20. package/dist/mail-editor.d.ts +10 -3
  21. package/dist/mail-editor.d.ts.map +1 -1
  22. package/dist/mail-editor.js +2 -2
  23. package/dist/menu-tool-BrT6-Pvh.js +61 -0
  24. package/dist/menu-tool-BrT6-Pvh.js.map +1 -0
  25. package/dist/properties/property-panel.d.ts +4 -4
  26. package/dist/properties/property-panel.d.ts.map +1 -1
  27. package/dist/sidebar/body-settings.d.ts +4 -4
  28. package/dist/sidebar/body-settings.d.ts.map +1 -1
  29. package/dist/sidebar/editor-sidebar.d.ts +4 -4
  30. package/dist/sidebar/editor-sidebar.d.ts.map +1 -1
  31. package/dist/social-tool-B4BUlJ2I.js +62 -0
  32. package/dist/social-tool-B4BUlJ2I.js.map +1 -0
  33. package/dist/state/design-factory.d.ts +3 -3
  34. package/dist/state/design-factory.d.ts.map +1 -1
  35. package/dist/state/design-lookup.d.ts +7 -7
  36. package/dist/state/design-lookup.d.ts.map +1 -1
  37. package/dist/state/editor-store.d.ts +33 -4
  38. package/dist/state/editor-store.d.ts.map +1 -1
  39. package/dist/state/history-manager.d.ts +4 -4
  40. package/dist/state/history-manager.d.ts.map +1 -1
  41. package/dist/table-tool-Bo_g3Un_.js +63 -0
  42. package/dist/table-tool-Bo_g3Un_.js.map +1 -0
  43. package/dist/timer-tool-3mF08efm.js +54 -0
  44. package/dist/timer-tool-3mF08efm.js.map +1 -0
  45. package/dist/tools/built-in/tool-manifest.d.ts +9 -0
  46. package/dist/tools/built-in/tool-manifest.d.ts.map +1 -0
  47. package/dist/tools/tool-registry.d.ts +52 -1
  48. package/dist/tools/tool-registry.d.ts.map +1 -1
  49. package/dist/utils/id-generator.d.ts +4 -4
  50. package/dist/utils/id-generator.d.ts.map +1 -1
  51. package/dist/utils/store-controller.d.ts +19 -0
  52. package/dist/utils/store-controller.d.ts.map +1 -0
  53. package/dist/video-tool-CwWMKobZ.js +52 -0
  54. package/dist/video-tool-CwWMKobZ.js.map +1 -0
  55. package/package.json +16 -4
  56. package/dist/mail-editor-ClkIyPni.js +0 -2245
  57. package/dist/mail-editor-ClkIyPni.js.map +0 -1
package/README.md ADDED
@@ -0,0 +1,425 @@
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 | ~14.6KB gzip |
32
+ | [`@emabuild/email-renderer`](https://www.npmjs.com/package/@emabuild/email-renderer) | Standalone HTML export engine (works server-side) | ~2.7KB 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
+ ## Performance
393
+
394
+ The editor is optimized for speed, even with large designs (100+ rows):
395
+
396
+ - **Fine-grained reactivity** — Components subscribe only to the store channels they need. A hover event re-renders only the affected block, not the entire tree.
397
+ - **Lazy tool loading** — 7 secondary tools are loaded on-demand via dynamic imports. The initial bundle contains only the 6 most-used tools. All lazy tools are preloaded during browser idle time via `requestIdleCallback`.
398
+ - **Minified bundle** — esbuild minification reduces the core package to ~63KB (14.6KB gzip).
399
+
400
+ | Metric | Value |
401
+ |--------|-------|
402
+ | Initial bundle | 63KB min / 14.6KB gzip |
403
+ | Lazy tool chunks | 7 × ~3KB each |
404
+ | Hover re-renders | O(1) — only the affected block |
405
+ | Time to interactive | < 200ms |
406
+
407
+ ## Development
408
+
409
+ ```bash
410
+ # Install dependencies
411
+ pnpm install
412
+
413
+ # Start the demo app
414
+ pnpm --filter @emabuild/demo dev
415
+
416
+ # Build all packages
417
+ pnpm build
418
+
419
+ # Publish to npm
420
+ pnpm -r publish --access public
421
+ ```
422
+
423
+ ## License
424
+
425
+ MIT
@@ -2,14 +2,14 @@ import { LitElement } from 'lit';
2
2
  import { DesignColumn } from '@emabuild/types';
3
3
  import { EditorStore } from '../state/editor-store.js';
4
4
  import { ToolRegistry } from '../tools/tool-registry.js';
5
- declare const ColumnRenderer_base: (new (...args: any[]) => LitElement) & typeof LitElement;
6
- export declare class ColumnRenderer extends ColumnRenderer_base {
5
+ export declare class ColumnRenderer extends LitElement {
7
6
  static styles: import('lit').CSSResult;
7
+ private storeCtrl;
8
8
  column: DesignColumn;
9
- store: EditorStore;
9
+ set store(s: EditorStore);
10
+ get store(): EditorStore;
10
11
  toolRegistry: ToolRegistry;
11
12
  widthPercent: number;
12
13
  render(): import('lit').TemplateResult<1>;
13
14
  }
14
- export {};
15
15
  //# sourceMappingURL=column-renderer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"column-renderer.d.ts","sourceRoot":"","sources":["../../src/canvas/column-renderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAE5C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAE9D,OAAO,uBAAuB,CAAC;;AAE/B,qBACa,cAAe,SAAQ,mBAA2B;IAC7D,MAAM,CAAC,MAAM,0BA6BX;IAE8B,MAAM,EAAG,YAAY,CAAC;IACtB,KAAK,EAAG,WAAW,CAAC;IACpB,YAAY,EAAG,YAAY,CAAC;IAChC,YAAY,SAAO;IAE/C,MAAM;CAgCP"}
1
+ {"version":3,"file":"column-renderer.d.ts","sourceRoot":"","sources":["../../src/canvas/column-renderer.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAE5C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAE9D,OAAO,uBAAuB,CAAC;AAE/B,qBACa,cAAe,SAAQ,UAAU;IAC5C,MAAM,CAAC,MAAM,0BA6BX;IAEF,OAAO,CAAC,SAAS,CAAyC;IAE1B,MAAM,EAAG,YAAY,CAAC;IAEtD,IACI,KAAK,CAAC,CAAC,EAAE,WAAW,EAAiC;IACzD,IAAI,KAAK,IAAI,WAAW,CAAkC;IAE1B,YAAY,EAAG,YAAY,CAAC;IAChC,YAAY,SAAO;IAE/C,MAAM;CAgCP"}
@@ -2,11 +2,12 @@ import { LitElement } from 'lit';
2
2
  import { DesignContent } from '@emabuild/types';
3
3
  import { EditorStore } from '../state/editor-store.js';
4
4
  import { ToolRegistry } from '../tools/tool-registry.js';
5
- declare const ContentRenderer_base: (new (...args: any[]) => LitElement) & typeof LitElement;
6
- export declare class ContentRenderer extends ContentRenderer_base {
5
+ export declare class ContentRenderer extends LitElement {
7
6
  static styles: import('lit').CSSResult;
7
+ private storeCtrl;
8
8
  content: DesignContent;
9
- store: EditorStore;
9
+ set store(s: EditorStore);
10
+ get store(): EditorStore;
10
11
  toolRegistry: ToolRegistry;
11
12
  private handleClick;
12
13
  private handleMouseEnter;
@@ -19,5 +20,4 @@ export declare class ContentRenderer extends ContentRenderer_base {
19
20
  disconnectedCallback(): void;
20
21
  render(): import('lit').TemplateResult<1>;
21
22
  }
22
- export {};
23
23
  //# sourceMappingURL=content-renderer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"content-renderer.d.ts","sourceRoot":"","sources":["../../src/canvas/content-renderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAG5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;;AAI9D,qBACa,eAAgB,SAAQ,oBAA2B;IAC9D,MAAM,CAAC,MAAM,0BA6CX;IAE8B,OAAO,EAAG,aAAa,CAAC;IACxB,KAAK,EAAG,WAAW,CAAC;IACpB,YAAY,EAAG,YAAY,CAAC;IAE5D,OAAO,CAAC,WAAW;IAKnB,OAAO,CAAC,gBAAgB;IAIxB,OAAO,CAAC,gBAAgB;IAIxB,OAAO,CAAC,YAAY;IAKpB,OAAO,CAAC,eAAe;IAKvB,OAAO,CAAC,YAAY,CAMlB;IAEF,OAAO,CAAC,UAAU,CAGhB;IAEF,iBAAiB;IAMjB,oBAAoB;IAMpB,MAAM;CAkCP"}
1
+ {"version":3,"file":"content-renderer.d.ts","sourceRoot":"","sources":["../../src/canvas/content-renderer.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAE5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAI9D,qBACa,eAAgB,SAAQ,UAAU;IAC7C,MAAM,CAAC,MAAM,0BAyBX;IAEF,OAAO,CAAC,SAAS,CAA+D;IAEhD,OAAO,EAAG,aAAa,CAAC;IAExD,IACI,KAAK,CAAC,CAAC,EAAE,WAAW,EAAiC;IACzD,IAAI,KAAK,IAAI,WAAW,CAAkC;IAE1B,YAAY,EAAG,YAAY,CAAC;IAE5D,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,gBAAgB;IACxB,OAAO,CAAC,gBAAgB;IACxB,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,eAAe;IAEvB,OAAO,CAAC,YAAY,CAKlB;IAEF,OAAO,CAAC,UAAU,CAGhB;IAEF,iBAAiB;IAMjB,oBAAoB;IAMpB,MAAM;CAiCP"}
@@ -1,14 +1,14 @@
1
1
  import { LitElement } from 'lit';
2
2
  import { EditorStore } from '../state/editor-store.js';
3
3
  import { ToolRegistry } from '../tools/tool-registry.js';
4
- declare const EditorCanvas_base: (new (...args: any[]) => LitElement) & typeof LitElement;
5
- export declare class EditorCanvas extends EditorCanvas_base {
4
+ export declare class EditorCanvas extends LitElement {
6
5
  static styles: import('lit').CSSResult;
7
- store: EditorStore;
6
+ private storeCtrl;
7
+ set store(s: EditorStore);
8
+ get store(): EditorStore;
8
9
  toolRegistry: ToolRegistry;
9
10
  private handleCanvasClick;
10
11
  private setViewMode;
11
12
  render(): import('lit').TemplateResult<1>;
12
13
  }
13
- export {};
14
14
  //# sourceMappingURL=editor-canvas.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"editor-canvas.d.ts","sourceRoot":"","sources":["../../src/canvas/editor-canvas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAE5C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAE9D,OAAO,mBAAmB,CAAC;;AAE3B,qBACa,YAAa,SAAQ,iBAA2B;IAC3D,MAAM,CAAC,MAAM,0BAqDX;IAE8B,KAAK,EAAG,WAAW,CAAC;IACpB,YAAY,EAAG,YAAY,CAAC;IAE5D,OAAO,CAAC,iBAAiB;IAIzB,OAAO,CAAC,WAAW;IAInB,MAAM;CA4CP"}
1
+ {"version":3,"file":"editor-canvas.d.ts","sourceRoot":"","sources":["../../src/canvas/editor-canvas.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAE5C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAE9D,OAAO,mBAAmB,CAAC;AAE3B,qBACa,YAAa,SAAQ,UAAU;IAC1C,MAAM,CAAC,MAAM,0BAqDX;IAEF,OAAO,CAAC,SAAS,CAAqD;IAEtE,IACI,KAAK,CAAC,CAAC,EAAE,WAAW,EAAiC;IACzD,IAAI,KAAK,IAAI,WAAW,CAAkC;IAE1B,YAAY,EAAG,YAAY,CAAC;IAE5D,OAAO,CAAC,iBAAiB;IAIzB,OAAO,CAAC,WAAW;IAInB,MAAM;CA4CP"}
@@ -2,11 +2,12 @@ import { LitElement } from 'lit';
2
2
  import { DesignRow } from '@emabuild/types';
3
3
  import { EditorStore } from '../state/editor-store.js';
4
4
  import { ToolRegistry } from '../tools/tool-registry.js';
5
- declare const RowRenderer_base: (new (...args: any[]) => LitElement) & typeof LitElement;
6
- export declare class RowRenderer extends RowRenderer_base {
5
+ export declare class RowRenderer extends LitElement {
7
6
  static styles: import('lit').CSSResult;
7
+ private storeCtrl;
8
8
  row: DesignRow;
9
- store: EditorStore;
9
+ set store(s: EditorStore);
10
+ get store(): EditorStore;
10
11
  toolRegistry: ToolRegistry;
11
12
  private handleMoveUp;
12
13
  private handleMoveDown;
@@ -14,5 +15,4 @@ export declare class RowRenderer extends RowRenderer_base {
14
15
  private handleDelete;
15
16
  render(): import('lit').TemplateResult<1>;
16
17
  }
17
- export {};
18
18
  //# sourceMappingURL=row-renderer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"row-renderer.d.ts","sourceRoot":"","sources":["../../src/canvas/row-renderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAE5C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAE9D,OAAO,sBAAsB,CAAC;;AAE9B,qBACa,WAAY,SAAQ,gBAA2B;IAC1D,MAAM,CAAC,MAAM,0BAuDX;IAE8B,GAAG,EAAG,SAAS,CAAC;IAChB,KAAK,EAAG,WAAW,CAAC;IACpB,YAAY,EAAG,YAAY,CAAC;IAE5D,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,eAAe;IAKvB,OAAO,CAAC,YAAY;IAKpB,MAAM;CA4CP"}
1
+ {"version":3,"file":"row-renderer.d.ts","sourceRoot":"","sources":["../../src/canvas/row-renderer.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAClD,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAE5C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAE9D,OAAO,sBAAsB,CAAC;AAE9B,qBACa,WAAY,SAAQ,UAAU;IACzC,MAAM,CAAC,MAAM,0BAuDX;IAEF,OAAO,CAAC,SAAS,CAAyC;IAE1B,GAAG,EAAG,SAAS,CAAC;IAEhD,IACI,KAAK,CAAC,CAAC,EAAE,WAAW,EAAiC;IACzD,IAAI,KAAK,IAAI,WAAW,CAAkC;IAE1B,YAAY,EAAG,YAAY,CAAC;IAE5D,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,eAAe;IAKvB,OAAO,CAAC,YAAY;IAKpB,MAAM;CA4CP"}
@@ -1 +1 @@
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"}
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,CA0BZ;IAEF,OAAO,CAAC,SAAS,CAGf;IAEF,OAAO,CAAC,WAAW,CAMjB;IAIF,OAAO,CAAC,gBAAgB;YAMV,cAAc;IAmB5B,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,69 @@
1
+ import { html as b } from "lit";
2
+ import { s as o, j as f, e as u } from "./mail-editor-DNPaJKo3.js";
3
+ const n = [
4
+ { label: "Name", name: "name", type: "text", placeholder: "Your name" },
5
+ { label: "Email", name: "email", type: "email", placeholder: "your@email.com" }
6
+ ], y = {
7
+ name: "form",
8
+ label: "Form",
9
+ icon: '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2"/><path d="M7 7h10"/><path d="M7 12h10"/><path d="M7 17h6"/></svg>',
10
+ supportedDisplayModes: ["web"],
11
+ position: 13,
12
+ options: {
13
+ form: {
14
+ title: "Form",
15
+ options: {
16
+ actionUrl: { label: "Action URL", defaultValue: "#", widget: "text" },
17
+ method: { label: "Method", defaultValue: "POST", widget: "text" },
18
+ submitText: { label: "Submit Text", defaultValue: "Submit", widget: "text" },
19
+ fields: { label: "Fields (JSON)", defaultValue: JSON.stringify(n), widget: "rich_text" }
20
+ }
21
+ },
22
+ style: {
23
+ title: "Style",
24
+ options: {
25
+ buttonBg: { label: "Button Color", defaultValue: "#3b82f6", widget: "color_picker" },
26
+ buttonColor: { label: "Button Text", defaultValue: "#ffffff", widget: "color_picker" }
27
+ }
28
+ },
29
+ spacing: {
30
+ title: "Spacing",
31
+ options: { containerPadding: { label: "Padding", defaultValue: "10px", widget: "padding" } }
32
+ }
33
+ },
34
+ defaultValues: {
35
+ actionUrl: "#",
36
+ method: "POST",
37
+ submitText: "Submit",
38
+ fields: JSON.stringify(n),
39
+ buttonBg: "#3b82f6",
40
+ buttonColor: "#ffffff",
41
+ containerPadding: "10px"
42
+ },
43
+ renderer: {
44
+ renderEditor(t) {
45
+ const l = o(t, "containerPadding", "10px"), r = o(t, "submitText", "Submit"), d = o(t, "buttonBg", "#3b82f6"), a = o(t, "buttonColor", "#ffffff"), s = f(t.fields, n);
46
+ return b`
47
+ <div style="padding:${l};font-family:arial,sans-serif;">
48
+ ${s.map((e) => b`
49
+ <div style="margin-bottom:12px;">
50
+ <label style="display:block;font-size:13px;color:#374151;margin-bottom:4px;font-weight:500;">${e.label}</label>
51
+ <input type=${e.type || "text"} placeholder=${e.placeholder || ""} style="width:100%;padding:8px 12px;border:1px solid #d1d5db;border-radius:4px;font-size:14px;box-sizing:border-box;" />
52
+ </div>
53
+ `)}
54
+ <button style="background:${d};color:${a};border:none;padding:10px 24px;border-radius:4px;font-size:14px;font-weight:600;cursor:pointer;">${r}</button>
55
+ </div>
56
+ `;
57
+ },
58
+ renderHtml(t) {
59
+ const l = o(t, "containerPadding", "10px"), r = o(t, "actionUrl", "#"), d = o(t, "method", "POST"), a = o(t, "submitText", "Submit"), s = o(t, "buttonBg", "#3b82f6"), e = o(t, "buttonColor", "#ffffff"), m = f(t.fields, n), p = "font-family:arial,helvetica,sans-serif;", c = m.map(
60
+ (i) => `<div style="margin-bottom:12px;"><label style="display:block;font-size:13px;color:#374151;margin-bottom:4px;font-weight:500;${p}">${i.label}</label><input type="${i.type || "text"}" name="${i.name}" placeholder="${i.placeholder || ""}" style="width:100%;padding:8px 12px;border:1px solid #d1d5db;border-radius:4px;font-size:14px;box-sizing:border-box;${p}" /></div>`
61
+ ).join(""), x = `<form action="${r}" method="${d}">${c}<button type="submit" style="background-color:${s};color:${e};border:none;padding:10px 24px;border-radius:4px;font-size:14px;font-weight:600;cursor:pointer;${p}">${a}</button></form>`;
62
+ return u(x, { padding: l });
63
+ }
64
+ }
65
+ };
66
+ export {
67
+ y as formTool
68
+ };
69
+ //# sourceMappingURL=form-tool-BucdYK9Z.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form-tool-BucdYK9Z.js","sources":["../src/tools/built-in/form-tool.ts"],"sourcesContent":["/**\n * @module form-tool\n *\n * Input form with configurable fields and submit button.\n * Only available in \"web\" display mode (forms don't work in email).\n *\n * Email compatibility: N/A — this tool is for web/popup display mode only.\n */\n\nimport { html, TemplateResult } from 'lit';\nimport type { ContentValues } from '@emabuild/types';\nimport type { LitToolDefinition } from '../tool-registry.js';\nimport { str, jsonParse } from '../helpers/value-extractor.js';\nimport { emailTableCell } from '../helpers/email-html.js';\nimport type { FormField } from '../helpers/types.js';\n\nconst DEFAULT_FIELDS: FormField[] = [\n { label: 'Name', name: 'name', type: 'text', placeholder: 'Your name' },\n { label: 'Email', name: 'email', type: 'email', placeholder: 'your@email.com' },\n];\n\nexport const formTool: LitToolDefinition = {\n name: 'form',\n label: 'Form',\n icon: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\"/><path d=\"M7 7h10\"/><path d=\"M7 12h10\"/><path d=\"M7 17h6\"/></svg>`,\n supportedDisplayModes: ['web'],\n position: 13,\n options: {\n form: {\n title: 'Form',\n options: {\n actionUrl: { label: 'Action URL', defaultValue: '#', widget: 'text' },\n method: { label: 'Method', defaultValue: 'POST', widget: 'text' },\n submitText: { label: 'Submit Text', defaultValue: 'Submit', widget: 'text' },\n fields: { label: 'Fields (JSON)', defaultValue: JSON.stringify(DEFAULT_FIELDS), widget: 'rich_text' },\n },\n },\n style: {\n title: 'Style',\n options: {\n buttonBg: { label: 'Button Color', defaultValue: '#3b82f6', widget: 'color_picker' },\n buttonColor: { label: 'Button Text', defaultValue: '#ffffff', widget: 'color_picker' },\n },\n },\n spacing: {\n title: 'Spacing',\n options: { containerPadding: { label: 'Padding', defaultValue: '10px', widget: 'padding' } },\n },\n },\n defaultValues: {\n actionUrl: '#', method: 'POST', submitText: 'Submit',\n fields: JSON.stringify(DEFAULT_FIELDS), buttonBg: '#3b82f6',\n buttonColor: '#ffffff', containerPadding: '10px',\n },\n renderer: {\n renderEditor(values: ContentValues): TemplateResult {\n const padding = str(values, 'containerPadding', '10px');\n const submitText = str(values, 'submitText', 'Submit');\n const btnBg = str(values, 'buttonBg', '#3b82f6');\n const btnColor = str(values, 'buttonColor', '#ffffff');\n const fields = jsonParse<FormField[]>(values.fields, DEFAULT_FIELDS);\n\n return html`\n <div style=\"padding:${padding};font-family:arial,sans-serif;\">\n ${fields.map((f) => html`\n <div style=\"margin-bottom:12px;\">\n <label style=\"display:block;font-size:13px;color:#374151;margin-bottom:4px;font-weight:500;\">${f.label}</label>\n <input type=${f.type || 'text'} placeholder=${f.placeholder || ''} style=\"width:100%;padding:8px 12px;border:1px solid #d1d5db;border-radius:4px;font-size:14px;box-sizing:border-box;\" />\n </div>\n `)}\n <button style=\"background:${btnBg};color:${btnColor};border:none;padding:10px 24px;border-radius:4px;font-size:14px;font-weight:600;cursor:pointer;\">${submitText}</button>\n </div>\n `;\n },\n renderHtml(values: ContentValues): string {\n const padding = str(values, 'containerPadding', '10px');\n const actionUrl = str(values, 'actionUrl', '#');\n const method = str(values, 'method', 'POST');\n const submitText = str(values, 'submitText', 'Submit');\n const btnBg = str(values, 'buttonBg', '#3b82f6');\n const btnColor = str(values, 'buttonColor', '#ffffff');\n const fields = jsonParse<FormField[]>(values.fields, DEFAULT_FIELDS);\n const font = 'font-family:arial,helvetica,sans-serif;';\n\n const fieldsHtml = fields.map((f) =>\n `<div style=\"margin-bottom:12px;\"><label style=\"display:block;font-size:13px;color:#374151;margin-bottom:4px;font-weight:500;${font}\">${f.label}</label><input type=\"${f.type || 'text'}\" name=\"${f.name}\" placeholder=\"${f.placeholder || ''}\" style=\"width:100%;padding:8px 12px;border:1px solid #d1d5db;border-radius:4px;font-size:14px;box-sizing:border-box;${font}\" /></div>`\n ).join('');\n\n const inner = `<form action=\"${actionUrl}\" method=\"${method}\">${fieldsHtml}<button type=\"submit\" style=\"background-color:${btnBg};color:${btnColor};border:none;padding:10px 24px;border-radius:4px;font-size:14px;font-weight:600;cursor:pointer;${font}\">${submitText}</button></form>`;\n return emailTableCell(inner, { padding });\n },\n },\n};\n"],"names":["DEFAULT_FIELDS","formTool","values","padding","str","submitText","btnBg","btnColor","fields","jsonParse","html","f","actionUrl","method","font","fieldsHtml","inner","emailTableCell"],"mappings":"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"}