@pagenflow/email 1.4.3 → 1.4.5
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 +7 -2
- package/dist/components/Column.d.ts +1 -1
- package/dist/components/Container.d.ts +1 -1
- package/dist/components/Divider.d.ts +0 -5
- package/dist/components/Image.d.ts +13 -0
- package/dist/components/Row.d.ts +1 -1
- package/dist/components/Section.d.ts +1 -1
- package/dist/components/Text.d.ts +2 -1
- package/dist/index.cjs.js +183 -88
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +183 -88
- package/dist/index.esm.js.map +1 -1
- package/dist/types/IInnerLink.d.ts +17 -0
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -1537,6 +1537,27 @@ const justifyMap$3 = {
|
|
|
1537
1537
|
center: "center",
|
|
1538
1538
|
end: "right",
|
|
1539
1539
|
};
|
|
1540
|
+
// Helper to build link href based on innerLink type (mirrors Icon component)
|
|
1541
|
+
function buildLinkHref$2(innerLink) {
|
|
1542
|
+
if (!innerLink || innerLink.type === "none")
|
|
1543
|
+
return null;
|
|
1544
|
+
switch (innerLink.type) {
|
|
1545
|
+
case "url":
|
|
1546
|
+
return innerLink.url || null;
|
|
1547
|
+
case "email":
|
|
1548
|
+
return innerLink.email ? `mailto:${innerLink.email}` : null;
|
|
1549
|
+
case "phone":
|
|
1550
|
+
return innerLink.phone ? `tel:${innerLink.phone}` : null;
|
|
1551
|
+
case "anchor":
|
|
1552
|
+
return innerLink.anchor ? `#${innerLink.anchor}` : null;
|
|
1553
|
+
case "page_top":
|
|
1554
|
+
return "#top";
|
|
1555
|
+
case "page_bottom":
|
|
1556
|
+
return "#bottom";
|
|
1557
|
+
default:
|
|
1558
|
+
return null;
|
|
1559
|
+
}
|
|
1560
|
+
}
|
|
1540
1561
|
function getBorderStyleString$2(border) {
|
|
1541
1562
|
if (!border)
|
|
1542
1563
|
return "";
|
|
@@ -1572,8 +1593,10 @@ function getBorderStyleString$2(border) {
|
|
|
1572
1593
|
return styles.join(" ");
|
|
1573
1594
|
}
|
|
1574
1595
|
function Button({ config, devMode }) {
|
|
1575
|
-
const {
|
|
1576
|
-
|
|
1596
|
+
const { innerLink, children, backgroundColor, color, padding, borderRadius, border, width, maxWidth, justifyContent, textAlign, fontSize, fontWeight, fontStyle, fontFamily, lineHeight, letterSpacing, textTransform, textDecoration, direction, verticalAlign, opacity, whiteSpace, wordBreak, } = config;
|
|
1597
|
+
// Resolve href from innerLink
|
|
1598
|
+
const href = buildLinkHref$2(innerLink);
|
|
1599
|
+
const target = (innerLink === null || innerLink === void 0 ? void 0 : innerLink.target) || "_blank";
|
|
1577
1600
|
// Sanitize fontFamily early so safeFontFamily is available for all paths below.
|
|
1578
1601
|
const safeFontFamily = fontFamily
|
|
1579
1602
|
? fontFamily.replace(/['"]/g, "")
|
|
@@ -1593,23 +1616,27 @@ function Button({ config, devMode }) {
|
|
|
1593
1616
|
// Check if width is percentage-based or not defined
|
|
1594
1617
|
const isPercentageWidth = !width || width.includes("%");
|
|
1595
1618
|
const useSimpleOutlookApproach = isPercentageWidth;
|
|
1596
|
-
const align = justifyMap$3[justifyContent];
|
|
1619
|
+
const align = justifyContent ? justifyMap$3[justifyContent] : undefined;
|
|
1597
1620
|
// --- VML Calculation and Code for Outlook Compatibility (Fixed Width Only) ---
|
|
1598
1621
|
let vmlButton = "";
|
|
1599
1622
|
if (!useSimpleOutlookApproach) {
|
|
1600
1623
|
// VML needs fixed pixel height. We estimate it based on padding and potential wrapping.
|
|
1601
|
-
const numericPadding =
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1624
|
+
const numericPadding = padding
|
|
1625
|
+
? parseInt(padding.split(" ")[0] || "12", 10)
|
|
1626
|
+
: 12;
|
|
1627
|
+
const numericFontSize = fontSize ? parseInt(fontSize, 10) : 0;
|
|
1628
|
+
const numericLineHeight = lineHeight
|
|
1629
|
+
? lineHeight.includes("px")
|
|
1630
|
+
? parseInt(lineHeight, 10)
|
|
1631
|
+
: numericFontSize * parseFloat(lineHeight)
|
|
1632
|
+
: numericFontSize;
|
|
1606
1633
|
// Trust user's explicit pixel width - no calculation needed
|
|
1607
1634
|
const vmlWidth = parseInt(width, 10);
|
|
1608
1635
|
// Calculate VML height - trust user's padding and let text wrap naturally
|
|
1609
1636
|
// VML v:textbox will handle text wrapping automatically
|
|
1610
1637
|
const textContent = typeof children === "string" ? children : "";
|
|
1611
1638
|
// Estimate number of lines based on text length and button width
|
|
1612
|
-
const horizontalPadding = padding.split(" ")[1]
|
|
1639
|
+
const horizontalPadding = (padding === null || padding === void 0 ? void 0 : padding.split(" ")[1])
|
|
1613
1640
|
? parseInt(padding.split(" ")[1], 10) * 2
|
|
1614
1641
|
: numericPadding * 2;
|
|
1615
1642
|
const availableTextWidth = vmlWidth - horizontalPadding;
|
|
@@ -1622,15 +1649,17 @@ function Button({ config, devMode }) {
|
|
|
1622
1649
|
// Add extra 4px buffer to prevent bottom cropping in VML
|
|
1623
1650
|
const vmlHeight = Math.max(numericPadding * 2 + textHeight + 4, 40);
|
|
1624
1651
|
// VML colors must use the full hex format (e.g., #000000)
|
|
1625
|
-
const vmlFillColor = backgroundColor
|
|
1626
|
-
? backgroundColor
|
|
1627
|
-
|
|
1652
|
+
const vmlFillColor = backgroundColor
|
|
1653
|
+
? backgroundColor.startsWith("#")
|
|
1654
|
+
? backgroundColor
|
|
1655
|
+
: `#${backgroundColor}`
|
|
1656
|
+
: undefined;
|
|
1628
1657
|
// VML stroke color for border
|
|
1629
1658
|
const vmlStrokeColor = (border === null || border === void 0 ? void 0 : border.color) || vmlFillColor;
|
|
1630
1659
|
const vmlStrokeWeight = (border === null || border === void 0 ? void 0 : border.width) ? parseInt(border.width, 10) : 0;
|
|
1631
1660
|
const hasVmlStroke = vmlStrokeWeight > 0;
|
|
1632
1661
|
// Build VML font styles - consistent with other rendering paths
|
|
1633
|
-
const vmlFontWeight = fontWeight
|
|
1662
|
+
const vmlFontWeight = fontWeight;
|
|
1634
1663
|
const vmlFontStyle = fontStyle === "italic" ? "font-style:italic;" : "";
|
|
1635
1664
|
const vmlLetterSpacing = letterSpacing
|
|
1636
1665
|
? `letter-spacing:${letterSpacing};`
|
|
@@ -1641,12 +1670,12 @@ function Button({ config, devMode }) {
|
|
|
1641
1670
|
const vmlTextDecoration = textDecoration && textDecoration !== "none"
|
|
1642
1671
|
? `text-decoration:${textDecoration};`
|
|
1643
1672
|
: "";
|
|
1644
|
-
const vmlWhiteSpace = whiteSpace
|
|
1673
|
+
const vmlWhiteSpace = whiteSpace ? `white-space:${whiteSpace};` : "";
|
|
1645
1674
|
const vmlDirection = direction ? `direction:${direction};` : "";
|
|
1646
1675
|
const vmlOpacity = opacity !== undefined ? `opacity:${opacity};` : "";
|
|
1647
1676
|
// VML code uses MSO conditional comments to render only in Outlook
|
|
1648
1677
|
// Use table with explicit MSO height for vertical centering
|
|
1649
|
-
const horizontalPaddingValue = padding.split(" ")[1]
|
|
1678
|
+
const horizontalPaddingValue = (padding === null || padding === void 0 ? void 0 : padding.split(" ")[1])
|
|
1650
1679
|
? parseInt(padding.split(" ")[1], 10)
|
|
1651
1680
|
: numericPadding;
|
|
1652
1681
|
// For VML, we need to use a table inside to properly apply padding and centering
|
|
@@ -1655,7 +1684,7 @@ function Button({ config, devMode }) {
|
|
|
1655
1684
|
if (textAlign === "center") {
|
|
1656
1685
|
vmlAlignAttr = 'align="center"';
|
|
1657
1686
|
}
|
|
1658
|
-
else {
|
|
1687
|
+
else if (textAlign) {
|
|
1659
1688
|
vmlAlignStyle = `text-align:${textAlign};`;
|
|
1660
1689
|
}
|
|
1661
1690
|
// Border radius is intentionally omitted (arcsize="0%") for Outlook Classic.
|
|
@@ -1663,12 +1692,12 @@ function Button({ config, devMode }) {
|
|
|
1663
1692
|
// is inconsistent, so we render sharp corners there instead.
|
|
1664
1693
|
vmlButton = `
|
|
1665
1694
|
<!--[if mso]>
|
|
1666
|
-
<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="0%" strokecolor="${vmlStrokeColor}" ${hasVmlStroke ? `strokeweight="${vmlStrokeWeight}px"` : 'stroke="f"'} fillcolor="${vmlFillColor}">
|
|
1695
|
+
<v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" ${href ? `href="${href}"` : ""} style="height:${vmlHeight}px;width:${vmlWidth}px;" arcsize="0%" ${vmlStrokeColor ? `strokecolor="${vmlStrokeColor}"` : ""} ${hasVmlStroke ? `strokeweight="${vmlStrokeWeight}px"` : 'stroke="f"'} ${vmlFillColor ? `fillcolor="${vmlFillColor}"` : ""}>
|
|
1667
1696
|
<w:anchorlock/>
|
|
1668
1697
|
<v:textbox inset="${horizontalPaddingValue}px,${numericPadding}px,${horizontalPaddingValue}px,${numericPadding}px">
|
|
1669
1698
|
<table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%" style="border-collapse:collapse;">
|
|
1670
1699
|
<tr>
|
|
1671
|
-
<td ${vmlAlignAttr} valign="middle" style="${vmlAlignStyle}color:${color}
|
|
1700
|
+
<td ${vmlAlignAttr} valign="middle" style="${vmlAlignStyle}${color ? `color:${color};` : ""}${safeFontFamily ? `font-family:${safeFontFamily};` : ""}${fontSize ? `font-size:${fontSize};` : ""}${vmlFontWeight ? `font-weight:${vmlFontWeight};` : ""}${vmlFontStyle}${vmlLetterSpacing}${vmlTextTransform}${vmlTextDecoration}${vmlWhiteSpace}${vmlDirection}${vmlOpacity}${lineHeight ? `line-height:${lineHeight};` : ""}mso-line-height-rule:exactly;">
|
|
1672
1701
|
${typeof children === "string" ? children : ""}
|
|
1673
1702
|
</td>
|
|
1674
1703
|
</tr>
|
|
@@ -1692,10 +1721,10 @@ function Button({ config, devMode }) {
|
|
|
1692
1721
|
const textTransformProp = textTransform
|
|
1693
1722
|
? `text-transform: ${textTransform};`
|
|
1694
1723
|
: "";
|
|
1695
|
-
const whiteSpaceProp = whiteSpace
|
|
1724
|
+
const whiteSpaceProp = whiteSpace ? `white-space: ${whiteSpace};` : "";
|
|
1696
1725
|
const directionProp = direction ? `direction: ${direction};` : "";
|
|
1697
1726
|
const opacityProp = opacity !== undefined ? `opacity: ${opacity};` : "";
|
|
1698
|
-
const wordBreakProp = wordBreak
|
|
1727
|
+
const wordBreakProp = wordBreak ? `word-break: ${wordBreak};` : "";
|
|
1699
1728
|
// Border radius is intentionally omitted from the Outlook Classic table cell.
|
|
1700
1729
|
// Outlook Classic ignores border-radius on table cells anyway, and including it
|
|
1701
1730
|
// can cause unexpected rendering artifacts, so we explicitly leave it out.
|
|
@@ -1703,13 +1732,17 @@ function Button({ config, devMode }) {
|
|
|
1703
1732
|
<!--[if mso]>
|
|
1704
1733
|
<table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%" style="border-collapse: collapse;">
|
|
1705
1734
|
<tr>
|
|
1706
|
-
<td align="${align}" style="padding: 0;">
|
|
1735
|
+
<td ${align ? `align="${align}"` : ""} style="padding: 0;">
|
|
1707
1736
|
<table role="presentation" cellpadding="0" cellspacing="0" border="0" width="${width || "auto"}" style="border-collapse: collapse;">
|
|
1708
1737
|
<tr>
|
|
1709
|
-
<td bgcolor="${backgroundColor}" align="${textAlign}" style="padding: ${padding}
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1738
|
+
<td ${backgroundColor ? `bgcolor="${backgroundColor}"` : ""} ${textAlign ? `align="${textAlign}"` : ""} style="${padding ? `padding: ${padding};` : ""} ${textAlign ? `text-align: ${textAlign};` : ""} ${borderStyleString}">
|
|
1739
|
+
${href
|
|
1740
|
+
? `<a href="${href}" target="${target}" rel="noopener noreferrer" style="${color ? `color: ${color};` : ""} ${textDecorationStyle} display: block; ${safeFontFamily ? `font-family: ${safeFontFamily};` : ""} ${fontSize ? `font-size: ${fontSize};` : ""} ${fontWeight ? `font-weight: ${fontWeight};` : ""} ${fontStyleProp} ${lineHeight ? `line-height: ${lineHeight};` : ""} ${letterSpacingProp} ${textTransformProp} ${textAlign ? `text-align: ${textAlign};` : ""} ${whiteSpaceProp} ${directionProp} ${opacityProp} ${wordBreakProp} mso-line-height-rule: exactly;">
|
|
1741
|
+
${typeof children === "string" ? children : ""}
|
|
1742
|
+
</a>`
|
|
1743
|
+
: `<span style="${color ? `color: ${color};` : ""} ${textDecorationStyle} display: block; ${safeFontFamily ? `font-family: ${safeFontFamily};` : ""} ${fontSize ? `font-size: ${fontSize};` : ""} ${fontWeight ? `font-weight: ${fontWeight};` : ""} ${fontStyleProp} ${lineHeight ? `line-height: ${lineHeight};` : ""} ${letterSpacingProp} ${textTransformProp} ${textAlign ? `text-align: ${textAlign};` : ""} ${whiteSpaceProp} ${directionProp} ${opacityProp} ${wordBreakProp} mso-line-height-rule: exactly;">
|
|
1744
|
+
${typeof children === "string" ? children : ""}
|
|
1745
|
+
</span>`}
|
|
1713
1746
|
</td>
|
|
1714
1747
|
</tr>
|
|
1715
1748
|
</table>
|
|
@@ -1723,7 +1756,7 @@ function Button({ config, devMode }) {
|
|
|
1723
1756
|
// fontFamily uses the sanitized value so embedded quotes never break the
|
|
1724
1757
|
// style attribute string (which is always wrapped in double quotes).
|
|
1725
1758
|
const sharedTextStyles = [
|
|
1726
|
-
`color: ${color}
|
|
1759
|
+
color ? `color: ${color};` : "",
|
|
1727
1760
|
safeFontFamily ? `font-family: ${safeFontFamily};` : "",
|
|
1728
1761
|
fontSize ? `font-size: ${fontSize};` : "",
|
|
1729
1762
|
fontWeight ? `font-weight: ${fontWeight};` : "",
|
|
@@ -1736,7 +1769,7 @@ function Button({ config, devMode }) {
|
|
|
1736
1769
|
: "",
|
|
1737
1770
|
direction ? `direction: ${direction};` : "",
|
|
1738
1771
|
opacity !== undefined ? `opacity: ${opacity};` : "",
|
|
1739
|
-
whiteSpace
|
|
1772
|
+
whiteSpace ? `white-space: ${whiteSpace};` : "",
|
|
1740
1773
|
]
|
|
1741
1774
|
.filter(Boolean)
|
|
1742
1775
|
.join(" ");
|
|
@@ -1770,20 +1803,24 @@ function Button({ config, devMode }) {
|
|
|
1770
1803
|
<table role="presentation" cellpadding="0" cellspacing="0" border="0" style="border-collapse: collapse; width: 100%;">
|
|
1771
1804
|
<tbody>
|
|
1772
1805
|
<tr>
|
|
1773
|
-
<td style="background-color: ${backgroundTdStyle.backgroundColor}
|
|
1774
|
-
<table role="presentation" cellpadding="0" cellspacing="0" border="0" style="border-collapse: separate; border-spacing: 0; border-radius: ${borderRadius}
|
|
1806
|
+
<td style="${backgroundTdStyle.backgroundColor ? `background-color: ${backgroundTdStyle.backgroundColor};` : ""} ${backgroundTdStyle.borderRadius ? `border-radius: ${backgroundTdStyle.borderRadius};` : ""} width: ${backgroundTdStyle.width}; ${maxWidth ? `max-width: ${maxWidth};` : ""} ${borderRadius ? "overflow: hidden;" : ""}">
|
|
1807
|
+
<table role="presentation" cellpadding="0" cellspacing="0" border="0" style="border-collapse: separate; border-spacing: 0; ${borderRadius ? `border-radius: ${borderRadius};` : ""} width: 100%; ${borderStyleString}">
|
|
1775
1808
|
<tbody>
|
|
1776
1809
|
<tr>
|
|
1777
1810
|
<td style="padding: 0;">
|
|
1778
1811
|
${devMode
|
|
1779
|
-
? `<span style="${sharedTextStyles} ${textDecoration && textDecoration !== "none" ? "" : "text-decoration: none;"} display: block; word-break: ${wordBreak}
|
|
1812
|
+
? `<span style="${sharedTextStyles} ${textDecoration && textDecoration !== "none" ? "" : "text-decoration: none;"} display: block; ${wordBreak ? `word-break: ${wordBreak};` : ""} ${textAlign ? `text-align: ${textAlign};` : ""} ${padding ? `padding: ${padding};` : ""}">
|
|
1780
1813
|
${typeof children === "string" ? children : ""}
|
|
1781
1814
|
</span>`
|
|
1782
|
-
:
|
|
1783
|
-
|
|
1815
|
+
: href
|
|
1816
|
+
? `<a href="${href}" target="${target}" rel="noopener noreferrer" style="${sharedTextStyles} ${textDecoration && textDecoration !== "none" ? "" : "text-decoration: none;"} display: block; ${wordBreak ? `word-break: ${wordBreak};` : ""} ${textAlign ? `text-align: ${textAlign};` : ""} ${padding ? `padding: ${padding};` : ""}">
|
|
1817
|
+
<span>
|
|
1818
|
+
${typeof children === "string" ? children : ""}
|
|
1819
|
+
</span>
|
|
1820
|
+
</a>`
|
|
1821
|
+
: `<span style="${sharedTextStyles} ${textDecoration && textDecoration !== "none" ? "" : "text-decoration: none;"} display: block; ${wordBreak ? `word-break: ${wordBreak};` : ""} ${textAlign ? `text-align: ${textAlign};` : ""} ${padding ? `padding: ${padding};` : ""}">
|
|
1784
1822
|
${typeof children === "string" ? children : ""}
|
|
1785
|
-
</span
|
|
1786
|
-
</a>`}
|
|
1823
|
+
</span>`}
|
|
1787
1824
|
</td>
|
|
1788
1825
|
</tr>
|
|
1789
1826
|
</tbody>
|
|
@@ -2102,40 +2139,48 @@ var Container_default = memo(Container, arePropsEqual);
|
|
|
2102
2139
|
|
|
2103
2140
|
function Divider({ config, devNode }) {
|
|
2104
2141
|
const { height = "1px", color = "#cccccc", width = "100%", margin = "20px 0", align = "center", hideOnMobile, } = config;
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
//
|
|
2113
|
-
const
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
backgroundColor: color,
|
|
2117
|
-
borderCollapse: "collapse",
|
|
2118
|
-
border: "0",
|
|
2119
|
-
// ✅ FIX 1: Use string literal indexing for MSO properties
|
|
2120
|
-
// ["mso-table-lspace" as string]: "0pt",
|
|
2121
|
-
["msoTableLspace"]: "0pt",
|
|
2122
|
-
// ["mso-table-rspace" as string]: "0pt",
|
|
2123
|
-
["msoTableRspace"]: "0pt",
|
|
2124
|
-
};
|
|
2125
|
-
// Parse height for the HTML attribute
|
|
2126
|
-
const dividerHeightAttribute = parseInt(height, 10) || 1;
|
|
2127
|
-
return (jsxs("table", { "aria-label": "Divider Wrapper", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: {
|
|
2128
|
-
// --- Start dev
|
|
2129
|
-
position: "relative",
|
|
2130
|
-
// --- End dev
|
|
2142
|
+
const heightPx = parseInt(height, 10) || 1;
|
|
2143
|
+
// Parse margin into paddingTop / paddingBottom for the outer TD.
|
|
2144
|
+
// Outlook ignores shorthand "20px 0" on TDs — must be explicit.
|
|
2145
|
+
const [marginTopRaw = "0", marginRightRaw = "0", marginBottomRaw, marginLeftRaw] = margin.trim().split(/\s+/);
|
|
2146
|
+
const marginTop = marginTopRaw;
|
|
2147
|
+
const marginBottom = marginBottomRaw !== null && marginBottomRaw !== void 0 ? marginBottomRaw : marginTopRaw; // "20px 0" → top=20px, bottom=20px
|
|
2148
|
+
// Outlook requires align on the outer TD to correctly position
|
|
2149
|
+
// a fixed-width inner table (e.g. width="300px").
|
|
2150
|
+
const alignAttr = align === "left" ? "left" : align === "right" ? "right" : "center";
|
|
2151
|
+
return (jsxs("table", { role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: {
|
|
2152
|
+
position: "relative", // dev overlay anchor
|
|
2131
2153
|
width: "100%",
|
|
2132
2154
|
borderCollapse: "collapse",
|
|
2133
|
-
|
|
2155
|
+
border: "0",
|
|
2156
|
+
}, className: hideOnMobile ? "hide-on-mobile" : undefined, children: [jsx("tbody", { children: jsx("tr", { children: jsx("td", { align: alignAttr, style: {
|
|
2157
|
+
paddingTop: marginTop,
|
|
2158
|
+
paddingBottom: marginBottom,
|
|
2159
|
+
paddingLeft: "0",
|
|
2160
|
+
paddingRight: "0",
|
|
2161
|
+
fontSize: "0",
|
|
2162
|
+
lineHeight: "0",
|
|
2163
|
+
}, children: jsx("table", { role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, align: alignAttr, style: {
|
|
2164
|
+
width: width,
|
|
2165
|
+
borderCollapse: "collapse",
|
|
2166
|
+
border: "0",
|
|
2167
|
+
}, children: jsx("tbody", { children: jsx("tr", { children: jsx("td", { ...{ height: heightPx }, ref: (el) => {
|
|
2168
|
+
if (!el)
|
|
2169
|
+
return;
|
|
2170
|
+
el.setAttribute("style", `height:${height};` +
|
|
2171
|
+
`line-height:${height};` +
|
|
2172
|
+
`font-size:0;` +
|
|
2173
|
+
`padding:0;` +
|
|
2174
|
+
`background-color:${color};` +
|
|
2175
|
+
`mso-line-height-rule:exactly;`);
|
|
2176
|
+
}, style: {
|
|
2177
|
+
// Fallback for non-Outlook clients (React-rendered style object).
|
|
2134
2178
|
height: height,
|
|
2179
|
+
lineHeight: height,
|
|
2135
2180
|
fontSize: "0",
|
|
2136
|
-
lineHeight: "0",
|
|
2137
2181
|
padding: "0",
|
|
2138
|
-
|
|
2182
|
+
backgroundColor: color,
|
|
2183
|
+
} }) }) }) }) }) }) }), devNode && (jsx("tfoot", { children: jsx("tr", { children: jsx("td", { children: devNode }) }) }))] }));
|
|
2139
2184
|
}
|
|
2140
2185
|
var Divider_default = memo(Divider, arePropsEqual);
|
|
2141
2186
|
|
|
@@ -2380,6 +2425,27 @@ function Html({ children, backgroundColor = "#ffffff", }) {
|
|
|
2380
2425
|
);
|
|
2381
2426
|
}
|
|
2382
2427
|
|
|
2428
|
+
// Helper to build link href based on innerLink type
|
|
2429
|
+
function buildLinkHref$1(innerLink) {
|
|
2430
|
+
if (!innerLink || innerLink.type === "none")
|
|
2431
|
+
return null;
|
|
2432
|
+
switch (innerLink.type) {
|
|
2433
|
+
case "url":
|
|
2434
|
+
return innerLink.url || null;
|
|
2435
|
+
case "email":
|
|
2436
|
+
return innerLink.email ? `mailto:${innerLink.email}` : null;
|
|
2437
|
+
case "phone":
|
|
2438
|
+
return innerLink.phone ? `tel:${innerLink.phone}` : null;
|
|
2439
|
+
case "anchor":
|
|
2440
|
+
return innerLink.anchor ? `#${innerLink.anchor}` : null;
|
|
2441
|
+
case "page_top":
|
|
2442
|
+
return "#top";
|
|
2443
|
+
case "page_bottom":
|
|
2444
|
+
return "#bottom";
|
|
2445
|
+
default:
|
|
2446
|
+
return null;
|
|
2447
|
+
}
|
|
2448
|
+
}
|
|
2383
2449
|
function getBorderStyle$3(border) {
|
|
2384
2450
|
if (!border)
|
|
2385
2451
|
return {};
|
|
@@ -2422,7 +2488,10 @@ function getBorderStyleString$1(border) {
|
|
|
2422
2488
|
}
|
|
2423
2489
|
function Image({ config, devNode, devMode }) {
|
|
2424
2490
|
var _a, _b;
|
|
2425
|
-
const { src, alt,
|
|
2491
|
+
const { src, alt, innerLink, mobile } = config;
|
|
2492
|
+
// Resolve href and target from innerLink
|
|
2493
|
+
const href = buildLinkHref$1(innerLink);
|
|
2494
|
+
const target = (innerLink === null || innerLink === void 0 ? void 0 : innerLink.target) || "_blank";
|
|
2426
2495
|
const seed = src + (alt || "");
|
|
2427
2496
|
const instanceId = seed
|
|
2428
2497
|
.split("")
|
|
@@ -2452,32 +2521,56 @@ function Image({ config, devNode, devMode }) {
|
|
|
2452
2521
|
? parseInt(config.maxWidth, 10)
|
|
2453
2522
|
: undefined;
|
|
2454
2523
|
const imgWidthAttr = isPercent ? (maxWidthPx !== null && maxWidthPx !== void 0 ? maxWidthPx : undefined) : widthAttr;
|
|
2455
|
-
// 2. Mobile Overrides
|
|
2524
|
+
// 2. Mobile Overrides — only emit CSS properties that are explicitly set,
|
|
2525
|
+
// so unspecified properties are left untouched (no forced defaults).
|
|
2456
2526
|
let mobileCss = "";
|
|
2457
2527
|
if (mobile) {
|
|
2528
|
+
// .wrap-${imgClass} rules
|
|
2529
|
+
const wrapRules = [
|
|
2530
|
+
// Always reset min-width so the px lock from desktop can be overridden
|
|
2531
|
+
"min-width: 0 !important;",
|
|
2532
|
+
];
|
|
2533
|
+
if (mobile.width !== undefined)
|
|
2534
|
+
wrapRules.push(`width: ${mobile.width} !important;`);
|
|
2535
|
+
if (mobile.maxWidth !== undefined)
|
|
2536
|
+
wrapRules.push(`max-width: ${mobile.maxWidth} !important;`);
|
|
2537
|
+
// .td-${imgClass} rules
|
|
2538
|
+
const tdRules = [];
|
|
2539
|
+
if (mobile.padding !== undefined)
|
|
2540
|
+
tdRules.push(`padding: ${mobile.padding} !important;`);
|
|
2541
|
+
if (mobile.backgroundColor !== undefined)
|
|
2542
|
+
tdRules.push(`background-color: ${mobile.backgroundColor} !important;`);
|
|
2543
|
+
// .${imgClass} rules
|
|
2544
|
+
const imgRules = [];
|
|
2545
|
+
if (mobile.width !== undefined)
|
|
2546
|
+
imgRules.push(`width: ${mobile.width} !important;`);
|
|
2547
|
+
if (mobile.height !== undefined)
|
|
2548
|
+
imgRules.push(`height: ${mobile.height} !important;`);
|
|
2549
|
+
if (mobile.maxWidth !== undefined)
|
|
2550
|
+
imgRules.push(`max-width: ${mobile.maxWidth} !important;`);
|
|
2551
|
+
if (mobile.maxHeight !== undefined)
|
|
2552
|
+
imgRules.push(`max-height: ${mobile.maxHeight} !important;`);
|
|
2553
|
+
if (mobile.borderRadius !== undefined)
|
|
2554
|
+
imgRules.push(`border-radius: ${mobile.borderRadius} !important;`);
|
|
2555
|
+
if (mobile.hidden !== undefined)
|
|
2556
|
+
imgRules.push(`display: ${mobile.hidden ? "none" : "block"} !important;`);
|
|
2557
|
+
if (mobile.objectFit !== undefined)
|
|
2558
|
+
imgRules.push(`object-fit: ${mobile.objectFit} !important;`);
|
|
2559
|
+
if (mobile.objectPosition !== undefined)
|
|
2560
|
+
imgRules.push(`object-position: ${mobile.objectPosition} !important;`);
|
|
2561
|
+
if (mobile.border !== undefined)
|
|
2562
|
+
imgRules.push(getBorderStyleString$1(mobile.border));
|
|
2458
2563
|
mobileCss = `
|
|
2459
2564
|
@media screen and (max-width: 768px) {
|
|
2460
2565
|
.wrap-${imgClass} {
|
|
2461
2566
|
/* This breaks the px lock from desktop and makes it fluid */
|
|
2462
|
-
|
|
2463
|
-
max-width: ${mobile.maxWidth || "100%"} !important;
|
|
2464
|
-
min-width: 0 !important;
|
|
2567
|
+
${wrapRules.join("\n ")}
|
|
2465
2568
|
}
|
|
2466
2569
|
.td-${imgClass} {
|
|
2467
|
-
|
|
2468
|
-
background-color: ${mobile.backgroundColor || "transparent"} !important;
|
|
2469
|
-
width: 100% !important;
|
|
2570
|
+
${tdRules.join("\n ")}
|
|
2470
2571
|
}
|
|
2471
2572
|
.${imgClass} {
|
|
2472
|
-
|
|
2473
|
-
height: ${mobile.height || "auto"} !important;
|
|
2474
|
-
max-width: ${mobile.maxWidth || "100%"} !important;
|
|
2475
|
-
max-height: ${mobile.maxHeight || "none"} !important;
|
|
2476
|
-
border-radius: ${mobile.borderRadius || "0"} !important;
|
|
2477
|
-
display: ${mobile.hidden ? "none" : "block"} !important;
|
|
2478
|
-
object-fit: ${mobile.objectFit || "fill"} !important;
|
|
2479
|
-
object-position: ${mobile.objectPosition || "center"} !important;
|
|
2480
|
-
${getBorderStyleString$1(mobile.border)}
|
|
2573
|
+
${imgRules.join("\n ")}
|
|
2481
2574
|
}
|
|
2482
2575
|
}
|
|
2483
2576
|
`;
|
|
@@ -2495,7 +2588,7 @@ function Image({ config, devNode, devMode }) {
|
|
|
2495
2588
|
objectFit: config.objectFit,
|
|
2496
2589
|
objectPosition: config.objectPosition,
|
|
2497
2590
|
};
|
|
2498
|
-
const imageElement = (jsx("img", { src: src, alt: alt, width: imgWidthAttr, height: heightAttr !== "auto" ? heightAttr : undefined, className: imgClass, style: imgStyle }));
|
|
2591
|
+
const imageElement = (jsx("img", { src: src, alt: alt, width: imgWidthAttr, height: heightAttr !== "auto" ? heightAttr : undefined, className: imgClass, style: imgStyle, draggable: !devMode }));
|
|
2499
2592
|
return (jsxs(Fragment$1, { children: [mobile && jsx("style", { dangerouslySetInnerHTML: { __html: mobileCss } }), jsxs("table", { role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, className: `wrap-${imgClass}`, align: "center" // Ensures a 300px image stays centered in its parent
|
|
2500
2593
|
, style: {
|
|
2501
2594
|
width: tableWidth, // Fixed px here prevents the 100% "ghost space"
|
|
@@ -2508,7 +2601,9 @@ function Image({ config, devNode, devMode }) {
|
|
|
2508
2601
|
fontSize: "0",
|
|
2509
2602
|
lineHeight: "0",
|
|
2510
2603
|
width: tableWidth, // Lock the cell as well
|
|
2511
|
-
}, children: href && !devMode ? (jsx("a", { href: href, target: target,
|
|
2604
|
+
}, children: href && !devMode ? (jsx("a", { href: href, target: target, ...(target === "_blank"
|
|
2605
|
+
? { rel: "noopener noreferrer" }
|
|
2606
|
+
: {}), style: { display: "block", width: "100%" }, children: imageElement })) : (imageElement) }) }) }), devMode && !!devNode && (jsx("tfoot", { children: jsx("tr", { children: jsx("td", { children: devNode }) }) }))] })] }));
|
|
2512
2607
|
}
|
|
2513
2608
|
var Image_default = memo(Image, arePropsEqual);
|
|
2514
2609
|
|
|
@@ -2582,7 +2677,7 @@ function Row({ children, config, devNode, devMode }) {
|
|
|
2582
2677
|
const childrenArray = (Array.isArray(children) ? children : [children]).filter((child) => child != null);
|
|
2583
2678
|
const numChildren = childrenArray.length;
|
|
2584
2679
|
const href = getHrefFromInnerLink(config.innerLink);
|
|
2585
|
-
const target = (_a = config.innerLink) === null || _a === void 0 ? void 0 : _a.target;
|
|
2680
|
+
const target = ((_a = config.innerLink) === null || _a === void 0 ? void 0 : _a.target) || "_blank";
|
|
2586
2681
|
// 1. Outer TD: Background, Border Radius, Width, Height.
|
|
2587
2682
|
const backgroundTdStyle = {
|
|
2588
2683
|
backgroundColor: config.backgroundColor,
|
|
@@ -2657,7 +2752,7 @@ function Row({ children, config, devNode, devMode }) {
|
|
|
2657
2752
|
}, className: "child-cell", children: child }), index < numChildren - 1 &&
|
|
2658
2753
|
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 }) }) }))] }));
|
|
2659
2754
|
if (href && !devMode) {
|
|
2660
|
-
return (jsx("a", { href: href, ...(
|
|
2755
|
+
return (jsx("a", { href: href, ...({ target }), style: {
|
|
2661
2756
|
textDecoration: "none",
|
|
2662
2757
|
color: "inherit",
|
|
2663
2758
|
display: "block",
|
|
@@ -2769,7 +2864,7 @@ function Spacer({ config, devNode }) {
|
|
|
2769
2864
|
var Spacer_default = memo(Spacer, arePropsEqual);
|
|
2770
2865
|
|
|
2771
2866
|
function Text({ config, devMode, children }) {
|
|
2772
|
-
const { text, padding, color, textAlign, fontFamily, fontSize, fontWeight, fontStyle, lineHeight, letterSpacing, textTransform, textDecoration, direction, verticalAlign, backgroundColor, opacity, whiteSpace, wordBreak = "break-all", maxWidth } = config;
|
|
2867
|
+
const { text, padding, color, textAlign, fontFamily, fontSize, fontWeight, fontStyle, lineHeight, letterSpacing, textTransform, textDecoration, direction, verticalAlign, backgroundColor, opacity, whiteSpace, wordBreak = "break-all", maxWidth, } = config;
|
|
2773
2868
|
// 1. TD Style: Where padding and background are reliably applied.
|
|
2774
2869
|
const tdStyle = {
|
|
2775
2870
|
padding: padding,
|
|
@@ -2796,7 +2891,7 @@ function Text({ config, devMode, children }) {
|
|
|
2796
2891
|
wordBreak: wordBreak,
|
|
2797
2892
|
margin: "0",
|
|
2798
2893
|
padding: "0",
|
|
2799
|
-
maxWidth
|
|
2894
|
+
maxWidth,
|
|
2800
2895
|
};
|
|
2801
2896
|
// Determine content to render
|
|
2802
2897
|
const content = text !== null && text !== void 0 ? text : children;
|
|
@@ -2903,7 +2998,7 @@ function buildIconifyUrl(config) {
|
|
|
2903
2998
|
const template = process.env.ICONIFY_API_IMAGE_URI ||
|
|
2904
2999
|
"https://iconify.pagenflow.com/api/image/{{height}}/{{color}}/{{rotate}}-{{rotate-orientation}}/{{icon-full-name}}.png";
|
|
2905
3000
|
return template
|
|
2906
|
-
.replace("{{height}}", String(numericHeight *
|
|
3001
|
+
.replace("{{height}}", String(numericHeight * 4))
|
|
2907
3002
|
.replace("{{color}}", cleanColor)
|
|
2908
3003
|
.replace("{{rotate}}", String(rotate))
|
|
2909
3004
|
.replace("{{rotate-orientation}}", rotateOrientation)
|
|
@@ -2937,7 +3032,7 @@ function Icon({ config, devNode, devMode, children }) {
|
|
|
2937
3032
|
// Determine icon source
|
|
2938
3033
|
const iconSrc = buildIconifyUrl(config);
|
|
2939
3034
|
const href = buildLinkHref(innerLink);
|
|
2940
|
-
const target = (innerLink === null || innerLink === void 0 ? void 0 : innerLink.target) || "
|
|
3035
|
+
const target = (innerLink === null || innerLink === void 0 ? void 0 : innerLink.target) || "_blank";
|
|
2941
3036
|
const align = justifyMap[justifyContent];
|
|
2942
3037
|
// Get border styles
|
|
2943
3038
|
const borderStyle = getBorderStyle(border);
|