@pagenflow/email 1.3.5 → 1.3.7

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
@@ -1529,80 +1529,235 @@ const justifyMap$3 = {
1529
1529
  center: "center",
1530
1530
  end: "right",
1531
1531
  };
1532
+ function getBorderStyle$6(border) {
1533
+ if (!border)
1534
+ return {};
1535
+ const style = {};
1536
+ // If a full border is specified, apply it
1537
+ if (border.width && border.style && border.color) {
1538
+ style.border = `${border.width} ${border.style} ${border.color}`;
1539
+ }
1540
+ else {
1541
+ // If only individual borders are specified, explicitly set others to 'none'
1542
+ // to prevent Outlook Classic from showing black borders
1543
+ const hasIndividualBorders = border.top || border.right || border.bottom || border.left;
1544
+ if (hasIndividualBorders) {
1545
+ // Default all borders to none
1546
+ style.borderTop = "none";
1547
+ style.borderRight = "none";
1548
+ style.borderBottom = "none";
1549
+ style.borderLeft = "none";
1550
+ }
1551
+ }
1552
+ // Override with specific borders if provided
1553
+ if (border.top) {
1554
+ style.borderTop = `${border.top.width} ${border.top.style} ${border.top.color}`;
1555
+ }
1556
+ if (border.right) {
1557
+ style.borderRight = `${border.right.width} ${border.right.style} ${border.right.color}`;
1558
+ }
1559
+ if (border.bottom) {
1560
+ style.borderBottom = `${border.bottom.width} ${border.bottom.style} ${border.bottom.color}`;
1561
+ }
1562
+ if (border.left) {
1563
+ style.borderLeft = `${border.left.width} ${border.left.style} ${border.left.color}`;
1564
+ }
1565
+ return style;
1566
+ }
1567
+ function getBorderStyleString$1(border) {
1568
+ if (!border)
1569
+ return "";
1570
+ const styles = [];
1571
+ // If a full border is specified, apply it
1572
+ if (border.width && border.style && border.color) {
1573
+ styles.push(`border: ${border.width} ${border.style} ${border.color};`);
1574
+ }
1575
+ else {
1576
+ // If only individual borders are specified
1577
+ const hasIndividualBorders = border.top || border.right || border.bottom || border.left;
1578
+ if (hasIndividualBorders) {
1579
+ // Default all borders to none
1580
+ styles.push("border-top: none;");
1581
+ styles.push("border-right: none;");
1582
+ styles.push("border-bottom: none;");
1583
+ styles.push("border-left: none;");
1584
+ }
1585
+ }
1586
+ // Override with specific borders if provided
1587
+ if (border.top) {
1588
+ styles.push(`border-top: ${border.top.width} ${border.top.style} ${border.top.color};`);
1589
+ }
1590
+ if (border.right) {
1591
+ styles.push(`border-right: ${border.right.width} ${border.right.style} ${border.right.color};`);
1592
+ }
1593
+ if (border.bottom) {
1594
+ styles.push(`border-bottom: ${border.bottom.width} ${border.bottom.style} ${border.bottom.color};`);
1595
+ }
1596
+ if (border.left) {
1597
+ styles.push(`border-left: ${border.left.width} ${border.left.style} ${border.left.color};`);
1598
+ }
1599
+ return styles.join(" ");
1600
+ }
1532
1601
  function Button({ config, devMode }) {
1533
1602
  const { href, children, backgroundColor = "#007bff", // Default blue
1534
- color = "#ffffff", padding = "12px 24px", borderRadius = "3px", width, justifyContent = "center", textAlign = "center", fontSize = "16px", fontWeight = "500", fontStyle, lineHeight = "1.2", letterSpacing, textTransform, textDecoration = "none", fontFamily = "Arial, sans-serif", whiteSpace = "normal", } = config;
1603
+ color = "#ffffff", padding = "12px 24px", borderRadius = "3px", border, width, maxWidth, justifyContent = "center", textAlign = "center", fontSize = "16px", fontWeight = "500", fontStyle, lineHeight = "1.2", letterSpacing, textTransform, textDecoration = "none", fontFamily = "Arial, sans-serif", whiteSpace = "normal", } = config;
1535
1604
  // 1. Link (A) Tag Styles (Fallback for Webmail/Mobile)
1536
1605
  const linkStyle = {
1537
1606
  display: "block",
1538
1607
  wordBreak: "break-word"};
1539
1608
  // 2. Outer TD Style for Background and Border Radius (no border)
1540
- const backgroundTdStyle = Object.assign({ backgroundColor: backgroundColor, borderRadius: borderRadius, width: width || "auto" }, (borderRadius && { overflow: "hidden" }));
1541
- // --- VML Calculation and Code for Outlook Compatibility ---
1542
- // VML needs fixed pixel height. We estimate it based on padding.
1543
- const numericPadding = parseInt(padding.split(" ")[0] || "12", 10);
1544
- const vmlHeight = numericPadding * 2 + 20; // Estimate height based on padding + font size
1545
- const vmlWidth = width ? parseInt(width, 10) : 200; // Default VML width (fixed)
1546
- // VML colors must use the full hex format (e.g., #000000)
1547
- const vmlFillColor = backgroundColor.startsWith("#")
1548
- ? backgroundColor
1549
- : `#${backgroundColor}`;
1609
+ const backgroundTdStyle = Object.assign(Object.assign({ backgroundColor: backgroundColor, borderRadius: borderRadius, width: width || "auto" }, (maxWidth && { maxWidth: maxWidth })), (borderRadius && { overflow: "hidden" }));
1610
+ // 3. Border styles
1611
+ getBorderStyle$6(border);
1612
+ const borderStyleString = getBorderStyleString$1(border);
1613
+ // --- Determine Button Approach Based on Width ---
1614
+ // Check if width is percentage-based or not defined
1615
+ const isPercentageWidth = !width || width.includes("%");
1616
+ const useSimpleOutlookApproach = isPercentageWidth;
1550
1617
  const align = justifyMap$3[justifyContent];
1551
- // Build VML font styles
1552
- const vmlFontWeight = fontWeight || "bold";
1553
- const vmlFontStyle = fontStyle === "italic" ? "font-style:italic;" : "";
1554
- const vmlLetterSpacing = letterSpacing
1555
- ? `letter-spacing:${letterSpacing};`
1556
- : "";
1557
- const vmlTextTransform = textTransform
1558
- ? `text-transform:${textTransform};`
1559
- : "";
1560
- const vmlTextDecoration = textDecoration && textDecoration !== "none"
1561
- ? `text-decoration:${textDecoration};`
1562
- : "";
1563
- const vmlWhiteSpace = whiteSpace && whiteSpace !== "normal" ? `white-space:${whiteSpace};` : "";
1564
- // VML code uses MSO conditional comments to render only in Outlook
1565
- const vmlButton = `
1618
+ // --- VML Calculation and Code for Outlook Compatibility (Fixed Width Only) ---
1619
+ let vmlButton = "";
1620
+ if (!useSimpleOutlookApproach) {
1621
+ // VML needs fixed pixel height. We estimate it based on padding and potential wrapping.
1622
+ const numericPadding = parseInt(padding.split(" ")[0] || "12", 10);
1623
+ const numericFontSize = parseInt(fontSize, 10);
1624
+ const numericLineHeight = lineHeight.includes("px")
1625
+ ? parseInt(lineHeight, 10)
1626
+ : numericFontSize * parseFloat(lineHeight);
1627
+ // Trust user's explicit pixel width - no calculation needed
1628
+ const vmlWidth = parseInt(width, 10);
1629
+ // Calculate VML height - trust user's padding and let text wrap naturally
1630
+ // VML v:textbox will handle text wrapping automatically
1631
+ const textContent = typeof children === "string" ? children : "";
1632
+ // Estimate number of lines based on text length and button width
1633
+ const horizontalPadding = padding.split(" ")[1]
1634
+ ? parseInt(padding.split(" ")[1], 10) * 2
1635
+ : numericPadding * 2;
1636
+ const availableTextWidth = vmlWidth - horizontalPadding;
1637
+ const charWidthMultiplier = fontWeight && parseInt(fontWeight) >= 500 ? 0.7 : 0.6;
1638
+ const avgCharWidth = numericFontSize * charWidthMultiplier;
1639
+ const charsPerLine = Math.max(Math.floor(availableTextWidth / avgCharWidth), 1);
1640
+ const numberOfLines = Math.max(Math.ceil(textContent.length / charsPerLine), 1);
1641
+ // Calculate height: vertical padding + (lines * line height) + extra buffer for VML
1642
+ const textHeight = numberOfLines * numericLineHeight;
1643
+ // Add extra 4px buffer to prevent bottom cropping in VML
1644
+ const vmlHeight = Math.max(numericPadding * 2 + textHeight + 4, 40);
1645
+ // VML colors must use the full hex format (e.g., #000000)
1646
+ const vmlFillColor = backgroundColor.startsWith("#")
1647
+ ? backgroundColor
1648
+ : `#${backgroundColor}`;
1649
+ // VML stroke color for border
1650
+ const vmlStrokeColor = (border === null || border === void 0 ? void 0 : border.color) || vmlFillColor;
1651
+ const vmlStrokeWeight = (border === null || border === void 0 ? void 0 : border.width) ? parseInt(border.width, 10) : 0;
1652
+ const hasVmlStroke = vmlStrokeWeight > 0;
1653
+ // Build VML font styles - consistent with other rendering paths
1654
+ const vmlFontWeight = fontWeight || "500";
1655
+ const vmlFontStyle = fontStyle === "italic" ? "font-style:italic;" : "";
1656
+ const vmlLetterSpacing = letterSpacing
1657
+ ? `letter-spacing:${letterSpacing};`
1658
+ : "";
1659
+ const vmlTextTransform = textTransform
1660
+ ? `text-transform:${textTransform};`
1661
+ : "";
1662
+ const vmlTextDecoration = textDecoration && textDecoration !== "none"
1663
+ ? `text-decoration:${textDecoration};`
1664
+ : "";
1665
+ const vmlWhiteSpace = whiteSpace !== "normal" ? `white-space:${whiteSpace};` : "";
1666
+ // VML code uses MSO conditional comments to render only in Outlook
1667
+ // Use table with explicit MSO height for vertical centering
1668
+ const horizontalPaddingValue = padding.split(" ")[1]
1669
+ ? parseInt(padding.split(" ")[1], 10)
1670
+ : numericPadding;
1671
+ // For VML, we need to use a table inside to properly apply padding and centering
1672
+ let vmlAlignAttr = "";
1673
+ let vmlAlignStyle = "";
1674
+ if (textAlign === "center") {
1675
+ vmlAlignAttr = 'align="center"';
1676
+ }
1677
+ else {
1678
+ vmlAlignStyle = `text-align:${textAlign};`;
1679
+ }
1680
+ vmlButton = `
1566
1681
  <!--[if mso]>
1567
- <v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" href="${href}" style="height:${vmlHeight}px;v-text-anchor:middle;width:${vmlWidth}px;" arcsize="${(parseInt(borderRadius) / vmlHeight) * 100}%" strokecolor="${vmlFillColor}" fillcolor="${vmlFillColor}">
1682
+ <v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" href="${href}" style="height:${vmlHeight}px;width:${vmlWidth}px;" arcsize="${Math.min((parseInt(borderRadius) / vmlHeight) * 100, 50)}%" strokecolor="${vmlStrokeColor}" ${hasVmlStroke ? `strokeweight="${vmlStrokeWeight}px"` : 'stroke="f"'} fillcolor="${vmlFillColor}">
1568
1683
  <w:anchorlock/>
1569
- <center style="color:${color};font-family:${fontFamily};font-size:${fontSize};font-weight:${vmlFontWeight};${vmlFontStyle}${vmlLetterSpacing}${vmlTextTransform}${vmlTextDecoration}${vmlWhiteSpace}">
1570
- ${typeof children === "string" ? children : ""}
1571
- </center>
1684
+ <v:textbox inset="${horizontalPaddingValue}px,${numericPadding}px,${horizontalPaddingValue}px,${numericPadding}px">
1685
+ <table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%" style="border-collapse:collapse;">
1686
+ <tr>
1687
+ <td ${vmlAlignAttr} valign="middle" style="${vmlAlignStyle}color:${color};font-family:${fontFamily};font-size:${fontSize};font-weight:${vmlFontWeight};${vmlFontStyle}${vmlLetterSpacing}${vmlTextTransform}${vmlTextDecoration}${vmlWhiteSpace}line-height:${lineHeight};mso-line-height-rule:exactly;">
1688
+ ${typeof children === "string" ? children : ""}
1689
+ </td>
1690
+ </tr>
1691
+ </table>
1692
+ </v:textbox>
1572
1693
  </v:roundrect>
1573
1694
  <![endif]-->
1574
1695
  `;
1696
+ }
1697
+ // --- Simple Outlook Approach for Percentage Widths ---
1698
+ let simpleOutlookButton = "";
1699
+ if (useSimpleOutlookApproach) {
1700
+ // Build consistent inline styles for text properties
1701
+ const textDecorationStyle = textDecoration && textDecoration !== "none" ? `text-decoration: ${textDecoration};` : "";
1702
+ const fontStyleProp = fontStyle ? `font-style: ${fontStyle};` : "";
1703
+ const letterSpacingProp = letterSpacing ? `letter-spacing: ${letterSpacing};` : "";
1704
+ const textTransformProp = textTransform ? `text-transform: ${textTransform};` : "";
1705
+ const whiteSpaceProp = whiteSpace !== "normal" ? `white-space: ${whiteSpace};` : "";
1706
+ simpleOutlookButton = `
1707
+ <!--[if mso]>
1708
+ <table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%" style="border-collapse: collapse;">
1709
+ <tr>
1710
+ <td align="${align}" style="padding: 0;">
1711
+ <table role="presentation" cellpadding="0" cellspacing="0" border="0" width="${width || "auto"}" style="border-collapse: collapse;">
1712
+ <tr>
1713
+ <td bgcolor="${backgroundColor}" align="${textAlign}" style="padding: ${padding}; text-align: ${textAlign}; border-radius: ${borderRadius}; ${borderStyleString}">
1714
+ <a href="${href}" target="_blank" rel="noopener noreferrer" style="color: ${color}; ${textDecorationStyle} display: block; font-family: ${fontFamily}; font-size: ${fontSize}; font-weight: ${fontWeight}; ${fontStyleProp} line-height: ${lineHeight}; ${letterSpacingProp} ${textTransformProp} text-align: ${textAlign}; ${whiteSpaceProp} mso-line-height-rule: exactly;">
1715
+ ${typeof children === "string" ? children : ""}
1716
+ </a>
1717
+ </td>
1718
+ </tr>
1719
+ </table>
1720
+ </td>
1721
+ </tr>
1722
+ </table>
1723
+ <![endif]-->
1724
+ `;
1725
+ }
1575
1726
  return (
1576
- // Outer table for alignment (center the button horizontally)
1577
- jsx("table", { role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, align: align, style: {
1578
- // --- Start dev
1579
- position: "relative",
1580
- // --- End dev
1581
- width: width || "auto",
1727
+ // Wrapper table for alignment - maintains proper positioning for hover indicators
1728
+ jsx("table", { role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: {
1729
+ width: "100%",
1582
1730
  borderCollapse: "collapse",
1583
- // base
1584
1731
  boxSizing: "border-box",
1585
1732
  border: 0,
1586
1733
  margin: 0,
1587
1734
  padding: 0,
1588
- }, onClick: devMode ? (e) => e.preventDefault() : undefined, children: jsx("tbody", { children: jsx("tr", { children: jsx("td", { dangerouslySetInnerHTML: {
1589
- __html: `
1590
- ${devMode ? "" : vmlButton}
1735
+ }, children: jsx("tbody", { children: jsx("tr", { children: jsx("td", { align: align, style: {
1736
+ padding: 0,
1737
+ }, children: jsx("table", { role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: Object.assign(Object.assign({
1738
+ // --- Start dev
1739
+ position: "relative",
1740
+ // --- End dev
1741
+ width: width || "auto" }, (maxWidth && { maxWidth: maxWidth })), { borderCollapse: "collapse",
1742
+ // base
1743
+ 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: {
1744
+ __html: `
1745
+ ${devMode ? "" : useSimpleOutlookApproach ? simpleOutlookButton : vmlButton}
1591
1746
  <!--[if !mso]><!-->
1592
1747
  <table role="presentation" cellpadding="0" cellspacing="0" border="0" style="border-collapse: collapse; width: 100%;">
1593
1748
  <tbody>
1594
1749
  <tr>
1595
- <td style="background-color: ${backgroundTdStyle.backgroundColor}; border-radius: ${backgroundTdStyle.borderRadius}; width: ${backgroundTdStyle.width}; ${borderRadius ? "overflow: hidden;" : ""}">
1596
- <table role="presentation" cellpadding="0" cellspacing="0" border="0" style="border-collapse: separate; border-spacing: 0; border-radius: ${borderRadius}; width: 100%;">
1750
+ <td style="background-color: ${backgroundTdStyle.backgroundColor}; border-radius: ${backgroundTdStyle.borderRadius}; width: ${backgroundTdStyle.width}; ${maxWidth ? `max-width: ${maxWidth};` : ""} ${borderRadius ? "overflow: hidden;" : ""}">
1751
+ <table role="presentation" cellpadding="0" cellspacing="0" border="0" style="border-collapse: separate; border-spacing: 0; border-radius: ${borderRadius}; width: 100%; ${borderStyleString}">
1597
1752
  <tbody>
1598
1753
  <tr>
1599
- <td style="padding: ${padding};">
1754
+ <td style="padding: 0;">
1600
1755
  ${devMode
1601
- ? `<span style="color: ${color}; font-family: ${fontFamily}; font-size: ${fontSize}; font-weight: ${fontWeight}; font-style: ${fontStyle || "normal"}; line-height: ${lineHeight}; letter-spacing: ${letterSpacing || "normal"}; text-transform: ${textTransform || "none"}; text-decoration: ${textDecoration}; white-space: ${whiteSpace}; display: ${linkStyle.display}; text-align: ${textAlign}; word-break: ${linkStyle.wordBreak};">
1756
+ ? `<span style="color: ${color}; font-family: ${fontFamily}; font-size: ${fontSize}; font-weight: ${fontWeight}; ${fontStyle ? `font-style: ${fontStyle};` : ""} line-height: ${lineHeight}; ${letterSpacing ? `letter-spacing: ${letterSpacing};` : ""} ${textTransform ? `text-transform: ${textTransform};` : ""} ${textDecoration && textDecoration !== "none" ? `text-decoration: ${textDecoration};` : ""} ${whiteSpace !== "normal" ? `white-space: ${whiteSpace};` : ""} display: ${linkStyle.display}; text-align: ${textAlign}; word-break: ${linkStyle.wordBreak}; padding: ${padding};">
1602
1757
  ${typeof children === "string" ? children : ""}
1603
1758
  </span>`
1604
- : `<a href="${href}" target="_blank" rel="noopener noreferrer" style="color: ${color}; text-decoration: ${textDecoration}; display: ${linkStyle.display}; word-break: ${linkStyle.wordBreak}; font-family: ${fontFamily}; font-size: ${fontSize}; font-weight: ${fontWeight}; font-style: ${fontStyle || "normal"}; line-height: ${lineHeight}; letter-spacing: ${letterSpacing || "normal"}; text-transform: ${textTransform || "none"}; text-align: ${textAlign}; white-space: ${whiteSpace};">
1605
- <span style="color: ${color}; font-family: ${fontFamily}; font-size: ${fontSize}; font-weight: ${fontWeight}; font-style: ${fontStyle || "normal"}; line-height: ${lineHeight}; letter-spacing: ${letterSpacing || "normal"}; text-transform: ${textTransform || "none"}; text-decoration: ${textDecoration}; white-space: ${whiteSpace};">
1759
+ : `<a href="${href}" target="_blank" rel="noopener noreferrer" style="color: ${color}; ${textDecoration && textDecoration !== "none" ? `text-decoration: ${textDecoration};` : "text-decoration: none;"} display: ${linkStyle.display}; word-break: ${linkStyle.wordBreak}; font-family: ${fontFamily}; font-size: ${fontSize}; font-weight: ${fontWeight}; ${fontStyle ? `font-style: ${fontStyle};` : ""} line-height: ${lineHeight}; ${letterSpacing ? `letter-spacing: ${letterSpacing};` : ""} ${textTransform ? `text-transform: ${textTransform};` : ""} text-align: ${textAlign}; ${whiteSpace !== "normal" ? `white-space: ${whiteSpace};` : ""} padding: ${padding};">
1760
+ <span style="color: ${color}; font-family: ${fontFamily}; font-size: ${fontSize}; font-weight: ${fontWeight}; ${fontStyle ? `font-style: ${fontStyle};` : ""} line-height: ${lineHeight}; ${letterSpacing ? `letter-spacing: ${letterSpacing};` : ""} ${textTransform ? `text-transform: ${textTransform};` : ""} ${textDecoration && textDecoration !== "none" ? `text-decoration: ${textDecoration};` : ""} ${whiteSpace !== "normal" ? `white-space: ${whiteSpace};` : ""}">
1606
1761
  ${typeof children === "string" ? children : ""}
1607
1762
  </span>
1608
1763
  </a>`}
@@ -1616,7 +1771,7 @@ function Button({ config, devMode }) {
1616
1771
  </table>
1617
1772
  <!--<![endif]-->
1618
1773
  `,
1619
- } }) }) }) }));
1774
+ } }) }) }) }) }) }) }) }));
1620
1775
  }
1621
1776
  var Button_default = memo(Button, arePropsEqual);
1622
1777
 
@@ -1633,15 +1788,27 @@ const alignMap$2 = {
1633
1788
  end: "right",
1634
1789
  };
1635
1790
  // Helper to convert border config to CSS border shorthand
1636
- function getBorderStyle$3(border) {
1791
+ function getBorderStyle$5(border) {
1637
1792
  if (!border)
1638
1793
  return {};
1639
1794
  const style = {};
1640
- // Check for unified border
1795
+ // If a full border is specified, apply it
1641
1796
  if (border.width && border.style && border.color) {
1642
1797
  style.border = `${border.width} ${border.style} ${border.color}`;
1643
1798
  }
1644
- // Individual sides override unified border
1799
+ else {
1800
+ // If only individual borders are specified, explicitly set others to 'none'
1801
+ // to prevent Outlook Classic from showing black borders
1802
+ const hasIndividualBorders = border.top || border.right || border.bottom || border.left;
1803
+ if (hasIndividualBorders) {
1804
+ // Default all borders to none
1805
+ style.borderTop = "none";
1806
+ style.borderRight = "none";
1807
+ style.borderBottom = "none";
1808
+ style.borderLeft = "none";
1809
+ }
1810
+ }
1811
+ // Override with specific borders if provided
1645
1812
  if (border.top) {
1646
1813
  style.borderTop = `${border.top.width} ${border.top.style} ${border.top.color}`;
1647
1814
  }
@@ -1661,24 +1828,32 @@ function Column({ children, config, devNode }) {
1661
1828
  // Process children array for gap support
1662
1829
  const childrenArray = (Array.isArray(children) ? children : [children]).filter((child) => child != null);
1663
1830
  const numChildren = childrenArray.length;
1664
- // 1. Outer table style: Takes up the full width/height of its parent TD
1831
+ // 1. Outer table style: Takes up the full width/height of its parent TD.
1832
+ // height here drives the *total* outer height of the column.
1665
1833
  const outerTableStyle = {
1666
1834
  width: "100%",
1667
1835
  height: config.height,
1668
1836
  borderCollapse: "collapse",
1669
1837
  };
1670
- // 2. Outer TD style: Background and Border Radius (no border here)
1838
+ // 2. Outer TD style: Background and Border Radius (no border here).
1839
+ // height is set so the TD occupies the full declared height.
1671
1840
  const outerTdStyle = Object.assign({ width: config.width, height: config.height, backgroundColor: config.backgroundColor, borderRadius: config.borderRadius,
1672
1841
  // Background Image styles
1673
1842
  backgroundImage: config.backgroundImage
1674
1843
  ? `url(${config.backgroundImage.src})`
1675
1844
  : 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" }));
1676
- // 2b. Inner table style: Border and Border Radius
1677
- const innerTableStyle = Object.assign({ width: "100%", height: config.height, borderCollapse: "separate", borderSpacing: 0, borderRadius: config.borderRadius }, getBorderStyle$3(config.border));
1678
- // 3. Inner TD style: Padding and Vertical Alignment
1845
+ // 2b. Inner table style: Border and Border Radius.
1846
+ // height: 100% so it stretches to fill the outer TD's declared height.
1847
+ const innerTableStyle = Object.assign({ width: "100%", height: "100%", borderCollapse: "separate", borderSpacing: 0, borderRadius: config.borderRadius }, getBorderStyle$5(config.border));
1848
+ // 3. Inner TD style: Padding and Vertical Alignment only.
1849
+ // *** No height here. ***
1850
+ // The outer TD/table owns the height; padding is purely inner spacing,
1851
+ // so the total rendered height = declared height (padding is inside).
1679
1852
  const innerTdStyle = {
1680
1853
  padding: config.padding,
1681
- height: config.height,
1854
+ // height intentionally omitted — setting it here would make browsers
1855
+ // treat it as content-box height and add padding on top, causing the
1856
+ // total to exceed the declared height in preview mode.
1682
1857
  verticalAlign: config.alignItems ? alignMap$2[config.alignItems] : "top",
1683
1858
  };
1684
1859
  // 4. Gap spacer style (used between children)
@@ -1689,7 +1864,7 @@ function Column({ children, config, devNode }) {
1689
1864
  width: "100%",
1690
1865
  };
1691
1866
  // Main content rendering
1692
- const renderContent = () => (jsx("table", { "aria-label": "Column Padding", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: innerTableStyle, children: jsx("tbody", { children: jsx("tr", { children: jsx("td", Object.assign({ style: innerTdStyle, valign: config.justifyContent ? vAlignMap[config.justifyContent] : "top", align: config.alignItems ? alignMap$2[config.alignItems] : "left" }, (config.height && { height: config.height }), { children: config.gap && numChildren > 1 ? (jsx("table", { "aria-label": "Column Gap Wrapper", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: {
1867
+ const renderContent = () => (jsx("table", { "aria-label": "Column Padding", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: innerTableStyle, children: jsx("tbody", { children: jsx("tr", { children: jsx("td", { style: innerTdStyle, valign: config.justifyContent ? vAlignMap[config.justifyContent] : "top", align: config.alignItems ? alignMap$2[config.alignItems] : "left", children: config.gap && numChildren > 1 ? (jsx("table", { "aria-label": "Column Gap Wrapper", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: {
1693
1868
  width: "100%",
1694
1869
  borderCollapse: "collapse",
1695
1870
  }, children: jsx("tbody", { children: childrenArray.map((child, index) => (jsxs(Fragment, { children: [jsx("tr", { children: jsx("td", { style: {
@@ -1700,7 +1875,7 @@ function Column({ children, config, devNode }) {
1700
1875
  ? vAlignMap[config.justifyContent]
1701
1876
  : "top", align: config.alignItems
1702
1877
  ? alignMap$2[config.alignItems]
1703
- : "left", children: child }) }), index < numChildren - 1 && (jsx("tr", { children: jsx("td", { style: gapSpacerStyle, children: "\u00A0" }) }))] }, `col-child-${index}`))) }) })) : (children) })) }) }) }));
1878
+ : "left", children: child }) }), index < numChildren - 1 && (jsx("tr", { children: jsx("td", { style: gapSpacerStyle, children: "\u00A0" }) }))] }, `col-child-${index}`))) }) })) : (children) }) }) }) }));
1704
1879
  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 }) }) }))] })));
1705
1880
  }
1706
1881
  var Column_default = memo(Column, arePropsEqual);
@@ -1715,13 +1890,27 @@ const justifyMap$2 = {
1715
1890
  center: "center",
1716
1891
  end: "right",
1717
1892
  };
1718
- function getBorderStyle$2(border) {
1893
+ function getBorderStyle$4(border) {
1719
1894
  if (!border)
1720
1895
  return {};
1721
1896
  const style = {};
1897
+ // If a full border is specified, apply it
1722
1898
  if (border.width && border.style && border.color) {
1723
1899
  style.border = `${border.width} ${border.style} ${border.color}`;
1724
1900
  }
1901
+ else {
1902
+ // If only individual borders are specified, explicitly set others to 'none'
1903
+ // to prevent Outlook Classic from showing black borders
1904
+ const hasIndividualBorders = border.top || border.right || border.bottom || border.left;
1905
+ if (hasIndividualBorders) {
1906
+ // Default all borders to none
1907
+ style.borderTop = "none";
1908
+ style.borderRight = "none";
1909
+ style.borderBottom = "none";
1910
+ style.borderLeft = "none";
1911
+ }
1912
+ }
1913
+ // Override with specific borders if provided
1725
1914
  if (border.top) {
1726
1915
  style.borderTop = `${border.top.width} ${border.top.style} ${border.top.color}`;
1727
1916
  }
@@ -1796,7 +1985,7 @@ function Container({ children, config, devMode, devNode }) {
1796
1985
  ? `url(${config.backgroundImage.src})`
1797
1986
  : 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" }));
1798
1987
  // 2. Border Table Style - Border and border radius
1799
- const borderTableStyle = Object.assign({ width: "100%", borderCollapse: "separate", borderSpacing: 0, borderRadius: config.borderRadius }, getBorderStyle$2(config.border));
1988
+ const borderTableStyle = Object.assign({ width: "100%", borderCollapse: "separate", borderSpacing: 0, borderRadius: config.borderRadius }, getBorderStyle$4(config.border));
1800
1989
  // 3. Padding TD Style
1801
1990
  const innerTdStyle = {
1802
1991
  padding: config.padding,
@@ -1850,7 +2039,7 @@ function Container({ children, config, devMode, devNode }) {
1850
2039
  var Container_default = memo(Container, arePropsEqual);
1851
2040
 
1852
2041
  function Divider({ config, devNode }) {
1853
- const { height = "1px", color = "#cccccc", width = "100%", margin = "20px 0", align = "center", } = config;
2042
+ const { height = "1px", color = "#cccccc", width = "100%", margin = "20px 0", align = "center", hideOnMobile, } = config;
1854
2043
  // 1. Outer TD Style: Applies the vertical spacing (margin)
1855
2044
  const outerTdStyle = {
1856
2045
  padding: margin,
@@ -1879,7 +2068,7 @@ function Divider({ config, devNode }) {
1879
2068
  // --- End dev
1880
2069
  width: "100%",
1881
2070
  borderCollapse: "collapse",
1882
- }, 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: {
2071
+ }, 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: {
1883
2072
  height: height,
1884
2073
  fontSize: "0",
1885
2074
  lineHeight: "0",
@@ -1888,7 +2077,7 @@ function Divider({ config, devNode }) {
1888
2077
  }
1889
2078
  var Divider_default = memo(Divider, arePropsEqual);
1890
2079
 
1891
- function Head({ children, backgroundColor = "#ffffff", title = "Email Preview", }) {
2080
+ function Head({ children, backgroundColor = "#ffffff", title = "Email Preview", rowGaps = [], }) {
1892
2081
  // Outlook (MSO) Styles and Reset
1893
2082
  const msoResetStyles = `
1894
2083
  /* Forces Outlook to render 100% width and prevents line-height issues */
@@ -1931,6 +2120,15 @@ function Head({ children, backgroundColor = "#ffffff", title = "Email Preview",
1931
2120
  }
1932
2121
  }
1933
2122
 
2123
+ @media screen and (max-width: 768px) {
2124
+ .hide-on-mobile {
2125
+ display: none !important;
2126
+ max-height: 0 !important;
2127
+ overflow: hidden !important;
2128
+ mso-hide: all;
2129
+ }
2130
+ }
2131
+
1934
2132
  @media screen and (max-width: 768px) {
1935
2133
  .stack-td {
1936
2134
  width: 100% !important;
@@ -1956,119 +2154,71 @@ function Head({ children, backgroundColor = "#ffffff", title = "Email Preview",
1956
2154
  }
1957
2155
 
1958
2156
  @media only screen and (max-width: 768px) {
1959
- /* 1. Handling Mobile Alignment (Justify) - Works for both wrapped and non-wrapped */
1960
- /* We target the inner table alignment */
1961
- .responsive-row[data-mobile-justify="center"] .content-table {
2157
+ /* 1. Handling Mobile Alignment (Justify) */
2158
+ .row-content-table[data-mobile-justify="center"] {
1962
2159
  margin: 0 auto !important;
1963
2160
  float: none !important;
1964
2161
  }
1965
- .responsive-row[data-mobile-justify="start"] .content-table {
2162
+ .row-content-table[data-mobile-justify="start"] {
1966
2163
  margin: 0 !important;
1967
2164
  float: left !important;
1968
2165
  }
1969
- .responsive-row[data-mobile-justify="end"] .content-table {
2166
+ .row-content-table[data-mobile-justify="end"] {
1970
2167
  margin: 0 0 0 auto !important;
1971
2168
  float: right !important;
1972
2169
  }
1973
2170
 
1974
- /* Mobile justify for wrapped children - we need to target the outer wrapper td */
1975
- .responsive-row[data-mobile-wrap="true"][data-mobile-justify="center"] td[align] {
1976
- text-align: center !important;
1977
- }
1978
- .responsive-row[data-mobile-wrap="true"][data-mobile-justify="start"] td[align] {
1979
- text-align: left !important;
1980
- }
1981
- .responsive-row[data-mobile-wrap="true"][data-mobile-justify="end"] td[align] {
1982
- text-align: right !important;
1983
- }
1984
-
1985
- /* Also apply to child content tables for better support */
1986
- .responsive-row[data-mobile-wrap="true"][data-mobile-justify="center"] .child-cell table {
1987
- margin-left: auto !important;
1988
- margin-right: auto !important;
1989
- }
1990
- .responsive-row[data-mobile-wrap="true"][data-mobile-justify="start"] .child-cell table {
1991
- margin-left: 0 !important;
1992
- margin-right: auto !important;
1993
- }
1994
- .responsive-row[data-mobile-wrap="true"][data-mobile-justify="end"] .child-cell table {
1995
- margin-left: auto !important;
1996
- margin-right: 0 !important;
1997
- }
1998
-
1999
2171
  /* 2. Handling Mobile Vertical Alignment (Align Items) */
2000
- /* For non-wrapped rows - controls vertical alignment when cells are side-by-side */
2001
- .responsive-row[data-mobile-align="center"]:not([data-mobile-wrap="true"]) .child-cell {
2002
- vertical-align: middle !important;
2003
- }
2004
- .responsive-row[data-mobile-align="start"]:not([data-mobile-wrap="true"]) .child-cell {
2005
- vertical-align: top !important;
2006
- }
2007
- .responsive-row[data-mobile-align="end"]:not([data-mobile-wrap="true"]) .child-cell {
2008
- vertical-align: bottom !important;
2009
- }
2010
-
2011
- /* For wrapped rows - alignItems controls vertical alignment of content within each child cell */
2012
- .responsive-row[data-mobile-wrap="true"][data-mobile-align="center"] .child-cell {
2172
+ .row-content-table[data-mobile-align="center"] .child-cell {
2013
2173
  vertical-align: middle !important;
2014
2174
  }
2015
- .responsive-row[data-mobile-wrap="true"][data-mobile-align="start"] .child-cell {
2175
+ .row-content-table[data-mobile-align="start"] .child-cell {
2016
2176
  vertical-align: top !important;
2017
2177
  }
2018
- .responsive-row[data-mobile-wrap="true"][data-mobile-align="end"] .child-cell {
2178
+ .row-content-table[data-mobile-align="end"] .child-cell {
2019
2179
  vertical-align: bottom !important;
2020
2180
  }
2021
2181
 
2022
2182
  /* 3. Handling Mobile Wrap - Pure CSS Solution */
2023
- /* Force table to act like block container */
2024
- .responsive-row[data-mobile-wrap="true"] .content-table {
2183
+
2184
+ /* Force table to be full width */
2185
+ .row-content-table[data-mobile-wrap="true"] {
2025
2186
  width: 100% !important;
2026
2187
  max-width: 100% !important;
2027
2188
  }
2028
2189
 
2029
2190
  /* Force table row to stack cells */
2030
- .responsive-row[data-mobile-wrap="true"] .content-tr {
2191
+ .row-content-table[data-mobile-wrap="true"] > tbody > .content-tr {
2031
2192
  display: block !important;
2032
2193
  }
2033
2194
 
2034
2195
  /* Force each child cell to be full width block */
2035
- .responsive-row[data-mobile-wrap="true"] .child-cell {
2196
+ .row-content-table[data-mobile-wrap="true"] > tbody > .content-tr > .child-cell {
2036
2197
  display: block !important;
2037
2198
  width: 100% !important;
2038
2199
  box-sizing: border-box !important;
2039
2200
  }
2040
2201
 
2041
- /* Hide horizontal gap cells and create vertical spacing with padding */
2042
- .responsive-row[data-mobile-wrap="true"] .row-gap-td {
2202
+ /* Hide horizontal gap cells */
2203
+ .row-content-table[data-mobile-wrap="true"] > tbody > .content-tr > .row-gap-td {
2043
2204
  display: none !important;
2044
2205
  width: 0 !important;
2045
2206
  height: 0 !important;
2046
2207
  }
2047
2208
 
2048
2209
  /* Add vertical spacing between stacked cells using margin */
2049
- .responsive-row[data-mobile-wrap="true"] .child-cell:not(:last-child) {
2210
+ .row-content-table[data-mobile-wrap="true"] > tbody > .content-tr > .child-cell:not(:last-child) {
2050
2211
  margin-bottom: 20px !important;
2051
2212
  }
2052
2213
 
2053
2214
  /* Dynamic gap support - common values */
2054
- .responsive-row[data-mobile-wrap="true"][data-gap="10px"] .child-cell:not(:last-child) {
2055
- margin-bottom: 10px !important;
2056
- }
2057
- .responsive-row[data-mobile-wrap="true"][data-gap="15px"] .child-cell:not(:last-child) {
2058
- margin-bottom: 15px !important;
2059
- }
2060
- .responsive-row[data-mobile-wrap="true"][data-gap="20px"] .child-cell:not(:last-child) {
2061
- margin-bottom: 20px !important;
2062
- }
2063
- .responsive-row[data-mobile-wrap="true"][data-gap="24px"] .child-cell:not(:last-child) {
2064
- margin-bottom: 24px !important;
2065
- }
2066
- .responsive-row[data-mobile-wrap="true"][data-gap="30px"] .child-cell:not(:last-child) {
2067
- margin-bottom: 30px !important;
2068
- }
2069
- .responsive-row[data-mobile-wrap="true"][data-gap="40px"] .child-cell:not(:last-child) {
2070
- margin-bottom: 40px !important;
2071
- }
2215
+ ${["10px", "15px", "20px", "24px", "30px", "40px", ...rowGaps]
2216
+ .filter((gap, index, self) => self.indexOf(gap) === index)
2217
+ .map((gap) => `
2218
+ .row-content-table[data-mobile-wrap="true"][data-gap="${gap}"] > tbody > .content-tr > .child-cell:not(:last-child) {
2219
+ margin-bottom: ${gap} !important;
2220
+ }`)
2221
+ .join("\n")}
2072
2222
  }
2073
2223
 
2074
2224
  /* ================================================= */
@@ -2148,7 +2298,7 @@ function Head({ children, backgroundColor = "#ffffff", title = "Email Preview",
2148
2298
  }
2149
2299
 
2150
2300
  function Heading({ config, devMode, children }) {
2151
- const { text, level = "h1", padding, color, textAlign, fontSize, fontWeight, fontStyle, lineHeight, letterSpacing, textTransform, textDecoration, direction, verticalAlign, backgroundColor, } = config;
2301
+ const { text, level = "h1", padding, color, textAlign, fontSize, fontWeight, fontStyle, lineHeight, letterSpacing, textTransform, textDecoration, direction, verticalAlign, backgroundColor, wordBreak, whiteSpace, } = config;
2152
2302
  // Determine the content to render
2153
2303
  const content = text !== null && text !== void 0 ? text : children;
2154
2304
  const isString = typeof content === "string";
@@ -2171,6 +2321,8 @@ function Heading({ config, devMode, children }) {
2171
2321
  textTransform: textTransform,
2172
2322
  textDecoration: textDecoration,
2173
2323
  direction: direction,
2324
+ wordBreak: wordBreak,
2325
+ whiteSpace: whiteSpace,
2174
2326
  // Critical: Remove default top/bottom margin from HTML heading tags
2175
2327
  margin: "0",
2176
2328
  padding: "0",
@@ -2210,22 +2362,53 @@ function Html({ children, backgroundColor = "#ffffff", }) {
2210
2362
  );
2211
2363
  }
2212
2364
 
2365
+ function getBorderStyle$3(border) {
2366
+ if (!border)
2367
+ return {};
2368
+ const style = {};
2369
+ // If a full border is specified, apply it
2370
+ if (border.width && border.style && border.color) {
2371
+ style.border = `${border.width} ${border.style} ${border.color}`;
2372
+ }
2373
+ else {
2374
+ // If only individual borders are specified, explicitly set others to 'none'
2375
+ // to prevent Outlook Classic from showing black borders
2376
+ const hasIndividualBorders = border.top || border.right || border.bottom || border.left;
2377
+ if (hasIndividualBorders) {
2378
+ // Default all borders to none
2379
+ style.borderTop = "none";
2380
+ style.borderRight = "none";
2381
+ style.borderBottom = "none";
2382
+ style.borderLeft = "none";
2383
+ }
2384
+ }
2385
+ // Override with specific borders if provided
2386
+ if (border.top) {
2387
+ style.borderTop = `${border.top.width} ${border.top.style} ${border.top.color}`;
2388
+ }
2389
+ if (border.right) {
2390
+ style.borderRight = `${border.right.width} ${border.right.style} ${border.right.color}`;
2391
+ }
2392
+ if (border.bottom) {
2393
+ style.borderBottom = `${border.bottom.width} ${border.bottom.style} ${border.bottom.color}`;
2394
+ }
2395
+ if (border.left) {
2396
+ style.borderLeft = `${border.left.width} ${border.left.style} ${border.left.color}`;
2397
+ }
2398
+ return style;
2399
+ }
2213
2400
  function Image({ config, devNode, devMode }) {
2214
- const { src, alt, width, height, maxHeight, maxWidth, backgroundColor, padding, borderRadius, href, target, } = config;
2401
+ const { src, alt, width, height, maxHeight, maxWidth, backgroundColor, padding, borderRadius, border, href, target, } = config;
2402
+ // Get border styles
2403
+ const borderStyle = getBorderStyle$3(border);
2215
2404
  // 1. Image Style: Critical for compatibility, especially display: block
2216
- const imgStyle = {
2405
+ const imgStyle = Object.assign({
2217
2406
  // Basic image properties
2218
- display: "block", // Prevents extra vertical space/gaps below the image
2219
- objectFit: "cover", // For controlling how the image fits (modern CSS, may be ignored)
2407
+ display: "block", objectFit: "cover",
2220
2408
  // Dimensions (using CSS fallback)
2221
- width: width || "100%",
2222
- height: height || "auto",
2223
- maxWidth: maxWidth || "100%",
2224
- maxHeight: maxHeight,
2409
+ width: width || "100%", height: height || "auto", maxWidth: maxWidth || "100%", maxHeight: maxHeight,
2225
2410
  // Styling
2226
- border: "0", // Ensures no default browser/client border
2227
- borderRadius: borderRadius,
2228
- };
2411
+ border: "0", borderRadius: borderRadius }, borderStyle);
2229
2412
  // 2. Link Style: Ensure no underline or color changes
2230
2413
  const linkStyle = {
2231
2414
  display: "block",
@@ -2277,13 +2460,27 @@ const alignMap = {
2277
2460
  center: "middle",
2278
2461
  end: "bottom",
2279
2462
  };
2280
- function getBorderStyle$1(border) {
2463
+ function getBorderStyle$2(border) {
2281
2464
  if (!border)
2282
2465
  return {};
2283
2466
  const style = {};
2467
+ // If a full border is specified, apply it
2284
2468
  if (border.width && border.style && border.color) {
2285
2469
  style.border = `${border.width} ${border.style} ${border.color}`;
2286
2470
  }
2471
+ else {
2472
+ // If only individual borders are specified, explicitly set others to 'none'
2473
+ // to prevent Outlook Classic from showing black borders
2474
+ const hasIndividualBorders = border.top || border.right || border.bottom || border.left;
2475
+ if (hasIndividualBorders) {
2476
+ // Default all borders to none
2477
+ style.borderTop = "none";
2478
+ style.borderRight = "none";
2479
+ style.borderBottom = "none";
2480
+ style.borderLeft = "none";
2481
+ }
2482
+ }
2483
+ // Override with specific borders if provided
2287
2484
  if (border.top) {
2288
2485
  style.borderTop = `${border.top.width} ${border.top.style} ${border.top.color}`;
2289
2486
  }
@@ -2298,23 +2495,50 @@ function getBorderStyle$1(border) {
2298
2495
  }
2299
2496
  return style;
2300
2497
  }
2301
- function Row({ children, config, devNode }) {
2302
- var _a, _b, _c, _d, _e, _f;
2498
+ function getHrefFromInnerLink(innerLink) {
2499
+ if (!innerLink || innerLink.type === "none")
2500
+ return undefined;
2501
+ switch (innerLink.type) {
2502
+ case "url":
2503
+ return innerLink.url;
2504
+ case "email":
2505
+ return innerLink.email ? `mailto:${innerLink.email}` : undefined;
2506
+ case "phone":
2507
+ return innerLink.phone ? `tel:${innerLink.phone}` : undefined;
2508
+ case "anchor":
2509
+ return innerLink.anchor ? `#${innerLink.anchor}` : undefined;
2510
+ case "page_top":
2511
+ return "#";
2512
+ case "page_bottom":
2513
+ return "#bottom";
2514
+ default:
2515
+ return undefined;
2516
+ }
2517
+ }
2518
+ function Row({ children, config, devNode, devMode }) {
2519
+ var _a, _b, _c, _d, _e, _f, _g;
2303
2520
  const childrenArray = (Array.isArray(children) ? children : [children]).filter((child) => child != null);
2304
2521
  const numChildren = childrenArray.length;
2305
- // 1. Outer TD for Background and Border Radius (no border here)
2522
+ const href = getHrefFromInnerLink(config.innerLink);
2523
+ const target = (_a = config.innerLink) === null || _a === void 0 ? void 0 : _a.target;
2524
+ // 1. Outer TD for Background and Border Radius (no border here).
2525
+ // height declared here is the *total* outer height.
2306
2526
  const backgroundTdStyle = Object.assign({ backgroundColor: config.backgroundColor, borderRadius: config.borderRadius, width: config.width || "100%", height: config.height,
2307
2527
  // Background Image styles
2308
2528
  backgroundImage: config.backgroundImage
2309
2529
  ? `url(${config.backgroundImage.src})`
2310
- : 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" }));
2311
- // 2. Inner Table for Border and Border Radius
2312
- const borderTableStyle = Object.assign({ width: "100%", height: "100%", borderCollapse: "separate", borderSpacing: 0, borderRadius: config.borderRadius }, getBorderStyle$1(config.border));
2313
- // 3. TD for Padding
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" }));
2531
+ // 2. Inner Table for Border and Border Radius.
2532
+ // height: 100% so it stretches to fill the outer TD.
2533
+ const borderTableStyle = Object.assign({ width: "100%", height: "100%", borderCollapse: "separate", borderSpacing: 0, borderRadius: config.borderRadius }, getBorderStyle$2(config.border));
2534
+ // 3. TD for Padding only — no height.
2535
+ // The outer TD owns the total height; setting height here would cause
2536
+ // browsers/email clients to treat it as content-box height and add
2537
+ // padding on top, making the row taller than the declared height.
2314
2538
  const paddingTdStyle = {
2315
2539
  padding: config.padding,
2316
2540
  width: "100%",
2317
- height: "100%",
2541
+ // height intentionally omitted — padding must be inner, not additive
2318
2542
  verticalAlign: "top",
2319
2543
  };
2320
2544
  // 4. Content Table - horizontal layout
@@ -2335,32 +2559,56 @@ function Row({ children, config, devNode }) {
2335
2559
  ? justifyMap$1[config.justifyContent]
2336
2560
  : "left";
2337
2561
  const tdValign = config.alignItems ? alignMap[config.alignItems] : "top";
2338
- return (jsxs("table", Object.assign({ "aria-label": "Row Outer", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: {
2562
+ // Content to render - wrapped in anchor if innerLink is defined
2563
+ const content = (jsxs("table", Object.assign({ "aria-label": "Row Outer", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: {
2339
2564
  position: "relative",
2340
2565
  width: config.width || "100%",
2341
2566
  height: config.height,
2342
2567
  borderCollapse: "collapse",
2343
- } }, (config.height && { height: config.height }), { "data-mobile-justify": (_d = config.mobile) === null || _d === void 0 ? void 0 : _d.justifyContent, "data-mobile-align": (_e = config.mobile) === null || _e === void 0 ? void 0 : _e.alignItems, "data-mobile-wrap": ((_f = config.mobile) === null || _f === void 0 ? void 0 : _f.wrap) ? "true" : undefined, "data-gap": config.gap, className: "responsive-row", 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: {
2568
+ } }, (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: {
2344
2569
  width: "100%",
2345
2570
  height: "100%",
2346
2571
  borderCollapse: "collapse",
2347
- }, children: jsx("tbody", { children: jsx("tr", { children: jsx("td", { align: tdAlign, 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", children: jsx("tbody", { children: jsx("tr", { className: "content-tr", children: childrenArray.map((child, index) => (jsxs(Fragment, { children: [jsx("td", { valign: tdValign, style: {
2572
+ }, children: jsx("tbody", { children: jsx("tr", { children: jsx("td", { align: tdAlign, 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: {
2348
2573
  verticalAlign: tdValign,
2349
2574
  textAlign: "left",
2350
2575
  padding: "0",
2351
2576
  margin: "0",
2352
2577
  }, className: "child-cell", children: child }), index < numChildren - 1 &&
2353
2578
  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 }) }) }))] })));
2579
+ // Wrap in anchor tag if innerLink is defined and NOT in dev mode
2580
+ if (href && !devMode) {
2581
+ return (jsx("a", Object.assign({ href: href }, (target && { target }), { style: {
2582
+ textDecoration: "none",
2583
+ color: "inherit",
2584
+ display: "block",
2585
+ }, children: content })));
2586
+ }
2587
+ return content;
2354
2588
  }
2355
2589
  var Row_default = memo(Row, arePropsEqual);
2356
2590
 
2357
- function getBorderStyle(border) {
2591
+ function getBorderStyle$1(border) {
2358
2592
  if (!border)
2359
2593
  return {};
2360
2594
  const style = {};
2595
+ // If a full border is specified, apply it
2361
2596
  if (border.width && border.style && border.color) {
2362
2597
  style.border = `${border.width} ${border.style} ${border.color}`;
2363
2598
  }
2599
+ else {
2600
+ // If only individual borders are specified, explicitly set others to 'none'
2601
+ // to prevent Outlook Classic from showing black borders
2602
+ const hasIndividualBorders = border.top || border.right || border.bottom || border.left;
2603
+ if (hasIndividualBorders) {
2604
+ // Default all borders to none
2605
+ style.borderTop = "none";
2606
+ style.borderRight = "none";
2607
+ style.borderBottom = "none";
2608
+ style.borderLeft = "none";
2609
+ }
2610
+ }
2611
+ // Override with specific borders if provided
2364
2612
  if (border.top) {
2365
2613
  style.borderTop = `${border.top.width} ${border.top.style} ${border.top.color}`;
2366
2614
  }
@@ -2378,7 +2626,7 @@ function getBorderStyle(border) {
2378
2626
  const Section = ({ config, children, devNode, }) => {
2379
2627
  var _a, _b, _c;
2380
2628
  const { sectionType, padding } = config;
2381
- 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(config.border)), { backgroundImage: config.backgroundImage
2629
+ 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
2382
2630
  ? `url(${config.backgroundImage.src})`
2383
2631
  : 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: {
2384
2632
  padding: padding,
@@ -2395,7 +2643,7 @@ const Section = ({ config, children, devNode, }) => {
2395
2643
  var Section_default = memo(Section, arePropsEqual);
2396
2644
 
2397
2645
  function Spacer({ config, devNode }) {
2398
- const { height } = config;
2646
+ const { height, hideOnMobile } = config;
2399
2647
  // 1. Spacer Table Style
2400
2648
  const spacerTableStyle = {
2401
2649
  // Crucial for compatibility: Ensures no background or border interference
@@ -2403,7 +2651,6 @@ function Spacer({ config, devNode }) {
2403
2651
  borderCollapse: "collapse",
2404
2652
  border: "0",
2405
2653
  width: "100%",
2406
- // ✅ FIX: Use string literal indexing for MSO properties
2407
2654
  // Note the CSS standard dash convention: 'mso-table-lspace'
2408
2655
  // ["mso-table-lspace" as string]: "0pt",
2409
2656
  ["msoTableLspace"]: "0pt",
@@ -2424,14 +2671,14 @@ function Spacer({ config, devNode }) {
2424
2671
  // Outer table ensures the spacer spans the full width of its container
2425
2672
  jsxs("table", Object.assign({ "aria-label": "Vertical Spacer", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: Object.assign({
2426
2673
  // --- Start dev
2427
- position: "relative" }, spacerTableStyle) }, { height: spacerHeightAttribute }, { children: [jsx("tbody", { children: jsx("tr", { children: jsx("td", { style: spacerTdStyle,
2674
+ position: "relative" }, spacerTableStyle) }, { height: spacerHeightAttribute }, { className: hideOnMobile ? "hide-on-mobile" : undefined, children: [jsx("tbody", { children: jsx("tr", { children: jsx("td", { style: spacerTdStyle,
2428
2675
  // Explicit height attribute
2429
2676
  height: spacerHeightAttribute, children: "\u00A0" }) }) }), devNode && (jsx("tfoot", { children: jsx("tr", { children: jsx("td", { children: devNode }) }) }))] })));
2430
2677
  }
2431
2678
  var Spacer_default = memo(Spacer, arePropsEqual);
2432
2679
 
2433
2680
  function Text({ config, devMode, children }) {
2434
- const { text, padding, color, textAlign, fontSize, fontWeight, fontStyle, lineHeight, letterSpacing, textTransform, textDecoration, direction, verticalAlign, backgroundColor, opacity, whiteSpace, } = config;
2681
+ const { text, padding, color, textAlign, fontSize, fontWeight, fontStyle, lineHeight, letterSpacing, textTransform, textDecoration, direction, verticalAlign, backgroundColor, opacity, whiteSpace, wordBreak = "break-all", } = config;
2435
2682
  // 1. TD Style: Where padding and background are reliably applied.
2436
2683
  const tdStyle = {
2437
2684
  padding: padding,
@@ -2454,6 +2701,7 @@ function Text({ config, devMode, children }) {
2454
2701
  verticalAlign: verticalAlign,
2455
2702
  opacity: opacity,
2456
2703
  whiteSpace: whiteSpace,
2704
+ wordBreak: wordBreak,
2457
2705
  margin: "0",
2458
2706
  padding: "0",
2459
2707
  fontFamily: "Arial, Helvetica, sans-serif",
@@ -2474,18 +2722,96 @@ const justifyMap = {
2474
2722
  center: "center",
2475
2723
  end: "right",
2476
2724
  };
2725
+ function getBorderStyle(border) {
2726
+ if (!border)
2727
+ return {};
2728
+ const style = {};
2729
+ // If a full border is specified, apply it
2730
+ if (border.width && border.style && border.color) {
2731
+ style.border = `${border.width} ${border.style} ${border.color}`;
2732
+ }
2733
+ else {
2734
+ // If only individual borders are specified, explicitly set others to 'none'
2735
+ // to prevent Outlook Classic from showing black borders
2736
+ const hasIndividualBorders = border.top || border.right || border.bottom || border.left;
2737
+ if (hasIndividualBorders) {
2738
+ // Default all borders to none
2739
+ style.borderTop = "none";
2740
+ style.borderRight = "none";
2741
+ style.borderBottom = "none";
2742
+ style.borderLeft = "none";
2743
+ }
2744
+ }
2745
+ // Override with specific borders if provided
2746
+ if (border.top) {
2747
+ style.borderTop = `${border.top.width} ${border.top.style} ${border.top.color}`;
2748
+ }
2749
+ if (border.right) {
2750
+ style.borderRight = `${border.right.width} ${border.right.style} ${border.right.color}`;
2751
+ }
2752
+ if (border.bottom) {
2753
+ style.borderBottom = `${border.bottom.width} ${border.bottom.style} ${border.bottom.color}`;
2754
+ }
2755
+ if (border.left) {
2756
+ style.borderLeft = `${border.left.width} ${border.left.style} ${border.left.color}`;
2757
+ }
2758
+ return style;
2759
+ }
2760
+ function getBorderStyleString(border) {
2761
+ if (!border)
2762
+ return "";
2763
+ const styles = [];
2764
+ // If a full border is specified, apply it
2765
+ if (border.width && border.style && border.color) {
2766
+ styles.push(`border: ${border.width} ${border.style} ${border.color};`);
2767
+ }
2768
+ else {
2769
+ // If only individual borders are specified
2770
+ const hasIndividualBorders = border.top || border.right || border.bottom || border.left;
2771
+ if (hasIndividualBorders) {
2772
+ // Default all borders to none
2773
+ styles.push("border-top: none;");
2774
+ styles.push("border-right: none;");
2775
+ styles.push("border-bottom: none;");
2776
+ styles.push("border-left: none;");
2777
+ }
2778
+ }
2779
+ // Override with specific borders if provided
2780
+ if (border.top) {
2781
+ styles.push(`border-top: ${border.top.width} ${border.top.style} ${border.top.color};`);
2782
+ }
2783
+ if (border.right) {
2784
+ styles.push(`border-right: ${border.right.width} ${border.right.style} ${border.right.color};`);
2785
+ }
2786
+ if (border.bottom) {
2787
+ styles.push(`border-bottom: ${border.bottom.width} ${border.bottom.style} ${border.bottom.color};`);
2788
+ }
2789
+ if (border.left) {
2790
+ styles.push(`border-left: ${border.left.width} ${border.left.style} ${border.left.color};`);
2791
+ }
2792
+ return styles.join(" ");
2793
+ }
2477
2794
  // Helper to build Iconify API URL
2478
2795
  function buildIconifyUrl(config) {
2479
2796
  const { iconIdentifier, height = 24, color = "000000", rotate = 0, rotateOrientation = "cw", } = config;
2480
2797
  if (!iconIdentifier)
2481
2798
  return null;
2799
+ // Parse height to extract numeric value
2800
+ const parseHeight = (h) => {
2801
+ if (typeof h === "number")
2802
+ return h;
2803
+ // Extract numeric value from string (e.g., "24px" -> 24)
2804
+ const match = String(h).match(/^(-?\d*\.?\d+)/);
2805
+ return match ? parseFloat(match[1]) : 24;
2806
+ };
2807
+ const numericHeight = parseHeight(height);
2482
2808
  // Remove # from color if present
2483
2809
  const cleanColor = color.replace("#", "");
2484
2810
  // Build URL from template
2485
2811
  const template = process.env.ICONIFY_API_IMAGE_URI ||
2486
2812
  "https://iconify.pagenflow.com/api/image/{{height}}/{{color}}/{{rotate}}-{{rotate-orientation}}/{{icon-full-name}}.png";
2487
2813
  return template
2488
- .replace("{{height}}", String(Number(height) * Number(2)))
2814
+ .replace("{{height}}", String(numericHeight * 2))
2489
2815
  .replace("{{color}}", cleanColor)
2490
2816
  .replace("{{rotate}}", String(rotate))
2491
2817
  .replace("{{rotate-orientation}}", rotateOrientation)
@@ -2515,12 +2841,15 @@ function buildLinkHref(innerLink) {
2515
2841
  function Icon({ config, devNode, devMode, children }) {
2516
2842
  const {
2517
2843
  // base64Source,
2518
- width, height, backgroundColor, padding = "0", borderRadius = "0", innerLink, justifyContent = "center", } = config;
2844
+ width, height, backgroundColor, padding = "0", borderRadius = "0", border, innerLink, justifyContent = "center", } = config;
2519
2845
  // Determine icon source
2520
2846
  const iconSrc = buildIconifyUrl(config);
2521
2847
  const href = buildLinkHref(innerLink);
2522
2848
  const target = (innerLink === null || innerLink === void 0 ? void 0 : innerLink.target) || "_self";
2523
2849
  const align = justifyMap[justifyContent];
2850
+ // Get border styles
2851
+ const borderStyle = getBorderStyle(border);
2852
+ const borderStyleString = getBorderStyleString(border);
2524
2853
  // Convert width/height to string with px if number
2525
2854
  const widthStr = typeof width === "number" ? `${width}px` : width;
2526
2855
  const heightStr = typeof height === "number" ? `${height}px` : height;
@@ -2541,6 +2870,7 @@ function Icon({ config, devNode, devMode, children }) {
2541
2870
  border: 0, // No default border
2542
2871
  width: widthStr || "auto",
2543
2872
  height: heightStr || "auto",
2873
+ objectFit: "contain",
2544
2874
  };
2545
2875
  // 2. Link Style: No underline or color changes
2546
2876
  const linkStyle = {
@@ -2549,14 +2879,21 @@ function Icon({ config, devNode, devMode, children }) {
2549
2879
  border: 0,
2550
2880
  outline: "none",
2551
2881
  };
2552
- // 3. TD Style: Padding and background
2553
- const tdStyle = {
2554
- padding: padding,
2882
+ // 3. Outer TD Style: Background and border-radius wrapper with border
2883
+ const outerTdStyle = {
2555
2884
  backgroundColor: backgroundColor,
2556
- fontSize: "0", // CRITICAL: Collapses extra space
2557
- lineHeight: "0", // CRITICAL: Collapses extra space7
2558
2885
  borderRadius: borderRadius,
2559
2886
  overflow: "hidden",
2887
+ fontSize: "0",
2888
+ lineHeight: "0",
2889
+ };
2890
+ // 4. Inner Table Style: Apply border here with border-collapse: separate
2891
+ const innerTableStyle = Object.assign({ width: "100%", borderCollapse: "separate", borderSpacing: 0, borderRadius: borderRadius }, borderStyle);
2892
+ // 5. Inner TD Style: Padding
2893
+ const innerTdStyle = {
2894
+ padding: padding,
2895
+ fontSize: "0", // CRITICAL: Collapses extra space
2896
+ lineHeight: "0", // CRITICAL: Collapses extra space
2560
2897
  };
2561
2898
  // --- VML Calculation for Outlook Compatibility ---
2562
2899
  const numericPadding = parseInt(padding.split(" ")[0] || "0", 10);
@@ -2573,15 +2910,19 @@ function Icon({ config, devNode, devMode, children }) {
2573
2910
  const arcsize = numericBorderRadius > 0
2574
2911
  ? Math.min((numericBorderRadius / Math.min(vmlWidth, vmlHeight)) * 100, 100)
2575
2912
  : 0;
2913
+ // VML stroke color for border
2914
+ const vmlStrokeColor = (border === null || border === void 0 ? void 0 : border.color) || vmlFillColor;
2915
+ const vmlStrokeWeight = (border === null || border === void 0 ? void 0 : border.width) ? parseInt(border.width, 10) : 0;
2916
+ const hasVmlStroke = vmlStrokeWeight > 0;
2576
2917
  // Build VML code for Outlook
2577
2918
  const vmlIcon = backgroundColor && numericBorderRadius > 0
2578
2919
  ? `
2579
2920
  <!--[if mso]>
2580
- <v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" ${href && !devMode ? `href="${href}"` : ""} style="height:${vmlHeight}px;width:${vmlWidth}px;v-text-anchor:middle;" arcsize="${arcsize}%" stroke="false" fillcolor="${vmlFillColor}">
2921
+ <v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" ${href && !devMode ? `href="${href}"` : ""} style="height:${vmlHeight}px;width:${vmlWidth}px;v-text-anchor:middle;" arcsize="${arcsize}%" ${hasVmlStroke ? `strokecolor="${vmlStrokeColor}" strokeweight="${vmlStrokeWeight}px"` : 'stroke="false"'} fillcolor="${vmlFillColor}">
2581
2922
  <w:anchorlock/>
2582
2923
  <v:textbox inset="0,0,0,0" style="text-align: center;">
2583
2924
  <center style="padding:${padding};">
2584
- <img src="${iconSrc || ""}" alt="" width="${widthNum || 24}" height="${heightNum || 24}" border="0" style="display:block;border:0;" />
2925
+ <img src="${iconSrc || ""}" alt="" width="${widthNum || 24}" height="${heightNum || 24}" border="0" style="display:block;border:0;object-fit:contain;" />
2585
2926
  </center>
2586
2927
  </v:textbox>
2587
2928
  </v:roundrect>
@@ -2593,8 +2934,7 @@ function Icon({ config, devNode, devMode, children }) {
2593
2934
  return null;
2594
2935
  }
2595
2936
  // Icon image element
2596
- const iconElement = devMode && !!children ? (children) : iconSrc ? (jsx("img", { draggable: false, src: iconSrc, alt: "" // Icons are decorative, empty alt is appropriate
2597
- , style: imgStyle, width: widthNum, height: heightNum, border: 0 })) : (jsx(Fragment$1, {}));
2937
+ const iconElement = devMode && !!children ? (children) : iconSrc ? (jsx("img", { draggable: false, src: iconSrc, alt: "", style: imgStyle, width: widthNum, height: heightNum, border: 0 })) : (jsx(Fragment$1, {}));
2598
2938
  // Wrap in link if href exists and not in dev mode
2599
2939
  const content = href && !devMode ? (jsx("a", Object.assign({ href: href, target: target, style: linkStyle }, (target === "_blank" ? { rel: "noopener noreferrer" } : {}), { children: iconElement }))) : (iconElement);
2600
2940
  // Build the HTML content with VML support (only when NOT in dev mode)
@@ -2606,12 +2946,20 @@ function Icon({ config, devNode, devMode, children }) {
2606
2946
  <table role="presentation" cellpadding="0" cellspacing="0" border="0" style="border-collapse: collapse; width: 100%;">
2607
2947
  <tbody>
2608
2948
  <tr>
2609
- <td style="background-color: ${backgroundColor}; border-radius: ${borderRadius}; padding: ${padding}; font-size: 0; line-height: 0; overflow: hidden;">
2610
- ${href
2949
+ <td style="background-color: ${backgroundColor}; border-radius: ${borderRadius}; overflow: hidden; font-size: 0; line-height: 0;">
2950
+ <table role="presentation" cellpadding="0" cellspacing="0" border="0" style="border-collapse: separate; border-spacing: 0; border-radius: ${borderRadius}; width: 100%; ${borderStyleString}">
2951
+ <tbody>
2952
+ <tr>
2953
+ <td style="padding: ${padding}; font-size: 0; line-height: 0;">
2954
+ ${href
2611
2955
  ? `<a href="${href}" target="${target}" style="display:block;text-decoration:none;border:0;outline:none;" ${target === "_blank" ? 'rel="noopener noreferrer"' : ""}>
2612
- <img draggable="false" src="${iconSrc}" alt="" width="${widthNum || 24}" height="${heightNum || 24}" border="0" style="display:block;border:0;width:${widthStr || "auto"};height:${heightStr || "auto"};" />
2613
- </a>`
2614
- : `<img draggable="false" src="${iconSrc}" alt="" width="${widthNum || 24}" height="${heightNum || 24}" border="0" style="display:block;border:0;width:${widthStr || "auto"};height:${heightStr || "auto"};" />`}
2956
+ <img draggable="false" src="${iconSrc}" alt="" width="${widthNum || 24}" height="${heightNum || 24}" border="0" style="display:block;border:0;width:${widthStr || "auto"};height:${heightStr || "auto"};object-fit:contain;" />
2957
+ </a>`
2958
+ : `<img draggable="false" src="${iconSrc}" alt="" width="${widthNum || 24}" height="${heightNum || 24}" border="0" style="display:block;border:0;width:${widthStr || "auto"};height:${heightStr || "auto"};object-fit:contain;" />`}
2959
+ </td>
2960
+ </tr>
2961
+ </tbody>
2962
+ </table>
2615
2963
  </td>
2616
2964
  </tr>
2617
2965
  </tbody>
@@ -2623,7 +2971,7 @@ function Icon({ config, devNode, devMode, children }) {
2623
2971
  // --- Start dev
2624
2972
  position: "relative",
2625
2973
  // --- End dev
2626
- width: widthStr || "auto",
2974
+ width: "auto",
2627
2975
  borderCollapse: "collapse",
2628
2976
  // base
2629
2977
  boxSizing: "border-box",
@@ -2632,7 +2980,7 @@ function Icon({ config, devNode, devMode, children }) {
2632
2980
  padding: 0,
2633
2981
  }, onClick: devMode ? (e) => e.preventDefault() : undefined, children: [jsx("tbody", { children: jsx("tr", { children: useVML ? (jsx("td", { dangerouslySetInnerHTML: {
2634
2982
  __html: htmlContent !== null && htmlContent !== void 0 ? htmlContent : "",
2635
- } })) : (jsx("td", { style: tdStyle, align: align, children: content })) }) }), devMode && !!devNode && (jsx("tfoot", { children: jsx("tr", { children: jsx("td", { children: devNode }) }) }))] }));
2983
+ } })) : (jsx("td", { style: outerTdStyle, align: align, children: jsx("table", { role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: innerTableStyle, children: jsx("tbody", { children: jsx("tr", { children: jsx("td", { style: innerTdStyle, align: align, children: content }) }) }) }) })) }) }), devMode && !!devNode && (jsx("tfoot", { children: jsx("tr", { children: jsx("td", { children: devNode }) }) }))] }));
2636
2984
  }
2637
2985
  var Icon_default = memo(Icon, arePropsEqual);
2638
2986