@cymbal/atoms-email-renderer 0.2.1 → 0.2.2

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.cjs CHANGED
@@ -439,6 +439,9 @@ function mjmlLayoutProps(ls) {
439
439
  ...backgroundImageProps
440
440
  });
441
441
  }
442
+ function layoutHasChrome(ls) {
443
+ return backgroundColorFromAtomBg(ls.background) !== void 0 || isImageBackground(ls.background) || ls.border !== "none" || cornerRadiusToCssValue(ls.borderRadius) !== void 0;
444
+ }
442
445
  function suppressLayoutBackground(layoutStyles) {
443
446
  return {
444
447
  ...layoutStyles,
@@ -805,7 +808,7 @@ function renderColumnContentAtom(atom, ctx) {
805
808
  case "divider":
806
809
  return React.cloneElement(renderDividerAtom(atom, ctx), { key: ctx.keyPrefix });
807
810
  case "rows":
808
- return renderRowsAsColumnContent(atom, ctx);
811
+ return /* @__PURE__ */ React.createElement(RawHtml, { key: ctx.keyPrefix, html: renderRawRowsAtom(atom, ctx) });
809
812
  case "columns":
810
813
  return /* @__PURE__ */ React.createElement(RawHtml, { key: ctx.keyPrefix, html: renderRawColumnsAtom(atom, ctx) });
811
814
  case "automation-upcoming-events":
@@ -818,48 +821,6 @@ function renderColumnContentAtom(atom, ctx) {
818
821
  return null;
819
822
  }
820
823
  }
821
- function renderChildrenAsColumnContent({
822
- children,
823
- resolvedRows,
824
- ctx
825
- }) {
826
- const gap = resolvedRows.gap;
827
- const nodes = [];
828
- children.forEach((child, index) => {
829
- if (index > 0 && gap > 0) {
830
- nodes.push(
831
- /* @__PURE__ */ React.createElement(
832
- RawHtml,
833
- {
834
- key: `${ctx.keyPrefix}-gap-${index}`,
835
- html: `<div style="height:${gap}px;line-height:${gap}px">&nbsp;</div>`
836
- }
837
- )
838
- );
839
- }
840
- const childLayout = resolveAtomLayoutStyles(child, ctx.globalAtomStyles);
841
- const childOuterWidth = roundWidth(
842
- calculateRowChildWidth({
843
- contentWidth: ctx.contentWidthPx,
844
- child,
845
- globalAtomStyles: ctx.globalAtomStyles
846
- })
847
- );
848
- const childContentWidth = roundWidth(computeAtomContentWidth(childOuterWidth, childLayout));
849
- const childCtx = {
850
- ...ctx,
851
- contentWidthPx: childContentWidth,
852
- parentRowBlockHorizontalAlign: resolvedRows.contentHorizontalAlign,
853
- keyPrefix: `${ctx.keyPrefix}-${child.atomKey}-${index}`
854
- };
855
- nodes.push(renderColumnContentAtom(child, childCtx));
856
- });
857
- return nodes;
858
- }
859
- function renderRowsAsColumnContent(atom, ctx) {
860
- const resolvedRows = resolveRowsStyles(atom.rowsStyles, ctx.globalAtomStyles.rowsStyles.rowsStyles);
861
- return renderChildrenAsColumnContent({ children: atom.children, resolvedRows, ctx });
862
- }
863
824
  function renderBodyAtom(atom, ctx) {
864
825
  switch (atom.type) {
865
826
  case "rows":
@@ -892,6 +853,19 @@ function renderRowsAsBodySections(atom, ctx) {
892
853
  /* @__PURE__ */ React.createElement(mjmlReact.MjmlSection, { key: `${ctx.keyPrefix}-empty`, ...mjmlLayoutProps(resolvedLayout) }, /* @__PURE__ */ React.createElement(mjmlReact.MjmlColumn, { width: `${innerWidth}px`, padding: "0" }, /* @__PURE__ */ React.createElement(mjmlReact.MjmlText, { padding: "0" }, "\xA0")))
893
854
  ];
894
855
  }
856
+ if (layoutHasChrome(resolvedLayout) && (atom.children.length > 1 || atom.children.some((child) => child.type === "columns"))) {
857
+ return /* @__PURE__ */ React.createElement(mjmlReact.MjmlSection, { key: ctx.keyPrefix, padding: "0" }, /* @__PURE__ */ React.createElement(mjmlReact.MjmlColumn, { width: `${outerWidth}px`, padding: "0" }, /* @__PURE__ */ React.createElement(
858
+ RawHtml,
859
+ {
860
+ html: renderRawChildrenRows({
861
+ children: atom.children,
862
+ resolvedLayout,
863
+ resolvedRows,
864
+ ctx
865
+ })
866
+ }
867
+ )));
868
+ }
895
869
  return atom.children.map((child, index) => {
896
870
  const childResolved = resolveAtomLayoutStyles(child, ctx.globalAtomStyles);
897
871
  const childOuterWidth = roundWidth(
@@ -918,7 +892,8 @@ function renderRowsAsBodySections(atom, ctx) {
918
892
  paddingTop: index > 0 ? resolvedRows.gap : 0,
919
893
  padding: rowChildSectionPadding(resolvedLayout, index, atom.children.length, resolvedRows.gap),
920
894
  width: childOuterWidth,
921
- align: childHorizontalAlign});
895
+ align: childHorizontalAlign
896
+ });
922
897
  }
923
898
  if (child.type === "rows") {
924
899
  return renderLeafAsBodySection(child, childCtx, {
@@ -949,12 +924,13 @@ function renderLeafAsBodySection(atom, ctx, opts) {
949
924
  padding: opts?.padding ?? `${sectionPaddingTop}px 0 0 0`,
950
925
  textAlign: opts?.align
951
926
  });
952
- return /* @__PURE__ */ React.createElement(mjmlReact.MjmlSection, { key: opts?.key ?? ctx.keyPrefix, ...sectionProps }, /* @__PURE__ */ React.createElement(mjmlReact.MjmlColumn, { width: `${width}px`, padding: "0" }, renderColumnContentAtom(atom, { ...ctx, contentWidthPx: width })));
927
+ return /* @__PURE__ */ React.createElement(mjmlReact.MjmlSection, { key: opts?.key ?? ctx.keyPrefix, ...sectionProps }, /* @__PURE__ */ React.createElement(mjmlReact.MjmlColumn, { width: `${width}px`, padding: "0" }, renderColumnContentAtom(atom, ctx)));
953
928
  }
954
929
  function renderColumnsAsBodySection(atom, ctx, opts) {
955
930
  const resolvedCols = resolveColumnsStyles(atom.columnsStyles, ctx.globalAtomStyles.columnsStyles.columnsStyles);
956
931
  if (resolvedCols.format === "table") {
957
- return /* @__PURE__ */ React.createElement(mjmlReact.MjmlSection, { key: opts?.key ?? ctx.keyPrefix, padding: opts?.padding ?? `${opts?.paddingTop ?? 0}px 0 0 0` }, /* @__PURE__ */ React.createElement(mjmlReact.MjmlColumn, { padding: "0" }, /* @__PURE__ */ React.createElement(RawHtml, { html: renderRawColumnsAtom(atom, ctx) })));
932
+ const rawCtx = opts?.width === void 0 ? ctx : { ...ctx, contentWidthPx: opts.width };
933
+ return /* @__PURE__ */ React.createElement(mjmlReact.MjmlSection, { key: opts?.key ?? ctx.keyPrefix, padding: opts?.padding ?? `${opts?.paddingTop ?? 0}px 0 0 0` }, /* @__PURE__ */ React.createElement(mjmlReact.MjmlColumn, { padding: "0" }, /* @__PURE__ */ React.createElement(RawHtml, { html: renderRawColumnsAtom(atom, rawCtx) })));
958
934
  }
959
935
  const resolvedLayout = resolveAtomLayoutStyles(atom, ctx.globalAtomStyles);
960
936
  const outerWidth = opts?.width ?? boxOuterWidth(ctx.contentWidthPx, resolvedLayout);
@@ -1147,8 +1123,35 @@ function renderRawColumnsAtom(atom, ctx) {
1147
1123
  gap: gapPx,
1148
1124
  globalAtomStyles: ctx.globalAtomStyles
1149
1125
  }).widthsPx.map(roundWidth);
1150
- const maxRows = Math.max(1, ...atom.children.map((child) => child.type === "rows" ? child.children.length : 1));
1151
1126
  const vAlign = resolvedCols.contentVerticalAlign === "middle" ? "middle" : resolvedCols.contentVerticalAlign;
1127
+ if (resolvedCols.format !== "table") {
1128
+ const cells = atom.children.map((child, columnIndex) => {
1129
+ const columnWidth = columnWidths[columnIndex] ?? 0;
1130
+ const gapBefore = columnIndex === 0 ? 0 : gapPx;
1131
+ const cellWidth = columnWidth + gapBefore;
1132
+ const childLayout = resolveAtomLayoutStyles(child, ctx.globalAtomStyles);
1133
+ const childCtx = {
1134
+ ...ctx,
1135
+ contentWidthPx: roundWidth(computeAtomContentWidth(columnWidth, childLayout)),
1136
+ parentRowBlockHorizontalAlign: null,
1137
+ keyPrefix: `${ctx.keyPrefix}-${child.atomKey}-${columnIndex}`
1138
+ };
1139
+ const gapCell = columnIndex > 0 && gapPx > 0 ? `<td width="${gapPx}" valign="${vAlign}" style="${rawCellStyle(gapPx, {
1140
+ fontSize: 0,
1141
+ lineHeight: 0,
1142
+ verticalAlign: vAlign
1143
+ })}">&nbsp;</td>` : "";
1144
+ return `${gapCell}<td width="${cellWidth}" valign="${vAlign}" style="${rawCellStyle(cellWidth, {
1145
+ verticalAlign: vAlign
1146
+ })}">${renderRawAtom(child, childCtx)}</td>`;
1147
+ }).join("");
1148
+ const totalWidth2 = columnWidths.reduce((sum, width) => sum + width, 0) + gapPx * Math.max(0, atom.children.length - 1);
1149
+ const table2 = `<div class="table-min-width-100"><table role="presentation" border="0" cellpadding="0" cellspacing="0" width="${totalWidth2}" align="${alignAttr(
1150
+ resolvedCols.contentHorizontalAlign
1151
+ )}" style="${rawTableStyle(totalWidth2)}"><tr>${cells}</tr></table></div>`;
1152
+ return renderRawWrappedBox(table2, outerWidth, resolvedLayout);
1153
+ }
1154
+ const maxRows = Math.max(1, ...atom.children.map((child) => child.type === "rows" ? child.children.length : 1));
1152
1155
  const rows = Array.from({ length: maxRows }).map((_, rowIndex) => {
1153
1156
  const cells = atom.children.map((child, columnIndex) => {
1154
1157
  const columnWidth = columnWidths[columnIndex] ?? 0;
package/dist/index.mjs CHANGED
@@ -437,6 +437,9 @@ function mjmlLayoutProps(ls) {
437
437
  ...backgroundImageProps
438
438
  });
439
439
  }
440
+ function layoutHasChrome(ls) {
441
+ return backgroundColorFromAtomBg(ls.background) !== void 0 || isImageBackground(ls.background) || ls.border !== "none" || cornerRadiusToCssValue(ls.borderRadius) !== void 0;
442
+ }
440
443
  function suppressLayoutBackground(layoutStyles) {
441
444
  return {
442
445
  ...layoutStyles,
@@ -803,7 +806,7 @@ function renderColumnContentAtom(atom, ctx) {
803
806
  case "divider":
804
807
  return React.cloneElement(renderDividerAtom(atom, ctx), { key: ctx.keyPrefix });
805
808
  case "rows":
806
- return renderRowsAsColumnContent(atom, ctx);
809
+ return /* @__PURE__ */ React.createElement(RawHtml, { key: ctx.keyPrefix, html: renderRawRowsAtom(atom, ctx) });
807
810
  case "columns":
808
811
  return /* @__PURE__ */ React.createElement(RawHtml, { key: ctx.keyPrefix, html: renderRawColumnsAtom(atom, ctx) });
809
812
  case "automation-upcoming-events":
@@ -816,48 +819,6 @@ function renderColumnContentAtom(atom, ctx) {
816
819
  return null;
817
820
  }
818
821
  }
819
- function renderChildrenAsColumnContent({
820
- children,
821
- resolvedRows,
822
- ctx
823
- }) {
824
- const gap = resolvedRows.gap;
825
- const nodes = [];
826
- children.forEach((child, index) => {
827
- if (index > 0 && gap > 0) {
828
- nodes.push(
829
- /* @__PURE__ */ React.createElement(
830
- RawHtml,
831
- {
832
- key: `${ctx.keyPrefix}-gap-${index}`,
833
- html: `<div style="height:${gap}px;line-height:${gap}px">&nbsp;</div>`
834
- }
835
- )
836
- );
837
- }
838
- const childLayout = resolveAtomLayoutStyles(child, ctx.globalAtomStyles);
839
- const childOuterWidth = roundWidth(
840
- calculateRowChildWidth({
841
- contentWidth: ctx.contentWidthPx,
842
- child,
843
- globalAtomStyles: ctx.globalAtomStyles
844
- })
845
- );
846
- const childContentWidth = roundWidth(computeAtomContentWidth(childOuterWidth, childLayout));
847
- const childCtx = {
848
- ...ctx,
849
- contentWidthPx: childContentWidth,
850
- parentRowBlockHorizontalAlign: resolvedRows.contentHorizontalAlign,
851
- keyPrefix: `${ctx.keyPrefix}-${child.atomKey}-${index}`
852
- };
853
- nodes.push(renderColumnContentAtom(child, childCtx));
854
- });
855
- return nodes;
856
- }
857
- function renderRowsAsColumnContent(atom, ctx) {
858
- const resolvedRows = resolveRowsStyles(atom.rowsStyles, ctx.globalAtomStyles.rowsStyles.rowsStyles);
859
- return renderChildrenAsColumnContent({ children: atom.children, resolvedRows, ctx });
860
- }
861
822
  function renderBodyAtom(atom, ctx) {
862
823
  switch (atom.type) {
863
824
  case "rows":
@@ -890,6 +851,19 @@ function renderRowsAsBodySections(atom, ctx) {
890
851
  /* @__PURE__ */ React.createElement(MjmlSection, { key: `${ctx.keyPrefix}-empty`, ...mjmlLayoutProps(resolvedLayout) }, /* @__PURE__ */ React.createElement(MjmlColumn, { width: `${innerWidth}px`, padding: "0" }, /* @__PURE__ */ React.createElement(MjmlText, { padding: "0" }, "\xA0")))
891
852
  ];
892
853
  }
854
+ if (layoutHasChrome(resolvedLayout) && (atom.children.length > 1 || atom.children.some((child) => child.type === "columns"))) {
855
+ return /* @__PURE__ */ React.createElement(MjmlSection, { key: ctx.keyPrefix, padding: "0" }, /* @__PURE__ */ React.createElement(MjmlColumn, { width: `${outerWidth}px`, padding: "0" }, /* @__PURE__ */ React.createElement(
856
+ RawHtml,
857
+ {
858
+ html: renderRawChildrenRows({
859
+ children: atom.children,
860
+ resolvedLayout,
861
+ resolvedRows,
862
+ ctx
863
+ })
864
+ }
865
+ )));
866
+ }
893
867
  return atom.children.map((child, index) => {
894
868
  const childResolved = resolveAtomLayoutStyles(child, ctx.globalAtomStyles);
895
869
  const childOuterWidth = roundWidth(
@@ -916,7 +890,8 @@ function renderRowsAsBodySections(atom, ctx) {
916
890
  paddingTop: index > 0 ? resolvedRows.gap : 0,
917
891
  padding: rowChildSectionPadding(resolvedLayout, index, atom.children.length, resolvedRows.gap),
918
892
  width: childOuterWidth,
919
- align: childHorizontalAlign});
893
+ align: childHorizontalAlign
894
+ });
920
895
  }
921
896
  if (child.type === "rows") {
922
897
  return renderLeafAsBodySection(child, childCtx, {
@@ -947,12 +922,13 @@ function renderLeafAsBodySection(atom, ctx, opts) {
947
922
  padding: opts?.padding ?? `${sectionPaddingTop}px 0 0 0`,
948
923
  textAlign: opts?.align
949
924
  });
950
- return /* @__PURE__ */ React.createElement(MjmlSection, { key: opts?.key ?? ctx.keyPrefix, ...sectionProps }, /* @__PURE__ */ React.createElement(MjmlColumn, { width: `${width}px`, padding: "0" }, renderColumnContentAtom(atom, { ...ctx, contentWidthPx: width })));
925
+ return /* @__PURE__ */ React.createElement(MjmlSection, { key: opts?.key ?? ctx.keyPrefix, ...sectionProps }, /* @__PURE__ */ React.createElement(MjmlColumn, { width: `${width}px`, padding: "0" }, renderColumnContentAtom(atom, ctx)));
951
926
  }
952
927
  function renderColumnsAsBodySection(atom, ctx, opts) {
953
928
  const resolvedCols = resolveColumnsStyles(atom.columnsStyles, ctx.globalAtomStyles.columnsStyles.columnsStyles);
954
929
  if (resolvedCols.format === "table") {
955
- return /* @__PURE__ */ React.createElement(MjmlSection, { key: opts?.key ?? ctx.keyPrefix, padding: opts?.padding ?? `${opts?.paddingTop ?? 0}px 0 0 0` }, /* @__PURE__ */ React.createElement(MjmlColumn, { padding: "0" }, /* @__PURE__ */ React.createElement(RawHtml, { html: renderRawColumnsAtom(atom, ctx) })));
930
+ const rawCtx = opts?.width === void 0 ? ctx : { ...ctx, contentWidthPx: opts.width };
931
+ return /* @__PURE__ */ React.createElement(MjmlSection, { key: opts?.key ?? ctx.keyPrefix, padding: opts?.padding ?? `${opts?.paddingTop ?? 0}px 0 0 0` }, /* @__PURE__ */ React.createElement(MjmlColumn, { padding: "0" }, /* @__PURE__ */ React.createElement(RawHtml, { html: renderRawColumnsAtom(atom, rawCtx) })));
956
932
  }
957
933
  const resolvedLayout = resolveAtomLayoutStyles(atom, ctx.globalAtomStyles);
958
934
  const outerWidth = opts?.width ?? boxOuterWidth(ctx.contentWidthPx, resolvedLayout);
@@ -1145,8 +1121,35 @@ function renderRawColumnsAtom(atom, ctx) {
1145
1121
  gap: gapPx,
1146
1122
  globalAtomStyles: ctx.globalAtomStyles
1147
1123
  }).widthsPx.map(roundWidth);
1148
- const maxRows = Math.max(1, ...atom.children.map((child) => child.type === "rows" ? child.children.length : 1));
1149
1124
  const vAlign = resolvedCols.contentVerticalAlign === "middle" ? "middle" : resolvedCols.contentVerticalAlign;
1125
+ if (resolvedCols.format !== "table") {
1126
+ const cells = atom.children.map((child, columnIndex) => {
1127
+ const columnWidth = columnWidths[columnIndex] ?? 0;
1128
+ const gapBefore = columnIndex === 0 ? 0 : gapPx;
1129
+ const cellWidth = columnWidth + gapBefore;
1130
+ const childLayout = resolveAtomLayoutStyles(child, ctx.globalAtomStyles);
1131
+ const childCtx = {
1132
+ ...ctx,
1133
+ contentWidthPx: roundWidth(computeAtomContentWidth(columnWidth, childLayout)),
1134
+ parentRowBlockHorizontalAlign: null,
1135
+ keyPrefix: `${ctx.keyPrefix}-${child.atomKey}-${columnIndex}`
1136
+ };
1137
+ const gapCell = columnIndex > 0 && gapPx > 0 ? `<td width="${gapPx}" valign="${vAlign}" style="${rawCellStyle(gapPx, {
1138
+ fontSize: 0,
1139
+ lineHeight: 0,
1140
+ verticalAlign: vAlign
1141
+ })}">&nbsp;</td>` : "";
1142
+ return `${gapCell}<td width="${cellWidth}" valign="${vAlign}" style="${rawCellStyle(cellWidth, {
1143
+ verticalAlign: vAlign
1144
+ })}">${renderRawAtom(child, childCtx)}</td>`;
1145
+ }).join("");
1146
+ const totalWidth2 = columnWidths.reduce((sum, width) => sum + width, 0) + gapPx * Math.max(0, atom.children.length - 1);
1147
+ const table2 = `<div class="table-min-width-100"><table role="presentation" border="0" cellpadding="0" cellspacing="0" width="${totalWidth2}" align="${alignAttr(
1148
+ resolvedCols.contentHorizontalAlign
1149
+ )}" style="${rawTableStyle(totalWidth2)}"><tr>${cells}</tr></table></div>`;
1150
+ return renderRawWrappedBox(table2, outerWidth, resolvedLayout);
1151
+ }
1152
+ const maxRows = Math.max(1, ...atom.children.map((child) => child.type === "rows" ? child.children.length : 1));
1150
1153
  const rows = Array.from({ length: maxRows }).map((_, rowIndex) => {
1151
1154
  const cells = atom.children.map((child, columnIndex) => {
1152
1155
  const columnWidth = columnWidths[columnIndex] ?? 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cymbal/atoms-email-renderer",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "main": "./dist/index.cjs",
5
5
  "module": "./dist/index.mjs",
6
6
  "types": "./dist/index.d.ts",