@emabuild/email-renderer 0.0.8 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- function k(t, a, n) {
2
- const e = n.backgroundColor || "#e7e7e7", d = n.contentWidth || "600px", i = n.fontFamily?.value || "arial,helvetica,sans-serif", s = n.textColor || "#000000", o = n.preheaderText || "", c = o ? `<div style="display:none;font-size:1px;color:${e};line-height:1px;max-height:0px;max-width:0px;opacity:0;overflow:hidden;">${o}${"&zwnj;&nbsp;".repeat(80)}</div>` : "";
1
+ function k(e, i, n) {
2
+ const t = n.backgroundColor || "#e7e7e7", r = n.contentWidth || "600px", l = n.fontFamily?.value || "arial,helvetica,sans-serif", s = n.textColor || "#000000", o = n.preheaderText || "", p = o ? `<div style="display:none;font-size:1px;color:${t};line-height:1px;max-height:0px;max-width:0px;opacity:0;overflow:hidden;">${o}${"&zwnj;&nbsp;".repeat(80)}</div>` : "";
3
3
  return `<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
4
4
  <html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">
5
5
  <head>
@@ -18,12 +18,12 @@ function k(t, a, n) {
18
18
  </o:OfficeDocumentSettings>
19
19
  </xml></noscript>
20
20
  <style type="text/css">
21
- table, td, th { font-family: ${i} !important; }
21
+ table, td, th { font-family: ${l} !important; }
22
22
  </style>
23
23
  <![endif]-->
24
24
  <!--[if !mso]><!-->
25
25
  <style type="text/css">
26
- ${a}
26
+ ${i}
27
27
  </style>
28
28
  <!--<![endif]-->
29
29
  <style type="text/css">
@@ -35,14 +35,14 @@ function k(t, a, n) {
35
35
  a[x-apple-data-detectors='true'] { color: inherit !important; text-decoration: none !important; }
36
36
  </style>
37
37
  </head>
38
- <body class="clean-body u_body" style="margin:0;padding:0;-webkit-text-size-adjust:100%;background-color:${e};color:${s};">
39
- ${c}
40
- <table id="u_body" style="border-collapse:collapse;table-layout:fixed;border-spacing:0;mso-table-lspace:0pt;mso-table-rspace:0pt;vertical-align:top;min-width:320px;margin:0 auto;background-color:${e};width:100%;" cellpadding="0" cellspacing="0" border="0">
38
+ <body class="clean-body u_body" style="margin:0;padding:0;-webkit-text-size-adjust:100%;background-color:${t};color:${s};">
39
+ ${p}
40
+ <table id="u_body" style="border-collapse:collapse;table-layout:fixed;border-spacing:0;mso-table-lspace:0pt;mso-table-rspace:0pt;vertical-align:top;min-width:320px;margin:0 auto;background-color:${t};width:100%;" cellpadding="0" cellspacing="0" border="0">
41
41
  <tbody>
42
42
  <tr style="vertical-align:top;">
43
43
  <td style="word-break:break-word;border-collapse:collapse !important;vertical-align:top;">
44
- <!--[if (mso)|(IE)]><table width="${parseInt(d)}" align="center" cellpadding="0" cellspacing="0" border="0"><tr><td><![endif]-->
45
- ${t}
44
+ <!--[if (mso)|(IE)]><table width="${parseInt(r)}" align="center" cellpadding="0" cellspacing="0" border="0"><tr><td><![endif]-->
45
+ ${e}
46
46
  <!--[if (mso)|(IE)]></td></tr></table><![endif]-->
47
47
  </td>
48
48
  </tr>
@@ -51,68 +51,70 @@ function k(t, a, n) {
51
51
  </body>
52
52
  </html>`;
53
53
  }
54
- function w(t, a, n) {
55
- const e = parseInt(a.contentWidth || "600"), d = t.values.backgroundColor || "", i = t.values.columnsBackgroundColor || "", s = t.values.padding || "0px", o = t.cells.reduce((u, h) => u + h, 0), c = d ? `background-color:${d};` : "", m = t.values.backgroundImage?.url ? `background-image:url('${t.values.backgroundImage.url}');background-repeat:${t.values.backgroundImage.repeat ? "repeat" : "no-repeat"};background-position:center top;background-size:${t.values.backgroundImage.cover ? "cover" : "auto"};` : "", r = t.columns.map((u, h) => {
56
- const b = Math.round(t.cells[h] / o * e);
57
- return y(u, b, i, a, n);
58
- }), l = t.columns.length > 1;
59
- let p;
60
- if (l) {
61
- const u = t.columns.map((h, b) => {
62
- const g = Math.round(t.cells[b] / o * e), v = y(h, g, i, a, n);
63
- return `<!--[if (mso)|(IE)]><td align="center" width="${g}" style="width:${g}px;padding:0px;border:none;" valign="top"><![endif]-->
54
+ function $(e, i, n) {
55
+ const t = parseInt(i.contentWidth || "600"), r = e.values.backgroundColor || "", l = e.values.columnsBackgroundColor || "", s = e.values.padding || "0px", o = e.cells.reduce((c, h) => c + h, 0), p = r ? `background-color:${r};` : "", u = e.values.backgroundImage?.url ? `background-image:url('${e.values.backgroundImage.url}');background-repeat:${e.values.backgroundImage.repeat ? "repeat" : "no-repeat"};background-position:center top;background-size:${e.values.backgroundImage.cover ? "cover" : "auto"};` : "", a = e.columns.map((c, h) => {
56
+ const y = Math.round(e.cells[h] / o * t);
57
+ return x(c, y, l, i, n);
58
+ }), d = e.columns.length > 1;
59
+ let m;
60
+ if (d) {
61
+ const c = e.columns.map((h, y) => {
62
+ const f = Math.round(e.cells[y] / o * t), v = x(h, f, l, i, n);
63
+ return `<!--[if (mso)|(IE)]><td align="center" width="${f}" style="width:${f}px;padding:0px;border:none;" valign="top"><![endif]-->
64
64
  ${v}
65
65
  <!--[if (mso)|(IE)]></td><![endif]-->`;
66
66
  });
67
- p = `<!--[if (mso)|(IE)]><table role="presentation" width="${e}" cellpadding="0" cellspacing="0" border="0"><tr>${u.join(`
67
+ m = `<!--[if (mso)|(IE)]><table role="presentation" width="${t}" cellpadding="0" cellspacing="0" border="0"><tr>${c.join(`
68
68
  `)}</tr></table><![endif]-->
69
69
 
70
70
  <!--[if !mso]><!-->
71
- <div style="max-width:${e}px;margin:0 auto;">
72
- ${r.join(`
71
+ <div style="max-width:${t}px;margin:0 auto;">
72
+ ${a.join(`
73
73
  `)}
74
74
  </div>
75
75
  <!--<![endif]-->`;
76
76
  } else
77
- p = r.join(`
77
+ m = a.join(`
78
78
  `);
79
- const x = t.values.hideDesktop ? " u_hide_desktop" : "", f = t.values.hideMobile ? " u_hide_mobile" : "";
80
- return `<div class="u_row${x}${f}" style="padding:${s};${c}${m}">
81
- <div style="margin:0 auto;min-width:320px;max-width:${e}px;overflow-wrap:break-word;word-wrap:break-word;word-break:break-word;background-color:transparent;">
79
+ const b = e.values.hideDesktop ? " u_hide_desktop" : "", g = e.values.hideMobile ? " u_hide_mobile" : "";
80
+ return `<div class="u_row${b}${g}" style="padding:${s};${p}${u}">
81
+ <div style="margin:0 auto;min-width:320px;max-width:${t}px;overflow-wrap:break-word;word-wrap:break-word;word-break:break-word;background-color:transparent;">
82
82
  <div style="border-collapse:collapse;display:table;width:100%;height:100%;background-color:transparent;">
83
- ${p}
83
+ ${m}
84
84
  </div>
85
85
  </div>
86
86
  </div>`;
87
87
  }
88
- function y(t, a, n, e, d) {
89
- const i = t.values.backgroundColor || n || "", s = t.values.padding || "0px", o = t.values.borderRadius || "0px", c = i ? `background-color:${i};` : "", m = t.contents.map((r) => {
90
- const l = d.get(r.type);
91
- if (!l) return `<!-- unknown tool: ${r.type} -->`;
92
- const p = {
93
- columnWidth: a,
88
+ function x(e, i, n, t, r) {
89
+ const l = e.values.backgroundColor || n || "", s = e.values.padding || "0px", o = e.values.borderRadius || "0px", p = l ? `background-color:${l};` : "", u = e.contents.map((a) => {
90
+ const d = r.get(a.type);
91
+ if (!d) return `<!-- unknown tool: ${a.type} -->`;
92
+ const m = {
93
+ columnWidth: i,
94
94
  displayMode: "email",
95
- contentWidth: parseInt(e.contentWidth || "600"),
96
- bodyValues: e
95
+ contentWidth: parseInt(t.contentWidth || "600"),
96
+ bodyValues: t
97
97
  };
98
- return l(r.values, p);
98
+ let b = d(a.values, m);
99
+ const g = !!a.values.hideDesktop, c = !!a.values.hideMobile;
100
+ return (g || c) && (b = `<div class="${[g && "u_hide_desktop", c && "u_hide_mobile"].filter(Boolean).join(" ")}">${b}</div>`), b;
99
101
  }).join(`
100
102
  `);
101
- return `<div class="u_column" style="max-width:${a}px;min-width:${Math.min(a, 320)}px;display:table-cell;vertical-align:top;">
102
- <div style="height:100%;width:100% !important;border-radius:${o};-webkit-border-radius:${o};${c}">
103
+ return `<div class="u_column" style="max-width:${i}px;min-width:${Math.min(i, 320)}px;display:table-cell;vertical-align:top;">
104
+ <div style="height:100%;width:100% !important;border-radius:${o};-webkit-border-radius:${o};${p}">
103
105
  <div style="box-sizing:border-box;height:100%;padding:${s};border:none;border-radius:${o};-webkit-border-radius:${o};">
104
- ${m || '<!--[if (!mso)&(!IE)]><!--><div style="height:0;min-height:1px;font-size:0;">&nbsp;</div><!--<![endif]-->'}
106
+ ${u || '<!--[if (!mso)&(!IE)]><!--><div style="height:0;min-height:1px;font-size:0;">&nbsp;</div><!--<![endif]-->'}
105
107
  </div>
106
108
  </div>
107
109
  </div>`;
108
110
  }
109
- function $(t) {
111
+ function w(e) {
110
112
  return `
111
- @media only screen and (min-width: ${t + 20}px) {
113
+ @media only screen and (min-width: ${e + 20}px) {
112
114
  .u_row .u_column { display: table-cell; }
113
115
  }
114
116
 
115
- @media only screen and (max-width: ${t + 20}px) {
117
+ @media only screen and (max-width: ${e + 20}px) {
116
118
  .u_row .u_column {
117
119
  display: block !important;
118
120
  width: 100% !important;
@@ -146,40 +148,40 @@ function $(t) {
146
148
  .u_hide_desktop { display: block !important; }
147
149
  .u_hide_mobile { display: block !important; }
148
150
 
149
- @media only screen and (max-width: ${t + 20}px) {
151
+ @media only screen and (max-width: ${e + 20}px) {
150
152
  .u_hide_desktop { display: block !important; }
151
153
  .u_hide_mobile { display: none !important; }
152
154
  }
153
155
 
154
- @media only screen and (min-width: ${t + 21}px) {
156
+ @media only screen and (min-width: ${e + 21}px) {
155
157
  .u_hide_desktop { display: none !important; }
156
158
  .u_hide_mobile { display: block !important; }
157
159
  }`;
158
160
  }
159
- function _(t, a, n) {
160
- const e = t.body.values, d = parseInt(e.contentWidth || "600"), i = t.body.rows.map((l) => w(l, e, a)).join(`
161
- `), s = $(d);
162
- let o = k(i, s, e);
161
+ function _(e, i, n) {
162
+ const t = e.body.values, r = parseInt(t.contentWidth || "600"), l = e.body.rows.map((d) => $(d, t, i)).join(`
163
+ `), s = w(r);
164
+ let o = k(l, s, t);
163
165
  if (n?.mergeTags)
164
- for (const [l, p] of Object.entries(n.mergeTags))
165
- o = o.replaceAll(`{{${l}}}`, p);
166
- const c = o.match(/<body[^>]*>([\s\S]*)<\/body>/i), m = o.match(/<style[^>]*>([\s\S]*?)<\/style>/gi), r = [];
167
- return e.fontFamily?.url && r.push(e.fontFamily.url), {
168
- design: structuredClone(t),
166
+ for (const [d, m] of Object.entries(n.mergeTags))
167
+ o = o.replaceAll(`{{${d}}}`, m);
168
+ const p = o.match(/<body[^>]*>([\s\S]*)<\/body>/i), u = o.match(/<style[^>]*>([\s\S]*?)<\/style>/gi), a = [];
169
+ return t.fontFamily?.url && a.push(t.fontFamily.url), {
170
+ design: structuredClone(e),
169
171
  html: o,
170
172
  chunks: {
171
- body: c?.[1] ?? i,
172
- css: m?.map((l) => l.replace(/<\/?style[^>]*>/gi, "")).join(`
173
+ body: p?.[1] ?? l,
174
+ css: u?.map((d) => d.replace(/<\/?style[^>]*>/gi, "")).join(`
173
175
  `) ?? s,
174
- fonts: r,
176
+ fonts: a,
175
177
  js: ""
176
178
  }
177
179
  };
178
180
  }
179
181
  export {
180
- $ as getResponsiveCss,
182
+ w as getResponsiveCss,
181
183
  _ as renderDesignToHtml,
182
- w as renderRow,
184
+ $ as renderRow,
183
185
  k as wrapInDocumentShell
184
186
  };
185
187
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/layout/document-shell.ts","../src/layout/fluid-hybrid.ts","../src/utils/responsive-css.ts","../src/render.ts"],"sourcesContent":["import type { BodyValues } from '@emabuild/types';\n\nexport function wrapInDocumentShell(bodyHtml: string, cssBlock: string, bodyValues: BodyValues): string {\n const bgColor = bodyValues.backgroundColor || '#e7e7e7';\n const contentWidth = bodyValues.contentWidth || '600px';\n const fontFamily = bodyValues.fontFamily?.value || 'arial,helvetica,sans-serif';\n const textColor = bodyValues.textColor || '#000000';\n const preheaderText = bodyValues.preheaderText || '';\n\n const preheader = preheaderText\n ? `<div style=\"display:none;font-size:1px;color:${bgColor};line-height:1px;max-height:0px;max-width:0px;opacity:0;overflow:hidden;\">${preheaderText}${'&zwnj;&nbsp;'.repeat(80)}</div>`\n : '';\n\n return `<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:v=\"urn:schemas-microsoft-com:vml\" xmlns:o=\"urn:schemas-microsoft-com:office:office\">\n<head>\n <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n <meta name=\"x-apple-disable-message-reformatting\">\n <meta name=\"format-detection\" content=\"telephone=no,address=no,email=no,date=no,url=no\">\n <meta name=\"color-scheme\" content=\"light dark\">\n <meta name=\"supported-color-schemes\" content=\"light dark\">\n <title></title>\n <!--[if mso]>\n <noscript><xml>\n <o:OfficeDocumentSettings>\n <o:AllowPNG/><o:PixelsPerInch>96</o:PixelsPerInch>\n </o:OfficeDocumentSettings>\n </xml></noscript>\n <style type=\"text/css\">\n table, td, th { font-family: ${fontFamily} !important; }\n </style>\n <![endif]-->\n <!--[if !mso]><!-->\n <style type=\"text/css\">\n ${cssBlock}\n </style>\n <!--<![endif]-->\n <style type=\"text/css\">\n body { margin: 0; padding: 0; }\n table, tr, td { vertical-align: top; border-collapse: collapse; }\n p { margin: 0; }\n .ie-container table, .mso-container table { table-layout: fixed; }\n * { line-height: inherit; }\n a[x-apple-data-detectors='true'] { color: inherit !important; text-decoration: none !important; }\n </style>\n</head>\n<body class=\"clean-body u_body\" style=\"margin:0;padding:0;-webkit-text-size-adjust:100%;background-color:${bgColor};color:${textColor};\">\n ${preheader}\n <table id=\"u_body\" style=\"border-collapse:collapse;table-layout:fixed;border-spacing:0;mso-table-lspace:0pt;mso-table-rspace:0pt;vertical-align:top;min-width:320px;margin:0 auto;background-color:${bgColor};width:100%;\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n <tbody>\n <tr style=\"vertical-align:top;\">\n <td style=\"word-break:break-word;border-collapse:collapse !important;vertical-align:top;\">\n <!--[if (mso)|(IE)]><table width=\"${parseInt(contentWidth)}\" align=\"center\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\"><tr><td><![endif]-->\n ${bodyHtml}\n <!--[if (mso)|(IE)]></td></tr></table><![endif]-->\n </td>\n </tr>\n </tbody>\n </table>\n</body>\n</html>`;\n}\n","import type { DesignRow, DesignColumn, BodyValues } from '@emabuild/types';\n\ntype ContentRenderer = (values: Record<string, unknown>, ctx: any) => string;\n\nexport function renderRow(\n row: DesignRow,\n bodyValues: BodyValues,\n toolRenderers: Map<string, ContentRenderer>,\n): string {\n const contentWidth = parseInt(bodyValues.contentWidth || '600');\n const bgColor = row.values.backgroundColor || '';\n const colsBgColor = row.values.columnsBackgroundColor || '';\n const padding = row.values.padding || '0px';\n const totalCells = row.cells.reduce((a, b) => a + b, 0);\n\n const bgStyle = bgColor ? `background-color:${bgColor};` : '';\n const bgImage = row.values.backgroundImage?.url\n ? `background-image:url('${row.values.backgroundImage.url}');background-repeat:${row.values.backgroundImage.repeat ? 'repeat' : 'no-repeat'};background-position:center top;background-size:${row.values.backgroundImage.cover ? 'cover' : 'auto'};`\n : '';\n\n const columnsHtml = row.columns.map((col, i) => {\n const colWidthPx = Math.round((row.cells[i] / totalCells) * contentWidth);\n return renderColumn(col, colWidthPx, colsBgColor, bodyValues, toolRenderers);\n });\n\n // For multi-column layouts, use MSO ghost tables\n const needsGhostTable = row.columns.length > 1;\n\n let innerHtml: string;\n if (needsGhostTable) {\n const ghostCols = row.columns.map((col, i) => {\n const colWidthPx = Math.round((row.cells[i] / totalCells) * contentWidth);\n const colHtml = renderColumn(col, colWidthPx, colsBgColor, bodyValues, toolRenderers);\n return `<!--[if (mso)|(IE)]><td align=\"center\" width=\"${colWidthPx}\" style=\"width:${colWidthPx}px;padding:0px;border:none;\" valign=\"top\"><![endif]-->\n${colHtml}\n<!--[if (mso)|(IE)]></td><![endif]-->`;\n });\n\n innerHtml = `<!--[if (mso)|(IE)]><table role=\"presentation\" width=\"${contentWidth}\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\"><tr>${ghostCols.join('\\n')}</tr></table><![endif]-->\n\n<!--[if !mso]><!-->\n<div style=\"max-width:${contentWidth}px;margin:0 auto;\">\n${columnsHtml.join('\\n')}\n</div>\n<!--<![endif]-->`;\n } else {\n innerHtml = columnsHtml.join('\\n');\n }\n\n // Visibility classes\n const hideDesktop = row.values.hideDesktop ? ' u_hide_desktop' : '';\n const hideMobile = row.values.hideMobile ? ' u_hide_mobile' : '';\n\n return `<div class=\"u_row${hideDesktop}${hideMobile}\" style=\"padding:${padding};${bgStyle}${bgImage}\">\n <div style=\"margin:0 auto;min-width:320px;max-width:${contentWidth}px;overflow-wrap:break-word;word-wrap:break-word;word-break:break-word;background-color:transparent;\">\n <div style=\"border-collapse:collapse;display:table;width:100%;height:100%;background-color:transparent;\">\n ${innerHtml}\n </div>\n </div>\n</div>`;\n}\n\nfunction renderColumn(\n col: DesignColumn,\n widthPx: number,\n colsBgColor: string,\n bodyValues: BodyValues,\n toolRenderers: Map<string, ContentRenderer>,\n): string {\n const bgColor = col.values.backgroundColor || colsBgColor || '';\n const padding = col.values.padding || '0px';\n const borderRadius = col.values.borderRadius || '0px';\n const bgStyle = bgColor ? `background-color:${bgColor};` : '';\n\n const contentsHtml = col.contents\n .map((content) => {\n const renderer = toolRenderers.get(content.type);\n if (!renderer) return `<!-- unknown tool: ${content.type} -->`;\n const ctx = {\n columnWidth: widthPx,\n displayMode: 'email',\n contentWidth: parseInt(bodyValues.contentWidth || '600'),\n bodyValues,\n };\n return renderer(content.values, ctx);\n })\n .join('\\n');\n\n return `<div class=\"u_column\" style=\"max-width:${widthPx}px;min-width:${Math.min(widthPx, 320)}px;display:table-cell;vertical-align:top;\">\n <div style=\"height:100%;width:100% !important;border-radius:${borderRadius};-webkit-border-radius:${borderRadius};${bgStyle}\">\n <div style=\"box-sizing:border-box;height:100%;padding:${padding};border:none;border-radius:${borderRadius};-webkit-border-radius:${borderRadius};\">\n ${contentsHtml || '<!--[if (!mso)&(!IE)]><!--><div style=\"height:0;min-height:1px;font-size:0;\">&nbsp;</div><!--<![endif]-->'}\n </div>\n </div>\n</div>`;\n}\n","export function getResponsiveCss(contentWidth: number): string {\n return `\n@media only screen and (min-width: ${contentWidth + 20}px) {\n .u_row .u_column { display: table-cell; }\n}\n\n@media only screen and (max-width: ${contentWidth + 20}px) {\n .u_row .u_column {\n display: block !important;\n width: 100% !important;\n min-width: 320px !important;\n max-width: 100% !important;\n }\n .u_row {\n width: 100% !important;\n }\n}\n\n@media only screen and (max-width: 620px) {\n .u_row-container {\n max-width: 100% !important;\n padding-left: 0 !important;\n padding-right: 0 !important;\n }\n}\n\n@media (prefers-color-scheme: dark) {\n /* Dark mode overrides — add per-client rules as needed */\n}\n\n/* Outlook dark mode */\n[data-ogsb] body,\n[data-ogsb] table,\n[data-ogsb] td {\n /* Preserve original colors */\n}\n\n.u_hide_desktop { display: block !important; }\n.u_hide_mobile { display: block !important; }\n\n@media only screen and (max-width: ${contentWidth + 20}px) {\n .u_hide_desktop { display: block !important; }\n .u_hide_mobile { display: none !important; }\n}\n\n@media only screen and (min-width: ${contentWidth + 21}px) {\n .u_hide_desktop { display: none !important; }\n .u_hide_mobile { display: block !important; }\n}`;\n}\n","import type { EmailDesign, ExportResult, ExportOptions, BodyValues } from '@emabuild/types';\nimport { wrapInDocumentShell } from './layout/document-shell.js';\nimport { renderRow } from './layout/fluid-hybrid.js';\nimport { getResponsiveCss } from './utils/responsive-css.js';\n\ntype ContentRenderer = (values: Record<string, unknown>, ctx: any) => string;\n\nexport function renderDesignToHtml(\n design: EmailDesign,\n toolRenderers: Map<string, ContentRenderer>,\n options?: ExportOptions,\n): ExportResult {\n const bodyValues = design.body.values;\n const contentWidth = parseInt(bodyValues.contentWidth || '600');\n\n // Render all rows\n const rowsHtml = design.body.rows\n .map((row) => renderRow(row, bodyValues, toolRenderers))\n .join('\\n');\n\n // Build responsive CSS\n const cssBlock = getResponsiveCss(contentWidth);\n\n // Build full document\n let fullHtml = wrapInDocumentShell(rowsHtml, cssBlock, bodyValues);\n\n // Process merge tags if provided\n if (options?.mergeTags) {\n for (const [tag, value] of Object.entries(options.mergeTags)) {\n fullHtml = fullHtml.replaceAll(`{{${tag}}}`, value);\n }\n }\n\n // Extract chunks\n const bodyMatch = fullHtml.match(/<body[^>]*>([\\s\\S]*)<\\/body>/i);\n const cssMatch = fullHtml.match(/<style[^>]*>([\\s\\S]*?)<\\/style>/gi);\n const fontsUsed: string[] = [];\n\n // Collect Google Fonts\n if (bodyValues.fontFamily?.url) {\n fontsUsed.push(bodyValues.fontFamily.url);\n }\n\n return {\n design: structuredClone(design),\n html: fullHtml,\n chunks: {\n body: bodyMatch?.[1] ?? rowsHtml,\n css: cssMatch?.map((s) => s.replace(/<\\/?style[^>]*>/gi, '')).join('\\n') ?? cssBlock,\n fonts: fontsUsed,\n js: '',\n },\n };\n}\n"],"names":["wrapInDocumentShell","bodyHtml","cssBlock","bodyValues","bgColor","contentWidth","fontFamily","textColor","preheaderText","preheader","renderRow","row","toolRenderers","colsBgColor","padding","totalCells","a","b","bgStyle","bgImage","columnsHtml","col","i","colWidthPx","renderColumn","needsGhostTable","innerHtml","ghostCols","colHtml","hideDesktop","hideMobile","widthPx","borderRadius","contentsHtml","content","renderer","ctx","getResponsiveCss","renderDesignToHtml","design","options","rowsHtml","fullHtml","tag","value","bodyMatch","cssMatch","fontsUsed","s"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/layout/document-shell.ts","../src/layout/fluid-hybrid.ts","../src/utils/responsive-css.ts","../src/render.ts"],"sourcesContent":["import type { BodyValues } from '@emabuild/types';\n\nexport function wrapInDocumentShell(bodyHtml: string, cssBlock: string, bodyValues: BodyValues): string {\n const bgColor = bodyValues.backgroundColor || '#e7e7e7';\n const contentWidth = bodyValues.contentWidth || '600px';\n const fontFamily = bodyValues.fontFamily?.value || 'arial,helvetica,sans-serif';\n const textColor = bodyValues.textColor || '#000000';\n const preheaderText = bodyValues.preheaderText || '';\n\n const preheader = preheaderText\n ? `<div style=\"display:none;font-size:1px;color:${bgColor};line-height:1px;max-height:0px;max-width:0px;opacity:0;overflow:hidden;\">${preheaderText}${'&zwnj;&nbsp;'.repeat(80)}</div>`\n : '';\n\n return `<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:v=\"urn:schemas-microsoft-com:vml\" xmlns:o=\"urn:schemas-microsoft-com:office:office\">\n<head>\n <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n <meta name=\"x-apple-disable-message-reformatting\">\n <meta name=\"format-detection\" content=\"telephone=no,address=no,email=no,date=no,url=no\">\n <meta name=\"color-scheme\" content=\"light dark\">\n <meta name=\"supported-color-schemes\" content=\"light dark\">\n <title></title>\n <!--[if mso]>\n <noscript><xml>\n <o:OfficeDocumentSettings>\n <o:AllowPNG/><o:PixelsPerInch>96</o:PixelsPerInch>\n </o:OfficeDocumentSettings>\n </xml></noscript>\n <style type=\"text/css\">\n table, td, th { font-family: ${fontFamily} !important; }\n </style>\n <![endif]-->\n <!--[if !mso]><!-->\n <style type=\"text/css\">\n ${cssBlock}\n </style>\n <!--<![endif]-->\n <style type=\"text/css\">\n body { margin: 0; padding: 0; }\n table, tr, td { vertical-align: top; border-collapse: collapse; }\n p { margin: 0; }\n .ie-container table, .mso-container table { table-layout: fixed; }\n * { line-height: inherit; }\n a[x-apple-data-detectors='true'] { color: inherit !important; text-decoration: none !important; }\n </style>\n</head>\n<body class=\"clean-body u_body\" style=\"margin:0;padding:0;-webkit-text-size-adjust:100%;background-color:${bgColor};color:${textColor};\">\n ${preheader}\n <table id=\"u_body\" style=\"border-collapse:collapse;table-layout:fixed;border-spacing:0;mso-table-lspace:0pt;mso-table-rspace:0pt;vertical-align:top;min-width:320px;margin:0 auto;background-color:${bgColor};width:100%;\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n <tbody>\n <tr style=\"vertical-align:top;\">\n <td style=\"word-break:break-word;border-collapse:collapse !important;vertical-align:top;\">\n <!--[if (mso)|(IE)]><table width=\"${parseInt(contentWidth)}\" align=\"center\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\"><tr><td><![endif]-->\n ${bodyHtml}\n <!--[if (mso)|(IE)]></td></tr></table><![endif]-->\n </td>\n </tr>\n </tbody>\n </table>\n</body>\n</html>`;\n}\n","import type { DesignRow, DesignColumn, BodyValues } from '@emabuild/types';\n\ntype ContentRenderer = (values: Record<string, unknown>, ctx: any) => string;\n\nexport function renderRow(\n row: DesignRow,\n bodyValues: BodyValues,\n toolRenderers: Map<string, ContentRenderer>,\n): string {\n const contentWidth = parseInt(bodyValues.contentWidth || '600');\n const bgColor = row.values.backgroundColor || '';\n const colsBgColor = row.values.columnsBackgroundColor || '';\n const padding = row.values.padding || '0px';\n const totalCells = row.cells.reduce((a, b) => a + b, 0);\n\n const bgStyle = bgColor ? `background-color:${bgColor};` : '';\n const bgImage = row.values.backgroundImage?.url\n ? `background-image:url('${row.values.backgroundImage.url}');background-repeat:${row.values.backgroundImage.repeat ? 'repeat' : 'no-repeat'};background-position:center top;background-size:${row.values.backgroundImage.cover ? 'cover' : 'auto'};`\n : '';\n\n const columnsHtml = row.columns.map((col, i) => {\n const colWidthPx = Math.round((row.cells[i] / totalCells) * contentWidth);\n return renderColumn(col, colWidthPx, colsBgColor, bodyValues, toolRenderers);\n });\n\n // For multi-column layouts, use MSO ghost tables\n const needsGhostTable = row.columns.length > 1;\n\n let innerHtml: string;\n if (needsGhostTable) {\n const ghostCols = row.columns.map((col, i) => {\n const colWidthPx = Math.round((row.cells[i] / totalCells) * contentWidth);\n const colHtml = renderColumn(col, colWidthPx, colsBgColor, bodyValues, toolRenderers);\n return `<!--[if (mso)|(IE)]><td align=\"center\" width=\"${colWidthPx}\" style=\"width:${colWidthPx}px;padding:0px;border:none;\" valign=\"top\"><![endif]-->\n${colHtml}\n<!--[if (mso)|(IE)]></td><![endif]-->`;\n });\n\n innerHtml = `<!--[if (mso)|(IE)]><table role=\"presentation\" width=\"${contentWidth}\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\"><tr>${ghostCols.join('\\n')}</tr></table><![endif]-->\n\n<!--[if !mso]><!-->\n<div style=\"max-width:${contentWidth}px;margin:0 auto;\">\n${columnsHtml.join('\\n')}\n</div>\n<!--<![endif]-->`;\n } else {\n innerHtml = columnsHtml.join('\\n');\n }\n\n // Visibility classes\n const hideDesktop = row.values.hideDesktop ? ' u_hide_desktop' : '';\n const hideMobile = row.values.hideMobile ? ' u_hide_mobile' : '';\n\n return `<div class=\"u_row${hideDesktop}${hideMobile}\" style=\"padding:${padding};${bgStyle}${bgImage}\">\n <div style=\"margin:0 auto;min-width:320px;max-width:${contentWidth}px;overflow-wrap:break-word;word-wrap:break-word;word-break:break-word;background-color:transparent;\">\n <div style=\"border-collapse:collapse;display:table;width:100%;height:100%;background-color:transparent;\">\n ${innerHtml}\n </div>\n </div>\n</div>`;\n}\n\nfunction renderColumn(\n col: DesignColumn,\n widthPx: number,\n colsBgColor: string,\n bodyValues: BodyValues,\n toolRenderers: Map<string, ContentRenderer>,\n): string {\n const bgColor = col.values.backgroundColor || colsBgColor || '';\n const padding = col.values.padding || '0px';\n const borderRadius = col.values.borderRadius || '0px';\n const bgStyle = bgColor ? `background-color:${bgColor};` : '';\n\n const contentsHtml = col.contents\n .map((content) => {\n const renderer = toolRenderers.get(content.type);\n if (!renderer) return `<!-- unknown tool: ${content.type} -->`;\n const ctx = {\n columnWidth: widthPx,\n displayMode: 'email',\n contentWidth: parseInt(bodyValues.contentWidth || '600'),\n bodyValues,\n };\n let html = renderer(content.values, ctx);\n\n // Wrap with visibility classes if hideDesktop/hideMobile is set\n const hideDesktop = !!content.values.hideDesktop;\n const hideMobile = !!content.values.hideMobile;\n if (hideDesktop || hideMobile) {\n const cls = [hideDesktop && 'u_hide_desktop', hideMobile && 'u_hide_mobile'].filter(Boolean).join(' ');\n html = `<div class=\"${cls}\">${html}</div>`;\n }\n\n return html;\n })\n .join('\\n');\n\n return `<div class=\"u_column\" style=\"max-width:${widthPx}px;min-width:${Math.min(widthPx, 320)}px;display:table-cell;vertical-align:top;\">\n <div style=\"height:100%;width:100% !important;border-radius:${borderRadius};-webkit-border-radius:${borderRadius};${bgStyle}\">\n <div style=\"box-sizing:border-box;height:100%;padding:${padding};border:none;border-radius:${borderRadius};-webkit-border-radius:${borderRadius};\">\n ${contentsHtml || '<!--[if (!mso)&(!IE)]><!--><div style=\"height:0;min-height:1px;font-size:0;\">&nbsp;</div><!--<![endif]-->'}\n </div>\n </div>\n</div>`;\n}\n","export function getResponsiveCss(contentWidth: number): string {\n return `\n@media only screen and (min-width: ${contentWidth + 20}px) {\n .u_row .u_column { display: table-cell; }\n}\n\n@media only screen and (max-width: ${contentWidth + 20}px) {\n .u_row .u_column {\n display: block !important;\n width: 100% !important;\n min-width: 320px !important;\n max-width: 100% !important;\n }\n .u_row {\n width: 100% !important;\n }\n}\n\n@media only screen and (max-width: 620px) {\n .u_row-container {\n max-width: 100% !important;\n padding-left: 0 !important;\n padding-right: 0 !important;\n }\n}\n\n@media (prefers-color-scheme: dark) {\n /* Dark mode overrides — add per-client rules as needed */\n}\n\n/* Outlook dark mode */\n[data-ogsb] body,\n[data-ogsb] table,\n[data-ogsb] td {\n /* Preserve original colors */\n}\n\n.u_hide_desktop { display: block !important; }\n.u_hide_mobile { display: block !important; }\n\n@media only screen and (max-width: ${contentWidth + 20}px) {\n .u_hide_desktop { display: block !important; }\n .u_hide_mobile { display: none !important; }\n}\n\n@media only screen and (min-width: ${contentWidth + 21}px) {\n .u_hide_desktop { display: none !important; }\n .u_hide_mobile { display: block !important; }\n}`;\n}\n","import type { EmailDesign, ExportResult, ExportOptions, BodyValues } from '@emabuild/types';\nimport { wrapInDocumentShell } from './layout/document-shell.js';\nimport { renderRow } from './layout/fluid-hybrid.js';\nimport { getResponsiveCss } from './utils/responsive-css.js';\n\ntype ContentRenderer = (values: Record<string, unknown>, ctx: any) => string;\n\nexport function renderDesignToHtml(\n design: EmailDesign,\n toolRenderers: Map<string, ContentRenderer>,\n options?: ExportOptions,\n): ExportResult {\n const bodyValues = design.body.values;\n const contentWidth = parseInt(bodyValues.contentWidth || '600');\n\n // Render all rows\n const rowsHtml = design.body.rows\n .map((row) => renderRow(row, bodyValues, toolRenderers))\n .join('\\n');\n\n // Build responsive CSS\n const cssBlock = getResponsiveCss(contentWidth);\n\n // Build full document\n let fullHtml = wrapInDocumentShell(rowsHtml, cssBlock, bodyValues);\n\n // Process merge tags if provided\n if (options?.mergeTags) {\n for (const [tag, value] of Object.entries(options.mergeTags)) {\n fullHtml = fullHtml.replaceAll(`{{${tag}}}`, value);\n }\n }\n\n // Extract chunks\n const bodyMatch = fullHtml.match(/<body[^>]*>([\\s\\S]*)<\\/body>/i);\n const cssMatch = fullHtml.match(/<style[^>]*>([\\s\\S]*?)<\\/style>/gi);\n const fontsUsed: string[] = [];\n\n // Collect Google Fonts\n if (bodyValues.fontFamily?.url) {\n fontsUsed.push(bodyValues.fontFamily.url);\n }\n\n return {\n design: structuredClone(design),\n html: fullHtml,\n chunks: {\n body: bodyMatch?.[1] ?? rowsHtml,\n css: cssMatch?.map((s) => s.replace(/<\\/?style[^>]*>/gi, '')).join('\\n') ?? cssBlock,\n fonts: fontsUsed,\n js: '',\n },\n };\n}\n"],"names":["wrapInDocumentShell","bodyHtml","cssBlock","bodyValues","bgColor","contentWidth","fontFamily","textColor","preheaderText","preheader","renderRow","row","toolRenderers","colsBgColor","padding","totalCells","a","b","bgStyle","bgImage","columnsHtml","col","i","colWidthPx","renderColumn","needsGhostTable","innerHtml","ghostCols","colHtml","hideDesktop","hideMobile","widthPx","borderRadius","contentsHtml","content","renderer","ctx","html","getResponsiveCss","renderDesignToHtml","design","options","rowsHtml","fullHtml","tag","value","bodyMatch","cssMatch","fontsUsed","s"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@emabuild/email-renderer",
3
- "version": "0.0.8",
3
+ "version": "0.1.0",
4
4
  "description": "Email HTML renderer — converts design JSON to cross-client email HTML",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -17,7 +17,7 @@
17
17
  "README.md"
18
18
  ],
19
19
  "dependencies": {
20
- "@emabuild/types": "0.0.8"
20
+ "@emabuild/types": "0.1.0"
21
21
  },
22
22
  "devDependencies": {
23
23
  "vite": "^6.2.0",