@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.
- package/README.md +425 -0
- package/dist/canvas/column-renderer.d.ts +4 -4
- package/dist/canvas/column-renderer.d.ts.map +1 -1
- package/dist/canvas/content-renderer.d.ts +4 -4
- package/dist/canvas/content-renderer.d.ts.map +1 -1
- package/dist/canvas/editor-canvas.d.ts +4 -4
- package/dist/canvas/editor-canvas.d.ts.map +1 -1
- package/dist/canvas/row-renderer.d.ts +4 -4
- package/dist/canvas/row-renderer.d.ts.map +1 -1
- package/dist/dnd/drag-manager.d.ts.map +1 -1
- package/dist/form-tool-BucdYK9Z.js +69 -0
- package/dist/form-tool-BucdYK9Z.js.map +1 -0
- package/dist/html-tool-CDX3fL-9.js +49 -0
- package/dist/html-tool-CDX3fL-9.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -4
- package/dist/mail-editor-DNPaJKo3.js +1568 -0
- package/dist/mail-editor-DNPaJKo3.js.map +1 -0
- package/dist/mail-editor.d.ts +10 -3
- package/dist/mail-editor.d.ts.map +1 -1
- package/dist/mail-editor.js +2 -2
- package/dist/menu-tool-BrT6-Pvh.js +61 -0
- package/dist/menu-tool-BrT6-Pvh.js.map +1 -0
- package/dist/properties/property-panel.d.ts +4 -4
- package/dist/properties/property-panel.d.ts.map +1 -1
- package/dist/sidebar/body-settings.d.ts +4 -4
- package/dist/sidebar/body-settings.d.ts.map +1 -1
- package/dist/sidebar/editor-sidebar.d.ts +4 -4
- package/dist/sidebar/editor-sidebar.d.ts.map +1 -1
- package/dist/social-tool-B4BUlJ2I.js +62 -0
- package/dist/social-tool-B4BUlJ2I.js.map +1 -0
- package/dist/state/design-factory.d.ts +3 -3
- package/dist/state/design-factory.d.ts.map +1 -1
- package/dist/state/design-lookup.d.ts +7 -7
- package/dist/state/design-lookup.d.ts.map +1 -1
- package/dist/state/editor-store.d.ts +33 -4
- package/dist/state/editor-store.d.ts.map +1 -1
- package/dist/state/history-manager.d.ts +4 -4
- package/dist/state/history-manager.d.ts.map +1 -1
- package/dist/table-tool-Bo_g3Un_.js +63 -0
- package/dist/table-tool-Bo_g3Un_.js.map +1 -0
- package/dist/timer-tool-3mF08efm.js +54 -0
- package/dist/timer-tool-3mF08efm.js.map +1 -0
- package/dist/tools/built-in/tool-manifest.d.ts +9 -0
- package/dist/tools/built-in/tool-manifest.d.ts.map +1 -0
- package/dist/tools/tool-registry.d.ts +52 -1
- package/dist/tools/tool-registry.d.ts.map +1 -1
- package/dist/utils/id-generator.d.ts +4 -4
- package/dist/utils/id-generator.d.ts.map +1 -1
- package/dist/utils/store-controller.d.ts +19 -0
- package/dist/utils/store-controller.d.ts.map +1 -0
- package/dist/video-tool-CwWMKobZ.js +52 -0
- package/dist/video-tool-CwWMKobZ.js.map +1 -0
- package/package.json +16 -4
- package/dist/mail-editor-ClkIyPni.js +0 -2245
- 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
|
|
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
|
|
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
|
|
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;
|
|
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
|
|
5
|
-
export declare class EditorCanvas extends EditorCanvas_base {
|
|
4
|
+
export declare class EditorCanvas extends LitElement {
|
|
6
5
|
static styles: import('lit').CSSResult;
|
|
7
|
-
|
|
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
|
|
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
|
|
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
|
|
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,
|
|
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":";;AAgBA,MAAMA,IAA8B;AAAA,EAClC,EAAE,OAAO,QAAQ,MAAM,QAAQ,MAAM,QAAQ,aAAa,YAAA;AAAA,EAC1D,EAAE,OAAO,SAAS,MAAM,SAAS,MAAM,SAAS,aAAa,iBAAA;AAC/D,GAEaC,IAA8B;AAAA,EACzC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,MAAM;AAAA,EACN,uBAAuB,CAAC,KAAK;AAAA,EAC7B,UAAU;AAAA,EACV,SAAS;AAAA,IACP,MAAM;AAAA,MACJ,OAAO;AAAA,MACP,SAAS;AAAA,QACP,WAAW,EAAE,OAAO,cAAc,cAAc,KAAK,QAAQ,OAAA;AAAA,QAC7D,QAAQ,EAAE,OAAO,UAAU,cAAc,QAAQ,QAAQ,OAAA;AAAA,QACzD,YAAY,EAAE,OAAO,eAAe,cAAc,UAAU,QAAQ,OAAA;AAAA,QACpE,QAAQ,EAAE,OAAO,iBAAiB,cAAc,KAAK,UAAUD,CAAc,GAAG,QAAQ,YAAA;AAAA,MAAY;AAAA,IACtG;AAAA,IAEF,OAAO;AAAA,MACL,OAAO;AAAA,MACP,SAAS;AAAA,QACP,UAAU,EAAE,OAAO,gBAAgB,cAAc,WAAW,QAAQ,eAAA;AAAA,QACpE,aAAa,EAAE,OAAO,eAAe,cAAc,WAAW,QAAQ,eAAA;AAAA,MAAe;AAAA,IACvF;AAAA,IAEF,SAAS;AAAA,MACP,OAAO;AAAA,MACP,SAAS,EAAE,kBAAkB,EAAE,OAAO,WAAW,cAAc,QAAQ,QAAQ,UAAA,EAAU;AAAA,IAAE;AAAA,EAC7F;AAAA,EAEF,eAAe;AAAA,IACb,WAAW;AAAA,IAAK,QAAQ;AAAA,IAAQ,YAAY;AAAA,IAC5C,QAAQ,KAAK,UAAUA,CAAc;AAAA,IAAG,UAAU;AAAA,IAClD,aAAa;AAAA,IAAW,kBAAkB;AAAA,EAAA;AAAA,EAE5C,UAAU;AAAA,IACR,aAAaE,GAAuC;AAClD,YAAMC,IAAUC,EAAIF,GAAQ,oBAAoB,MAAM,GAChDG,IAAaD,EAAIF,GAAQ,cAAc,QAAQ,GAC/CI,IAAQF,EAAIF,GAAQ,YAAY,SAAS,GACzCK,IAAWH,EAAIF,GAAQ,eAAe,SAAS,GAC/CM,IAASC,EAAuBP,EAAO,QAAQF,CAAc;AAEnE,aAAOU;AAAA,8BACiBP,CAAO;AAAA,YACzBK,EAAO,IAAI,CAACG,MAAMD;AAAA;AAAA,6GAE+EC,EAAE,KAAK;AAAA,4BACxFA,EAAE,QAAQ,MAAM,gBAAgBA,EAAE,eAAe,EAAE;AAAA;AAAA,WAEpE,CAAC;AAAA,sCAC0BL,CAAK,UAAUC,CAAQ,oGAAoGF,CAAU;AAAA;AAAA;AAAA,IAGvK;AAAA,IACA,WAAWH,GAA+B;AACxC,YAAMC,IAAUC,EAAIF,GAAQ,oBAAoB,MAAM,GAChDU,IAAYR,EAAIF,GAAQ,aAAa,GAAG,GACxCW,IAAST,EAAIF,GAAQ,UAAU,MAAM,GACrCG,IAAaD,EAAIF,GAAQ,cAAc,QAAQ,GAC/CI,IAAQF,EAAIF,GAAQ,YAAY,SAAS,GACzCK,IAAWH,EAAIF,GAAQ,eAAe,SAAS,GAC/CM,IAASC,EAAuBP,EAAO,QAAQF,CAAc,GAC7Dc,IAAO,2CAEPC,IAAaP,EAAO;AAAA,QAAI,CAACG,MAC7B,+HAA+HG,CAAI,KAAKH,EAAE,KAAK,wBAAwBA,EAAE,QAAQ,MAAM,WAAWA,EAAE,IAAI,kBAAkBA,EAAE,eAAe,EAAE,wHAAwHG,CAAI;AAAA,MAAA,EACzW,KAAK,EAAE,GAEHE,IAAQ,iBAAiBJ,CAAS,aAAaC,CAAM,KAAKE,CAAU,iDAAiDT,CAAK,UAAUC,CAAQ,kGAAkGO,CAAI,KAAKT,CAAU;AACvQ,aAAOY,EAAeD,GAAO,EAAE,SAAAb,GAAS;AAAA,IAC1C;AAAA,EAAA;AAEJ;"}
|