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