@pagenflow/email 1.3.5 → 1.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/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 +529 -181
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +529 -181
- 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,119 +2154,71 @@ function Head({ children, backgroundColor = "#ffffff", title = "Email Preview",
|
|
|
1956
2154
|
}
|
|
1957
2155
|
|
|
1958
2156
|
@media only screen and (max-width: 768px) {
|
|
1959
|
-
/* 1. Handling Mobile Alignment (Justify)
|
|
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
|
-
|
|
2024
|
-
|
|
2183
|
+
|
|
2184
|
+
/* Force table to be full width */
|
|
2185
|
+
.row-content-table[data-mobile-wrap="true"] {
|
|
2025
2186
|
width: 100% !important;
|
|
2026
2187
|
max-width: 100% !important;
|
|
2027
2188
|
}
|
|
2028
2189
|
|
|
2029
2190
|
/* Force table row to stack cells */
|
|
2030
|
-
.
|
|
2191
|
+
.row-content-table[data-mobile-wrap="true"] > tbody > .content-tr {
|
|
2031
2192
|
display: block !important;
|
|
2032
2193
|
}
|
|
2033
2194
|
|
|
2034
2195
|
/* Force each child cell to be full width block */
|
|
2035
|
-
.
|
|
2196
|
+
.row-content-table[data-mobile-wrap="true"] > tbody > .content-tr > .child-cell {
|
|
2036
2197
|
display: block !important;
|
|
2037
2198
|
width: 100% !important;
|
|
2038
2199
|
box-sizing: border-box !important;
|
|
2039
2200
|
}
|
|
2040
2201
|
|
|
2041
|
-
/* Hide horizontal gap cells
|
|
2042
|
-
.
|
|
2202
|
+
/* Hide horizontal gap cells */
|
|
2203
|
+
.row-content-table[data-mobile-wrap="true"] > tbody > .content-tr > .row-gap-td {
|
|
2043
2204
|
display: none !important;
|
|
2044
2205
|
width: 0 !important;
|
|
2045
2206
|
height: 0 !important;
|
|
2046
2207
|
}
|
|
2047
2208
|
|
|
2048
2209
|
/* Add vertical spacing between stacked cells using margin */
|
|
2049
|
-
.
|
|
2210
|
+
.row-content-table[data-mobile-wrap="true"] > tbody > .content-tr > .child-cell:not(:last-child) {
|
|
2050
2211
|
margin-bottom: 20px !important;
|
|
2051
2212
|
}
|
|
2052
2213
|
|
|
2053
2214
|
/* Dynamic gap support - common values */
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
margin-bottom: 20px !important;
|
|
2062
|
-
}
|
|
2063
|
-
.responsive-row[data-mobile-wrap="true"][data-gap="24px"] .child-cell:not(:last-child) {
|
|
2064
|
-
margin-bottom: 24px !important;
|
|
2065
|
-
}
|
|
2066
|
-
.responsive-row[data-mobile-wrap="true"][data-gap="30px"] .child-cell:not(:last-child) {
|
|
2067
|
-
margin-bottom: 30px !important;
|
|
2068
|
-
}
|
|
2069
|
-
.responsive-row[data-mobile-wrap="true"][data-gap="40px"] .child-cell:not(:last-child) {
|
|
2070
|
-
margin-bottom: 40px !important;
|
|
2071
|
-
}
|
|
2215
|
+
${["10px", "15px", "20px", "24px", "30px", "40px", ...rowGaps]
|
|
2216
|
+
.filter((gap, index, self) => self.indexOf(gap) === index)
|
|
2217
|
+
.map((gap) => `
|
|
2218
|
+
.row-content-table[data-mobile-wrap="true"][data-gap="${gap}"] > tbody > .content-tr > .child-cell:not(:last-child) {
|
|
2219
|
+
margin-bottom: ${gap} !important;
|
|
2220
|
+
}`)
|
|
2221
|
+
.join("\n")}
|
|
2072
2222
|
}
|
|
2073
2223
|
|
|
2074
2224
|
/* ================================================= */
|
|
@@ -2148,7 +2298,7 @@ function Head({ children, backgroundColor = "#ffffff", title = "Email Preview",
|
|
|
2148
2298
|
}
|
|
2149
2299
|
|
|
2150
2300
|
function Heading({ config, devMode, children }) {
|
|
2151
|
-
const { text, level = "h1", padding, color, textAlign, fontSize, fontWeight, fontStyle, lineHeight, letterSpacing, textTransform, textDecoration, direction, verticalAlign, backgroundColor, } = config;
|
|
2301
|
+
const { text, level = "h1", padding, color, textAlign, fontSize, fontWeight, fontStyle, lineHeight, letterSpacing, textTransform, textDecoration, direction, verticalAlign, backgroundColor, wordBreak, whiteSpace, } = config;
|
|
2152
2302
|
// Determine the content to render
|
|
2153
2303
|
const content = text !== null && text !== void 0 ? text : children;
|
|
2154
2304
|
const isString = typeof content === "string";
|
|
@@ -2171,6 +2321,8 @@ function Heading({ config, devMode, children }) {
|
|
|
2171
2321
|
textTransform: textTransform,
|
|
2172
2322
|
textDecoration: textDecoration,
|
|
2173
2323
|
direction: direction,
|
|
2324
|
+
wordBreak: wordBreak,
|
|
2325
|
+
whiteSpace: whiteSpace,
|
|
2174
2326
|
// Critical: Remove default top/bottom margin from HTML heading tags
|
|
2175
2327
|
margin: "0",
|
|
2176
2328
|
padding: "0",
|
|
@@ -2210,22 +2362,53 @@ function Html({ children, backgroundColor = "#ffffff", }) {
|
|
|
2210
2362
|
);
|
|
2211
2363
|
}
|
|
2212
2364
|
|
|
2365
|
+
function getBorderStyle$3(border) {
|
|
2366
|
+
if (!border)
|
|
2367
|
+
return {};
|
|
2368
|
+
const style = {};
|
|
2369
|
+
// If a full border is specified, apply it
|
|
2370
|
+
if (border.width && border.style && border.color) {
|
|
2371
|
+
style.border = `${border.width} ${border.style} ${border.color}`;
|
|
2372
|
+
}
|
|
2373
|
+
else {
|
|
2374
|
+
// If only individual borders are specified, explicitly set others to 'none'
|
|
2375
|
+
// to prevent Outlook Classic from showing black borders
|
|
2376
|
+
const hasIndividualBorders = border.top || border.right || border.bottom || border.left;
|
|
2377
|
+
if (hasIndividualBorders) {
|
|
2378
|
+
// Default all borders to none
|
|
2379
|
+
style.borderTop = "none";
|
|
2380
|
+
style.borderRight = "none";
|
|
2381
|
+
style.borderBottom = "none";
|
|
2382
|
+
style.borderLeft = "none";
|
|
2383
|
+
}
|
|
2384
|
+
}
|
|
2385
|
+
// Override with specific borders if provided
|
|
2386
|
+
if (border.top) {
|
|
2387
|
+
style.borderTop = `${border.top.width} ${border.top.style} ${border.top.color}`;
|
|
2388
|
+
}
|
|
2389
|
+
if (border.right) {
|
|
2390
|
+
style.borderRight = `${border.right.width} ${border.right.style} ${border.right.color}`;
|
|
2391
|
+
}
|
|
2392
|
+
if (border.bottom) {
|
|
2393
|
+
style.borderBottom = `${border.bottom.width} ${border.bottom.style} ${border.bottom.color}`;
|
|
2394
|
+
}
|
|
2395
|
+
if (border.left) {
|
|
2396
|
+
style.borderLeft = `${border.left.width} ${border.left.style} ${border.left.color}`;
|
|
2397
|
+
}
|
|
2398
|
+
return style;
|
|
2399
|
+
}
|
|
2213
2400
|
function Image({ config, devNode, devMode }) {
|
|
2214
|
-
const { src, alt, width, height, maxHeight, maxWidth, backgroundColor, padding, borderRadius, href, target, } = config;
|
|
2401
|
+
const { src, alt, width, height, maxHeight, maxWidth, backgroundColor, padding, borderRadius, border, href, target, } = config;
|
|
2402
|
+
// Get border styles
|
|
2403
|
+
const borderStyle = getBorderStyle$3(border);
|
|
2215
2404
|
// 1. Image Style: Critical for compatibility, especially display: block
|
|
2216
|
-
const imgStyle = {
|
|
2405
|
+
const imgStyle = Object.assign({
|
|
2217
2406
|
// Basic image properties
|
|
2218
|
-
display: "block",
|
|
2219
|
-
objectFit: "cover", // For controlling how the image fits (modern CSS, may be ignored)
|
|
2407
|
+
display: "block", objectFit: "cover",
|
|
2220
2408
|
// Dimensions (using CSS fallback)
|
|
2221
|
-
width: width || "100%",
|
|
2222
|
-
height: height || "auto",
|
|
2223
|
-
maxWidth: maxWidth || "100%",
|
|
2224
|
-
maxHeight: maxHeight,
|
|
2409
|
+
width: width || "100%", height: height || "auto", maxWidth: maxWidth || "100%", maxHeight: maxHeight,
|
|
2225
2410
|
// Styling
|
|
2226
|
-
border: "0",
|
|
2227
|
-
borderRadius: borderRadius,
|
|
2228
|
-
};
|
|
2411
|
+
border: "0", borderRadius: borderRadius }, borderStyle);
|
|
2229
2412
|
// 2. Link Style: Ensure no underline or color changes
|
|
2230
2413
|
const linkStyle = {
|
|
2231
2414
|
display: "block",
|
|
@@ -2277,13 +2460,27 @@ const alignMap = {
|
|
|
2277
2460
|
center: "middle",
|
|
2278
2461
|
end: "bottom",
|
|
2279
2462
|
};
|
|
2280
|
-
function getBorderStyle$
|
|
2463
|
+
function getBorderStyle$2(border) {
|
|
2281
2464
|
if (!border)
|
|
2282
2465
|
return {};
|
|
2283
2466
|
const style = {};
|
|
2467
|
+
// If a full border is specified, apply it
|
|
2284
2468
|
if (border.width && border.style && border.color) {
|
|
2285
2469
|
style.border = `${border.width} ${border.style} ${border.color}`;
|
|
2286
2470
|
}
|
|
2471
|
+
else {
|
|
2472
|
+
// If only individual borders are specified, explicitly set others to 'none'
|
|
2473
|
+
// to prevent Outlook Classic from showing black borders
|
|
2474
|
+
const hasIndividualBorders = border.top || border.right || border.bottom || border.left;
|
|
2475
|
+
if (hasIndividualBorders) {
|
|
2476
|
+
// Default all borders to none
|
|
2477
|
+
style.borderTop = "none";
|
|
2478
|
+
style.borderRight = "none";
|
|
2479
|
+
style.borderBottom = "none";
|
|
2480
|
+
style.borderLeft = "none";
|
|
2481
|
+
}
|
|
2482
|
+
}
|
|
2483
|
+
// Override with specific borders if provided
|
|
2287
2484
|
if (border.top) {
|
|
2288
2485
|
style.borderTop = `${border.top.width} ${border.top.style} ${border.top.color}`;
|
|
2289
2486
|
}
|
|
@@ -2298,23 +2495,50 @@ function getBorderStyle$1(border) {
|
|
|
2298
2495
|
}
|
|
2299
2496
|
return style;
|
|
2300
2497
|
}
|
|
2301
|
-
function
|
|
2302
|
-
|
|
2498
|
+
function getHrefFromInnerLink(innerLink) {
|
|
2499
|
+
if (!innerLink || innerLink.type === "none")
|
|
2500
|
+
return undefined;
|
|
2501
|
+
switch (innerLink.type) {
|
|
2502
|
+
case "url":
|
|
2503
|
+
return innerLink.url;
|
|
2504
|
+
case "email":
|
|
2505
|
+
return innerLink.email ? `mailto:${innerLink.email}` : undefined;
|
|
2506
|
+
case "phone":
|
|
2507
|
+
return innerLink.phone ? `tel:${innerLink.phone}` : undefined;
|
|
2508
|
+
case "anchor":
|
|
2509
|
+
return innerLink.anchor ? `#${innerLink.anchor}` : undefined;
|
|
2510
|
+
case "page_top":
|
|
2511
|
+
return "#";
|
|
2512
|
+
case "page_bottom":
|
|
2513
|
+
return "#bottom";
|
|
2514
|
+
default:
|
|
2515
|
+
return undefined;
|
|
2516
|
+
}
|
|
2517
|
+
}
|
|
2518
|
+
function Row({ children, config, devNode, devMode }) {
|
|
2519
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
2303
2520
|
const childrenArray = (Array.isArray(children) ? children : [children]).filter((child) => child != null);
|
|
2304
2521
|
const numChildren = childrenArray.length;
|
|
2305
|
-
|
|
2522
|
+
const href = getHrefFromInnerLink(config.innerLink);
|
|
2523
|
+
const target = (_a = config.innerLink) === null || _a === void 0 ? void 0 : _a.target;
|
|
2524
|
+
// 1. Outer TD for Background and Border Radius (no border here).
|
|
2525
|
+
// height declared here is the *total* outer height.
|
|
2306
2526
|
const backgroundTdStyle = Object.assign({ backgroundColor: config.backgroundColor, borderRadius: config.borderRadius, width: config.width || "100%", height: config.height,
|
|
2307
2527
|
// Background Image styles
|
|
2308
2528
|
backgroundImage: config.backgroundImage
|
|
2309
2529
|
? `url(${config.backgroundImage.src})`
|
|
2310
|
-
: undefined, backgroundRepeat: (
|
|
2311
|
-
// 2. Inner Table for Border and Border Radius
|
|
2312
|
-
|
|
2313
|
-
|
|
2530
|
+
: undefined, backgroundRepeat: (_b = config.backgroundImage) === null || _b === void 0 ? void 0 : _b.repeat, backgroundSize: (_c = config.backgroundImage) === null || _c === void 0 ? void 0 : _c.size, backgroundPosition: (_d = config.backgroundImage) === null || _d === void 0 ? void 0 : _d.position }, (config.borderRadius && { overflow: "hidden" }));
|
|
2531
|
+
// 2. Inner Table for Border and Border Radius.
|
|
2532
|
+
// height: 100% so it stretches to fill the outer TD.
|
|
2533
|
+
const borderTableStyle = Object.assign({ width: "100%", height: "100%", borderCollapse: "separate", borderSpacing: 0, borderRadius: config.borderRadius }, getBorderStyle$2(config.border));
|
|
2534
|
+
// 3. TD for Padding only — no height.
|
|
2535
|
+
// The outer TD owns the total height; setting height here would cause
|
|
2536
|
+
// browsers/email clients to treat it as content-box height and add
|
|
2537
|
+
// padding on top, making the row taller than the declared height.
|
|
2314
2538
|
const paddingTdStyle = {
|
|
2315
2539
|
padding: config.padding,
|
|
2316
2540
|
width: "100%",
|
|
2317
|
-
height
|
|
2541
|
+
// height intentionally omitted — padding must be inner, not additive
|
|
2318
2542
|
verticalAlign: "top",
|
|
2319
2543
|
};
|
|
2320
2544
|
// 4. Content Table - horizontal layout
|
|
@@ -2335,32 +2559,56 @@ function Row({ children, config, devNode }) {
|
|
|
2335
2559
|
? justifyMap$1[config.justifyContent]
|
|
2336
2560
|
: "left";
|
|
2337
2561
|
const tdValign = config.alignItems ? alignMap[config.alignItems] : "top";
|
|
2338
|
-
|
|
2562
|
+
// Content to render - wrapped in anchor if innerLink is defined
|
|
2563
|
+
const content = (jsxs("table", Object.assign({ "aria-label": "Row Outer", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: {
|
|
2339
2564
|
position: "relative",
|
|
2340
2565
|
width: config.width || "100%",
|
|
2341
2566
|
height: config.height,
|
|
2342
2567
|
borderCollapse: "collapse",
|
|
2343
|
-
} }, (config.height && { height: config.height }), {
|
|
2568
|
+
} }, (config.height && { height: config.height }), { children: [jsx("tbody", { children: jsx("tr", { children: jsx("td", Object.assign({ style: backgroundTdStyle }, (config.height && { height: config.height }), { children: jsx("table", { "aria-label": "Row Border Wrapper", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: borderTableStyle, children: jsx("tbody", { children: jsx("tr", { children: jsx("td", { style: paddingTdStyle, children: jsx("table", { "aria-label": "Row Justification Wrapper", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: {
|
|
2344
2569
|
width: "100%",
|
|
2345
2570
|
height: "100%",
|
|
2346
2571
|
borderCollapse: "collapse",
|
|
2347
|
-
}, children: jsx("tbody", { children: jsx("tr", { children: jsx("td", { align: tdAlign, children: jsx("table", Object.assign({ "aria-label": "Row Content", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: contentTableStyle }, (config.height && { height: config.height }), { className: "content-table", children: jsx("tbody", { children: jsx("tr", { className: "content-tr", children: childrenArray.map((child, index) => (jsxs(Fragment, { children: [jsx("td", { valign: tdValign, style: {
|
|
2572
|
+
}, children: jsx("tbody", { children: jsx("tr", { children: jsx("td", { align: tdAlign, children: jsx("table", Object.assign({ "aria-label": "Row Content", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: contentTableStyle }, (config.height && { height: config.height }), { className: "content-table row-content-table", "data-mobile-justify": (_e = config.mobile) === null || _e === void 0 ? void 0 : _e.justifyContent, "data-mobile-align": (_f = config.mobile) === null || _f === void 0 ? void 0 : _f.alignItems, "data-mobile-wrap": ((_g = config.mobile) === null || _g === void 0 ? void 0 : _g.wrap) ? "true" : undefined, "data-gap": config.gap, children: jsx("tbody", { children: jsx("tr", { className: "content-tr", children: childrenArray.map((child, index) => (jsxs(Fragment, { children: [jsx("td", { valign: tdValign, style: {
|
|
2348
2573
|
verticalAlign: tdValign,
|
|
2349
2574
|
textAlign: "left",
|
|
2350
2575
|
padding: "0",
|
|
2351
2576
|
margin: "0",
|
|
2352
2577
|
}, className: "child-cell", children: child }), index < numChildren - 1 &&
|
|
2353
2578
|
config.gap && (jsx("td", { width: config.gap, style: gapTdStyle, className: "row-gap-td", children: "\u00A0" }, `row-gap-${index}`))] }, `row-child-${index}`))) }) }) })) }) }) }) }) }) }) }) }) })) }) }), devNode && (jsx("tfoot", { children: jsx("tr", { children: jsx("td", { children: devNode }) }) }))] })));
|
|
2579
|
+
// Wrap in anchor tag if innerLink is defined and NOT in dev mode
|
|
2580
|
+
if (href && !devMode) {
|
|
2581
|
+
return (jsx("a", Object.assign({ href: href }, (target && { target }), { style: {
|
|
2582
|
+
textDecoration: "none",
|
|
2583
|
+
color: "inherit",
|
|
2584
|
+
display: "block",
|
|
2585
|
+
}, children: content })));
|
|
2586
|
+
}
|
|
2587
|
+
return content;
|
|
2354
2588
|
}
|
|
2355
2589
|
var Row_default = memo(Row, arePropsEqual);
|
|
2356
2590
|
|
|
2357
|
-
function getBorderStyle(border) {
|
|
2591
|
+
function getBorderStyle$1(border) {
|
|
2358
2592
|
if (!border)
|
|
2359
2593
|
return {};
|
|
2360
2594
|
const style = {};
|
|
2595
|
+
// If a full border is specified, apply it
|
|
2361
2596
|
if (border.width && border.style && border.color) {
|
|
2362
2597
|
style.border = `${border.width} ${border.style} ${border.color}`;
|
|
2363
2598
|
}
|
|
2599
|
+
else {
|
|
2600
|
+
// If only individual borders are specified, explicitly set others to 'none'
|
|
2601
|
+
// to prevent Outlook Classic from showing black borders
|
|
2602
|
+
const hasIndividualBorders = border.top || border.right || border.bottom || border.left;
|
|
2603
|
+
if (hasIndividualBorders) {
|
|
2604
|
+
// Default all borders to none
|
|
2605
|
+
style.borderTop = "none";
|
|
2606
|
+
style.borderRight = "none";
|
|
2607
|
+
style.borderBottom = "none";
|
|
2608
|
+
style.borderLeft = "none";
|
|
2609
|
+
}
|
|
2610
|
+
}
|
|
2611
|
+
// Override with specific borders if provided
|
|
2364
2612
|
if (border.top) {
|
|
2365
2613
|
style.borderTop = `${border.top.width} ${border.top.style} ${border.top.color}`;
|
|
2366
2614
|
}
|
|
@@ -2378,7 +2626,7 @@ function getBorderStyle(border) {
|
|
|
2378
2626
|
const Section = ({ config, children, devNode, }) => {
|
|
2379
2627
|
var _a, _b, _c;
|
|
2380
2628
|
const { sectionType, padding } = config;
|
|
2381
|
-
return (jsxs("table", { "aria-label": `Section |Table | ${sectionType}`, role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: Object.assign(Object.assign({ position: "relative", width: "100%", backgroundColor: config.backgroundColor }, getBorderStyle(config.border)), { backgroundImage: config.backgroundImage
|
|
2629
|
+
return (jsxs("table", { "aria-label": `Section |Table | ${sectionType}`, role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: Object.assign(Object.assign({ position: "relative", width: "100%", backgroundColor: config.backgroundColor }, getBorderStyle$1(config.border)), { backgroundImage: config.backgroundImage
|
|
2382
2630
|
? `url(${config.backgroundImage.src})`
|
|
2383
2631
|
: undefined, backgroundRepeat: (_a = config.backgroundImage) === null || _a === void 0 ? void 0 : _a.repeat, backgroundSize: (_b = config.backgroundImage) === null || _b === void 0 ? void 0 : _b.size, backgroundPosition: (_c = config.backgroundImage) === null || _c === void 0 ? void 0 : _c.position }), children: [jsx("tbody", { children: jsx("tr", { children: jsx("td", { style: {
|
|
2384
2632
|
padding: padding,
|
|
@@ -2395,7 +2643,7 @@ const Section = ({ config, children, devNode, }) => {
|
|
|
2395
2643
|
var Section_default = memo(Section, arePropsEqual);
|
|
2396
2644
|
|
|
2397
2645
|
function Spacer({ config, devNode }) {
|
|
2398
|
-
const { height } = config;
|
|
2646
|
+
const { height, hideOnMobile } = config;
|
|
2399
2647
|
// 1. Spacer Table Style
|
|
2400
2648
|
const spacerTableStyle = {
|
|
2401
2649
|
// Crucial for compatibility: Ensures no background or border interference
|
|
@@ -2403,7 +2651,6 @@ function Spacer({ config, devNode }) {
|
|
|
2403
2651
|
borderCollapse: "collapse",
|
|
2404
2652
|
border: "0",
|
|
2405
2653
|
width: "100%",
|
|
2406
|
-
// ✅ FIX: Use string literal indexing for MSO properties
|
|
2407
2654
|
// Note the CSS standard dash convention: 'mso-table-lspace'
|
|
2408
2655
|
// ["mso-table-lspace" as string]: "0pt",
|
|
2409
2656
|
["msoTableLspace"]: "0pt",
|
|
@@ -2424,14 +2671,14 @@ function Spacer({ config, devNode }) {
|
|
|
2424
2671
|
// Outer table ensures the spacer spans the full width of its container
|
|
2425
2672
|
jsxs("table", Object.assign({ "aria-label": "Vertical Spacer", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: Object.assign({
|
|
2426
2673
|
// --- Start dev
|
|
2427
|
-
position: "relative" }, spacerTableStyle) }, { height: spacerHeightAttribute }, { children: [jsx("tbody", { children: jsx("tr", { children: jsx("td", { style: spacerTdStyle,
|
|
2674
|
+
position: "relative" }, spacerTableStyle) }, { height: spacerHeightAttribute }, { className: hideOnMobile ? "hide-on-mobile" : undefined, children: [jsx("tbody", { children: jsx("tr", { children: jsx("td", { style: spacerTdStyle,
|
|
2428
2675
|
// Explicit height attribute
|
|
2429
2676
|
height: spacerHeightAttribute, children: "\u00A0" }) }) }), devNode && (jsx("tfoot", { children: jsx("tr", { children: jsx("td", { children: devNode }) }) }))] })));
|
|
2430
2677
|
}
|
|
2431
2678
|
var Spacer_default = memo(Spacer, arePropsEqual);
|
|
2432
2679
|
|
|
2433
2680
|
function Text({ config, devMode, children }) {
|
|
2434
|
-
const { text, padding, color, textAlign, fontSize, fontWeight, fontStyle, lineHeight, letterSpacing, textTransform, textDecoration, direction, verticalAlign, backgroundColor, opacity, whiteSpace, } = config;
|
|
2681
|
+
const { text, padding, color, textAlign, fontSize, fontWeight, fontStyle, lineHeight, letterSpacing, textTransform, textDecoration, direction, verticalAlign, backgroundColor, opacity, whiteSpace, wordBreak = "break-all", } = config;
|
|
2435
2682
|
// 1. TD Style: Where padding and background are reliably applied.
|
|
2436
2683
|
const tdStyle = {
|
|
2437
2684
|
padding: padding,
|
|
@@ -2454,6 +2701,7 @@ function Text({ config, devMode, children }) {
|
|
|
2454
2701
|
verticalAlign: verticalAlign,
|
|
2455
2702
|
opacity: opacity,
|
|
2456
2703
|
whiteSpace: whiteSpace,
|
|
2704
|
+
wordBreak: wordBreak,
|
|
2457
2705
|
margin: "0",
|
|
2458
2706
|
padding: "0",
|
|
2459
2707
|
fontFamily: "Arial, Helvetica, sans-serif",
|
|
@@ -2474,18 +2722,96 @@ const justifyMap = {
|
|
|
2474
2722
|
center: "center",
|
|
2475
2723
|
end: "right",
|
|
2476
2724
|
};
|
|
2725
|
+
function getBorderStyle(border) {
|
|
2726
|
+
if (!border)
|
|
2727
|
+
return {};
|
|
2728
|
+
const style = {};
|
|
2729
|
+
// If a full border is specified, apply it
|
|
2730
|
+
if (border.width && border.style && border.color) {
|
|
2731
|
+
style.border = `${border.width} ${border.style} ${border.color}`;
|
|
2732
|
+
}
|
|
2733
|
+
else {
|
|
2734
|
+
// If only individual borders are specified, explicitly set others to 'none'
|
|
2735
|
+
// to prevent Outlook Classic from showing black borders
|
|
2736
|
+
const hasIndividualBorders = border.top || border.right || border.bottom || border.left;
|
|
2737
|
+
if (hasIndividualBorders) {
|
|
2738
|
+
// Default all borders to none
|
|
2739
|
+
style.borderTop = "none";
|
|
2740
|
+
style.borderRight = "none";
|
|
2741
|
+
style.borderBottom = "none";
|
|
2742
|
+
style.borderLeft = "none";
|
|
2743
|
+
}
|
|
2744
|
+
}
|
|
2745
|
+
// Override with specific borders if provided
|
|
2746
|
+
if (border.top) {
|
|
2747
|
+
style.borderTop = `${border.top.width} ${border.top.style} ${border.top.color}`;
|
|
2748
|
+
}
|
|
2749
|
+
if (border.right) {
|
|
2750
|
+
style.borderRight = `${border.right.width} ${border.right.style} ${border.right.color}`;
|
|
2751
|
+
}
|
|
2752
|
+
if (border.bottom) {
|
|
2753
|
+
style.borderBottom = `${border.bottom.width} ${border.bottom.style} ${border.bottom.color}`;
|
|
2754
|
+
}
|
|
2755
|
+
if (border.left) {
|
|
2756
|
+
style.borderLeft = `${border.left.width} ${border.left.style} ${border.left.color}`;
|
|
2757
|
+
}
|
|
2758
|
+
return style;
|
|
2759
|
+
}
|
|
2760
|
+
function getBorderStyleString(border) {
|
|
2761
|
+
if (!border)
|
|
2762
|
+
return "";
|
|
2763
|
+
const styles = [];
|
|
2764
|
+
// If a full border is specified, apply it
|
|
2765
|
+
if (border.width && border.style && border.color) {
|
|
2766
|
+
styles.push(`border: ${border.width} ${border.style} ${border.color};`);
|
|
2767
|
+
}
|
|
2768
|
+
else {
|
|
2769
|
+
// If only individual borders are specified
|
|
2770
|
+
const hasIndividualBorders = border.top || border.right || border.bottom || border.left;
|
|
2771
|
+
if (hasIndividualBorders) {
|
|
2772
|
+
// Default all borders to none
|
|
2773
|
+
styles.push("border-top: none;");
|
|
2774
|
+
styles.push("border-right: none;");
|
|
2775
|
+
styles.push("border-bottom: none;");
|
|
2776
|
+
styles.push("border-left: none;");
|
|
2777
|
+
}
|
|
2778
|
+
}
|
|
2779
|
+
// Override with specific borders if provided
|
|
2780
|
+
if (border.top) {
|
|
2781
|
+
styles.push(`border-top: ${border.top.width} ${border.top.style} ${border.top.color};`);
|
|
2782
|
+
}
|
|
2783
|
+
if (border.right) {
|
|
2784
|
+
styles.push(`border-right: ${border.right.width} ${border.right.style} ${border.right.color};`);
|
|
2785
|
+
}
|
|
2786
|
+
if (border.bottom) {
|
|
2787
|
+
styles.push(`border-bottom: ${border.bottom.width} ${border.bottom.style} ${border.bottom.color};`);
|
|
2788
|
+
}
|
|
2789
|
+
if (border.left) {
|
|
2790
|
+
styles.push(`border-left: ${border.left.width} ${border.left.style} ${border.left.color};`);
|
|
2791
|
+
}
|
|
2792
|
+
return styles.join(" ");
|
|
2793
|
+
}
|
|
2477
2794
|
// Helper to build Iconify API URL
|
|
2478
2795
|
function buildIconifyUrl(config) {
|
|
2479
2796
|
const { iconIdentifier, height = 24, color = "000000", rotate = 0, rotateOrientation = "cw", } = config;
|
|
2480
2797
|
if (!iconIdentifier)
|
|
2481
2798
|
return null;
|
|
2799
|
+
// Parse height to extract numeric value
|
|
2800
|
+
const parseHeight = (h) => {
|
|
2801
|
+
if (typeof h === "number")
|
|
2802
|
+
return h;
|
|
2803
|
+
// Extract numeric value from string (e.g., "24px" -> 24)
|
|
2804
|
+
const match = String(h).match(/^(-?\d*\.?\d+)/);
|
|
2805
|
+
return match ? parseFloat(match[1]) : 24;
|
|
2806
|
+
};
|
|
2807
|
+
const numericHeight = parseHeight(height);
|
|
2482
2808
|
// Remove # from color if present
|
|
2483
2809
|
const cleanColor = color.replace("#", "");
|
|
2484
2810
|
// Build URL from template
|
|
2485
2811
|
const template = process.env.ICONIFY_API_IMAGE_URI ||
|
|
2486
2812
|
"https://iconify.pagenflow.com/api/image/{{height}}/{{color}}/{{rotate}}-{{rotate-orientation}}/{{icon-full-name}}.png";
|
|
2487
2813
|
return template
|
|
2488
|
-
.replace("{{height}}", String(
|
|
2814
|
+
.replace("{{height}}", String(numericHeight * 2))
|
|
2489
2815
|
.replace("{{color}}", cleanColor)
|
|
2490
2816
|
.replace("{{rotate}}", String(rotate))
|
|
2491
2817
|
.replace("{{rotate-orientation}}", rotateOrientation)
|
|
@@ -2515,12 +2841,15 @@ function buildLinkHref(innerLink) {
|
|
|
2515
2841
|
function Icon({ config, devNode, devMode, children }) {
|
|
2516
2842
|
const {
|
|
2517
2843
|
// base64Source,
|
|
2518
|
-
width, height, backgroundColor, padding = "0", borderRadius = "0", innerLink, justifyContent = "center", } = config;
|
|
2844
|
+
width, height, backgroundColor, padding = "0", borderRadius = "0", border, innerLink, justifyContent = "center", } = config;
|
|
2519
2845
|
// Determine icon source
|
|
2520
2846
|
const iconSrc = buildIconifyUrl(config);
|
|
2521
2847
|
const href = buildLinkHref(innerLink);
|
|
2522
2848
|
const target = (innerLink === null || innerLink === void 0 ? void 0 : innerLink.target) || "_self";
|
|
2523
2849
|
const align = justifyMap[justifyContent];
|
|
2850
|
+
// Get border styles
|
|
2851
|
+
const borderStyle = getBorderStyle(border);
|
|
2852
|
+
const borderStyleString = getBorderStyleString(border);
|
|
2524
2853
|
// Convert width/height to string with px if number
|
|
2525
2854
|
const widthStr = typeof width === "number" ? `${width}px` : width;
|
|
2526
2855
|
const heightStr = typeof height === "number" ? `${height}px` : height;
|
|
@@ -2541,6 +2870,7 @@ function Icon({ config, devNode, devMode, children }) {
|
|
|
2541
2870
|
border: 0, // No default border
|
|
2542
2871
|
width: widthStr || "auto",
|
|
2543
2872
|
height: heightStr || "auto",
|
|
2873
|
+
objectFit: "contain",
|
|
2544
2874
|
};
|
|
2545
2875
|
// 2. Link Style: No underline or color changes
|
|
2546
2876
|
const linkStyle = {
|
|
@@ -2549,14 +2879,21 @@ function Icon({ config, devNode, devMode, children }) {
|
|
|
2549
2879
|
border: 0,
|
|
2550
2880
|
outline: "none",
|
|
2551
2881
|
};
|
|
2552
|
-
// 3. TD Style:
|
|
2553
|
-
const
|
|
2554
|
-
padding: padding,
|
|
2882
|
+
// 3. Outer TD Style: Background and border-radius wrapper with border
|
|
2883
|
+
const outerTdStyle = {
|
|
2555
2884
|
backgroundColor: backgroundColor,
|
|
2556
|
-
fontSize: "0", // CRITICAL: Collapses extra space
|
|
2557
|
-
lineHeight: "0", // CRITICAL: Collapses extra space7
|
|
2558
2885
|
borderRadius: borderRadius,
|
|
2559
2886
|
overflow: "hidden",
|
|
2887
|
+
fontSize: "0",
|
|
2888
|
+
lineHeight: "0",
|
|
2889
|
+
};
|
|
2890
|
+
// 4. Inner Table Style: Apply border here with border-collapse: separate
|
|
2891
|
+
const innerTableStyle = Object.assign({ width: "100%", borderCollapse: "separate", borderSpacing: 0, borderRadius: borderRadius }, borderStyle);
|
|
2892
|
+
// 5. Inner TD Style: Padding
|
|
2893
|
+
const innerTdStyle = {
|
|
2894
|
+
padding: padding,
|
|
2895
|
+
fontSize: "0", // CRITICAL: Collapses extra space
|
|
2896
|
+
lineHeight: "0", // CRITICAL: Collapses extra space
|
|
2560
2897
|
};
|
|
2561
2898
|
// --- VML Calculation for Outlook Compatibility ---
|
|
2562
2899
|
const numericPadding = parseInt(padding.split(" ")[0] || "0", 10);
|
|
@@ -2573,15 +2910,19 @@ function Icon({ config, devNode, devMode, children }) {
|
|
|
2573
2910
|
const arcsize = numericBorderRadius > 0
|
|
2574
2911
|
? Math.min((numericBorderRadius / Math.min(vmlWidth, vmlHeight)) * 100, 100)
|
|
2575
2912
|
: 0;
|
|
2913
|
+
// VML stroke color for border
|
|
2914
|
+
const vmlStrokeColor = (border === null || border === void 0 ? void 0 : border.color) || vmlFillColor;
|
|
2915
|
+
const vmlStrokeWeight = (border === null || border === void 0 ? void 0 : border.width) ? parseInt(border.width, 10) : 0;
|
|
2916
|
+
const hasVmlStroke = vmlStrokeWeight > 0;
|
|
2576
2917
|
// Build VML code for Outlook
|
|
2577
2918
|
const vmlIcon = backgroundColor && numericBorderRadius > 0
|
|
2578
2919
|
? `
|
|
2579
2920
|
<!--[if mso]>
|
|
2580
|
-
<v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" ${href && !devMode ? `href="${href}"` : ""} style="height:${vmlHeight}px;width:${vmlWidth}px;v-text-anchor:middle;" arcsize="${arcsize}%" stroke="false" fillcolor="${vmlFillColor}">
|
|
2921
|
+
<v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" ${href && !devMode ? `href="${href}"` : ""} style="height:${vmlHeight}px;width:${vmlWidth}px;v-text-anchor:middle;" arcsize="${arcsize}%" ${hasVmlStroke ? `strokecolor="${vmlStrokeColor}" strokeweight="${vmlStrokeWeight}px"` : 'stroke="false"'} fillcolor="${vmlFillColor}">
|
|
2581
2922
|
<w:anchorlock/>
|
|
2582
2923
|
<v:textbox inset="0,0,0,0" style="text-align: center;">
|
|
2583
2924
|
<center style="padding:${padding};">
|
|
2584
|
-
<img src="${iconSrc || ""}" alt="" width="${widthNum || 24}" height="${heightNum || 24}" border="0" style="display:block;border:0;" />
|
|
2925
|
+
<img src="${iconSrc || ""}" alt="" width="${widthNum || 24}" height="${heightNum || 24}" border="0" style="display:block;border:0;object-fit:contain;" />
|
|
2585
2926
|
</center>
|
|
2586
2927
|
</v:textbox>
|
|
2587
2928
|
</v:roundrect>
|
|
@@ -2593,8 +2934,7 @@ function Icon({ config, devNode, devMode, children }) {
|
|
|
2593
2934
|
return null;
|
|
2594
2935
|
}
|
|
2595
2936
|
// Icon image element
|
|
2596
|
-
const iconElement = devMode && !!children ? (children) : iconSrc ? (jsx("img", { draggable: false, src: iconSrc, alt: ""
|
|
2597
|
-
, style: imgStyle, width: widthNum, height: heightNum, border: 0 })) : (jsx(Fragment$1, {}));
|
|
2937
|
+
const iconElement = devMode && !!children ? (children) : iconSrc ? (jsx("img", { draggable: false, src: iconSrc, alt: "", style: imgStyle, width: widthNum, height: heightNum, border: 0 })) : (jsx(Fragment$1, {}));
|
|
2598
2938
|
// Wrap in link if href exists and not in dev mode
|
|
2599
2939
|
const content = href && !devMode ? (jsx("a", Object.assign({ href: href, target: target, style: linkStyle }, (target === "_blank" ? { rel: "noopener noreferrer" } : {}), { children: iconElement }))) : (iconElement);
|
|
2600
2940
|
// Build the HTML content with VML support (only when NOT in dev mode)
|
|
@@ -2606,12 +2946,20 @@ function Icon({ config, devNode, devMode, children }) {
|
|
|
2606
2946
|
<table role="presentation" cellpadding="0" cellspacing="0" border="0" style="border-collapse: collapse; width: 100%;">
|
|
2607
2947
|
<tbody>
|
|
2608
2948
|
<tr>
|
|
2609
|
-
<td style="background-color: ${backgroundColor}; border-radius: ${borderRadius};
|
|
2610
|
-
${
|
|
2949
|
+
<td style="background-color: ${backgroundColor}; border-radius: ${borderRadius}; overflow: hidden; font-size: 0; line-height: 0;">
|
|
2950
|
+
<table role="presentation" cellpadding="0" cellspacing="0" border="0" style="border-collapse: separate; border-spacing: 0; border-radius: ${borderRadius}; width: 100%; ${borderStyleString}">
|
|
2951
|
+
<tbody>
|
|
2952
|
+
<tr>
|
|
2953
|
+
<td style="padding: ${padding}; font-size: 0; line-height: 0;">
|
|
2954
|
+
${href
|
|
2611
2955
|
? `<a href="${href}" target="${target}" style="display:block;text-decoration:none;border:0;outline:none;" ${target === "_blank" ? 'rel="noopener noreferrer"' : ""}>
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
: `<img draggable="false" src="${iconSrc}" alt="" width="${widthNum || 24}" height="${heightNum || 24}" border="0" style="display:block;border:0;width:${widthStr || "auto"};height:${heightStr || "auto"};" />`}
|
|
2956
|
+
<img draggable="false" src="${iconSrc}" alt="" width="${widthNum || 24}" height="${heightNum || 24}" border="0" style="display:block;border:0;width:${widthStr || "auto"};height:${heightStr || "auto"};object-fit:contain;" />
|
|
2957
|
+
</a>`
|
|
2958
|
+
: `<img draggable="false" src="${iconSrc}" alt="" width="${widthNum || 24}" height="${heightNum || 24}" border="0" style="display:block;border:0;width:${widthStr || "auto"};height:${heightStr || "auto"};object-fit:contain;" />`}
|
|
2959
|
+
</td>
|
|
2960
|
+
</tr>
|
|
2961
|
+
</tbody>
|
|
2962
|
+
</table>
|
|
2615
2963
|
</td>
|
|
2616
2964
|
</tr>
|
|
2617
2965
|
</tbody>
|
|
@@ -2623,7 +2971,7 @@ function Icon({ config, devNode, devMode, children }) {
|
|
|
2623
2971
|
// --- Start dev
|
|
2624
2972
|
position: "relative",
|
|
2625
2973
|
// --- End dev
|
|
2626
|
-
width:
|
|
2974
|
+
width: "auto",
|
|
2627
2975
|
borderCollapse: "collapse",
|
|
2628
2976
|
// base
|
|
2629
2977
|
boxSizing: "border-box",
|
|
@@ -2632,7 +2980,7 @@ function Icon({ config, devNode, devMode, children }) {
|
|
|
2632
2980
|
padding: 0,
|
|
2633
2981
|
}, onClick: devMode ? (e) => e.preventDefault() : undefined, children: [jsx("tbody", { children: jsx("tr", { children: useVML ? (jsx("td", { dangerouslySetInnerHTML: {
|
|
2634
2982
|
__html: htmlContent !== null && htmlContent !== void 0 ? htmlContent : "",
|
|
2635
|
-
} })) : (jsx("td", { style:
|
|
2983
|
+
} })) : (jsx("td", { style: outerTdStyle, align: align, children: jsx("table", { role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: innerTableStyle, children: jsx("tbody", { children: jsx("tr", { children: jsx("td", { style: innerTdStyle, align: align, children: content }) }) }) }) })) }) }), devMode && !!devNode && (jsx("tfoot", { children: jsx("tr", { children: jsx("td", { children: devNode }) }) }))] }));
|
|
2636
2984
|
}
|
|
2637
2985
|
var Icon_default = memo(Icon, arePropsEqual);
|
|
2638
2986
|
|