@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
@@ -1 +1 @@
1
- {"version":3,"file":"editor-sidebar.d.ts","sourceRoot":"","sources":["../../src/sidebar/editor-sidebar.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAE5C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAqB,MAAM,2BAA2B,CAAC;AAGjF,OAAO,oBAAoB,CAAC;;AAE5B,qBACa,aAAc,SAAQ,kBAA2B;IAC5D,MAAM,CAAC,MAAM,0BAkHX;IAE8B,KAAK,EAAG,WAAW,CAAC;IACpB,YAAY,EAAG,YAAY,CAAC;IAE5D,OAAO,CAAC,eAAe;IAKvB,OAAO,CAAC,qBAAqB;IAK7B,OAAO,CAAC,gBAAgB;IAKxB,MAAM;IAmBN,OAAO,CAAC,gBAAgB;IA8BxB,OAAO,CAAC,kBAAkB;IAiB1B,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,aAAa;CAGtB"}
1
+ {"version":3,"file":"editor-sidebar.d.ts","sourceRoot":"","sources":["../../src/sidebar/editor-sidebar.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAE5C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAmC,MAAM,2BAA2B,CAAC;AAG/F,OAAO,oBAAoB,CAAC;AAE5B,qBACa,aAAc,SAAQ,UAAU;IAC3C,MAAM,CAAC,MAAM,0BAqIX;IAEF,OAAO,CAAC,SAAS,CAA4C;IAE7D,IACI,KAAK,CAAC,CAAC,EAAE,WAAW,EAAiC;IACzD,IAAI,KAAK,IAAI,WAAW,CAAkC;IAE1B,YAAY,EAAG,YAAY,CAAC;IAE5D,OAAO,CAAC,eAAe;IAKvB,OAAO,CAAC,qBAAqB;IAK7B,OAAO,CAAC,gBAAgB;IAKxB,MAAM;IAmBN,OAAO,CAAC,gBAAgB;IA8BxB,OAAO,CAAC,kBAAkB;IAiB1B,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,aAAa;CAGtB"}
@@ -0,0 +1,62 @@
1
+ import { html as s } from "lit";
2
+ import { s as t, j as g, e as x } from "./mail-editor-DNPaJKo3.js";
3
+ const l = [
4
+ { name: "Facebook", url: "https://facebook.com/", icon: "f", color: "#1877F2" },
5
+ { name: "Twitter", url: "https://twitter.com/", icon: "𝕏", color: "#000000" },
6
+ { name: "Instagram", url: "https://instagram.com/", icon: "📷", color: "#E4405F" },
7
+ { name: "LinkedIn", url: "https://linkedin.com/", icon: "in", color: "#0A66C2" }
8
+ ], h = {
9
+ name: "social",
10
+ label: "Social",
11
+ 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"><circle cx="18" cy="5" r="3"/><circle cx="6" cy="12" r="3"/><circle cx="18" cy="19" r="3"/><line x1="8.59" y1="13.51" x2="15.42" y2="17.49"/><line x1="15.41" y1="6.51" x2="8.59" y2="10.49"/></svg>',
12
+ supportedDisplayModes: ["email", "web"],
13
+ position: 8,
14
+ options: {
15
+ icons: {
16
+ title: "Social Icons",
17
+ options: {
18
+ icons: { label: "Icons (JSON)", defaultValue: JSON.stringify(l), widget: "rich_text" },
19
+ iconSize: { label: "Icon Size", defaultValue: "32px", widget: "text" },
20
+ iconSpacing: { label: "Spacing", defaultValue: "8px", widget: "text" }
21
+ }
22
+ },
23
+ style: {
24
+ title: "Style",
25
+ options: { textAlign: { label: "Align", defaultValue: "center", widget: "alignment" } }
26
+ },
27
+ spacing: {
28
+ title: "Spacing",
29
+ options: { containerPadding: { label: "Padding", defaultValue: "10px", widget: "padding" } }
30
+ }
31
+ },
32
+ defaultValues: {
33
+ icons: JSON.stringify(l),
34
+ iconSize: "32px",
35
+ iconSpacing: "8px",
36
+ textAlign: "center",
37
+ containerPadding: "10px"
38
+ },
39
+ renderer: {
40
+ renderEditor(n) {
41
+ const c = t(n, "containerPadding", "10px"), o = t(n, "textAlign", "center"), i = t(n, "iconSize", "32px"), a = t(n, "iconSpacing", "8px"), d = g(n.icons, l);
42
+ return s`
43
+ <div style="padding:${c};text-align:${o};">
44
+ ${d.map((e) => s`
45
+ <a href=${e.url} target="_blank" style="display:inline-block;width:${i};height:${i};line-height:${i};text-align:center;background:${e.color};color:white;border-radius:50%;text-decoration:none;font-size:14px;font-weight:bold;margin:0 ${a};font-family:arial,sans-serif;vertical-align:middle;">${e.icon}</a>
46
+ `)}
47
+ </div>
48
+ `;
49
+ },
50
+ renderHtml(n) {
51
+ const c = t(n, "containerPadding", "10px"), o = t(n, "textAlign", "center"), i = t(n, "iconSize", "32"), a = t(n, "iconSpacing", "8px"), e = g(n.icons, l).map(
52
+ (r) => `<td align="center" valign="middle" style="padding:0 ${a};"><a href="${r.url}" target="_blank" style="text-decoration:none;"><table role="presentation" cellpadding="0" cellspacing="0" border="0"><tr><td width="${i}" height="${i}" align="center" valign="middle" style="width:${i}px;height:${i}px;background:${r.color};border-radius:50%;color:#fff;font-size:14px;font-weight:bold;font-family:arial,sans-serif;">${r.icon}</td></tr></table></a></td>`
53
+ ).join(`
54
+ `), p = `<table role="presentation" cellpadding="0" cellspacing="0" border="0" align="${o}"><tr>${e}</tr></table>`;
55
+ return x(p, { padding: c, align: o });
56
+ }
57
+ }
58
+ };
59
+ export {
60
+ h as socialTool
61
+ };
62
+ //# sourceMappingURL=social-tool-B4BUlJ2I.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"social-tool-B4BUlJ2I.js","sources":["../src/tools/built-in/social-tool.ts"],"sourcesContent":["/**\n * @module social-tool\n *\n * Social media icon links (Facebook, Twitter, Instagram, LinkedIn, etc.).\n *\n * Email compatibility: Uses nested tables for icon layout.\n * Each icon is a colored circle with centered text, rendered\n * as a table cell for cross-client consistency.\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 { SocialIcon } from '../helpers/types.js';\n\nconst DEFAULT_ICONS: SocialIcon[] = [\n { name: 'Facebook', url: 'https://facebook.com/', icon: 'f', color: '#1877F2' },\n { name: 'Twitter', url: 'https://twitter.com/', icon: '𝕏', color: '#000000' },\n { name: 'Instagram', url: 'https://instagram.com/', icon: '📷', color: '#E4405F' },\n { name: 'LinkedIn', url: 'https://linkedin.com/', icon: 'in', color: '#0A66C2' },\n];\n\nexport const socialTool: LitToolDefinition = {\n name: 'social',\n label: 'Social',\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\"><circle cx=\"18\" cy=\"5\" r=\"3\"/><circle cx=\"6\" cy=\"12\" r=\"3\"/><circle cx=\"18\" cy=\"19\" r=\"3\"/><line x1=\"8.59\" y1=\"13.51\" x2=\"15.42\" y2=\"17.49\"/><line x1=\"15.41\" y1=\"6.51\" x2=\"8.59\" y2=\"10.49\"/></svg>`,\n supportedDisplayModes: ['email', 'web'],\n position: 8,\n options: {\n icons: {\n title: 'Social Icons',\n options: {\n icons: { label: 'Icons (JSON)', defaultValue: JSON.stringify(DEFAULT_ICONS), widget: 'rich_text' },\n iconSize: { label: 'Icon Size', defaultValue: '32px', widget: 'text' },\n iconSpacing: { label: 'Spacing', defaultValue: '8px', widget: 'text' },\n },\n },\n style: {\n title: 'Style',\n options: { textAlign: { label: 'Align', defaultValue: 'center', widget: 'alignment' } },\n },\n spacing: {\n title: 'Spacing',\n options: { containerPadding: { label: 'Padding', defaultValue: '10px', widget: 'padding' } },\n },\n },\n defaultValues: {\n icons: JSON.stringify(DEFAULT_ICONS), iconSize: '32px', iconSpacing: '8px',\n textAlign: 'center', containerPadding: '10px',\n },\n renderer: {\n renderEditor(values: ContentValues): TemplateResult {\n const padding = str(values, 'containerPadding', '10px');\n const align = str(values, 'textAlign', 'center');\n const iconSize = str(values, 'iconSize', '32px');\n const spacing = str(values, 'iconSpacing', '8px');\n const icons = jsonParse<SocialIcon[]>(values.icons, DEFAULT_ICONS);\n\n return html`\n <div style=\"padding:${padding};text-align:${align};\">\n ${icons.map((s) => html`\n <a href=${s.url} target=\"_blank\" style=\"display:inline-block;width:${iconSize};height:${iconSize};line-height:${iconSize};text-align:center;background:${s.color};color:white;border-radius:50%;text-decoration:none;font-size:14px;font-weight:bold;margin:0 ${spacing};font-family:arial,sans-serif;vertical-align:middle;\">${s.icon}</a>\n `)}\n </div>\n `;\n },\n renderHtml(values: ContentValues): string {\n const padding = str(values, 'containerPadding', '10px');\n const align = str(values, 'textAlign', 'center');\n const iconSize = str(values, 'iconSize', '32');\n const spacing = str(values, 'iconSpacing', '8px');\n const icons = jsonParse<SocialIcon[]>(values.icons, DEFAULT_ICONS);\n\n const cells = icons.map((s) =>\n `<td align=\"center\" valign=\"middle\" style=\"padding:0 ${spacing};\"><a href=\"${s.url}\" target=\"_blank\" style=\"text-decoration:none;\"><table role=\"presentation\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\"><tr><td width=\"${iconSize}\" height=\"${iconSize}\" align=\"center\" valign=\"middle\" style=\"width:${iconSize}px;height:${iconSize}px;background:${s.color};border-radius:50%;color:#fff;font-size:14px;font-weight:bold;font-family:arial,sans-serif;\">${s.icon}</td></tr></table></a></td>`\n ).join('\\n');\n\n const inner = `<table role=\"presentation\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" align=\"${align}\"><tr>${cells}</tr></table>`;\n return emailTableCell(inner, { padding, align });\n },\n },\n};\n"],"names":["DEFAULT_ICONS","socialTool","values","padding","str","align","iconSize","spacing","icons","jsonParse","html","s","cells","inner","emailTableCell"],"mappings":";;AAiBA,MAAMA,IAA8B;AAAA,EAClC,EAAE,MAAM,YAAY,KAAK,yBAAyB,MAAM,KAAK,OAAO,UAAA;AAAA,EACpE,EAAE,MAAM,WAAW,KAAK,wBAAwB,MAAM,MAAM,OAAO,UAAA;AAAA,EACnE,EAAE,MAAM,aAAa,KAAK,0BAA0B,MAAM,MAAM,OAAO,UAAA;AAAA,EACvE,EAAE,MAAM,YAAY,KAAK,yBAAyB,MAAM,MAAM,OAAO,UAAA;AACvE,GAEaC,IAAgC;AAAA,EAC3C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,MAAM;AAAA,EACN,uBAAuB,CAAC,SAAS,KAAK;AAAA,EACtC,UAAU;AAAA,EACV,SAAS;AAAA,IACP,OAAO;AAAA,MACL,OAAO;AAAA,MACP,SAAS;AAAA,QACP,OAAO,EAAE,OAAO,gBAAgB,cAAc,KAAK,UAAUD,CAAa,GAAG,QAAQ,YAAA;AAAA,QACrF,UAAU,EAAE,OAAO,aAAa,cAAc,QAAQ,QAAQ,OAAA;AAAA,QAC9D,aAAa,EAAE,OAAO,WAAW,cAAc,OAAO,QAAQ,OAAA;AAAA,MAAO;AAAA,IACvE;AAAA,IAEF,OAAO;AAAA,MACL,OAAO;AAAA,MACP,SAAS,EAAE,WAAW,EAAE,OAAO,SAAS,cAAc,UAAU,QAAQ,YAAA,EAAY;AAAA,IAAE;AAAA,IAExF,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,OAAO,KAAK,UAAUA,CAAa;AAAA,IAAG,UAAU;AAAA,IAAQ,aAAa;AAAA,IACrE,WAAW;AAAA,IAAU,kBAAkB;AAAA,EAAA;AAAA,EAEzC,UAAU;AAAA,IACR,aAAaE,GAAuC;AAClD,YAAMC,IAAUC,EAAIF,GAAQ,oBAAoB,MAAM,GAChDG,IAAQD,EAAIF,GAAQ,aAAa,QAAQ,GACzCI,IAAWF,EAAIF,GAAQ,YAAY,MAAM,GACzCK,IAAUH,EAAIF,GAAQ,eAAe,KAAK,GAC1CM,IAAQC,EAAwBP,EAAO,OAAOF,CAAa;AAEjE,aAAOU;AAAA,8BACiBP,CAAO,eAAeE,CAAK;AAAA,YAC7CG,EAAM,IAAI,CAACG,MAAMD;AAAA,sBACPC,EAAE,GAAG,sDAAsDL,CAAQ,WAAWA,CAAQ,gBAAgBA,CAAQ,iCAAiCK,EAAE,KAAK,gGAAgGJ,CAAO,yDAAyDI,EAAE,IAAI;AAAA,WACvU,CAAC;AAAA;AAAA;AAAA,IAGR;AAAA,IACA,WAAWT,GAA+B;AACxC,YAAMC,IAAUC,EAAIF,GAAQ,oBAAoB,MAAM,GAChDG,IAAQD,EAAIF,GAAQ,aAAa,QAAQ,GACzCI,IAAWF,EAAIF,GAAQ,YAAY,IAAI,GACvCK,IAAUH,EAAIF,GAAQ,eAAe,KAAK,GAG1CU,IAFQH,EAAwBP,EAAO,OAAOF,CAAa,EAE7C;AAAA,QAAI,CAACW,MACvB,uDAAuDJ,CAAO,eAAeI,EAAE,GAAG,wIAAwIL,CAAQ,aAAaA,CAAQ,iDAAiDA,CAAQ,aAAaA,CAAQ,iBAAiBK,EAAE,KAAK,gGAAgGA,EAAE,IAAI;AAAA,MAAA,EACnc,KAAK;AAAA,CAAI,GAELE,IAAQ,gFAAgFR,CAAK,SAASO,CAAK;AACjH,aAAOE,EAAeD,GAAO,EAAE,SAAAV,GAAS,OAAAE,GAAO;AAAA,IACjD;AAAA,EAAA;AAEJ;"}
@@ -1,7 +1,7 @@
1
- import { UnlayerDesign, DesignRow, DesignContent } from '@emabuild/types';
1
+ import { EmailDesign, DesignRow, DesignContent } from '@emabuild/types';
2
2
  import { CounterManager } from '../utils/id-generator.js';
3
- /** Create a blank Unlayer-compatible design */
4
- export declare function createEmptyDesign(): UnlayerDesign;
3
+ /** Create a blank design */
4
+ export declare function createEmptyDesign(): EmailDesign;
5
5
  /** Create a new row with the given column proportions (e.g. [1,1] for 50/50) */
6
6
  export declare function createRow(cm: CounterManager, cellProportions: number[]): DesignRow;
7
7
  /** Create a new content block for the given tool type */
@@ -1 +1 @@
1
- {"version":3,"file":"design-factory.d.ts","sourceRoot":"","sources":["../../src/state/design-factory.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAC/E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE/D,+CAA+C;AAC/C,wBAAgB,iBAAiB,IAAI,aAAa,CA4CjD;AAED,gFAAgF;AAChF,wBAAgB,SAAS,CAAC,EAAE,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,EAAE,GAAG,SAAS,CAmClF;AAED,yDAAyD;AACzD,wBAAgB,aAAa,CAAC,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,aAAa,CAiBnH"}
1
+ {"version":3,"file":"design-factory.d.ts","sourceRoot":"","sources":["../../src/state/design-factory.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAC7E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE/D,4BAA4B;AAC5B,wBAAgB,iBAAiB,IAAI,WAAW,CA4C/C;AAED,gFAAgF;AAChF,wBAAgB,SAAS,CAAC,EAAE,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,EAAE,GAAG,SAAS,CAmClF;AAED,yDAAyD;AACzD,wBAAgB,aAAa,CAAC,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,aAAa,CAiBnH"}
@@ -1,14 +1,14 @@
1
- import { UnlayerDesign, DesignRow, DesignColumn, DesignContent } from '@emabuild/types';
1
+ import { EmailDesign, DesignRow, DesignColumn, DesignContent } from '@emabuild/types';
2
2
  /** Find a row by ID */
3
- export declare function findRow(design: UnlayerDesign, rowId: string): DesignRow | undefined;
3
+ export declare function findRow(design: EmailDesign, rowId: string): DesignRow | undefined;
4
4
  /** Find a column by ID across all rows */
5
- export declare function findColumn(design: UnlayerDesign, columnId: string): DesignColumn | undefined;
5
+ export declare function findColumn(design: EmailDesign, columnId: string): DesignColumn | undefined;
6
6
  /** Find a content block by ID across all rows and columns */
7
- export declare function findContent(design: UnlayerDesign, contentId: string): DesignContent | undefined;
7
+ export declare function findContent(design: EmailDesign, contentId: string): DesignContent | undefined;
8
8
  /** Find the column that contains a given content block */
9
- export declare function findParentColumn(design: UnlayerDesign, contentId: string): DesignColumn | undefined;
9
+ export declare function findParentColumn(design: EmailDesign, contentId: string): DesignColumn | undefined;
10
10
  /** Find the row that contains a given column */
11
- export declare function findParentRow(design: UnlayerDesign, columnId: string): DesignRow | undefined;
11
+ export declare function findParentRow(design: EmailDesign, columnId: string): DesignRow | undefined;
12
12
  /** Get the index of a row within the design */
13
- export declare function getRowIndex(design: UnlayerDesign, rowId: string): number;
13
+ export declare function getRowIndex(design: EmailDesign, rowId: string): number;
14
14
  //# sourceMappingURL=design-lookup.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"design-lookup.d.ts","sourceRoot":"","sources":["../../src/state/design-lookup.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAE7F,uBAAuB;AACvB,wBAAgB,OAAO,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAEnF;AAED,0CAA0C;AAC1C,wBAAgB,UAAU,CAAC,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAM5F;AAED,6DAA6D;AAC7D,wBAAgB,WAAW,CAAC,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAQ/F;AAED,0DAA0D;AAC1D,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAOnG;AAED,gDAAgD;AAChD,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAK5F;AAED,+CAA+C;AAC/C,wBAAgB,WAAW,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAExE"}
1
+ {"version":3,"file":"design-lookup.d.ts","sourceRoot":"","sources":["../../src/state/design-lookup.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAE3F,uBAAuB;AACvB,wBAAgB,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAEjF;AAED,0CAA0C;AAC1C,wBAAgB,UAAU,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAM1F;AAED,6DAA6D;AAC7D,wBAAgB,WAAW,CAAC,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAQ7F;AAED,0DAA0D;AAC1D,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAOjG;AAED,gDAAgD;AAChD,wBAAgB,aAAa,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAK1F;AAED,+CAA+C;AAC/C,wBAAgB,WAAW,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAEtE"}
@@ -1,11 +1,26 @@
1
- import { UnlayerDesign, DesignBody, DesignRow, DesignColumn, DesignContent, BodyValues, RowValues, ColumnValues, ContentValues } from '@emabuild/types';
1
+ import { EmailDesign, DesignBody, DesignRow, DesignColumn, DesignContent, BodyValues, RowValues, ColumnValues, ContentValues } from '@emabuild/types';
2
2
  import { EventEmitter } from '../utils/event-emitter.js';
3
3
  export type StoreSubscriber = () => void;
4
+ /**
5
+ * Notification channels for fine-grained reactivity.
6
+ * Components subscribe only to the channels they care about,
7
+ * avoiding unnecessary re-renders.
8
+ *
9
+ * - `design` — row/column/content mutations, body value changes, undo/redo, load
10
+ * - `selection` — selected element changed
11
+ * - `hover` — hovered element changed
12
+ * - `viewMode` — desktop/mobile toggle
13
+ * - `activeTab` — sidebar tab switch
14
+ */
15
+ export type StoreChannel = 'design' | 'selection' | 'hover' | 'viewMode' | 'activeTab';
4
16
  export declare class EditorStore {
5
17
  private design;
6
18
  private history;
7
19
  private counterManager;
20
+ /** Legacy: subscribers that listen to ALL changes */
8
21
  private subscribers;
22
+ /** Channel-based subscribers: only notified on specific changes */
23
+ private channelSubscribers;
9
24
  /** Public event emitter for design:loaded, design:updated, etc. */
10
25
  readonly events: EventEmitter;
11
26
  private _selectedId;
@@ -13,11 +28,25 @@ export declare class EditorStore {
13
28
  private _viewMode;
14
29
  private _activeTab;
15
30
  constructor();
16
- /** Subscribe to all state changes. Returns an unsubscribe function. */
31
+ /** Subscribe to ALL state changes (legacy). Returns an unsubscribe function. */
17
32
  subscribe(fn: StoreSubscriber): () => void;
33
+ /**
34
+ * Subscribe to specific channels only. The callback is invoked only
35
+ * when one of the listed channels fires. Returns an unsubscribe function.
36
+ *
37
+ * @example
38
+ * ```ts
39
+ * // Only re-render when the design changes, not on hover/selection
40
+ * store.subscribeChannels(['design'], () => this.requestUpdate());
41
+ * ```
42
+ */
43
+ subscribeChannels(channels: StoreChannel[], fn: StoreSubscriber): () => void;
44
+ /** Notify legacy (all) subscribers */
18
45
  private notify;
46
+ /** Notify only subscribers of specific channels + legacy subscribers */
47
+ private notifyChannels;
19
48
  /** Get the full design document */
20
- getDesign(): UnlayerDesign;
49
+ getDesign(): EmailDesign;
21
50
  /** Get the design body */
22
51
  getBody(): DesignBody;
23
52
  /** Get all rows */
@@ -31,7 +60,7 @@ export declare class EditorStore {
31
60
  get canUndo(): boolean;
32
61
  get canRedo(): boolean;
33
62
  /** Load a design document, resetting history and selection */
34
- loadDesign(design: UnlayerDesign): void;
63
+ loadDesign(design: EmailDesign): void;
35
64
  undo(): void;
36
65
  redo(): void;
37
66
  select(id: string | null): void;
@@ -1 +1 @@
1
- {"version":3,"file":"editor-store.d.ts","sourceRoot":"","sources":["../../src/state/editor-store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"editor-store.d.ts","sourceRoot":"","sources":["../../src/state/editor-store.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { UnlayerDesign } from '@emabuild/types';
1
+ import { EmailDesign } from '@emabuild/types';
2
2
  export declare class HistoryManager {
3
3
  private undoStack;
4
4
  private redoStack;
@@ -9,11 +9,11 @@ export declare class HistoryManager {
9
9
  /** Whether there are states to redo to */
10
10
  get canRedo(): boolean;
11
11
  /** Save current design to the undo stack before a mutation */
12
- push(design: UnlayerDesign): void;
12
+ push(design: EmailDesign): void;
13
13
  /** Restore the previous state, pushing current state to redo. Returns the restored design or undefined. */
14
- undo(currentDesign: UnlayerDesign): UnlayerDesign | undefined;
14
+ undo(currentDesign: EmailDesign): EmailDesign | undefined;
15
15
  /** Restore the next state, pushing current state to undo. Returns the restored design or undefined. */
16
- redo(currentDesign: UnlayerDesign): UnlayerDesign | undefined;
16
+ redo(currentDesign: EmailDesign): EmailDesign | undefined;
17
17
  /** Clear all history (e.g. when loading a new design) */
18
18
  clear(): void;
19
19
  }
@@ -1 +1 @@
1
- {"version":3,"file":"history-manager.d.ts","sourceRoot":"","sources":["../../src/state/history-manager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD,qBAAa,cAAc;IACzB,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;gBAExB,UAAU,SAAK;IAI3B,0CAA0C;IAC1C,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,0CAA0C;IAC1C,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,8DAA8D;IAC9D,IAAI,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI;IAQjC,2GAA2G;IAC3G,IAAI,CAAC,aAAa,EAAE,aAAa,GAAG,aAAa,GAAG,SAAS;IAO7D,uGAAuG;IACvG,IAAI,CAAC,aAAa,EAAE,aAAa,GAAG,aAAa,GAAG,SAAS;IAO7D,yDAAyD;IACzD,KAAK,IAAI,IAAI;CAId"}
1
+ {"version":3,"file":"history-manager.d.ts","sourceRoot":"","sources":["../../src/state/history-manager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEnD,qBAAa,cAAc;IACzB,OAAO,CAAC,SAAS,CAAqB;IACtC,OAAO,CAAC,SAAS,CAAqB;IACtC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;gBAExB,UAAU,SAAK;IAI3B,0CAA0C;IAC1C,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,0CAA0C;IAC1C,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,8DAA8D;IAC9D,IAAI,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI;IAQ/B,2GAA2G;IAC3G,IAAI,CAAC,aAAa,EAAE,WAAW,GAAG,WAAW,GAAG,SAAS;IAOzD,uGAAuG;IACvG,IAAI,CAAC,aAAa,EAAE,WAAW,GAAG,WAAW,GAAG,SAAS;IAOzD,yDAAyD;IACzD,KAAK,IAAI,IAAI;CAId"}
@@ -0,0 +1,63 @@
1
+ import { html as i } from "lit";
2
+ import { s as t, j as f, e as C } from "./mail-editor-DNPaJKo3.js";
3
+ const n = [
4
+ ["Header 1", "Header 2", "Header 3"],
5
+ ["Cell 1", "Cell 2", "Cell 3"],
6
+ ["Cell 4", "Cell 5", "Cell 6"]
7
+ ], m = {
8
+ name: "table",
9
+ label: "Table",
10
+ 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="M3 9h18"/><path d="M3 15h18"/><path d="M9 3v18"/><path d="M15 3v18"/></svg>',
11
+ supportedDisplayModes: ["email", "web"],
12
+ position: 12,
13
+ options: {
14
+ table: {
15
+ title: "Table",
16
+ options: { tableData: { label: "Table Data (JSON)", defaultValue: JSON.stringify(n), widget: "rich_text" } }
17
+ },
18
+ style: {
19
+ title: "Style",
20
+ options: {
21
+ headerBg: { label: "Header Background", defaultValue: "#f3f4f6", widget: "color_picker" },
22
+ headerColor: { label: "Header Text Color", defaultValue: "#111827", widget: "color_picker" },
23
+ borderColor: { label: "Border Color", defaultValue: "#e5e7eb", widget: "color_picker" },
24
+ cellPadding: { label: "Cell Padding", defaultValue: "8px 12px", widget: "text" },
25
+ fontSize: { label: "Font Size", defaultValue: "14px", widget: "text" }
26
+ }
27
+ },
28
+ spacing: {
29
+ title: "Spacing",
30
+ options: { containerPadding: { label: "Padding", defaultValue: "10px", widget: "padding" } }
31
+ }
32
+ },
33
+ defaultValues: {
34
+ tableData: JSON.stringify(n),
35
+ headerBg: "#f3f4f6",
36
+ headerColor: "#111827",
37
+ borderColor: "#e5e7eb",
38
+ cellPadding: "8px 12px",
39
+ fontSize: "14px",
40
+ containerPadding: "10px"
41
+ },
42
+ renderer: {
43
+ renderEditor(e) {
44
+ const s = t(e, "containerPadding", "10px"), p = t(e, "headerBg", "#f3f4f6"), c = t(e, "headerColor", "#111827"), l = t(e, "borderColor", "#e5e7eb"), a = t(e, "cellPadding", "8px 12px"), r = t(e, "fontSize", "14px"), d = f(e.tableData, n);
45
+ return i`
46
+ <div style="padding:${s};overflow-x:auto;">
47
+ <table style="width:100%;border-collapse:collapse;font-size:${r};font-family:arial,sans-serif;">
48
+ <thead><tr>${d[0]?.map((o) => i`<th style="padding:${a};background:${p};color:${c};border:1px solid ${l};text-align:left;font-weight:600;">${o}</th>`)}</tr></thead>
49
+ <tbody>${d.slice(1).map((o) => i`<tr>${o.map((g) => i`<td style="padding:${a};border:1px solid ${l};">${g}</td>`)}</tr>`)}</tbody>
50
+ </table>
51
+ </div>
52
+ `;
53
+ },
54
+ renderHtml(e) {
55
+ const s = t(e, "containerPadding", "10px"), p = t(e, "headerBg", "#f3f4f6"), c = t(e, "headerColor", "#111827"), l = t(e, "borderColor", "#e5e7eb"), a = t(e, "cellPadding", "8px 12px"), r = t(e, "fontSize", "14px"), d = f(e.tableData, n), o = "font-family:arial,helvetica,sans-serif;", g = (d[0] || []).map((b) => `<th style="padding:${a};background-color:${p};color:${c};border:1px solid ${l};text-align:left;font-weight:600;${o}font-size:${r};">${b}</th>`).join(""), h = d.slice(1).map((b) => `<tr>${b.map(($) => `<td style="padding:${a};border:1px solid ${l};${o}font-size:${r};">${$}</td>`).join("")}</tr>`).join(""), x = `<table cellpadding="0" cellspacing="0" width="100%" border="0" style="border-collapse:collapse;"><thead><tr>${g}</tr></thead><tbody>${h}</tbody></table>`;
56
+ return C(x, { padding: s });
57
+ }
58
+ }
59
+ };
60
+ export {
61
+ m as tableTool
62
+ };
63
+ //# sourceMappingURL=table-tool-Bo_g3Un_.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table-tool-Bo_g3Un_.js","sources":["../src/tools/built-in/table-tool.ts"],"sourcesContent":["/**\n * @module table-tool\n *\n * Data table with configurable header styling and borders.\n *\n * Email compatibility: Uses standard HTML `<table>` with inline styles.\n * All borders, padding, and colors are inline for cross-client support.\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';\n\nconst DEFAULT_DATA = [\n ['Header 1', 'Header 2', 'Header 3'],\n ['Cell 1', 'Cell 2', 'Cell 3'],\n ['Cell 4', 'Cell 5', 'Cell 6'],\n];\n\nexport const tableTool: LitToolDefinition = {\n name: 'table',\n label: 'Table',\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=\"M3 9h18\"/><path d=\"M3 15h18\"/><path d=\"M9 3v18\"/><path d=\"M15 3v18\"/></svg>`,\n supportedDisplayModes: ['email', 'web'],\n position: 12,\n options: {\n table: {\n title: 'Table',\n options: { tableData: { label: 'Table Data (JSON)', defaultValue: JSON.stringify(DEFAULT_DATA), widget: 'rich_text' } },\n },\n style: {\n title: 'Style',\n options: {\n headerBg: { label: 'Header Background', defaultValue: '#f3f4f6', widget: 'color_picker' },\n headerColor: { label: 'Header Text Color', defaultValue: '#111827', widget: 'color_picker' },\n borderColor: { label: 'Border Color', defaultValue: '#e5e7eb', widget: 'color_picker' },\n cellPadding: { label: 'Cell Padding', defaultValue: '8px 12px', widget: 'text' },\n fontSize: { label: 'Font Size', defaultValue: '14px', widget: 'text' },\n },\n },\n spacing: {\n title: 'Spacing',\n options: { containerPadding: { label: 'Padding', defaultValue: '10px', widget: 'padding' } },\n },\n },\n defaultValues: {\n tableData: JSON.stringify(DEFAULT_DATA), headerBg: '#f3f4f6', headerColor: '#111827',\n borderColor: '#e5e7eb', cellPadding: '8px 12px', fontSize: '14px', containerPadding: '10px',\n },\n renderer: {\n renderEditor(values: ContentValues): TemplateResult {\n const padding = str(values, 'containerPadding', '10px');\n const hBg = str(values, 'headerBg', '#f3f4f6');\n const hColor = str(values, 'headerColor', '#111827');\n const bColor = str(values, 'borderColor', '#e5e7eb');\n const cPad = str(values, 'cellPadding', '8px 12px');\n const fSize = str(values, 'fontSize', '14px');\n const data = jsonParse<string[][]>(values.tableData, DEFAULT_DATA);\n\n return html`\n <div style=\"padding:${padding};overflow-x:auto;\">\n <table style=\"width:100%;border-collapse:collapse;font-size:${fSize};font-family:arial,sans-serif;\">\n <thead><tr>${data[0]?.map((c) => html`<th style=\"padding:${cPad};background:${hBg};color:${hColor};border:1px solid ${bColor};text-align:left;font-weight:600;\">${c}</th>`)}</tr></thead>\n <tbody>${data.slice(1).map((row) => html`<tr>${row.map((c) => html`<td style=\"padding:${cPad};border:1px solid ${bColor};\">${c}</td>`)}</tr>`)}</tbody>\n </table>\n </div>\n `;\n },\n renderHtml(values: ContentValues): string {\n const padding = str(values, 'containerPadding', '10px');\n const hBg = str(values, 'headerBg', '#f3f4f6');\n const hColor = str(values, 'headerColor', '#111827');\n const bColor = str(values, 'borderColor', '#e5e7eb');\n const cPad = str(values, 'cellPadding', '8px 12px');\n const fSize = str(values, 'fontSize', '14px');\n const data = jsonParse<string[][]>(values.tableData, DEFAULT_DATA);\n const font = 'font-family:arial,helvetica,sans-serif;';\n\n const hCells = (data[0] || []).map((c) => `<th style=\"padding:${cPad};background-color:${hBg};color:${hColor};border:1px solid ${bColor};text-align:left;font-weight:600;${font}font-size:${fSize};\">${c}</th>`).join('');\n const bRows = data.slice(1).map((row) => `<tr>${row.map((c) => `<td style=\"padding:${cPad};border:1px solid ${bColor};${font}font-size:${fSize};\">${c}</td>`).join('')}</tr>`).join('');\n const inner = `<table cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" border=\"0\" style=\"border-collapse:collapse;\"><thead><tr>${hCells}</tr></thead><tbody>${bRows}</tbody></table>`;\n return emailTableCell(inner, { padding });\n },\n },\n};\n"],"names":["DEFAULT_DATA","tableTool","values","padding","str","hBg","hColor","bColor","cPad","fSize","data","jsonParse","html","c","row","font","hCells","bRows","inner","emailTableCell"],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ import { html as a } from "lit";
2
+ import { s as t, e as p } from "./mail-editor-DNPaJKo3.js";
3
+ const g = {
4
+ name: "timer",
5
+ label: "Timer",
6
+ 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"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>',
7
+ supportedDisplayModes: ["email", "web"],
8
+ position: 11,
9
+ options: {
10
+ timer: {
11
+ title: "Timer",
12
+ options: {
13
+ endDate: { label: "End Date (ISO)", defaultValue: new Date(Date.now() + 7 * 864e5).toISOString().split("T")[0], widget: "text" },
14
+ expiredMessage: { label: "Expired Message", defaultValue: "This offer has expired", widget: "text" }
15
+ }
16
+ },
17
+ style: {
18
+ title: "Style",
19
+ options: {
20
+ textAlign: { label: "Align", defaultValue: "center", widget: "alignment" },
21
+ backgroundColor: { label: "Background", defaultValue: "#1f2937", widget: "color_picker" },
22
+ textColor: { label: "Text Color", defaultValue: "#ffffff", widget: "color_picker" },
23
+ fontSize: { label: "Font Size", defaultValue: "32px", widget: "text" }
24
+ }
25
+ },
26
+ spacing: {
27
+ title: "Spacing",
28
+ options: { containerPadding: { label: "Padding", defaultValue: "10px", widget: "padding" } }
29
+ }
30
+ },
31
+ defaultValues: {
32
+ endDate: new Date(Date.now() + 7 * 864e5).toISOString().split("T")[0],
33
+ expiredMessage: "This offer has expired",
34
+ textAlign: "center",
35
+ backgroundColor: "#1f2937",
36
+ textColor: "#ffffff",
37
+ fontSize: "32px",
38
+ containerPadding: "10px"
39
+ },
40
+ renderer: {
41
+ renderEditor(e) {
42
+ const i = t(e, "containerPadding", "10px"), n = t(e, "backgroundColor", "#1f2937"), r = t(e, "textColor", "#ffffff"), l = t(e, "fontSize", "32px"), o = t(e, "textAlign", "center");
43
+ return a`<div style="padding:${i};"><div style="background:${n};color:${r};font-size:${l};text-align:${o};padding:20px;border-radius:4px;font-family:monospace;font-weight:bold;letter-spacing:4px;">00 : 00 : 00 : 00<div style="font-size:11px;letter-spacing:8px;opacity:0.6;margin-top:4px;">DAYS &nbsp; HRS &nbsp; MIN &nbsp; SEC</div></div></div>`;
44
+ },
45
+ renderHtml(e) {
46
+ const i = t(e, "containerPadding", "10px"), n = t(e, "backgroundColor", "#1f2937"), r = t(e, "textColor", "#ffffff"), l = t(e, "fontSize", "32px"), o = t(e, "textAlign", "center"), d = `<div style="background-color:${n};color:${r};font-size:${l};text-align:${o};padding:20px;border-radius:4px;font-family:'Courier New',monospace;font-weight:bold;letter-spacing:4px;"><div>00 : 00 : 00 : 00</div><div style="font-size:11px;letter-spacing:8px;opacity:0.6;margin-top:4px;">DAYS &nbsp; HRS &nbsp; MIN &nbsp; SEC</div></div>`;
47
+ return p(d, { padding: i, align: o });
48
+ }
49
+ }
50
+ };
51
+ export {
52
+ g as timerTool
53
+ };
54
+ //# sourceMappingURL=timer-tool-3mF08efm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timer-tool-3mF08efm.js","sources":["../src/tools/built-in/timer-tool.ts"],"sourcesContent":["/**\n * @module timer-tool\n *\n * Countdown timer display block.\n *\n * Email compatibility: Renders as a static styled block.\n * For live countdowns, integrate with a third-party countdown\n * image service (e.g. CountdownMail) in the `endDate` property.\n */\n\nimport { html, TemplateResult } from 'lit';\nimport type { ContentValues } from '@emabuild/types';\nimport type { LitToolDefinition } from '../tool-registry.js';\nimport { str } from '../helpers/value-extractor.js';\nimport { emailTableCell } from '../helpers/email-html.js';\n\nexport const timerTool: LitToolDefinition = {\n name: 'timer',\n label: 'Timer',\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\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><polyline points=\"12 6 12 12 16 14\"/></svg>`,\n supportedDisplayModes: ['email', 'web'],\n position: 11,\n options: {\n timer: {\n title: 'Timer',\n options: {\n endDate: { label: 'End Date (ISO)', defaultValue: new Date(Date.now() + 7 * 86400000).toISOString().split('T')[0], widget: 'text' },\n expiredMessage: { label: 'Expired Message', defaultValue: 'This offer has expired', widget: 'text' },\n },\n },\n style: {\n title: 'Style',\n options: {\n textAlign: { label: 'Align', defaultValue: 'center', widget: 'alignment' },\n backgroundColor: { label: 'Background', defaultValue: '#1f2937', widget: 'color_picker' },\n textColor: { label: 'Text Color', defaultValue: '#ffffff', widget: 'color_picker' },\n fontSize: { label: 'Font Size', defaultValue: '32px', widget: 'text' },\n },\n },\n spacing: {\n title: 'Spacing',\n options: { containerPadding: { label: 'Padding', defaultValue: '10px', widget: 'padding' } },\n },\n },\n defaultValues: {\n endDate: new Date(Date.now() + 7 * 86400000).toISOString().split('T')[0],\n expiredMessage: 'This offer has expired', textAlign: 'center',\n backgroundColor: '#1f2937', textColor: '#ffffff', fontSize: '32px', containerPadding: '10px',\n },\n renderer: {\n renderEditor(values: ContentValues): TemplateResult {\n const padding = str(values, 'containerPadding', '10px');\n const bg = str(values, 'backgroundColor', '#1f2937');\n const color = str(values, 'textColor', '#ffffff');\n const fontSize = str(values, 'fontSize', '32px');\n const align = str(values, 'textAlign', 'center');\n\n return html`<div style=\"padding:${padding};\"><div style=\"background:${bg};color:${color};font-size:${fontSize};text-align:${align};padding:20px;border-radius:4px;font-family:monospace;font-weight:bold;letter-spacing:4px;\">00 : 00 : 00 : 00<div style=\"font-size:11px;letter-spacing:8px;opacity:0.6;margin-top:4px;\">DAYS &nbsp; HRS &nbsp; MIN &nbsp; SEC</div></div></div>`;\n },\n renderHtml(values: ContentValues): string {\n const padding = str(values, 'containerPadding', '10px');\n const bg = str(values, 'backgroundColor', '#1f2937');\n const color = str(values, 'textColor', '#ffffff');\n const fontSize = str(values, 'fontSize', '32px');\n const align = str(values, 'textAlign', 'center');\n\n const inner = `<div style=\"background-color:${bg};color:${color};font-size:${fontSize};text-align:${align};padding:20px;border-radius:4px;font-family:'Courier New',monospace;font-weight:bold;letter-spacing:4px;\"><div>00 : 00 : 00 : 00</div><div style=\"font-size:11px;letter-spacing:8px;opacity:0.6;margin-top:4px;\">DAYS &nbsp; HRS &nbsp; MIN &nbsp; SEC</div></div>`;\n return emailTableCell(inner, { padding, align });\n },\n },\n};\n"],"names":["timerTool","values","padding","str","bg","color","fontSize","align","html","inner","emailTableCell"],"mappings":";;AAgBO,MAAMA,IAA+B;AAAA,EAC1C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,MAAM;AAAA,EACN,uBAAuB,CAAC,SAAS,KAAK;AAAA,EACtC,UAAU;AAAA,EACV,SAAS;AAAA,IACP,OAAO;AAAA,MACL,OAAO;AAAA,MACP,SAAS;AAAA,QACP,SAAS,EAAE,OAAO,kBAAkB,cAAc,IAAI,KAAK,KAAK,QAAQ,IAAI,KAAQ,EAAE,cAAc,MAAM,GAAG,EAAE,CAAC,GAAG,QAAQ,OAAA;AAAA,QAC3H,gBAAgB,EAAE,OAAO,mBAAmB,cAAc,0BAA0B,QAAQ,OAAA;AAAA,MAAO;AAAA,IACrG;AAAA,IAEF,OAAO;AAAA,MACL,OAAO;AAAA,MACP,SAAS;AAAA,QACP,WAAW,EAAE,OAAO,SAAS,cAAc,UAAU,QAAQ,YAAA;AAAA,QAC7D,iBAAiB,EAAE,OAAO,cAAc,cAAc,WAAW,QAAQ,eAAA;AAAA,QACzE,WAAW,EAAE,OAAO,cAAc,cAAc,WAAW,QAAQ,eAAA;AAAA,QACnE,UAAU,EAAE,OAAO,aAAa,cAAc,QAAQ,QAAQ,OAAA;AAAA,MAAO;AAAA,IACvE;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,SAAS,IAAI,KAAK,KAAK,QAAQ,IAAI,KAAQ,EAAE,YAAA,EAAc,MAAM,GAAG,EAAE,CAAC;AAAA,IACvE,gBAAgB;AAAA,IAA0B,WAAW;AAAA,IACrD,iBAAiB;AAAA,IAAW,WAAW;AAAA,IAAW,UAAU;AAAA,IAAQ,kBAAkB;AAAA,EAAA;AAAA,EAExF,UAAU;AAAA,IACR,aAAaC,GAAuC;AAClD,YAAMC,IAAUC,EAAIF,GAAQ,oBAAoB,MAAM,GAChDG,IAAKD,EAAIF,GAAQ,mBAAmB,SAAS,GAC7CI,IAAQF,EAAIF,GAAQ,aAAa,SAAS,GAC1CK,IAAWH,EAAIF,GAAQ,YAAY,MAAM,GACzCM,IAAQJ,EAAIF,GAAQ,aAAa,QAAQ;AAE/C,aAAOO,wBAA2BN,CAAO,6BAA6BE,CAAE,UAAUC,CAAK,cAAcC,CAAQ,eAAeC,CAAK;AAAA,IACnI;AAAA,IACA,WAAWN,GAA+B;AACxC,YAAMC,IAAUC,EAAIF,GAAQ,oBAAoB,MAAM,GAChDG,IAAKD,EAAIF,GAAQ,mBAAmB,SAAS,GAC7CI,IAAQF,EAAIF,GAAQ,aAAa,SAAS,GAC1CK,IAAWH,EAAIF,GAAQ,YAAY,MAAM,GACzCM,IAAQJ,EAAIF,GAAQ,aAAa,QAAQ,GAEzCQ,IAAQ,gCAAgCL,CAAE,UAAUC,CAAK,cAAcC,CAAQ,eAAeC,CAAK;AACzG,aAAOG,EAAeD,GAAO,EAAE,SAAAP,GAAS,OAAAK,GAAO;AAAA,IACjD;AAAA,EAAA;AAEJ;"}
@@ -0,0 +1,9 @@
1
+ import { LitToolDefinition, LazyToolMeta, LazyToolLoader } from '../tool-registry.js';
2
+ /** Tools loaded eagerly in the initial bundle */
3
+ export declare const eagerTools: LitToolDefinition[];
4
+ /** Tools loaded lazily on first use — metadata for sidebar display + loader */
5
+ export declare const lazyTools: Array<{
6
+ meta: LazyToolMeta;
7
+ loader: LazyToolLoader;
8
+ }>;
9
+ //# sourceMappingURL=tool-manifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-manifest.d.ts","sourceRoot":"","sources":["../../../src/tools/built-in/tool-manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAU3F,iDAAiD;AACjD,eAAO,MAAM,UAAU,EAAE,iBAAiB,EAOzC,CAAC;AAEF,+EAA+E;AAC/E,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,MAAM,EAAE,cAAc,CAAA;CAAE,CA6B3E,CAAC"}
@@ -1,18 +1,69 @@
1
1
  import { TemplateResult } from 'lit';
2
2
  import { ToolDefinition, ToolPropertyGroup, ContentValues, EditorRenderContext, ExportRenderContext } from '@emabuild/types';
3
+ /** Lit-specific tool definition (narrows TEditorResult to TemplateResult) */
3
4
  export interface LitToolDefinition extends ToolDefinition<TemplateResult> {
4
5
  renderer: {
5
6
  renderEditor(values: ContentValues, context: EditorRenderContext): TemplateResult;
6
7
  renderHtml(values: ContentValues, context: ExportRenderContext): string;
7
8
  };
8
9
  }
10
+ /** Lazy loader function that returns the tool definition */
11
+ export type LazyToolLoader = () => Promise<LitToolDefinition>;
12
+ /** Minimal metadata for displaying a lazy tool in the sidebar before it's loaded */
13
+ export interface LazyToolMeta {
14
+ name: string;
15
+ label: string;
16
+ icon: string;
17
+ position?: number;
18
+ }
9
19
  export declare class ToolRegistry {
10
20
  private tools;
21
+ private lazyLoaders;
22
+ private lazyMeta;
23
+ private loadingPromises;
24
+ /** Register a tool eagerly (available immediately) */
11
25
  register(tool: LitToolDefinition): void;
26
+ /**
27
+ * Register a tool lazily. The tool's code is only loaded when first needed.
28
+ * Provide metadata (name, label, icon) so the tool can appear in the sidebar.
29
+ *
30
+ * @param meta - Display metadata for the sidebar palette
31
+ * @param loader - Async function that imports and returns the tool definition
32
+ *
33
+ * @example
34
+ * ```ts
35
+ * registry.registerLazy(
36
+ * { name: 'timer', label: 'Timer', icon: '<svg>...</svg>', position: 11 },
37
+ * () => import('./built-in/timer-tool.js').then(m => m.timerTool),
38
+ * );
39
+ * ```
40
+ */
41
+ registerLazy(meta: LazyToolMeta, loader: LazyToolLoader): void;
42
+ /** Get a tool by name. Returns undefined if not loaded yet (use ensureLoaded for lazy tools). */
12
43
  get(name: string): LitToolDefinition | undefined;
13
- getAll(): LitToolDefinition[];
44
+ /** Check if a tool is registered (eager or lazy) */
14
45
  has(name: string): boolean;
46
+ /** Check if a tool is fully loaded and ready to render */
47
+ isLoaded(name: string): boolean;
48
+ /**
49
+ * Ensure a lazy tool is loaded. Returns the tool definition.
50
+ * If the tool is already loaded, returns it immediately.
51
+ * If it's being loaded, returns the in-flight promise.
52
+ */
53
+ ensureLoaded(name: string): Promise<LitToolDefinition | undefined>;
54
+ /**
55
+ * Get all tools for display in the sidebar palette.
56
+ * Returns both loaded tools and lazy tool metadata, sorted by position.
57
+ */
58
+ getAll(): LitToolDefinition[];
59
+ /**
60
+ * Get all tool names and display metadata (including lazy tools not yet loaded).
61
+ * Used by the sidebar to show all available tools.
62
+ */
63
+ getAllMeta(): LazyToolMeta[];
64
+ /** Get default values for a tool. Loads lazily if needed (sync — returns empty if not loaded). */
15
65
  getDefaultValues(name: string): Record<string, unknown>;
66
+ /** Get property groups for a tool */
16
67
  getPropertyGroups(name: string): Record<string, ToolPropertyGroup>;
17
68
  }
18
69
  //# sourceMappingURL=tool-registry.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tool-registry.d.ts","sourceRoot":"","sources":["../../src/tools/tool-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,KAAK,CAAC;AAC1C,OAAO,KAAK,EAAE,cAAc,EAAE,iBAAiB,EAAE,aAAa,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAMlI,MAAM,WAAW,iBAAkB,SAAQ,cAAc,CAAC,cAAc,CAAC;IACvE,QAAQ,EAAE;QACR,YAAY,CAAC,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,mBAAmB,GAAG,cAAc,CAAC;QAClF,UAAU,CAAC,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,mBAAmB,GAAG,MAAM,CAAC;KACzE,CAAC;CACH;AAMD,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAAwC;IAErD,QAAQ,CAAC,IAAI,EAAE,iBAAiB,GAAG,IAAI;IAIvC,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS;IAIhD,MAAM,IAAI,iBAAiB,EAAE;IAI7B,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI1B,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAkBvD,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC;CAGnE"}
1
+ {"version":3,"file":"tool-registry.d.ts","sourceRoot":"","sources":["../../src/tools/tool-registry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,KAAK,CAAC;AAC1C,OAAO,KAAK,EAAE,cAAc,EAAE,iBAAiB,EAAE,aAAa,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAElI,6EAA6E;AAC7E,MAAM,WAAW,iBAAkB,SAAQ,cAAc,CAAC,cAAc,CAAC;IACvE,QAAQ,EAAE;QACR,YAAY,CAAC,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,mBAAmB,GAAG,cAAc,CAAC;QAClF,UAAU,CAAC,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,mBAAmB,GAAG,MAAM,CAAC;KACzE,CAAC;CACH;AAED,4DAA4D;AAC5D,MAAM,MAAM,cAAc,GAAG,MAAM,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAE9D,oFAAoF;AACpF,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAAwC;IACrD,OAAO,CAAC,WAAW,CAAqC;IACxD,OAAO,CAAC,QAAQ,CAAmC;IACnD,OAAO,CAAC,eAAe,CAAiD;IAExE,sDAAsD;IACtD,QAAQ,CAAC,IAAI,EAAE,iBAAiB,GAAG,IAAI;IAMvC;;;;;;;;;;;;;;OAcG;IACH,YAAY,CAAC,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,cAAc,GAAG,IAAI;IAM9D,iGAAiG;IACjG,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS;IAIhD,oDAAoD;IACpD,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI1B,0DAA0D;IAC1D,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI/B;;;;OAIG;IACG,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC;IAoBxE;;;OAGG;IACH,MAAM,IAAI,iBAAiB,EAAE;IAI7B;;;OAGG;IACH,UAAU,IAAI,YAAY,EAAE;IAa5B,kGAAkG;IAClG,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAevD,qCAAqC;IACrC,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC;CAGnE"}
@@ -1,11 +1,11 @@
1
1
  /**
2
- * Unique ID generator and Unlayer-compatible counter manager.
2
+ * Unique ID generator and counter manager.
3
3
  *
4
4
  * The counter manager tracks incrementing IDs per prefix
5
5
  * (e.g. `u_row`, `u_column`, `u_content_text`) to match
6
- * Unlayer's `counters` field in the design JSON.
6
+ * email editor's `counters` field in the design JSON.
7
7
  */
8
- /** Generate a unique ID for internal use (not Unlayer-compatible) */
8
+ /** Generate a unique ID for internal use (not email editor-compatible) */
9
9
  export declare function generateId(): string;
10
10
  /** Counter manager return type */
11
11
  export interface CounterManager {
@@ -16,6 +16,6 @@ export interface CounterManager {
16
16
  /** Increment and return the next value for a given prefix */
17
17
  next(prefix: string): number;
18
18
  }
19
- /** Create an Unlayer-compatible counter manager for ID generation */
19
+ /** Create an counter manager for ID generation */
20
20
  export declare function createCounterManager(): CounterManager;
21
21
  //# sourceMappingURL=id-generator.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"id-generator.d.ts","sourceRoot":"","sources":["../../src/utils/id-generator.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,qEAAqE;AACrE,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,kCAAkC;AAClC,MAAM,WAAW,cAAc;IAC7B,6CAA6C;IAC7C,WAAW,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,wDAAwD;IACxD,WAAW,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IACpD,6DAA6D;IAC7D,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;CAC9B;AAED,qEAAqE;AACrE,wBAAgB,oBAAoB,IAAI,cAAc,CAqBrD"}
1
+ {"version":3,"file":"id-generator.d.ts","sourceRoot":"","sources":["../../src/utils/id-generator.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,0EAA0E;AAC1E,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,kCAAkC;AAClC,MAAM,WAAW,cAAc;IAC7B,6CAA6C;IAC7C,WAAW,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,wDAAwD;IACxD,WAAW,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IACpD,6DAA6D;IAC7D,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;CAC9B;AAED,kDAAkD;AAClD,wBAAgB,oBAAoB,IAAI,cAAc,CAqBrD"}
@@ -0,0 +1,19 @@
1
+ import { ReactiveController, ReactiveControllerHost } from 'lit';
2
+ import { EditorStore, StoreChannel } from '../state/editor-store.js';
3
+ export declare class StoreController implements ReactiveController {
4
+ private host;
5
+ private channels;
6
+ private unsub?;
7
+ store: EditorStore | null;
8
+ /**
9
+ * @param host - The Lit component that owns this controller
10
+ * @param channels - Which store channels to subscribe to
11
+ */
12
+ constructor(host: ReactiveControllerHost, channels: StoreChannel[]);
13
+ /** Set or change the store reference. Re-subscribes automatically. */
14
+ setStore(store: EditorStore): void;
15
+ hostConnected(): void;
16
+ hostDisconnected(): void;
17
+ private subscribe;
18
+ }
19
+ //# sourceMappingURL=store-controller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store-controller.d.ts","sourceRoot":"","sources":["../../src/utils/store-controller.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,KAAK,CAAC;AACtE,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAE1E,qBAAa,eAAgB,YAAW,kBAAkB;IACxD,OAAO,CAAC,IAAI,CAAyB;IACrC,OAAO,CAAC,QAAQ,CAAiB;IACjC,OAAO,CAAC,KAAK,CAAC,CAAa;IAC3B,KAAK,EAAE,WAAW,GAAG,IAAI,CAAQ;IAEjC;;;OAGG;gBACS,IAAI,EAAE,sBAAsB,EAAE,QAAQ,EAAE,YAAY,EAAE;IAMlE,sEAAsE;IACtE,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IAOlC,aAAa,IAAI,IAAI;IAIrB,gBAAgB,IAAI,IAAI;IAKxB,OAAO,CAAC,SAAS;CAMlB"}
@@ -0,0 +1,52 @@
1
+ import { html as a } from "lit";
2
+ import { s as e, e as u } from "./mail-editor-DNPaJKo3.js";
3
+ function d(t) {
4
+ const i = t.match(/(?:youtube\.com\/watch\?v=|youtu\.be\/|youtube\.com\/embed\/)([a-zA-Z0-9_-]{11})/);
5
+ return i ? `https://img.youtube.com/vi/${i[1]}/maxresdefault.jpg` : null;
6
+ }
7
+ const m = {
8
+ name: "video",
9
+ label: "Video",
10
+ 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"><polygon points="5 3 19 12 5 21 5 3"/></svg>',
11
+ supportedDisplayModes: ["email", "web"],
12
+ position: 10,
13
+ options: {
14
+ video: {
15
+ title: "Video",
16
+ options: {
17
+ url: { label: "Video URL", defaultValue: "https://www.youtube.com/watch?v=dQw4w9WgXcQ", widget: "text" },
18
+ thumbnailUrl: { label: "Thumbnail URL (auto)", defaultValue: "", widget: "text" },
19
+ alt: { label: "Alt Text", defaultValue: "Video", widget: "text" }
20
+ }
21
+ },
22
+ style: {
23
+ title: "Style",
24
+ options: { textAlign: { label: "Align", defaultValue: "center", widget: "alignment" } }
25
+ },
26
+ spacing: {
27
+ title: "Spacing",
28
+ options: { containerPadding: { label: "Padding", defaultValue: "10px", widget: "padding" } }
29
+ }
30
+ },
31
+ defaultValues: {
32
+ url: "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
33
+ thumbnailUrl: "",
34
+ alt: "Video",
35
+ textAlign: "center",
36
+ containerPadding: "10px"
37
+ },
38
+ renderer: {
39
+ renderEditor(t) {
40
+ const i = e(t, "containerPadding", "10px"), l = e(t, "url"), n = e(t, "thumbnailUrl") || d(l) || "", o = e(t, "textAlign", "center");
41
+ return n ? a`<div style="padding:${i};text-align:${o};"><div style="position:relative;display:inline-block;max-width:100%;cursor:pointer;"><img src=${n} alt="Video thumbnail" style="display:block;max-width:100%;border-radius:4px;" /><div style="position:absolute;inset:0;display:flex;align-items:center;justify-content:center;"><div style="width:60px;height:60px;background:rgba(0,0,0,0.7);border-radius:50%;display:flex;align-items:center;justify-content:center;color:white;font-size:24px;">▶</div></div></div></div>` : a`<div style="padding:${i};text-align:${o};"><div style="background:#0f172a;border-radius:8px;padding:40px;text-align:center;color:white;font-family:sans-serif;"><div style="font-size:48px;opacity:0.8;">▶</div><div style="font-size:12px;margin-top:8px;opacity:0.6;">${l || "Enter video URL"}</div></div></div>`;
42
+ },
43
+ renderHtml(t, i) {
44
+ const l = e(t, "containerPadding", "10px"), n = e(t, "url", "#"), o = e(t, "thumbnailUrl") || d(n) || "", r = e(t, "alt", "Video"), s = e(t, "textAlign", "center"), c = o ? `<img src="${o}" alt="${r}" width="${i.columnWidth}" style="display:block;max-width:100%;width:${i.columnWidth}px;border:0;" />` : '<div style="background:#0f172a;padding:40px;text-align:center;color:white;font-family:arial,sans-serif;font-size:16px;">▶ Watch Video</div>';
45
+ return u(`<a href="${n}" target="_blank" style="text-decoration:none;">${c}</a>`, { padding: l, align: s });
46
+ }
47
+ }
48
+ };
49
+ export {
50
+ m as videoTool
51
+ };
52
+ //# sourceMappingURL=video-tool-CwWMKobZ.js.map