@pagenflow/email 1.3.6 → 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,121 +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
- /* Target only the direct row-content-table, not nested ones */
2024
2183
 
2025
- /* Force table to act like block container */
2026
- .responsive-row[data-mobile-wrap="true"] > tbody > tr > td > table > tbody > tr > td > table > tbody > tr > td > .row-content-table {
2184
+ /* Force table to be full width */
2185
+ .row-content-table[data-mobile-wrap="true"] {
2027
2186
  width: 100% !important;
2028
2187
  max-width: 100% !important;
2029
2188
  }
2030
2189
 
2031
2190
  /* Force table row to stack cells */
2032
- .responsive-row[data-mobile-wrap="true"] > tbody > tr > td > table > tbody > tr > td > table > tbody > tr > td > .row-content-table > tbody > .content-tr {
2191
+ .row-content-table[data-mobile-wrap="true"] > tbody > .content-tr {
2033
2192
  display: block !important;
2034
2193
  }
2035
2194
 
2036
2195
  /* Force each child cell to be full width block */
2037
- .responsive-row[data-mobile-wrap="true"] > tbody > tr > td > table > tbody > tr > td > table > tbody > tr > td > .row-content-table > tbody > .content-tr > .child-cell {
2196
+ .row-content-table[data-mobile-wrap="true"] > tbody > .content-tr > .child-cell {
2038
2197
  display: block !important;
2039
2198
  width: 100% !important;
2040
2199
  box-sizing: border-box !important;
2041
2200
  }
2042
2201
 
2043
- /* Hide horizontal gap cells and create vertical spacing with padding */
2044
- .responsive-row[data-mobile-wrap="true"] > tbody > tr > td > table > tbody > tr > td > table > tbody > tr > td > .row-content-table > tbody > .content-tr > .row-gap-td {
2202
+ /* Hide horizontal gap cells */
2203
+ .row-content-table[data-mobile-wrap="true"] > tbody > .content-tr > .row-gap-td {
2045
2204
  display: none !important;
2046
2205
  width: 0 !important;
2047
2206
  height: 0 !important;
2048
2207
  }
2049
2208
 
2050
2209
  /* Add vertical spacing between stacked cells using margin */
2051
- .responsive-row[data-mobile-wrap="true"] > tbody > tr > td > table > tbody > tr > td > table > tbody > tr > td > .row-content-table > tbody > .content-tr > .child-cell:not(:last-child) {
2210
+ .row-content-table[data-mobile-wrap="true"] > tbody > .content-tr > .child-cell:not(:last-child) {
2052
2211
  margin-bottom: 20px !important;
2053
2212
  }
2054
2213
 
2055
2214
  /* Dynamic gap support - common values */
2056
- .responsive-row[data-mobile-wrap="true"][data-gap="10px"] > tbody > tr > td > table > tbody > tr > td > table > tbody > tr > td > .row-content-table > tbody > .content-tr > .child-cell:not(:last-child) {
2057
- margin-bottom: 10px !important;
2058
- }
2059
- .responsive-row[data-mobile-wrap="true"][data-gap="15px"] > tbody > tr > td > table > tbody > tr > td > table > tbody > tr > td > .row-content-table > tbody > .content-tr > .child-cell:not(:last-child) {
2060
- margin-bottom: 15px !important;
2061
- }
2062
- .responsive-row[data-mobile-wrap="true"][data-gap="20px"] > tbody > tr > td > table > tbody > tr > td > table > tbody > tr > td > .row-content-table > tbody > .content-tr > .child-cell:not(:last-child) {
2063
- margin-bottom: 20px !important;
2064
- }
2065
- .responsive-row[data-mobile-wrap="true"][data-gap="24px"] > tbody > tr > td > table > tbody > tr > td > table > tbody > tr > td > .row-content-table > tbody > .content-tr > .child-cell:not(:last-child) {
2066
- margin-bottom: 24px !important;
2067
- }
2068
- .responsive-row[data-mobile-wrap="true"][data-gap="30px"] > tbody > tr > td > table > tbody > tr > td > table > tbody > tr > td > .row-content-table > tbody > .content-tr > .child-cell:not(:last-child) {
2069
- margin-bottom: 30px !important;
2070
- }
2071
- .responsive-row[data-mobile-wrap="true"][data-gap="40px"] > tbody > tr > td > table > tbody > tr > td > table > tbody > tr > td > .row-content-table > tbody > .content-tr > .child-cell:not(:last-child) {
2072
- margin-bottom: 40px !important;
2073
- }
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")}
2074
2222
  }
2075
2223
 
2076
2224
  /* ================================================= */
@@ -2150,7 +2298,7 @@ function Head({ children, backgroundColor = "#ffffff", title = "Email Preview",
2150
2298
  }
2151
2299
 
2152
2300
  function Heading({ config, devMode, children }) {
2153
- 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;
2154
2302
  // Determine the content to render
2155
2303
  const content = text !== null && text !== void 0 ? text : children;
2156
2304
  const isString = typeof content === "string";
@@ -2173,6 +2321,8 @@ function Heading({ config, devMode, children }) {
2173
2321
  textTransform: textTransform,
2174
2322
  textDecoration: textDecoration,
2175
2323
  direction: direction,
2324
+ wordBreak: wordBreak,
2325
+ whiteSpace: whiteSpace,
2176
2326
  // Critical: Remove default top/bottom margin from HTML heading tags
2177
2327
  margin: "0",
2178
2328
  padding: "0",
@@ -2212,22 +2362,53 @@ function Html({ children, backgroundColor = "#ffffff", }) {
2212
2362
  );
2213
2363
  }
2214
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
+ }
2215
2400
  function Image({ config, devNode, devMode }) {
2216
- 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);
2217
2404
  // 1. Image Style: Critical for compatibility, especially display: block
2218
- const imgStyle = {
2405
+ const imgStyle = Object.assign({
2219
2406
  // Basic image properties
2220
- display: "block", // Prevents extra vertical space/gaps below the image
2221
- objectFit: "cover", // For controlling how the image fits (modern CSS, may be ignored)
2407
+ display: "block", objectFit: "cover",
2222
2408
  // Dimensions (using CSS fallback)
2223
- width: width || "100%",
2224
- height: height || "auto",
2225
- maxWidth: maxWidth || "100%",
2226
- maxHeight: maxHeight,
2409
+ width: width || "100%", height: height || "auto", maxWidth: maxWidth || "100%", maxHeight: maxHeight,
2227
2410
  // Styling
2228
- border: "0", // Ensures no default browser/client border
2229
- borderRadius: borderRadius,
2230
- };
2411
+ border: "0", borderRadius: borderRadius }, borderStyle);
2231
2412
  // 2. Link Style: Ensure no underline or color changes
2232
2413
  const linkStyle = {
2233
2414
  display: "block",
@@ -2279,13 +2460,27 @@ const alignMap = {
2279
2460
  center: "middle",
2280
2461
  end: "bottom",
2281
2462
  };
2282
- function getBorderStyle$1(border) {
2463
+ function getBorderStyle$2(border) {
2283
2464
  if (!border)
2284
2465
  return {};
2285
2466
  const style = {};
2467
+ // If a full border is specified, apply it
2286
2468
  if (border.width && border.style && border.color) {
2287
2469
  style.border = `${border.width} ${border.style} ${border.color}`;
2288
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
2289
2484
  if (border.top) {
2290
2485
  style.borderTop = `${border.top.width} ${border.top.style} ${border.top.color}`;
2291
2486
  }
@@ -2300,23 +2495,50 @@ function getBorderStyle$1(border) {
2300
2495
  }
2301
2496
  return style;
2302
2497
  }
2303
- function Row({ children, config, devNode }) {
2304
- 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;
2305
2520
  const childrenArray = (Array.isArray(children) ? children : [children]).filter((child) => child != null);
2306
2521
  const numChildren = childrenArray.length;
2307
- // 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.
2308
2526
  const backgroundTdStyle = Object.assign({ backgroundColor: config.backgroundColor, borderRadius: config.borderRadius, width: config.width || "100%", height: config.height,
2309
2527
  // Background Image styles
2310
2528
  backgroundImage: config.backgroundImage
2311
2529
  ? `url(${config.backgroundImage.src})`
2312
- : 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" }));
2313
- // 2. Inner Table for Border and Border Radius
2314
- const borderTableStyle = Object.assign({ width: "100%", height: "100%", borderCollapse: "separate", borderSpacing: 0, borderRadius: config.borderRadius }, getBorderStyle$1(config.border));
2315
- // 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.
2316
2538
  const paddingTdStyle = {
2317
2539
  padding: config.padding,
2318
2540
  width: "100%",
2319
- height: "100%",
2541
+ // height intentionally omitted — padding must be inner, not additive
2320
2542
  verticalAlign: "top",
2321
2543
  };
2322
2544
  // 4. Content Table - horizontal layout
@@ -2337,32 +2559,56 @@ function Row({ children, config, devNode }) {
2337
2559
  ? justifyMap$1[config.justifyContent]
2338
2560
  : "left";
2339
2561
  const tdValign = config.alignItems ? alignMap[config.alignItems] : "top";
2340
- 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: {
2341
2564
  position: "relative",
2342
2565
  width: config.width || "100%",
2343
2566
  height: config.height,
2344
2567
  borderCollapse: "collapse",
2345
- } }, (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: {
2346
2569
  width: "100%",
2347
2570
  height: "100%",
2348
2571
  borderCollapse: "collapse",
2349
- }, 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", 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: {
2350
2573
  verticalAlign: tdValign,
2351
2574
  textAlign: "left",
2352
2575
  padding: "0",
2353
2576
  margin: "0",
2354
2577
  }, className: "child-cell", children: child }), index < numChildren - 1 &&
2355
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;
2356
2588
  }
2357
2589
  var Row_default = memo(Row, arePropsEqual);
2358
2590
 
2359
- function getBorderStyle(border) {
2591
+ function getBorderStyle$1(border) {
2360
2592
  if (!border)
2361
2593
  return {};
2362
2594
  const style = {};
2595
+ // If a full border is specified, apply it
2363
2596
  if (border.width && border.style && border.color) {
2364
2597
  style.border = `${border.width} ${border.style} ${border.color}`;
2365
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
2366
2612
  if (border.top) {
2367
2613
  style.borderTop = `${border.top.width} ${border.top.style} ${border.top.color}`;
2368
2614
  }
@@ -2380,7 +2626,7 @@ function getBorderStyle(border) {
2380
2626
  const Section = ({ config, children, devNode, }) => {
2381
2627
  var _a, _b, _c;
2382
2628
  const { sectionType, padding } = config;
2383
- 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
2384
2630
  ? `url(${config.backgroundImage.src})`
2385
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: {
2386
2632
  padding: padding,
@@ -2397,7 +2643,7 @@ const Section = ({ config, children, devNode, }) => {
2397
2643
  var Section_default = memo(Section, arePropsEqual);
2398
2644
 
2399
2645
  function Spacer({ config, devNode }) {
2400
- const { height } = config;
2646
+ const { height, hideOnMobile } = config;
2401
2647
  // 1. Spacer Table Style
2402
2648
  const spacerTableStyle = {
2403
2649
  // Crucial for compatibility: Ensures no background or border interference
@@ -2405,7 +2651,6 @@ function Spacer({ config, devNode }) {
2405
2651
  borderCollapse: "collapse",
2406
2652
  border: "0",
2407
2653
  width: "100%",
2408
- // ✅ FIX: Use string literal indexing for MSO properties
2409
2654
  // Note the CSS standard dash convention: 'mso-table-lspace'
2410
2655
  // ["mso-table-lspace" as string]: "0pt",
2411
2656
  ["msoTableLspace"]: "0pt",
@@ -2426,14 +2671,14 @@ function Spacer({ config, devNode }) {
2426
2671
  // Outer table ensures the spacer spans the full width of its container
2427
2672
  jsxs("table", Object.assign({ "aria-label": "Vertical Spacer", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: Object.assign({
2428
2673
  // --- Start dev
2429
- 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,
2430
2675
  // Explicit height attribute
2431
2676
  height: spacerHeightAttribute, children: "\u00A0" }) }) }), devNode && (jsx("tfoot", { children: jsx("tr", { children: jsx("td", { children: devNode }) }) }))] })));
2432
2677
  }
2433
2678
  var Spacer_default = memo(Spacer, arePropsEqual);
2434
2679
 
2435
2680
  function Text({ config, devMode, children }) {
2436
- 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;
2437
2682
  // 1. TD Style: Where padding and background are reliably applied.
2438
2683
  const tdStyle = {
2439
2684
  padding: padding,
@@ -2456,6 +2701,7 @@ function Text({ config, devMode, children }) {
2456
2701
  verticalAlign: verticalAlign,
2457
2702
  opacity: opacity,
2458
2703
  whiteSpace: whiteSpace,
2704
+ wordBreak: wordBreak,
2459
2705
  margin: "0",
2460
2706
  padding: "0",
2461
2707
  fontFamily: "Arial, Helvetica, sans-serif",
@@ -2476,18 +2722,96 @@ const justifyMap = {
2476
2722
  center: "center",
2477
2723
  end: "right",
2478
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
+ }
2479
2794
  // Helper to build Iconify API URL
2480
2795
  function buildIconifyUrl(config) {
2481
2796
  const { iconIdentifier, height = 24, color = "000000", rotate = 0, rotateOrientation = "cw", } = config;
2482
2797
  if (!iconIdentifier)
2483
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);
2484
2808
  // Remove # from color if present
2485
2809
  const cleanColor = color.replace("#", "");
2486
2810
  // Build URL from template
2487
2811
  const template = process.env.ICONIFY_API_IMAGE_URI ||
2488
2812
  "https://iconify.pagenflow.com/api/image/{{height}}/{{color}}/{{rotate}}-{{rotate-orientation}}/{{icon-full-name}}.png";
2489
2813
  return template
2490
- .replace("{{height}}", String(Number(height) * Number(2)))
2814
+ .replace("{{height}}", String(numericHeight * 2))
2491
2815
  .replace("{{color}}", cleanColor)
2492
2816
  .replace("{{rotate}}", String(rotate))
2493
2817
  .replace("{{rotate-orientation}}", rotateOrientation)
@@ -2517,12 +2841,15 @@ function buildLinkHref(innerLink) {
2517
2841
  function Icon({ config, devNode, devMode, children }) {
2518
2842
  const {
2519
2843
  // base64Source,
2520
- width, height, backgroundColor, padding = "0", borderRadius = "0", innerLink, justifyContent = "center", } = config;
2844
+ width, height, backgroundColor, padding = "0", borderRadius = "0", border, innerLink, justifyContent = "center", } = config;
2521
2845
  // Determine icon source
2522
2846
  const iconSrc = buildIconifyUrl(config);
2523
2847
  const href = buildLinkHref(innerLink);
2524
2848
  const target = (innerLink === null || innerLink === void 0 ? void 0 : innerLink.target) || "_self";
2525
2849
  const align = justifyMap[justifyContent];
2850
+ // Get border styles
2851
+ const borderStyle = getBorderStyle(border);
2852
+ const borderStyleString = getBorderStyleString(border);
2526
2853
  // Convert width/height to string with px if number
2527
2854
  const widthStr = typeof width === "number" ? `${width}px` : width;
2528
2855
  const heightStr = typeof height === "number" ? `${height}px` : height;
@@ -2543,6 +2870,7 @@ function Icon({ config, devNode, devMode, children }) {
2543
2870
  border: 0, // No default border
2544
2871
  width: widthStr || "auto",
2545
2872
  height: heightStr || "auto",
2873
+ objectFit: "contain",
2546
2874
  };
2547
2875
  // 2. Link Style: No underline or color changes
2548
2876
  const linkStyle = {
@@ -2551,14 +2879,21 @@ function Icon({ config, devNode, devMode, children }) {
2551
2879
  border: 0,
2552
2880
  outline: "none",
2553
2881
  };
2554
- // 3. TD Style: Padding and background
2555
- const tdStyle = {
2556
- padding: padding,
2882
+ // 3. Outer TD Style: Background and border-radius wrapper with border
2883
+ const outerTdStyle = {
2557
2884
  backgroundColor: backgroundColor,
2558
- fontSize: "0", // CRITICAL: Collapses extra space
2559
- lineHeight: "0", // CRITICAL: Collapses extra space7
2560
2885
  borderRadius: borderRadius,
2561
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
2562
2897
  };
2563
2898
  // --- VML Calculation for Outlook Compatibility ---
2564
2899
  const numericPadding = parseInt(padding.split(" ")[0] || "0", 10);
@@ -2575,15 +2910,19 @@ function Icon({ config, devNode, devMode, children }) {
2575
2910
  const arcsize = numericBorderRadius > 0
2576
2911
  ? Math.min((numericBorderRadius / Math.min(vmlWidth, vmlHeight)) * 100, 100)
2577
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;
2578
2917
  // Build VML code for Outlook
2579
2918
  const vmlIcon = backgroundColor && numericBorderRadius > 0
2580
2919
  ? `
2581
2920
  <!--[if mso]>
2582
- <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}">
2583
2922
  <w:anchorlock/>
2584
2923
  <v:textbox inset="0,0,0,0" style="text-align: center;">
2585
2924
  <center style="padding:${padding};">
2586
- <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;" />
2587
2926
  </center>
2588
2927
  </v:textbox>
2589
2928
  </v:roundrect>
@@ -2595,8 +2934,7 @@ function Icon({ config, devNode, devMode, children }) {
2595
2934
  return null;
2596
2935
  }
2597
2936
  // Icon image element
2598
- const iconElement = devMode && !!children ? (children) : iconSrc ? (jsx("img", { draggable: false, src: iconSrc, alt: "" // Icons are decorative, empty alt is appropriate
2599
- , 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, {}));
2600
2938
  // Wrap in link if href exists and not in dev mode
2601
2939
  const content = href && !devMode ? (jsx("a", Object.assign({ href: href, target: target, style: linkStyle }, (target === "_blank" ? { rel: "noopener noreferrer" } : {}), { children: iconElement }))) : (iconElement);
2602
2940
  // Build the HTML content with VML support (only when NOT in dev mode)
@@ -2608,12 +2946,20 @@ function Icon({ config, devNode, devMode, children }) {
2608
2946
  <table role="presentation" cellpadding="0" cellspacing="0" border="0" style="border-collapse: collapse; width: 100%;">
2609
2947
  <tbody>
2610
2948
  <tr>
2611
- <td style="background-color: ${backgroundColor}; border-radius: ${borderRadius}; padding: ${padding}; font-size: 0; line-height: 0; overflow: hidden;">
2612
- ${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
2613
2955
  ? `<a href="${href}" target="${target}" style="display:block;text-decoration:none;border:0;outline:none;" ${target === "_blank" ? 'rel="noopener noreferrer"' : ""}>
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"};" />
2615
- </a>`
2616
- : `<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>
2617
2963
  </td>
2618
2964
  </tr>
2619
2965
  </tbody>
@@ -2625,7 +2971,7 @@ function Icon({ config, devNode, devMode, children }) {
2625
2971
  // --- Start dev
2626
2972
  position: "relative",
2627
2973
  // --- End dev
2628
- width: widthStr || "auto",
2974
+ width: "auto",
2629
2975
  borderCollapse: "collapse",
2630
2976
  // base
2631
2977
  boxSizing: "border-box",
@@ -2634,7 +2980,7 @@ function Icon({ config, devNode, devMode, children }) {
2634
2980
  padding: 0,
2635
2981
  }, onClick: devMode ? (e) => e.preventDefault() : undefined, children: [jsx("tbody", { children: jsx("tr", { children: useVML ? (jsx("td", { dangerouslySetInnerHTML: {
2636
2982
  __html: htmlContent !== null && htmlContent !== void 0 ? htmlContent : "",
2637
- } })) : (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 }) }) }))] }));
2638
2984
  }
2639
2985
  var Icon_default = memo(Icon, arePropsEqual);
2640
2986