@pagenflow/email 1.4.3 → 1.4.4
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 +3 -2
- package/dist/components/Divider.d.ts +0 -5
- package/dist/components/Image.d.ts +7 -2
- package/dist/index.cjs.js +179 -86
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +179 -86
- package/dist/index.esm.js.map +1 -1
- 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,25 @@ 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 = parseInt(padding.split(" ")[0] || "12", 10);
|
|
1602
|
-
const numericFontSize = parseInt(fontSize, 10);
|
|
1603
|
-
const numericLineHeight = lineHeight
|
|
1604
|
-
?
|
|
1605
|
-
|
|
1624
|
+
const numericPadding = padding ? parseInt(padding.split(" ")[0] || "12", 10) : 12;
|
|
1625
|
+
const numericFontSize = fontSize ? parseInt(fontSize, 10) : 0;
|
|
1626
|
+
const numericLineHeight = lineHeight
|
|
1627
|
+
? lineHeight.includes("px")
|
|
1628
|
+
? parseInt(lineHeight, 10)
|
|
1629
|
+
: numericFontSize * parseFloat(lineHeight)
|
|
1630
|
+
: numericFontSize;
|
|
1606
1631
|
// Trust user's explicit pixel width - no calculation needed
|
|
1607
1632
|
const vmlWidth = parseInt(width, 10);
|
|
1608
1633
|
// Calculate VML height - trust user's padding and let text wrap naturally
|
|
1609
1634
|
// VML v:textbox will handle text wrapping automatically
|
|
1610
1635
|
const textContent = typeof children === "string" ? children : "";
|
|
1611
1636
|
// Estimate number of lines based on text length and button width
|
|
1612
|
-
const horizontalPadding = padding.split(" ")[1]
|
|
1637
|
+
const horizontalPadding = (padding === null || padding === void 0 ? void 0 : padding.split(" ")[1])
|
|
1613
1638
|
? parseInt(padding.split(" ")[1], 10) * 2
|
|
1614
1639
|
: numericPadding * 2;
|
|
1615
1640
|
const availableTextWidth = vmlWidth - horizontalPadding;
|
|
@@ -1622,15 +1647,17 @@ function Button({ config, devMode }) {
|
|
|
1622
1647
|
// Add extra 4px buffer to prevent bottom cropping in VML
|
|
1623
1648
|
const vmlHeight = Math.max(numericPadding * 2 + textHeight + 4, 40);
|
|
1624
1649
|
// VML colors must use the full hex format (e.g., #000000)
|
|
1625
|
-
const vmlFillColor = backgroundColor
|
|
1626
|
-
? backgroundColor
|
|
1627
|
-
|
|
1650
|
+
const vmlFillColor = backgroundColor
|
|
1651
|
+
? backgroundColor.startsWith("#")
|
|
1652
|
+
? backgroundColor
|
|
1653
|
+
: `#${backgroundColor}`
|
|
1654
|
+
: undefined;
|
|
1628
1655
|
// VML stroke color for border
|
|
1629
1656
|
const vmlStrokeColor = (border === null || border === void 0 ? void 0 : border.color) || vmlFillColor;
|
|
1630
1657
|
const vmlStrokeWeight = (border === null || border === void 0 ? void 0 : border.width) ? parseInt(border.width, 10) : 0;
|
|
1631
1658
|
const hasVmlStroke = vmlStrokeWeight > 0;
|
|
1632
1659
|
// Build VML font styles - consistent with other rendering paths
|
|
1633
|
-
const vmlFontWeight = fontWeight
|
|
1660
|
+
const vmlFontWeight = fontWeight;
|
|
1634
1661
|
const vmlFontStyle = fontStyle === "italic" ? "font-style:italic;" : "";
|
|
1635
1662
|
const vmlLetterSpacing = letterSpacing
|
|
1636
1663
|
? `letter-spacing:${letterSpacing};`
|
|
@@ -1641,12 +1668,12 @@ function Button({ config, devMode }) {
|
|
|
1641
1668
|
const vmlTextDecoration = textDecoration && textDecoration !== "none"
|
|
1642
1669
|
? `text-decoration:${textDecoration};`
|
|
1643
1670
|
: "";
|
|
1644
|
-
const vmlWhiteSpace = whiteSpace
|
|
1671
|
+
const vmlWhiteSpace = whiteSpace ? `white-space:${whiteSpace};` : "";
|
|
1645
1672
|
const vmlDirection = direction ? `direction:${direction};` : "";
|
|
1646
1673
|
const vmlOpacity = opacity !== undefined ? `opacity:${opacity};` : "";
|
|
1647
1674
|
// VML code uses MSO conditional comments to render only in Outlook
|
|
1648
1675
|
// Use table with explicit MSO height for vertical centering
|
|
1649
|
-
const horizontalPaddingValue = padding.split(" ")[1]
|
|
1676
|
+
const horizontalPaddingValue = (padding === null || padding === void 0 ? void 0 : padding.split(" ")[1])
|
|
1650
1677
|
? parseInt(padding.split(" ")[1], 10)
|
|
1651
1678
|
: numericPadding;
|
|
1652
1679
|
// For VML, we need to use a table inside to properly apply padding and centering
|
|
@@ -1655,7 +1682,7 @@ function Button({ config, devMode }) {
|
|
|
1655
1682
|
if (textAlign === "center") {
|
|
1656
1683
|
vmlAlignAttr = 'align="center"';
|
|
1657
1684
|
}
|
|
1658
|
-
else {
|
|
1685
|
+
else if (textAlign) {
|
|
1659
1686
|
vmlAlignStyle = `text-align:${textAlign};`;
|
|
1660
1687
|
}
|
|
1661
1688
|
// Border radius is intentionally omitted (arcsize="0%") for Outlook Classic.
|
|
@@ -1663,12 +1690,12 @@ function Button({ config, devMode }) {
|
|
|
1663
1690
|
// is inconsistent, so we render sharp corners there instead.
|
|
1664
1691
|
vmlButton = `
|
|
1665
1692
|
<!--[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}">
|
|
1693
|
+
<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
1694
|
<w:anchorlock/>
|
|
1668
1695
|
<v:textbox inset="${horizontalPaddingValue}px,${numericPadding}px,${horizontalPaddingValue}px,${numericPadding}px">
|
|
1669
1696
|
<table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%" style="border-collapse:collapse;">
|
|
1670
1697
|
<tr>
|
|
1671
|
-
<td ${vmlAlignAttr} valign="middle" style="${vmlAlignStyle}color:${color}
|
|
1698
|
+
<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
1699
|
${typeof children === "string" ? children : ""}
|
|
1673
1700
|
</td>
|
|
1674
1701
|
</tr>
|
|
@@ -1692,10 +1719,10 @@ function Button({ config, devMode }) {
|
|
|
1692
1719
|
const textTransformProp = textTransform
|
|
1693
1720
|
? `text-transform: ${textTransform};`
|
|
1694
1721
|
: "";
|
|
1695
|
-
const whiteSpaceProp = whiteSpace
|
|
1722
|
+
const whiteSpaceProp = whiteSpace ? `white-space: ${whiteSpace};` : "";
|
|
1696
1723
|
const directionProp = direction ? `direction: ${direction};` : "";
|
|
1697
1724
|
const opacityProp = opacity !== undefined ? `opacity: ${opacity};` : "";
|
|
1698
|
-
const wordBreakProp = wordBreak
|
|
1725
|
+
const wordBreakProp = wordBreak ? `word-break: ${wordBreak};` : "";
|
|
1699
1726
|
// Border radius is intentionally omitted from the Outlook Classic table cell.
|
|
1700
1727
|
// Outlook Classic ignores border-radius on table cells anyway, and including it
|
|
1701
1728
|
// can cause unexpected rendering artifacts, so we explicitly leave it out.
|
|
@@ -1703,13 +1730,17 @@ function Button({ config, devMode }) {
|
|
|
1703
1730
|
<!--[if mso]>
|
|
1704
1731
|
<table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%" style="border-collapse: collapse;">
|
|
1705
1732
|
<tr>
|
|
1706
|
-
<td align="${align}" style="padding: 0;">
|
|
1733
|
+
<td ${align ? `align="${align}"` : ""} style="padding: 0;">
|
|
1707
1734
|
<table role="presentation" cellpadding="0" cellspacing="0" border="0" width="${width || "auto"}" style="border-collapse: collapse;">
|
|
1708
1735
|
<tr>
|
|
1709
|
-
<td bgcolor="${backgroundColor}" align="${textAlign}" style="padding: ${padding}
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1736
|
+
<td ${backgroundColor ? `bgcolor="${backgroundColor}"` : ""} ${textAlign ? `align="${textAlign}"` : ""} style="${padding ? `padding: ${padding};` : ""} ${textAlign ? `text-align: ${textAlign};` : ""} ${borderStyleString}">
|
|
1737
|
+
${href
|
|
1738
|
+
? `<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;">
|
|
1739
|
+
${typeof children === "string" ? children : ""}
|
|
1740
|
+
</a>`
|
|
1741
|
+
: `<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;">
|
|
1742
|
+
${typeof children === "string" ? children : ""}
|
|
1743
|
+
</span>`}
|
|
1713
1744
|
</td>
|
|
1714
1745
|
</tr>
|
|
1715
1746
|
</table>
|
|
@@ -1723,7 +1754,7 @@ function Button({ config, devMode }) {
|
|
|
1723
1754
|
// fontFamily uses the sanitized value so embedded quotes never break the
|
|
1724
1755
|
// style attribute string (which is always wrapped in double quotes).
|
|
1725
1756
|
const sharedTextStyles = [
|
|
1726
|
-
`color: ${color}
|
|
1757
|
+
color ? `color: ${color};` : "",
|
|
1727
1758
|
safeFontFamily ? `font-family: ${safeFontFamily};` : "",
|
|
1728
1759
|
fontSize ? `font-size: ${fontSize};` : "",
|
|
1729
1760
|
fontWeight ? `font-weight: ${fontWeight};` : "",
|
|
@@ -1736,7 +1767,7 @@ function Button({ config, devMode }) {
|
|
|
1736
1767
|
: "",
|
|
1737
1768
|
direction ? `direction: ${direction};` : "",
|
|
1738
1769
|
opacity !== undefined ? `opacity: ${opacity};` : "",
|
|
1739
|
-
whiteSpace
|
|
1770
|
+
whiteSpace ? `white-space: ${whiteSpace};` : "",
|
|
1740
1771
|
]
|
|
1741
1772
|
.filter(Boolean)
|
|
1742
1773
|
.join(" ");
|
|
@@ -1770,20 +1801,24 @@ function Button({ config, devMode }) {
|
|
|
1770
1801
|
<table role="presentation" cellpadding="0" cellspacing="0" border="0" style="border-collapse: collapse; width: 100%;">
|
|
1771
1802
|
<tbody>
|
|
1772
1803
|
<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}
|
|
1804
|
+
<td style="${backgroundTdStyle.backgroundColor ? `background-color: ${backgroundTdStyle.backgroundColor};` : ""} ${backgroundTdStyle.borderRadius ? `border-radius: ${backgroundTdStyle.borderRadius};` : ""} width: ${backgroundTdStyle.width}; ${maxWidth ? `max-width: ${maxWidth};` : ""} ${borderRadius ? "overflow: hidden;" : ""}">
|
|
1805
|
+
<table role="presentation" cellpadding="0" cellspacing="0" border="0" style="border-collapse: separate; border-spacing: 0; ${borderRadius ? `border-radius: ${borderRadius};` : ""} width: 100%; ${borderStyleString}">
|
|
1775
1806
|
<tbody>
|
|
1776
1807
|
<tr>
|
|
1777
1808
|
<td style="padding: 0;">
|
|
1778
1809
|
${devMode
|
|
1779
|
-
? `<span style="${sharedTextStyles} ${textDecoration && textDecoration !== "none" ? "" : "text-decoration: none;"} display: block; word-break: ${wordBreak}
|
|
1810
|
+
? `<span style="${sharedTextStyles} ${textDecoration && textDecoration !== "none" ? "" : "text-decoration: none;"} display: block; ${wordBreak ? `word-break: ${wordBreak};` : ""} ${textAlign ? `text-align: ${textAlign};` : ""} ${padding ? `padding: ${padding};` : ""}">
|
|
1780
1811
|
${typeof children === "string" ? children : ""}
|
|
1781
1812
|
</span>`
|
|
1782
|
-
:
|
|
1783
|
-
|
|
1813
|
+
: href
|
|
1814
|
+
? `<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};` : ""}">
|
|
1815
|
+
<span>
|
|
1816
|
+
${typeof children === "string" ? children : ""}
|
|
1817
|
+
</span>
|
|
1818
|
+
</a>`
|
|
1819
|
+
: `<span style="${sharedTextStyles} ${textDecoration && textDecoration !== "none" ? "" : "text-decoration: none;"} display: block; ${wordBreak ? `word-break: ${wordBreak};` : ""} ${textAlign ? `text-align: ${textAlign};` : ""} ${padding ? `padding: ${padding};` : ""}">
|
|
1784
1820
|
${typeof children === "string" ? children : ""}
|
|
1785
|
-
</span
|
|
1786
|
-
</a>`}
|
|
1821
|
+
</span>`}
|
|
1787
1822
|
</td>
|
|
1788
1823
|
</tr>
|
|
1789
1824
|
</tbody>
|
|
@@ -2102,40 +2137,48 @@ var Container_default = memo(Container, arePropsEqual);
|
|
|
2102
2137
|
|
|
2103
2138
|
function Divider({ config, devNode }) {
|
|
2104
2139
|
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
|
|
2140
|
+
const heightPx = parseInt(height, 10) || 1;
|
|
2141
|
+
// Parse margin into paddingTop / paddingBottom for the outer TD.
|
|
2142
|
+
// Outlook ignores shorthand "20px 0" on TDs — must be explicit.
|
|
2143
|
+
const [marginTopRaw = "0", marginRightRaw = "0", marginBottomRaw, marginLeftRaw] = margin.trim().split(/\s+/);
|
|
2144
|
+
const marginTop = marginTopRaw;
|
|
2145
|
+
const marginBottom = marginBottomRaw !== null && marginBottomRaw !== void 0 ? marginBottomRaw : marginTopRaw; // "20px 0" → top=20px, bottom=20px
|
|
2146
|
+
// Outlook requires align on the outer TD to correctly position
|
|
2147
|
+
// a fixed-width inner table (e.g. width="300px").
|
|
2148
|
+
const alignAttr = align === "left" ? "left" : align === "right" ? "right" : "center";
|
|
2149
|
+
return (jsxs("table", { role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: {
|
|
2150
|
+
position: "relative", // dev overlay anchor
|
|
2131
2151
|
width: "100%",
|
|
2132
2152
|
borderCollapse: "collapse",
|
|
2133
|
-
|
|
2153
|
+
border: "0",
|
|
2154
|
+
}, className: hideOnMobile ? "hide-on-mobile" : undefined, children: [jsx("tbody", { children: jsx("tr", { children: jsx("td", { align: alignAttr, style: {
|
|
2155
|
+
paddingTop: marginTop,
|
|
2156
|
+
paddingBottom: marginBottom,
|
|
2157
|
+
paddingLeft: "0",
|
|
2158
|
+
paddingRight: "0",
|
|
2159
|
+
fontSize: "0",
|
|
2160
|
+
lineHeight: "0",
|
|
2161
|
+
}, children: jsx("table", { role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, align: alignAttr, style: {
|
|
2162
|
+
width: width,
|
|
2163
|
+
borderCollapse: "collapse",
|
|
2164
|
+
border: "0",
|
|
2165
|
+
}, children: jsx("tbody", { children: jsx("tr", { children: jsx("td", { ...{ height: heightPx }, ref: (el) => {
|
|
2166
|
+
if (!el)
|
|
2167
|
+
return;
|
|
2168
|
+
el.setAttribute("style", `height:${height};` +
|
|
2169
|
+
`line-height:${height};` +
|
|
2170
|
+
`font-size:0;` +
|
|
2171
|
+
`padding:0;` +
|
|
2172
|
+
`background-color:${color};` +
|
|
2173
|
+
`mso-line-height-rule:exactly;`);
|
|
2174
|
+
}, style: {
|
|
2175
|
+
// Fallback for non-Outlook clients (React-rendered style object).
|
|
2134
2176
|
height: height,
|
|
2177
|
+
lineHeight: height,
|
|
2135
2178
|
fontSize: "0",
|
|
2136
|
-
lineHeight: "0",
|
|
2137
2179
|
padding: "0",
|
|
2138
|
-
|
|
2180
|
+
backgroundColor: color,
|
|
2181
|
+
} }) }) }) }) }) }) }), devNode && (jsx("tfoot", { children: jsx("tr", { children: jsx("td", { children: devNode }) }) }))] }));
|
|
2139
2182
|
}
|
|
2140
2183
|
var Divider_default = memo(Divider, arePropsEqual);
|
|
2141
2184
|
|
|
@@ -2380,6 +2423,27 @@ function Html({ children, backgroundColor = "#ffffff", }) {
|
|
|
2380
2423
|
);
|
|
2381
2424
|
}
|
|
2382
2425
|
|
|
2426
|
+
// Helper to build link href based on innerLink type
|
|
2427
|
+
function buildLinkHref$1(innerLink) {
|
|
2428
|
+
if (!innerLink || innerLink.type === "none")
|
|
2429
|
+
return null;
|
|
2430
|
+
switch (innerLink.type) {
|
|
2431
|
+
case "url":
|
|
2432
|
+
return innerLink.url || null;
|
|
2433
|
+
case "email":
|
|
2434
|
+
return innerLink.email ? `mailto:${innerLink.email}` : null;
|
|
2435
|
+
case "phone":
|
|
2436
|
+
return innerLink.phone ? `tel:${innerLink.phone}` : null;
|
|
2437
|
+
case "anchor":
|
|
2438
|
+
return innerLink.anchor ? `#${innerLink.anchor}` : null;
|
|
2439
|
+
case "page_top":
|
|
2440
|
+
return "#top";
|
|
2441
|
+
case "page_bottom":
|
|
2442
|
+
return "#bottom";
|
|
2443
|
+
default:
|
|
2444
|
+
return null;
|
|
2445
|
+
}
|
|
2446
|
+
}
|
|
2383
2447
|
function getBorderStyle$3(border) {
|
|
2384
2448
|
if (!border)
|
|
2385
2449
|
return {};
|
|
@@ -2422,7 +2486,10 @@ function getBorderStyleString$1(border) {
|
|
|
2422
2486
|
}
|
|
2423
2487
|
function Image({ config, devNode, devMode }) {
|
|
2424
2488
|
var _a, _b;
|
|
2425
|
-
const { src, alt,
|
|
2489
|
+
const { src, alt, innerLink, mobile } = config;
|
|
2490
|
+
// Resolve href and target from innerLink
|
|
2491
|
+
const href = buildLinkHref$1(innerLink);
|
|
2492
|
+
const target = (innerLink === null || innerLink === void 0 ? void 0 : innerLink.target) || "_blank";
|
|
2426
2493
|
const seed = src + (alt || "");
|
|
2427
2494
|
const instanceId = seed
|
|
2428
2495
|
.split("")
|
|
@@ -2452,32 +2519,56 @@ function Image({ config, devNode, devMode }) {
|
|
|
2452
2519
|
? parseInt(config.maxWidth, 10)
|
|
2453
2520
|
: undefined;
|
|
2454
2521
|
const imgWidthAttr = isPercent ? (maxWidthPx !== null && maxWidthPx !== void 0 ? maxWidthPx : undefined) : widthAttr;
|
|
2455
|
-
// 2. Mobile Overrides
|
|
2522
|
+
// 2. Mobile Overrides — only emit CSS properties that are explicitly set,
|
|
2523
|
+
// so unspecified properties are left untouched (no forced defaults).
|
|
2456
2524
|
let mobileCss = "";
|
|
2457
2525
|
if (mobile) {
|
|
2526
|
+
// .wrap-${imgClass} rules
|
|
2527
|
+
const wrapRules = [
|
|
2528
|
+
// Always reset min-width so the px lock from desktop can be overridden
|
|
2529
|
+
"min-width: 0 !important;",
|
|
2530
|
+
];
|
|
2531
|
+
if (mobile.width !== undefined)
|
|
2532
|
+
wrapRules.push(`width: ${mobile.width} !important;`);
|
|
2533
|
+
if (mobile.maxWidth !== undefined)
|
|
2534
|
+
wrapRules.push(`max-width: ${mobile.maxWidth} !important;`);
|
|
2535
|
+
// .td-${imgClass} rules
|
|
2536
|
+
const tdRules = [];
|
|
2537
|
+
if (mobile.padding !== undefined)
|
|
2538
|
+
tdRules.push(`padding: ${mobile.padding} !important;`);
|
|
2539
|
+
if (mobile.backgroundColor !== undefined)
|
|
2540
|
+
tdRules.push(`background-color: ${mobile.backgroundColor} !important;`);
|
|
2541
|
+
// .${imgClass} rules
|
|
2542
|
+
const imgRules = [];
|
|
2543
|
+
if (mobile.width !== undefined)
|
|
2544
|
+
imgRules.push(`width: ${mobile.width} !important;`);
|
|
2545
|
+
if (mobile.height !== undefined)
|
|
2546
|
+
imgRules.push(`height: ${mobile.height} !important;`);
|
|
2547
|
+
if (mobile.maxWidth !== undefined)
|
|
2548
|
+
imgRules.push(`max-width: ${mobile.maxWidth} !important;`);
|
|
2549
|
+
if (mobile.maxHeight !== undefined)
|
|
2550
|
+
imgRules.push(`max-height: ${mobile.maxHeight} !important;`);
|
|
2551
|
+
if (mobile.borderRadius !== undefined)
|
|
2552
|
+
imgRules.push(`border-radius: ${mobile.borderRadius} !important;`);
|
|
2553
|
+
if (mobile.hidden !== undefined)
|
|
2554
|
+
imgRules.push(`display: ${mobile.hidden ? "none" : "block"} !important;`);
|
|
2555
|
+
if (mobile.objectFit !== undefined)
|
|
2556
|
+
imgRules.push(`object-fit: ${mobile.objectFit} !important;`);
|
|
2557
|
+
if (mobile.objectPosition !== undefined)
|
|
2558
|
+
imgRules.push(`object-position: ${mobile.objectPosition} !important;`);
|
|
2559
|
+
if (mobile.border !== undefined)
|
|
2560
|
+
imgRules.push(getBorderStyleString$1(mobile.border));
|
|
2458
2561
|
mobileCss = `
|
|
2459
2562
|
@media screen and (max-width: 768px) {
|
|
2460
2563
|
.wrap-${imgClass} {
|
|
2461
2564
|
/* This breaks the px lock from desktop and makes it fluid */
|
|
2462
|
-
|
|
2463
|
-
max-width: ${mobile.maxWidth || "100%"} !important;
|
|
2464
|
-
min-width: 0 !important;
|
|
2565
|
+
${wrapRules.join("\n ")}
|
|
2465
2566
|
}
|
|
2466
2567
|
.td-${imgClass} {
|
|
2467
|
-
|
|
2468
|
-
background-color: ${mobile.backgroundColor || "transparent"} !important;
|
|
2469
|
-
width: 100% !important;
|
|
2568
|
+
${tdRules.join("\n ")}
|
|
2470
2569
|
}
|
|
2471
2570
|
.${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)}
|
|
2571
|
+
${imgRules.join("\n ")}
|
|
2481
2572
|
}
|
|
2482
2573
|
}
|
|
2483
2574
|
`;
|
|
@@ -2495,7 +2586,7 @@ function Image({ config, devNode, devMode }) {
|
|
|
2495
2586
|
objectFit: config.objectFit,
|
|
2496
2587
|
objectPosition: config.objectPosition,
|
|
2497
2588
|
};
|
|
2498
|
-
const imageElement = (jsx("img", { src: src, alt: alt, width: imgWidthAttr, height: heightAttr !== "auto" ? heightAttr : undefined, className: imgClass, style: imgStyle }));
|
|
2589
|
+
const imageElement = (jsx("img", { src: src, alt: alt, width: imgWidthAttr, height: heightAttr !== "auto" ? heightAttr : undefined, className: imgClass, style: imgStyle, draggable: !devMode }));
|
|
2499
2590
|
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
2591
|
, style: {
|
|
2501
2592
|
width: tableWidth, // Fixed px here prevents the 100% "ghost space"
|
|
@@ -2508,7 +2599,9 @@ function Image({ config, devNode, devMode }) {
|
|
|
2508
2599
|
fontSize: "0",
|
|
2509
2600
|
lineHeight: "0",
|
|
2510
2601
|
width: tableWidth, // Lock the cell as well
|
|
2511
|
-
}, children: href && !devMode ? (jsx("a", { href: href, target: target,
|
|
2602
|
+
}, children: href && !devMode ? (jsx("a", { href: href, target: target, ...(target === "_blank"
|
|
2603
|
+
? { rel: "noopener noreferrer" }
|
|
2604
|
+
: {}), style: { display: "block", width: "100%" }, children: imageElement })) : (imageElement) }) }) }), devMode && !!devNode && (jsx("tfoot", { children: jsx("tr", { children: jsx("td", { children: devNode }) }) }))] })] }));
|
|
2512
2605
|
}
|
|
2513
2606
|
var Image_default = memo(Image, arePropsEqual);
|
|
2514
2607
|
|
|
@@ -2582,7 +2675,7 @@ function Row({ children, config, devNode, devMode }) {
|
|
|
2582
2675
|
const childrenArray = (Array.isArray(children) ? children : [children]).filter((child) => child != null);
|
|
2583
2676
|
const numChildren = childrenArray.length;
|
|
2584
2677
|
const href = getHrefFromInnerLink(config.innerLink);
|
|
2585
|
-
const target = (_a = config.innerLink) === null || _a === void 0 ? void 0 : _a.target;
|
|
2678
|
+
const target = ((_a = config.innerLink) === null || _a === void 0 ? void 0 : _a.target) || "_blank";
|
|
2586
2679
|
// 1. Outer TD: Background, Border Radius, Width, Height.
|
|
2587
2680
|
const backgroundTdStyle = {
|
|
2588
2681
|
backgroundColor: config.backgroundColor,
|
|
@@ -2657,7 +2750,7 @@ function Row({ children, config, devNode, devMode }) {
|
|
|
2657
2750
|
}, className: "child-cell", children: child }), index < numChildren - 1 &&
|
|
2658
2751
|
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
2752
|
if (href && !devMode) {
|
|
2660
|
-
return (jsx("a", { href: href, ...(
|
|
2753
|
+
return (jsx("a", { href: href, ...({ target }), style: {
|
|
2661
2754
|
textDecoration: "none",
|
|
2662
2755
|
color: "inherit",
|
|
2663
2756
|
display: "block",
|
|
@@ -2903,7 +2996,7 @@ function buildIconifyUrl(config) {
|
|
|
2903
2996
|
const template = process.env.ICONIFY_API_IMAGE_URI ||
|
|
2904
2997
|
"https://iconify.pagenflow.com/api/image/{{height}}/{{color}}/{{rotate}}-{{rotate-orientation}}/{{icon-full-name}}.png";
|
|
2905
2998
|
return template
|
|
2906
|
-
.replace("{{height}}", String(numericHeight *
|
|
2999
|
+
.replace("{{height}}", String(numericHeight * 4))
|
|
2907
3000
|
.replace("{{color}}", cleanColor)
|
|
2908
3001
|
.replace("{{rotate}}", String(rotate))
|
|
2909
3002
|
.replace("{{rotate-orientation}}", rotateOrientation)
|
|
@@ -2937,7 +3030,7 @@ function Icon({ config, devNode, devMode, children }) {
|
|
|
2937
3030
|
// Determine icon source
|
|
2938
3031
|
const iconSrc = buildIconifyUrl(config);
|
|
2939
3032
|
const href = buildLinkHref(innerLink);
|
|
2940
|
-
const target = (innerLink === null || innerLink === void 0 ? void 0 : innerLink.target) || "
|
|
3033
|
+
const target = (innerLink === null || innerLink === void 0 ? void 0 : innerLink.target) || "_blank";
|
|
2941
3034
|
const align = justifyMap[justifyContent];
|
|
2942
3035
|
// Get border styles
|
|
2943
3036
|
const borderStyle = getBorderStyle(border);
|