@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/components/Button.d.ts +5 -0
- package/dist/components/Divider.d.ts +1 -0
- package/dist/components/Head.d.ts +3 -1
- package/dist/components/HeadDev.d.ts +3 -1
- package/dist/components/Heading.d.ts +4 -0
- package/dist/components/Icon.d.ts +3 -0
- package/dist/components/Image.d.ts +3 -0
- package/dist/components/Row.d.ts +4 -1
- package/dist/components/Spacer.d.ts +1 -0
- package/dist/components/Text.d.ts +2 -0
- package/dist/index.cjs.js +528 -182
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +528 -182
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -1
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
|
-
//
|
|
1542
|
-
|
|
1543
|
-
const
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
const
|
|
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
|
-
//
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
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;
|
|
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
|
-
<
|
|
1570
|
-
|
|
1571
|
-
|
|
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
|
-
//
|
|
1577
|
-
jsx("table", { role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0,
|
|
1578
|
-
|
|
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
|
-
},
|
|
1589
|
-
|
|
1590
|
-
|
|
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:
|
|
1754
|
+
<td style="padding: 0;">
|
|
1600
1755
|
${devMode
|
|
1601
|
-
|
|
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
|
-
|
|
1605
|
-
<span style="color: ${color}; font-family: ${fontFamily}; font-size: ${fontSize}; font-weight: ${fontWeight}; font-style: ${fontStyle
|
|
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$
|
|
1791
|
+
function getBorderStyle$5(border) {
|
|
1637
1792
|
if (!border)
|
|
1638
1793
|
return {};
|
|
1639
1794
|
const style = {};
|
|
1640
|
-
//
|
|
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
|
-
|
|
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
|
-
|
|
1678
|
-
|
|
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
|
|
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",
|
|
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$
|
|
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$
|
|
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)
|
|
1960
|
-
|
|
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
|
-
.
|
|
2162
|
+
.row-content-table[data-mobile-justify="start"] {
|
|
1966
2163
|
margin: 0 !important;
|
|
1967
2164
|
float: left !important;
|
|
1968
2165
|
}
|
|
1969
|
-
.
|
|
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
|
-
|
|
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
|
-
.
|
|
2175
|
+
.row-content-table[data-mobile-align="start"] .child-cell {
|
|
2016
2176
|
vertical-align: top !important;
|
|
2017
2177
|
}
|
|
2018
|
-
.
|
|
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
|
|
2026
|
-
.
|
|
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
|
-
.
|
|
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
|
-
.
|
|
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
|
|
2044
|
-
.
|
|
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
|
-
.
|
|
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
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
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",
|
|
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",
|
|
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$
|
|
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
|
|
2304
|
-
|
|
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
|
-
|
|
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: (
|
|
2313
|
-
// 2. Inner Table for Border and Border Radius
|
|
2314
|
-
|
|
2315
|
-
|
|
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
|
|
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
|
-
|
|
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 }), {
|
|
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(
|
|
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:
|
|
2555
|
-
const
|
|
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: ""
|
|
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};
|
|
2612
|
-
${
|
|
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
|
-
|
|
2615
|
-
|
|
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:
|
|
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:
|
|
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
|
|