@pagenflow/email 1.4.2 → 1.4.3

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.js CHANGED
@@ -17,24 +17,42 @@ function Body({ children, config = {} }) {
17
17
  const bgSize = ((_c = config.backgroundImage) === null || _c === void 0 ? void 0 : _c.size) || "cover";
18
18
  const bgPosition = ((_d = config.backgroundImage) === null || _d === void 0 ? void 0 : _d.position) || "center";
19
19
  // 1. Style for the <body> tag inline
20
- const bodyStyle = Object.assign({ backgroundColor: globalBackgroundColor, color: globalColor, fontSize: globalFontSize, lineHeight: globalLineHeight, padding: "0", margin: "0", WebkitTextSizeAdjust: "100%", overflowX: "hidden", ["msTextSizeAdjust"]: "100%", ["msoLineHeightRule"]: "exactly", fontFamily: globalFontFamily }, (bgImage && {
21
- backgroundImage: `url(${bgImage})`,
22
- backgroundRepeat: bgRepeat,
23
- backgroundSize: bgSize,
24
- backgroundPosition: bgPosition,
25
- }));
20
+ const bodyStyle = {
21
+ backgroundColor: globalBackgroundColor,
22
+ color: globalColor,
23
+ fontSize: globalFontSize,
24
+ lineHeight: globalLineHeight,
25
+ padding: "0",
26
+ margin: "0",
27
+ WebkitTextSizeAdjust: "100%",
28
+ overflowX: "hidden",
29
+ ["msTextSizeAdjust"]: "100%",
30
+ ["msoLineHeightRule"]: "exactly",
31
+ fontFamily: globalFontFamily,
32
+ // Background image support (if provided)
33
+ ...(bgImage && {
34
+ backgroundImage: `url(${bgImage})`,
35
+ backgroundRepeat: bgRepeat,
36
+ backgroundSize: bgSize,
37
+ backgroundPosition: bgPosition,
38
+ }),
39
+ };
26
40
  // 2. Style for the top-level <table> wrapper
27
41
  const outerTableStyle = {
28
42
  width: "100%",
29
43
  ["msoLineHeightRule"]: "exactly",
30
44
  borderCollapse: "collapse",
31
45
  };
32
- return (jsxRuntime.jsxs("body", { style: bodyStyle, children: [jsxRuntime.jsx("center", { style: Object.assign({ width: "100%", background: globalBackgroundColor }, (bgImage && {
33
- backgroundImage: `url(${bgImage})`,
34
- backgroundRepeat: bgRepeat,
35
- backgroundSize: bgSize,
36
- backgroundPosition: bgPosition,
37
- })), children: jsxRuntime.jsx("table", { role: "presentation", border: 0, cellPadding: 0, cellSpacing: 0, align: "center", width: "100%", style: outerTableStyle, children: jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { align: "center", style: { padding: "0", margin: "0" }, children: children }) }) }) }) }), jsxRuntime.jsx("div", { style: {
46
+ return (jsxRuntime.jsxs("body", { style: bodyStyle, children: [jsxRuntime.jsx("center", { style: {
47
+ width: "100%",
48
+ background: globalBackgroundColor,
49
+ ...(bgImage && {
50
+ backgroundImage: `url(${bgImage})`,
51
+ backgroundRepeat: bgRepeat,
52
+ backgroundSize: bgSize,
53
+ backgroundPosition: bgPosition,
54
+ }),
55
+ }, children: jsxRuntime.jsx("table", { role: "presentation", border: 0, cellPadding: 0, cellSpacing: 0, align: "center", width: "100%", style: outerTableStyle, children: jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { align: "center", style: { padding: "0", margin: "0" }, children: children }) }) }) }) }), jsxRuntime.jsx("div", { style: {
38
56
  display: "none",
39
57
  whiteSpace: "nowrap",
40
58
  font: "15px courier",
@@ -1521,41 +1539,6 @@ const justifyMap$3 = {
1521
1539
  center: "center",
1522
1540
  end: "right",
1523
1541
  };
1524
- function getBorderStyle$6(border) {
1525
- if (!border)
1526
- return {};
1527
- const style = {};
1528
- // If a full border is specified, apply it
1529
- if (border.width && border.style && border.color) {
1530
- style.border = `${border.width} ${border.style} ${border.color}`;
1531
- }
1532
- else {
1533
- // If only individual borders are specified, explicitly set others to 'none'
1534
- // to prevent Outlook Classic from showing black borders
1535
- const hasIndividualBorders = border.top || border.right || border.bottom || border.left;
1536
- if (hasIndividualBorders) {
1537
- // Default all borders to none
1538
- style.borderTop = "none";
1539
- style.borderRight = "none";
1540
- style.borderBottom = "none";
1541
- style.borderLeft = "none";
1542
- }
1543
- }
1544
- // Override with specific borders if provided
1545
- if (border.top) {
1546
- style.borderTop = `${border.top.width} ${border.top.style} ${border.top.color}`;
1547
- }
1548
- if (border.right) {
1549
- style.borderRight = `${border.right.width} ${border.right.style} ${border.right.color}`;
1550
- }
1551
- if (border.bottom) {
1552
- style.borderBottom = `${border.bottom.width} ${border.bottom.style} ${border.bottom.color}`;
1553
- }
1554
- if (border.left) {
1555
- style.borderLeft = `${border.left.width} ${border.left.style} ${border.left.color}`;
1556
- }
1557
- return style;
1558
- }
1559
1542
  function getBorderStyleString$2(border) {
1560
1543
  if (!border)
1561
1544
  return "";
@@ -1597,10 +1580,16 @@ function Button({ config, devMode }) {
1597
1580
  const safeFontFamily = fontFamily
1598
1581
  ? fontFamily.replace(/['"]/g, "")
1599
1582
  : fontFamily;
1600
- // 2. Outer TD Style for Background and Border Radius (no border)
1601
- const backgroundTdStyle = Object.assign(Object.assign({ backgroundColor: backgroundColor, borderRadius: borderRadius, width: width || "auto" }, (maxWidth && { maxWidth: maxWidth })), (borderRadius && { overflow: "hidden" }));
1602
- // 3. Border styles
1603
- getBorderStyle$6(border);
1583
+ // Outer TD Style for Background and Border Radius (no border)
1584
+ const backgroundTdStyle = {
1585
+ backgroundColor: backgroundColor,
1586
+ borderRadius: borderRadius,
1587
+ width: width || "auto",
1588
+ ...(maxWidth && { maxWidth: maxWidth }),
1589
+ // Overflow hidden to clip background to border-radius
1590
+ ...(borderRadius && { overflow: "hidden" }),
1591
+ };
1592
+ // Border styles
1604
1593
  const borderStyleString = getBorderStyleString$2(border);
1605
1594
  // --- Determine Button Approach Based on Width ---
1606
1595
  // Check if width is percentage-based or not defined
@@ -1764,15 +1753,21 @@ function Button({ config, devMode }) {
1764
1753
  padding: 0,
1765
1754
  }, children: jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { align: align, style: {
1766
1755
  padding: 0,
1767
- }, children: jsxRuntime.jsx("table", { role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: Object.assign(Object.assign({
1756
+ }, children: jsxRuntime.jsx("table", { role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: {
1768
1757
  // --- Start dev
1769
- position: "relative",
1758
+ position: "relative",
1770
1759
  // --- End dev
1771
- width: width || "auto" }, (maxWidth && { maxWidth: maxWidth })), { borderCollapse: "collapse",
1760
+ width: width || "auto",
1761
+ ...(maxWidth && { maxWidth: maxWidth }),
1762
+ borderCollapse: "collapse",
1772
1763
  // base
1773
- boxSizing: "border-box", border: 0, margin: 0, padding: 0 }), onClick: devMode ? (e) => e.preventDefault() : undefined, children: jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { dangerouslySetInnerHTML: {
1764
+ boxSizing: "border-box",
1765
+ border: 0,
1766
+ margin: 0,
1767
+ padding: 0,
1768
+ }, onClick: devMode ? (e) => e.preventDefault() : undefined, children: jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { dangerouslySetInnerHTML: {
1774
1769
  __html: `
1775
- ${devMode ? "" : useSimpleOutlookApproach ? simpleOutlookButton : vmlButton}
1770
+ ${useSimpleOutlookApproach ? simpleOutlookButton : vmlButton}
1776
1771
  <!--[if !mso]><!-->
1777
1772
  <table role="presentation" cellpadding="0" cellspacing="0" border="0" style="border-collapse: collapse; width: 100%;">
1778
1773
  <tbody>
@@ -1783,11 +1778,11 @@ function Button({ config, devMode }) {
1783
1778
  <tr>
1784
1779
  <td style="padding: 0;">
1785
1780
  ${devMode
1786
- ? `<span style="${sharedTextStyles} display: block; text-align: ${textAlign}; word-break: ${wordBreak}; padding: ${padding};">
1781
+ ? `<span style="${sharedTextStyles} ${textDecoration && textDecoration !== "none" ? "" : "text-decoration: none;"} display: block; word-break: ${wordBreak}; text-align: ${textAlign}; padding: ${padding};">
1787
1782
  ${typeof children === "string" ? children : ""}
1788
1783
  </span>`
1789
1784
  : `<a href="${href}" target="_blank" rel="noopener noreferrer" style="${sharedTextStyles} ${textDecoration && textDecoration !== "none" ? "" : "text-decoration: none;"} display: block; word-break: ${wordBreak}; text-align: ${textAlign}; padding: ${padding};">
1790
- <span style="${sharedTextStyles}">
1785
+ <span>
1791
1786
  ${typeof children === "string" ? children : ""}
1792
1787
  </span>
1793
1788
  </a>`}
@@ -1867,14 +1862,31 @@ function Column({ children, config, devNode }) {
1867
1862
  };
1868
1863
  // 2. Outer TD style: Background and Border Radius (no border here).
1869
1864
  // height is set so the TD occupies the full declared height.
1870
- const outerTdStyle = Object.assign({ width: config.width, height: config.height, backgroundColor: config.backgroundColor, borderRadius: config.borderRadius,
1865
+ const outerTdStyle = {
1866
+ width: config.width,
1867
+ height: config.height,
1868
+ backgroundColor: config.backgroundColor,
1869
+ borderRadius: config.borderRadius,
1871
1870
  // Background Image styles
1872
1871
  backgroundImage: config.backgroundImage
1873
1872
  ? `url(${config.backgroundImage.src})`
1874
- : undefined, backgroundRepeat: (_a = config.backgroundImage) === null || _a === void 0 ? void 0 : _a.repeat, backgroundSize: (_b = config.backgroundImage) === null || _b === void 0 ? void 0 : _b.size, backgroundPosition: (_c = config.backgroundImage) === null || _c === void 0 ? void 0 : _c.position }, (config.borderRadius && { overflow: "hidden" }));
1873
+ : undefined,
1874
+ backgroundRepeat: (_a = config.backgroundImage) === null || _a === void 0 ? void 0 : _a.repeat,
1875
+ backgroundSize: (_b = config.backgroundImage) === null || _b === void 0 ? void 0 : _b.size,
1876
+ backgroundPosition: (_c = config.backgroundImage) === null || _c === void 0 ? void 0 : _c.position,
1877
+ // Overflow hidden to clip background to border-radius
1878
+ ...(config.borderRadius && { overflow: "hidden" }),
1879
+ };
1875
1880
  // 2b. Inner table style: Border and Border Radius.
1876
1881
  // height: 100% so it stretches to fill the outer TD's declared height.
1877
- const innerTableStyle = Object.assign({ width: "100%", height: "100%", borderCollapse: "separate", borderSpacing: 0, borderRadius: config.borderRadius }, getBorderStyle$5(config.border));
1882
+ const innerTableStyle = {
1883
+ width: "100%",
1884
+ height: "100%", // fill the outer TD rather than re-declaring the pixel value
1885
+ borderCollapse: "separate",
1886
+ borderSpacing: 0,
1887
+ borderRadius: config.borderRadius,
1888
+ ...getBorderStyle$5(config.border),
1889
+ };
1878
1890
  // 3. Inner TD style: Padding and Vertical Alignment only.
1879
1891
  // *** No height here. ***
1880
1892
  // The outer TD/table owns the height; padding is purely inner spacing,
@@ -1906,7 +1918,10 @@ function Column({ children, config, devNode }) {
1906
1918
  : "top", align: config.alignItems
1907
1919
  ? alignMap$2[config.alignItems]
1908
1920
  : "left", children: child }) }), index < numChildren - 1 && (jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { style: gapSpacerStyle, children: "\u00A0" }) }))] }, `col-child-${index}`))) }) })) : (children) }) }) }) }));
1909
- return (jsxRuntime.jsxs("table", Object.assign({ "aria-label": "Column Wrapper", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: Object.assign({ position: "relative" }, outerTableStyle) }, (config.height && { height: config.height }), { children: [jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", Object.assign({ style: outerTdStyle }, (config.width && { width: config.width }), (config.height && { height: config.height }), { children: renderContent() })) }) }), devNode && (jsxRuntime.jsx("tfoot", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { children: devNode }) }) }))] })));
1921
+ return (jsxRuntime.jsxs("table", { "aria-label": "Column Wrapper", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: {
1922
+ position: "relative",
1923
+ ...outerTableStyle,
1924
+ }, ...(config.height && { height: config.height }), children: [jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { style: outerTdStyle, ...(config.width && { width: config.width }), ...(config.height && { height: config.height }), children: renderContent() }) }) }), devNode && (jsxRuntime.jsx("tfoot", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { children: devNode }) }) }))] }));
1910
1925
  }
1911
1926
  var Column_default = React.memo(Column, arePropsEqual);
1912
1927
 
@@ -2011,11 +2026,27 @@ function Container({ children, config, devMode, devNode }) {
2011
2026
  borderCollapse: "collapse",
2012
2027
  };
2013
2028
  // 1. Background TD Style - Background color, border radius, background image
2014
- const backgroundTdStyle = Object.assign({ backgroundColor: config.backgroundColor, borderRadius: config.borderRadius, maxWidth: widthType === "fixed" ? config.width || "600px" : undefined, backgroundImage: config.backgroundImage
2029
+ const backgroundTdStyle = {
2030
+ backgroundColor: config.backgroundColor,
2031
+ borderRadius: config.borderRadius,
2032
+ maxWidth: widthType === "fixed" ? config.width || "600px" : undefined,
2033
+ backgroundImage: config.backgroundImage
2015
2034
  ? `url(${config.backgroundImage.src})`
2016
- : undefined, backgroundRepeat: (_a = config.backgroundImage) === null || _a === void 0 ? void 0 : _a.repeat, backgroundSize: (_b = config.backgroundImage) === null || _b === void 0 ? void 0 : _b.size, backgroundPosition: (_c = config.backgroundImage) === null || _c === void 0 ? void 0 : _c.position }, (config.borderRadius && { overflow: "hidden" }));
2035
+ : undefined,
2036
+ backgroundRepeat: (_a = config.backgroundImage) === null || _a === void 0 ? void 0 : _a.repeat,
2037
+ backgroundSize: (_b = config.backgroundImage) === null || _b === void 0 ? void 0 : _b.size,
2038
+ backgroundPosition: (_c = config.backgroundImage) === null || _c === void 0 ? void 0 : _c.position,
2039
+ // Overflow hidden to clip background to border-radius
2040
+ ...(config.borderRadius && { overflow: "hidden" }),
2041
+ };
2017
2042
  // 2. Border Table Style - Border and border radius
2018
- const borderTableStyle = Object.assign({ width: "100%", borderCollapse: "separate", borderSpacing: 0, borderRadius: config.borderRadius }, getBorderStyle$4(config.border));
2043
+ const borderTableStyle = {
2044
+ width: "100%",
2045
+ borderCollapse: "separate",
2046
+ borderSpacing: 0,
2047
+ borderRadius: config.borderRadius,
2048
+ ...getBorderStyle$4(config.border),
2049
+ };
2019
2050
  // 3. Padding TD Style
2020
2051
  const innerTdStyle = {
2021
2052
  padding: config.padding,
@@ -2055,7 +2086,10 @@ function Container({ children, config, devMode, devNode }) {
2055
2086
  }
2056
2087
  return (jsxRuntime.jsx("td", { className: isStacking ? "stack-td" : undefined, width: getChildWidths[index], style: childTdStyle, children: child }, `child-${index}`));
2057
2088
  });
2058
- return (jsxRuntime.jsx("table", { "aria-label": `Container | Table Outer`, cellPadding: 0, cellSpacing: 0, role: "presentation", border: 0, style: Object.assign({ position: "relative" }, outerTableStyle), children: jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsxs("td", { align: justifyAlign, children: [jsxRuntime.jsx("div", { dangerouslySetInnerHTML: { __html: msoFixedWrapper } }), jsxRuntime.jsxs("table", { className: [
2089
+ return (jsxRuntime.jsx("table", { "aria-label": `Container | Table Outer`, cellPadding: 0, cellSpacing: 0, role: "presentation", border: 0, style: {
2090
+ position: "relative",
2091
+ ...outerTableStyle,
2092
+ }, children: jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsxs("td", { align: justifyAlign, children: [jsxRuntime.jsx("div", { dangerouslySetInnerHTML: { __html: msoFixedWrapper } }), jsxRuntime.jsxs("table", { className: [
2059
2093
  widthType === "fixed" ? "container-fixed-width" : undefined,
2060
2094
  devMode ? "main-wrapper relative" : undefined,
2061
2095
  ]
@@ -2098,12 +2132,12 @@ function Divider({ config, devNode }) {
2098
2132
  // --- End dev
2099
2133
  width: "100%",
2100
2134
  borderCollapse: "collapse",
2101
- }, className: hideOnMobile ? "hide-on-mobile" : undefined, children: [jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { style: outerTdStyle, align: align, children: jsxRuntime.jsx("table", Object.assign({ "aria-label": "Divider Line", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, align: align, style: dividerTableStyle }, { height: dividerHeightAttribute }, { children: jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { style: {
2135
+ }, className: hideOnMobile ? "hide-on-mobile" : undefined, children: [jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { style: outerTdStyle, align: align, children: jsxRuntime.jsx("table", { "aria-label": "Divider Line", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, align: align, style: dividerTableStyle, ...{ height: dividerHeightAttribute }, children: jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { style: {
2102
2136
  height: height,
2103
2137
  fontSize: "0",
2104
2138
  lineHeight: "0",
2105
2139
  padding: "0",
2106
- }, children: "\u00A0" }) }) }) })) }) }) }), devNode && (jsxRuntime.jsx("tfoot", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { children: devNode }) }) }))] }));
2140
+ }, children: "\u00A0" }) }) }) }) }) }) }), devNode && (jsxRuntime.jsx("tfoot", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { children: devNode }) }) }))] }));
2107
2141
  }
2108
2142
  var Divider_default = React.memo(Divider, arePropsEqual);
2109
2143
 
@@ -2281,7 +2315,7 @@ function Head({ children, backgroundColor = "#ffffff", title = "Email Preview",
2281
2315
  }
2282
2316
  h1, h2, h3, h4, h5, h6 { margin: 0; padding: 0; font-weight: inherit; }
2283
2317
  `;
2284
- return (jsxRuntime.jsxs("head", { children: [jsxRuntime.jsx("meta", { httpEquiv: "Content-Type", content: "text/html; charset=utf-8" }), jsxRuntime.jsx("meta", { name: "viewport", content: "width=device-width, initial-scale=1.0" }), jsxRuntime.jsx("meta", { httpEquiv: "X-UA-Compatible", content: "IE=edge" }), jsxRuntime.jsx("title", { children: title }), fonts.flatMap((resolved) => resolved.fontProps.map((props, i) => (jsxRuntime.jsx(Font, Object.assign({}, props), `${resolved.family}-${props.fontWeight}-${props.fontStyle}-${i}`)))), children, jsxRuntime.jsx("style", { type: "text/css", dangerouslySetInnerHTML: { __html: msoResetStyles } }), jsxRuntime.jsx("style", { type: "text/css", dangerouslySetInnerHTML: { __html: globalStyles } })] }));
2318
+ return (jsxRuntime.jsxs("head", { children: [jsxRuntime.jsx("meta", { httpEquiv: "Content-Type", content: "text/html; charset=utf-8" }), jsxRuntime.jsx("meta", { name: "viewport", content: "width=device-width, initial-scale=1.0" }), jsxRuntime.jsx("meta", { httpEquiv: "X-UA-Compatible", content: "IE=edge" }), jsxRuntime.jsx("title", { children: title }), fonts.flatMap((resolved) => resolved.fontProps.map((props, i) => (jsxRuntime.jsx(Font, { ...props }, `${resolved.family}-${props.fontWeight}-${props.fontStyle}-${i}`)))), children, jsxRuntime.jsx("style", { type: "text/css", dangerouslySetInnerHTML: { __html: msoResetStyles } }), jsxRuntime.jsx("style", { type: "text/css", dangerouslySetInnerHTML: { __html: globalStyles } })] }));
2285
2319
  }
2286
2320
 
2287
2321
  function Heading({ config, devMode, children }) {
@@ -2389,7 +2423,7 @@ function getBorderStyleString$1(border) {
2389
2423
  return styles.join(" ");
2390
2424
  }
2391
2425
  function Image({ config, devNode, devMode }) {
2392
- var _a;
2426
+ var _a, _b;
2393
2427
  const { src, alt, href, target, mobile } = config;
2394
2428
  const seed = src + (alt || "");
2395
2429
  const instanceId = seed
@@ -2405,6 +2439,21 @@ function Image({ config, devNode, devMode }) {
2405
2439
  // Determine the table's "initial" width.
2406
2440
  // If it's 300px, the table should be 300px, not 100%.
2407
2441
  const tableWidth = isPercent ? desktopWidth : `${widthAttr}px`;
2442
+ // When width is a percentage, Outlook ignores CSS and renders the image at
2443
+ // its intrinsic pixel size. Setting a concrete `width` HTML attribute gives
2444
+ // Outlook a value to constrain against while modern clients continue to use
2445
+ // the CSS `width: 100%` for fluid rendering.
2446
+ //
2447
+ // If `maxWidth` is a pixel value (e.g. "600px"), we extract the number and
2448
+ // use it as the HTML `width` attribute so Outlook enforces that cap.
2449
+ // Other clients ignore the attribute and rely on CSS styles instead.
2450
+ // If `maxWidth` is not set or is not a pixel value (e.g. "100%"), we fall
2451
+ // back to the original behaviour (numeric string for px widths, undefined
2452
+ // for % widths).
2453
+ const maxWidthPx = ((_b = config.maxWidth) === null || _b === void 0 ? void 0 : _b.endsWith("px"))
2454
+ ? parseInt(config.maxWidth, 10)
2455
+ : undefined;
2456
+ const imgWidthAttr = isPercent ? (maxWidthPx !== null && maxWidthPx !== void 0 ? maxWidthPx : undefined) : widthAttr;
2408
2457
  // 2. Mobile Overrides (Every property used)
2409
2458
  let mobileCss = "";
2410
2459
  if (mobile) {
@@ -2435,8 +2484,20 @@ function Image({ config, devNode, devMode }) {
2435
2484
  }
2436
2485
  `;
2437
2486
  }
2438
- const imgStyle = Object.assign(Object.assign({ display: "block", width: isPercent ? "100%" : desktopWidth, height: config.height || "auto", maxWidth: config.maxWidth || "100%", maxHeight: config.maxHeight || "none", borderRadius: config.borderRadius || "0" }, getBorderStyle$3(config.border)), { outline: "none", textDecoration: "none", objectFit: config.objectFit, objectPosition: config.objectPosition });
2439
- const imageElement = (jsxRuntime.jsx("img", { src: src, alt: alt, width: !isPercent ? widthAttr : undefined, height: heightAttr !== "auto" ? heightAttr : undefined, className: imgClass, style: imgStyle }));
2487
+ const imgStyle = {
2488
+ display: "block",
2489
+ width: isPercent ? "100%" : desktopWidth,
2490
+ height: config.height || "auto",
2491
+ maxWidth: config.maxWidth || "100%",
2492
+ maxHeight: config.maxHeight || "none",
2493
+ borderRadius: config.borderRadius || "0",
2494
+ ...getBorderStyle$3(config.border),
2495
+ outline: "none",
2496
+ textDecoration: "none",
2497
+ objectFit: config.objectFit,
2498
+ objectPosition: config.objectPosition,
2499
+ };
2500
+ const imageElement = (jsxRuntime.jsx("img", { src: src, alt: alt, width: imgWidthAttr, height: heightAttr !== "auto" ? heightAttr : undefined, className: imgClass, style: imgStyle }));
2440
2501
  return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [mobile && jsxRuntime.jsx("style", { dangerouslySetInnerHTML: { __html: mobileCss } }), jsxRuntime.jsxs("table", { role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, className: `wrap-${imgClass}`, align: "center" // Ensures a 300px image stays centered in its parent
2441
2502
  , style: {
2442
2503
  width: tableWidth, // Fixed px here prevents the 100% "ghost space"
@@ -2525,11 +2586,28 @@ function Row({ children, config, devNode, devMode }) {
2525
2586
  const href = getHrefFromInnerLink(config.innerLink);
2526
2587
  const target = (_a = config.innerLink) === null || _a === void 0 ? void 0 : _a.target;
2527
2588
  // 1. Outer TD: Background, Border Radius, Width, Height.
2528
- const backgroundTdStyle = Object.assign({ backgroundColor: config.backgroundColor, borderRadius: config.borderRadius, width: config.width || "100%", height: config.height, backgroundImage: config.backgroundImage
2589
+ const backgroundTdStyle = {
2590
+ backgroundColor: config.backgroundColor,
2591
+ borderRadius: config.borderRadius,
2592
+ width: config.width || "100%",
2593
+ height: config.height,
2594
+ backgroundImage: config.backgroundImage
2529
2595
  ? `url(${config.backgroundImage.src})`
2530
- : undefined, backgroundRepeat: (_b = config.backgroundImage) === null || _b === void 0 ? void 0 : _b.repeat, backgroundSize: (_c = config.backgroundImage) === null || _c === void 0 ? void 0 : _c.size, backgroundPosition: (_d = config.backgroundImage) === null || _d === void 0 ? void 0 : _d.position }, (config.borderRadius && { overflow: "hidden" }));
2596
+ : undefined,
2597
+ backgroundRepeat: (_b = config.backgroundImage) === null || _b === void 0 ? void 0 : _b.repeat,
2598
+ backgroundSize: (_c = config.backgroundImage) === null || _c === void 0 ? void 0 : _c.size,
2599
+ backgroundPosition: (_d = config.backgroundImage) === null || _d === void 0 ? void 0 : _d.position,
2600
+ ...(config.borderRadius && { overflow: "hidden" }),
2601
+ };
2531
2602
  // 2. Inner Table: Border and Border Radius.
2532
- const borderTableStyle = Object.assign({ width: "100%", height: "100%", borderCollapse: "separate", borderSpacing: 0, borderRadius: config.borderRadius }, getBorderStyle$2(config.border));
2603
+ const borderTableStyle = {
2604
+ width: "100%",
2605
+ height: "100%",
2606
+ borderCollapse: "separate",
2607
+ borderSpacing: 0,
2608
+ borderRadius: config.borderRadius,
2609
+ ...getBorderStyle$2(config.border),
2610
+ };
2533
2611
  // 3. Padding TD.
2534
2612
  const paddingTdStyle = {
2535
2613
  padding: config.padding,
@@ -2547,7 +2625,13 @@ function Row({ children, config, devNode, devMode }) {
2547
2625
  // Content table fills available space, giving Outlook Classic a hard
2548
2626
  // boundary so text children get a constrained box and line wrapping
2549
2627
  // triggers correctly. Use for rows containing text + image layouts.
2550
- const contentTableStyle = Object.assign({ width: config.fillWidth ? "100%" : "auto", height: "100%", borderCollapse: "collapse", minWidth: "1px" }, (!config.fillWidth && { maxWidth: config.width || "100%" }));
2628
+ const contentTableStyle = {
2629
+ width: config.fillWidth ? "100%" : "auto",
2630
+ height: "100%",
2631
+ borderCollapse: "collapse",
2632
+ minWidth: "1px",
2633
+ ...(!config.fillWidth && { maxWidth: config.width || "100%" }),
2634
+ };
2551
2635
  // 5. Gap TD.
2552
2636
  const gapTdStyle = {
2553
2637
  width: config.gap || "0",
@@ -2558,28 +2642,28 @@ function Row({ children, config, devNode, devMode }) {
2558
2642
  ? justifyMap$1[config.justifyContent]
2559
2643
  : "left";
2560
2644
  const tdValign = config.alignItems ? alignMap[config.alignItems] : "top";
2561
- const content = (jsxRuntime.jsxs("table", Object.assign({ "aria-label": "Row Outer", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: {
2645
+ const content = (jsxRuntime.jsxs("table", { "aria-label": "Row Outer", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: {
2562
2646
  position: "relative",
2563
2647
  width: config.width || "100%",
2564
2648
  height: config.height,
2565
2649
  borderCollapse: "collapse",
2566
- } }, (config.height && { height: config.height }), { children: [jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", Object.assign({ style: backgroundTdStyle }, (config.height && { height: config.height }), { children: jsxRuntime.jsx("table", { "aria-label": "Row Border Wrapper", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: borderTableStyle, children: jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { style: paddingTdStyle, children: jsxRuntime.jsx("table", { "aria-label": "Row Justification Wrapper", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: {
2650
+ }, ...(config.height && { height: config.height }), children: [jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { style: backgroundTdStyle, ...(config.height && { height: config.height }), children: jsxRuntime.jsx("table", { "aria-label": "Row Border Wrapper", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: borderTableStyle, children: jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { style: paddingTdStyle, children: jsxRuntime.jsx("table", { "aria-label": "Row Justification Wrapper", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: {
2567
2651
  width: "100%",
2568
2652
  height: "100%",
2569
2653
  borderCollapse: "collapse",
2570
- }, children: jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { align: tdAlign, width: "100%", style: { width: "100%" }, children: jsxRuntime.jsx("table", Object.assign({ "aria-label": "Row Content", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: contentTableStyle }, (config.height && { height: config.height }), { className: "content-table row-content-table", "data-mobile-justify": (_e = config.mobile) === null || _e === void 0 ? void 0 : _e.justifyContent, "data-mobile-align": (_f = config.mobile) === null || _f === void 0 ? void 0 : _f.alignItems, "data-mobile-wrap": ((_g = config.mobile) === null || _g === void 0 ? void 0 : _g.wrap) ? "true" : undefined, "data-gap": config.gap, children: jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { className: "content-tr", children: childrenArray.map((child, index) => (jsxRuntime.jsxs(React.Fragment, { children: [jsxRuntime.jsx("td", { valign: tdValign, style: {
2654
+ }, children: jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { align: tdAlign, width: "100%", style: { width: "100%" }, children: jsxRuntime.jsx("table", { "aria-label": "Row Content", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: contentTableStyle, ...(config.height && { height: config.height }), className: "content-table row-content-table", "data-mobile-justify": (_e = config.mobile) === null || _e === void 0 ? void 0 : _e.justifyContent, "data-mobile-align": (_f = config.mobile) === null || _f === void 0 ? void 0 : _f.alignItems, "data-mobile-wrap": ((_g = config.mobile) === null || _g === void 0 ? void 0 : _g.wrap) ? "true" : undefined, "data-gap": config.gap, children: jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { className: "content-tr", children: childrenArray.map((child, index) => (jsxRuntime.jsxs(React.Fragment, { children: [jsxRuntime.jsx("td", { valign: tdValign, style: {
2571
2655
  verticalAlign: tdValign,
2572
2656
  textAlign: "left",
2573
2657
  padding: "0",
2574
2658
  margin: "0",
2575
2659
  }, className: "child-cell", children: child }), index < numChildren - 1 &&
2576
- config.gap && (jsxRuntime.jsx("td", { width: config.gap, style: gapTdStyle, className: "row-gap-td", children: "\u00A0" }, `row-gap-${index}`))] }, `row-child-${index}`))) }) }) })) }) }) }) }) }) }) }) }) })) }) }), devNode && (jsxRuntime.jsx("tfoot", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { children: devNode }) }) }))] })));
2660
+ config.gap && (jsxRuntime.jsx("td", { width: config.gap, style: gapTdStyle, className: "row-gap-td", children: "\u00A0" }, `row-gap-${index}`))] }, `row-child-${index}`))) }) }) }) }) }) }) }) }) }) }) }) }) }) }), devNode && (jsxRuntime.jsx("tfoot", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { children: devNode }) }) }))] }));
2577
2661
  if (href && !devMode) {
2578
- return (jsxRuntime.jsx("a", Object.assign({ href: href }, (target && { target }), { style: {
2662
+ return (jsxRuntime.jsx("a", { href: href, ...(target && { target }), style: {
2579
2663
  textDecoration: "none",
2580
2664
  color: "inherit",
2581
2665
  display: "block",
2582
- }, children: content })));
2666
+ }, children: content }));
2583
2667
  }
2584
2668
  return content;
2585
2669
  }
@@ -2623,9 +2707,18 @@ function getBorderStyle$1(border) {
2623
2707
  const Section = ({ config, children, devNode, }) => {
2624
2708
  var _a, _b, _c;
2625
2709
  const { sectionType, padding } = config;
2626
- return (jsxRuntime.jsxs("table", { "aria-label": `Section |Table | ${sectionType}`, role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: Object.assign(Object.assign({ position: "relative", width: "100%", backgroundColor: config.backgroundColor }, getBorderStyle$1(config.border)), { backgroundImage: config.backgroundImage
2710
+ return (jsxRuntime.jsxs("table", { "aria-label": `Section |Table | ${sectionType}`, role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: {
2711
+ position: "relative",
2712
+ width: "100%",
2713
+ backgroundColor: config.backgroundColor,
2714
+ ...getBorderStyle$1(config.border),
2715
+ backgroundImage: config.backgroundImage
2627
2716
  ? `url(${config.backgroundImage.src})`
2628
- : undefined, backgroundRepeat: (_a = config.backgroundImage) === null || _a === void 0 ? void 0 : _a.repeat, backgroundSize: (_b = config.backgroundImage) === null || _b === void 0 ? void 0 : _b.size, backgroundPosition: (_c = config.backgroundImage) === null || _c === void 0 ? void 0 : _c.position }), children: [jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { style: {
2717
+ : undefined,
2718
+ backgroundRepeat: (_a = config.backgroundImage) === null || _a === void 0 ? void 0 : _a.repeat,
2719
+ backgroundSize: (_b = config.backgroundImage) === null || _b === void 0 ? void 0 : _b.size,
2720
+ backgroundPosition: (_c = config.backgroundImage) === null || _c === void 0 ? void 0 : _c.position,
2721
+ }, children: [jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { style: {
2629
2722
  padding: padding,
2630
2723
  }, children: children }) }) }), devNode && (jsxRuntime.jsx("tfoot", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsxs("td", { children: [jsxRuntime.jsxs("span", { style: {
2631
2724
  backgroundColor: "black",
@@ -2666,11 +2759,14 @@ function Spacer({ config, devNode }) {
2666
2759
  const spacerHeightAttribute = parseInt(height, 10) || 1;
2667
2760
  return (
2668
2761
  // Outer table ensures the spacer spans the full width of its container
2669
- jsxRuntime.jsxs("table", Object.assign({ "aria-label": "Vertical Spacer", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: Object.assign({
2762
+ jsxRuntime.jsxs("table", { "aria-label": "Vertical Spacer", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: {
2670
2763
  // --- Start dev
2671
- position: "relative" }, spacerTableStyle) }, { height: spacerHeightAttribute }, { className: hideOnMobile ? "hide-on-mobile" : undefined, children: [jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { style: spacerTdStyle,
2764
+ position: "relative",
2765
+ // --- End dev
2766
+ ...spacerTableStyle,
2767
+ }, ...{ height: spacerHeightAttribute }, className: hideOnMobile ? "hide-on-mobile" : undefined, children: [jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { style: spacerTdStyle,
2672
2768
  // Explicit height attribute
2673
- height: spacerHeightAttribute, children: "\u00A0" }) }) }), devNode && (jsxRuntime.jsx("tfoot", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { children: devNode }) }) }))] })));
2769
+ height: spacerHeightAttribute, children: "\u00A0" }) }) }), devNode && (jsxRuntime.jsx("tfoot", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { children: devNode }) }) }))] }));
2674
2770
  }
2675
2771
  var Spacer_default = React.memo(Spacer, arePropsEqual);
2676
2772
 
@@ -2886,7 +2982,13 @@ function Icon({ config, devNode, devMode, children }) {
2886
2982
  lineHeight: "0",
2887
2983
  };
2888
2984
  // 4. Inner Table Style: Apply border here with border-collapse: separate
2889
- const innerTableStyle = Object.assign({ width: "100%", borderCollapse: "separate", borderSpacing: 0, borderRadius: borderRadius }, borderStyle);
2985
+ const innerTableStyle = {
2986
+ width: "100%",
2987
+ borderCollapse: "separate",
2988
+ borderSpacing: 0,
2989
+ borderRadius: borderRadius,
2990
+ ...borderStyle,
2991
+ };
2890
2992
  // 5. Inner TD Style: Padding
2891
2993
  const innerTdStyle = {
2892
2994
  padding: padding,
@@ -2934,7 +3036,7 @@ function Icon({ config, devNode, devMode, children }) {
2934
3036
  // Icon image element
2935
3037
  const iconElement = devMode && !!children ? (children) : iconSrc ? (jsxRuntime.jsx("img", { draggable: false, src: iconSrc, alt: "", style: imgStyle, width: widthNum, height: heightNum, border: 0 })) : (jsxRuntime.jsx(jsxRuntime.Fragment, {}));
2936
3038
  // Wrap in link if href exists and not in dev mode
2937
- const content = href && !devMode ? (jsxRuntime.jsx("a", Object.assign({ href: href, target: target, style: linkStyle }, (target === "_blank" ? { rel: "noopener noreferrer" } : {}), { children: iconElement }))) : (iconElement);
3039
+ const content = href && !devMode ? (jsxRuntime.jsx("a", { href: href, target: target, style: linkStyle, ...(target === "_blank" ? { rel: "noopener noreferrer" } : {}), children: iconElement })) : (iconElement);
2938
3040
  // Build the HTML content with VML support (only when NOT in dev mode)
2939
3041
  const useVML = !devMode && backgroundColor && numericBorderRadius > 0;
2940
3042
  const htmlContent = useVML