@pagenflow/email 1.4.7 → 1.4.8
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 -1
- package/dist/components/Column.d.ts +3 -1
- package/dist/components/Container.d.ts +4 -2
- package/dist/components/Divider.d.ts +3 -1
- package/dist/components/Heading.d.ts +6 -1
- package/dist/components/Icon.d.ts +4 -2
- package/dist/components/Image.d.ts +25 -2
- package/dist/components/Row.d.ts +20 -1
- package/dist/components/Section.d.ts +2 -0
- package/dist/components/Spacer.d.ts +6 -1
- package/dist/components/Text.d.ts +6 -1
- package/dist/components/utils/bindingAttribute.d.ts +38 -0
- package/dist/components/utils/linearizeStyle.d.ts +10 -0
- package/dist/index.cjs.js +302 -133
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +302 -133
- package/dist/index.esm.js.map +1 -1
- package/dist/types/DataBindings.d.ts +87 -0
- package/package.json +1 -1
package/dist/index.cjs.js
CHANGED
|
@@ -1533,6 +1533,57 @@ function arePropsEqual(prevProps, nextProps) {
|
|
|
1533
1533
|
return isEqual(prevProps, nextProps);
|
|
1534
1534
|
}
|
|
1535
1535
|
|
|
1536
|
+
/**
|
|
1537
|
+
* bindingAttribute.ts
|
|
1538
|
+
* -------------------
|
|
1539
|
+
* Serialises DataBindings into discrete HTML attributes:
|
|
1540
|
+
*
|
|
1541
|
+
* data-bind-if → visible condition → stamped on the root element
|
|
1542
|
+
* data-bind-list → repeater (dataList + itemAlias) → stamped on the
|
|
1543
|
+
* direct parent of the children loop, NOT the root
|
|
1544
|
+
* data-bind → propertyMap → stamped on the root element
|
|
1545
|
+
*
|
|
1546
|
+
* Keeping the three concerns in separate attributes lets the post-processor
|
|
1547
|
+
* handle them independently without ambiguity.
|
|
1548
|
+
*/
|
|
1549
|
+
// ─── Root element props (visible + propertyMap) ───────────────────────────────
|
|
1550
|
+
/**
|
|
1551
|
+
* Props to spread onto the component's root element.
|
|
1552
|
+
* Carries `data-bind-if` and/or `data-bind` (propertyMap).
|
|
1553
|
+
*/
|
|
1554
|
+
function rootBindingProps(bindings) {
|
|
1555
|
+
if (!bindings)
|
|
1556
|
+
return {};
|
|
1557
|
+
const props = {};
|
|
1558
|
+
if (bindings.visible) {
|
|
1559
|
+
props['data-bind-if'] = bindings.visible;
|
|
1560
|
+
}
|
|
1561
|
+
if (bindings.propertyMap && Object.keys(bindings.propertyMap).length) {
|
|
1562
|
+
props['data-bind'] = JSON.stringify({ propertyMap: bindings.propertyMap });
|
|
1563
|
+
}
|
|
1564
|
+
return props;
|
|
1565
|
+
}
|
|
1566
|
+
// ─── List wrapper props (dataList + itemAlias) ────────────────────────────────
|
|
1567
|
+
/**
|
|
1568
|
+
* Props to spread onto the *direct parent* of the children loop.
|
|
1569
|
+
* Carries `data-bind-list` only when a repeater is defined.
|
|
1570
|
+
*
|
|
1571
|
+
* Usage inside a component:
|
|
1572
|
+
* <tbody {...listBindingProps(bindings)}>
|
|
1573
|
+
* {children}
|
|
1574
|
+
* </tbody>
|
|
1575
|
+
*/
|
|
1576
|
+
function listBindingProps(bindings) {
|
|
1577
|
+
if (!(bindings === null || bindings === void 0 ? void 0 : bindings.dataList))
|
|
1578
|
+
return {};
|
|
1579
|
+
return {
|
|
1580
|
+
'data-bind-list': JSON.stringify({
|
|
1581
|
+
dataList: bindings.dataList,
|
|
1582
|
+
...(bindings.itemAlias && { itemAlias: bindings.itemAlias }),
|
|
1583
|
+
}),
|
|
1584
|
+
};
|
|
1585
|
+
}
|
|
1586
|
+
|
|
1536
1587
|
// Map alignment to HTML 'align' attribute
|
|
1537
1588
|
const justifyMap$3 = {
|
|
1538
1589
|
start: "left",
|
|
@@ -1540,7 +1591,7 @@ const justifyMap$3 = {
|
|
|
1540
1591
|
end: "right",
|
|
1541
1592
|
};
|
|
1542
1593
|
// Helper to build link href based on innerLink type (mirrors Icon component)
|
|
1543
|
-
function buildLinkHref$
|
|
1594
|
+
function buildLinkHref$4(innerLink) {
|
|
1544
1595
|
if (!innerLink || innerLink.type === "none")
|
|
1545
1596
|
return null;
|
|
1546
1597
|
switch (innerLink.type) {
|
|
@@ -1594,10 +1645,10 @@ function getBorderStyleString$2(border) {
|
|
|
1594
1645
|
}
|
|
1595
1646
|
return styles.join(" ");
|
|
1596
1647
|
}
|
|
1597
|
-
function Button({ config, devMode }) {
|
|
1648
|
+
function Button({ config, devMode, bindings }) {
|
|
1598
1649
|
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;
|
|
1599
1650
|
// Resolve href from innerLink
|
|
1600
|
-
const href = buildLinkHref$
|
|
1651
|
+
const href = buildLinkHref$4(innerLink);
|
|
1601
1652
|
const target = (innerLink === null || innerLink === void 0 ? void 0 : innerLink.target) || "_blank";
|
|
1602
1653
|
// Sanitize fontFamily early so safeFontFamily is available for all paths below.
|
|
1603
1654
|
const safeFontFamily = fontFamily
|
|
@@ -1681,7 +1732,7 @@ function Button({ config, devMode }) {
|
|
|
1681
1732
|
.join(" ");
|
|
1682
1733
|
return (
|
|
1683
1734
|
// Wrapper table for alignment - maintains proper positioning for hover indicators
|
|
1684
|
-
jsxRuntime.jsx("table", { role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: {
|
|
1735
|
+
jsxRuntime.jsx("table", { role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, ...rootBindingProps(bindings), style: {
|
|
1685
1736
|
width: "100%",
|
|
1686
1737
|
borderCollapse: "collapse",
|
|
1687
1738
|
boxSizing: "border-box",
|
|
@@ -1789,7 +1840,7 @@ function getBorderStyle$5(border) {
|
|
|
1789
1840
|
}
|
|
1790
1841
|
return style;
|
|
1791
1842
|
}
|
|
1792
|
-
function Column({ children, config, devNode }) {
|
|
1843
|
+
function Column({ children, config, devNode, bindings }) {
|
|
1793
1844
|
var _a, _b, _c;
|
|
1794
1845
|
// Process children array for gap support
|
|
1795
1846
|
const childrenArray = (Array.isArray(children) ? children : [children]).filter((child) => child != null);
|
|
@@ -1841,6 +1892,7 @@ function Column({ children, config, devNode }) {
|
|
|
1841
1892
|
// treat it as content-box height and add padding on top, causing the
|
|
1842
1893
|
// total to exceed the declared height in preview mode.
|
|
1843
1894
|
verticalAlign: config.alignItems ? alignMap$2[config.alignItems] : "top",
|
|
1895
|
+
background: "transparent",
|
|
1844
1896
|
};
|
|
1845
1897
|
// 4. Gap spacer style (used between children)
|
|
1846
1898
|
const gapSpacerStyle = {
|
|
@@ -1848,6 +1900,7 @@ function Column({ children, config, devNode }) {
|
|
|
1848
1900
|
lineHeight: "1px",
|
|
1849
1901
|
fontSize: "1px",
|
|
1850
1902
|
width: "100%",
|
|
1903
|
+
background: "transparent",
|
|
1851
1904
|
};
|
|
1852
1905
|
// 5. maxWidth constraining table style (modern clients).
|
|
1853
1906
|
// The `width` HTML attribute on this table is what Outlook Classic
|
|
@@ -1862,10 +1915,10 @@ function Column({ children, config, devNode }) {
|
|
|
1862
1915
|
borderCollapse: "collapse",
|
|
1863
1916
|
};
|
|
1864
1917
|
// Main content rendering
|
|
1865
|
-
const renderContent = () => (jsxRuntime.jsx("table", { "aria-label": "Column Padding", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: innerTableStyle, children: jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { style: innerTdStyle, valign: config.justifyContent ? vAlignMap[config.justifyContent] : "top", align: config.alignItems ? alignMap$2[config.alignItems] : "left",
|
|
1918
|
+
const renderContent = () => (jsxRuntime.jsx("table", { "aria-label": "Column Padding", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: innerTableStyle, children: jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { style: innerTdStyle, valign: config.justifyContent ? vAlignMap[config.justifyContent] : "top", align: config.alignItems ? alignMap$2[config.alignItems] : "left", ...(numChildren > 1 ? {} : listBindingProps(bindings)), children: numChildren > 1 ? (jsxRuntime.jsx("table", { "aria-label": "Column Gap Wrapper", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: {
|
|
1866
1919
|
width: "100%",
|
|
1867
1920
|
borderCollapse: "collapse",
|
|
1868
|
-
}, children: jsxRuntime.jsx("tbody", { children: childrenArray.map((child, index) => (jsxRuntime.jsxs(React.Fragment, { children: [jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { style: {
|
|
1921
|
+
}, children: jsxRuntime.jsx("tbody", { ...listBindingProps(bindings), children: childrenArray.map((child, index) => (jsxRuntime.jsxs(React.Fragment, { children: [jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { style: {
|
|
1869
1922
|
verticalAlign: config.alignItems
|
|
1870
1923
|
? alignMap$2[config.alignItems]
|
|
1871
1924
|
: "top",
|
|
@@ -1874,7 +1927,7 @@ function Column({ children, config, devNode }) {
|
|
|
1874
1927
|
: "top", align: config.alignItems
|
|
1875
1928
|
? alignMap$2[config.alignItems]
|
|
1876
1929
|
: "left", children: child }) }), index < numChildren - 1 && (jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { style: gapSpacerStyle, children: "\u00A0" }) }))] }, `col-child-${index}`))) }) })) : (children) }) }) }) }));
|
|
1877
|
-
return (jsxRuntime.jsxs("table", { "aria-label": "Column Wrapper", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: {
|
|
1930
|
+
return (jsxRuntime.jsxs("table", { "aria-label": "Column Wrapper", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, ...rootBindingProps(bindings), style: {
|
|
1878
1931
|
position: "relative",
|
|
1879
1932
|
...outerTableStyle,
|
|
1880
1933
|
}, ...(config.height && { height: config.height }), children: [jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { style: outerTdStyle, ...(config.width && { width: config.width }), ...(config.height && { height: config.height }), children: config.maxWidth ? (
|
|
@@ -1943,7 +1996,7 @@ function getBorderStyle$4(border) {
|
|
|
1943
1996
|
}
|
|
1944
1997
|
return style;
|
|
1945
1998
|
}
|
|
1946
|
-
function Container({ children, config, devMode, devNode }) {
|
|
1999
|
+
function Container({ children, config, bindings, devMode, devNode, }) {
|
|
1947
2000
|
var _a, _b, _c;
|
|
1948
2001
|
const { widthType, childrenConstraints } = config;
|
|
1949
2002
|
const childrenArray = (Array.isArray(children) ? children : [children]).filter((child) => child != null);
|
|
@@ -1961,7 +2014,7 @@ function Container({ children, config, devMode, devNode }) {
|
|
|
1961
2014
|
return 0;
|
|
1962
2015
|
})();
|
|
1963
2016
|
const getChildWidths = (() => {
|
|
1964
|
-
const { widthDistributionType } = childrenConstraints;
|
|
2017
|
+
const { widthDistributionType } = childrenConstraints !== null && childrenConstraints !== void 0 ? childrenConstraints : {};
|
|
1965
2018
|
const totalGapSpace = gapWidthPx * (numChildren > 1 ? numChildren - 1 : 0);
|
|
1966
2019
|
const remainingContentSpace = containerWidthPx - totalGapSpace;
|
|
1967
2020
|
switch (widthDistributionType) {
|
|
@@ -2035,6 +2088,7 @@ function Container({ children, config, devMode, devNode }) {
|
|
|
2035
2088
|
width: config.gap || "0",
|
|
2036
2089
|
lineHeight: "1px",
|
|
2037
2090
|
fontSize: "1px",
|
|
2091
|
+
background: "transparent",
|
|
2038
2092
|
};
|
|
2039
2093
|
const justifyAlign = config.justifyContent
|
|
2040
2094
|
? justifyMap$2[config.justifyContent]
|
|
@@ -2055,6 +2109,7 @@ function Container({ children, config, devMode, devNode }) {
|
|
|
2055
2109
|
fontSize: "0",
|
|
2056
2110
|
lineHeight: "0",
|
|
2057
2111
|
height: config.gap,
|
|
2112
|
+
background: "transparent",
|
|
2058
2113
|
}, children: "\u00A0" }))] }, `child-${index}`), jsxRuntime.jsx("td", { className: isStacking ? "desktop-gap-column" : undefined, width: config.gap, style: gapTdStyle, children: "\u00A0" }, `gap-${index}`)] }, `ctn:${index}`));
|
|
2059
2114
|
}
|
|
2060
2115
|
return (jsxRuntime.jsx("td", { className: isStacking ? "stack-td" : undefined, width: getChildWidths[index], style: childTdStyle, children: child }, `child-${index}`));
|
|
@@ -2062,7 +2117,7 @@ function Container({ children, config, devMode, devNode }) {
|
|
|
2062
2117
|
return (jsxRuntime.jsx("table", { "aria-label": `Container | Table Outer`, cellPadding: 0, cellSpacing: 0, role: "presentation", border: 0, style: {
|
|
2063
2118
|
position: "relative",
|
|
2064
2119
|
...outerTableStyle,
|
|
2065
|
-
}, children: jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsxs("td", { align: justifyAlign, children: [jsxRuntime.jsx("div", { dangerouslySetInnerHTML: { __html: msoFixedWrapper } }), jsxRuntime.jsxs("table", { className: [
|
|
2120
|
+
}, ...rootBindingProps(bindings), children: jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsxs("td", { align: justifyAlign, children: [jsxRuntime.jsx("div", { dangerouslySetInnerHTML: { __html: msoFixedWrapper } }), jsxRuntime.jsxs("table", { className: [
|
|
2066
2121
|
widthType === "fixed" ? "container-fixed-width" : undefined,
|
|
2067
2122
|
devMode ? "main-wrapper relative" : undefined,
|
|
2068
2123
|
]
|
|
@@ -2071,22 +2126,22 @@ function Container({ children, config, devMode, devNode }) {
|
|
|
2071
2126
|
width: "100%",
|
|
2072
2127
|
maxWidth: widthType === "fixed" ? config.width || "600px" : undefined,
|
|
2073
2128
|
borderCollapse: "collapse",
|
|
2074
|
-
}, width: containerWidthAttr, children: [jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { style: backgroundTdStyle, children: jsxRuntime.jsx("table", { "aria-label": `Container | Border Wrapper`, cellPadding: 0, cellSpacing: 0, role: "presentation", border: 0, style: borderTableStyle, children: jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { style: innerTdStyle, children: jsxRuntime.jsx("table", { "aria-label": `Container | Content Table`, cellPadding: 0, cellSpacing: 0, role: "presentation", border: 0, style: contentTableStyle, children: jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: rowElements }) }) }) }) }) }) }) }) }) }), !!devNode && (jsxRuntime.jsx("tfoot", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { children: devNode }) }) }))] }), jsxRuntime.jsx("div", { dangerouslySetInnerHTML: { __html: msoFixedFooter } })] }) }) }) }));
|
|
2129
|
+
}, width: containerWidthAttr, children: [jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { style: backgroundTdStyle, children: jsxRuntime.jsx("table", { "aria-label": `Container | Border Wrapper`, cellPadding: 0, cellSpacing: 0, role: "presentation", border: 0, style: borderTableStyle, children: jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { style: innerTdStyle, children: jsxRuntime.jsx("table", { "aria-label": `Container | Content Table`, cellPadding: 0, cellSpacing: 0, role: "presentation", border: 0, style: contentTableStyle, children: jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { ...listBindingProps(bindings), children: rowElements }) }) }) }) }) }) }) }) }) }), !!devNode && (jsxRuntime.jsx("tfoot", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { children: devNode }) }) }))] }), jsxRuntime.jsx("div", { dangerouslySetInnerHTML: { __html: msoFixedFooter } })] }) }) }) }));
|
|
2075
2130
|
}
|
|
2076
2131
|
var Container_default = React.memo(Container, arePropsEqual);
|
|
2077
2132
|
|
|
2078
|
-
function Divider({ config, devNode }) {
|
|
2133
|
+
function Divider({ config, devNode, bindings }) {
|
|
2079
2134
|
const { height = "1px", color = "#cccccc", width = "100%", margin = "20px 0", align = "center", hideOnMobile, } = config;
|
|
2080
2135
|
const heightPx = parseInt(height, 10) || 1;
|
|
2081
2136
|
// Parse margin into paddingTop / paddingBottom for the outer TD.
|
|
2082
2137
|
// Outlook ignores shorthand "20px 0" on TDs — must be explicit.
|
|
2083
|
-
const [marginTopRaw = "0", marginRightRaw = "0", marginBottomRaw, marginLeftRaw] = margin.trim().split(/\s+/);
|
|
2138
|
+
const [marginTopRaw = "0", marginRightRaw = "0", marginBottomRaw, marginLeftRaw,] = margin.trim().split(/\s+/);
|
|
2084
2139
|
const marginTop = marginTopRaw;
|
|
2085
2140
|
const marginBottom = marginBottomRaw !== null && marginBottomRaw !== void 0 ? marginBottomRaw : marginTopRaw; // "20px 0" → top=20px, bottom=20px
|
|
2086
2141
|
// Outlook requires align on the outer TD to correctly position
|
|
2087
2142
|
// a fixed-width inner table (e.g. width="300px").
|
|
2088
2143
|
const alignAttr = align === "left" ? "left" : align === "right" ? "right" : "center";
|
|
2089
|
-
return (jsxRuntime.jsxs("table", { role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: {
|
|
2144
|
+
return (jsxRuntime.jsxs("table", { role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, ...rootBindingProps(bindings), style: {
|
|
2090
2145
|
position: "relative", // dev overlay anchor
|
|
2091
2146
|
width: "100%",
|
|
2092
2147
|
borderCollapse: "collapse",
|
|
@@ -2405,8 +2460,32 @@ function injectLinkStyles(html, fallback) {
|
|
|
2405
2460
|
return result;
|
|
2406
2461
|
}
|
|
2407
2462
|
|
|
2408
|
-
|
|
2409
|
-
|
|
2463
|
+
// Helper to build link href based on innerLink type
|
|
2464
|
+
function buildLinkHref$3(innerLink) {
|
|
2465
|
+
if (!innerLink || innerLink.type === "none")
|
|
2466
|
+
return null;
|
|
2467
|
+
switch (innerLink.type) {
|
|
2468
|
+
case "url":
|
|
2469
|
+
return innerLink.url || null;
|
|
2470
|
+
case "email":
|
|
2471
|
+
return innerLink.email ? `mailto:${innerLink.email}` : null;
|
|
2472
|
+
case "phone":
|
|
2473
|
+
return innerLink.phone ? `tel:${innerLink.phone}` : null;
|
|
2474
|
+
case "anchor":
|
|
2475
|
+
return innerLink.anchor ? `#${innerLink.anchor}` : null;
|
|
2476
|
+
case "page_top":
|
|
2477
|
+
return "#top";
|
|
2478
|
+
case "page_bottom":
|
|
2479
|
+
return "#bottom";
|
|
2480
|
+
default:
|
|
2481
|
+
return null;
|
|
2482
|
+
}
|
|
2483
|
+
}
|
|
2484
|
+
function Heading({ config, devMode, children, bindings }) {
|
|
2485
|
+
const { text, level = "h1", padding, color, textAlign, fontFamily, fontSize, fontWeight, fontStyle, lineHeight, letterSpacing, textTransform, textDecoration, direction, verticalAlign, backgroundColor, wordBreak, whiteSpace, innerLink, } = config;
|
|
2486
|
+
// Resolve href and target from innerLink
|
|
2487
|
+
const href = buildLinkHref$3(innerLink);
|
|
2488
|
+
const target = (innerLink === null || innerLink === void 0 ? void 0 : innerLink.target) || "_blank";
|
|
2410
2489
|
// Determine the content to render
|
|
2411
2490
|
const content = text !== null && text !== void 0 ? text : children;
|
|
2412
2491
|
const isString = typeof content === "string";
|
|
@@ -2443,12 +2522,17 @@ function Heading({ config, devMode, children }) {
|
|
|
2443
2522
|
: "";
|
|
2444
2523
|
// Dynamically create the Heading element
|
|
2445
2524
|
const HeadingTag = level;
|
|
2525
|
+
const headingElement = isString ? (jsxRuntime.jsx(HeadingTag, { style: headingStyle, dangerouslySetInnerHTML: { __html: processedHtml } })) : (jsxRuntime.jsx(HeadingTag, { style: headingStyle, children: content }));
|
|
2446
2526
|
return (
|
|
2447
2527
|
// Wrap the heading content in a table for padding/width/background management.
|
|
2448
|
-
jsxRuntime.jsx("table", { "aria-label": "Heading Block Wrapper", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: {
|
|
2528
|
+
jsxRuntime.jsx("table", { "aria-label": "Heading Block Wrapper", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, ...rootBindingProps(bindings), style: {
|
|
2449
2529
|
width: "100%",
|
|
2450
2530
|
borderCollapse: "collapse",
|
|
2451
|
-
}, children: jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { style: tdStyle, align: textAlign, children:
|
|
2531
|
+
}, children: jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { style: tdStyle, align: textAlign, children: href && !devMode ? (jsxRuntime.jsx("a", { href: href, target: target, ...(target === "_blank" ? { rel: "noopener noreferrer" } : {}), style: {
|
|
2532
|
+
display: "block",
|
|
2533
|
+
textDecoration: "none",
|
|
2534
|
+
color: "inherit",
|
|
2535
|
+
}, children: headingElement })) : (headingElement) }) }) }) }));
|
|
2452
2536
|
}
|
|
2453
2537
|
var Heading_default = React.memo(Heading, arePropsEqual);
|
|
2454
2538
|
|
|
@@ -2473,7 +2557,7 @@ function Html({ children, backgroundColor = "#ffffff", }) {
|
|
|
2473
2557
|
}
|
|
2474
2558
|
|
|
2475
2559
|
// Helper to build link href based on innerLink type
|
|
2476
|
-
function buildLinkHref$
|
|
2560
|
+
function buildLinkHref$2(innerLink) {
|
|
2477
2561
|
if (!innerLink || innerLink.type === "none")
|
|
2478
2562
|
return null;
|
|
2479
2563
|
switch (innerLink.type) {
|
|
@@ -2533,11 +2617,15 @@ function getBorderStyleString$1(border) {
|
|
|
2533
2617
|
styles.push(`border-left:${border.left.width} ${border.left.style} ${border.left.color} !important;`);
|
|
2534
2618
|
return styles.join(" ");
|
|
2535
2619
|
}
|
|
2536
|
-
function Image({ config, devNode, devMode }) {
|
|
2620
|
+
function Image({ config, devNode, devMode, bindings }) {
|
|
2537
2621
|
var _a, _b;
|
|
2538
|
-
const { src, alt, innerLink, mobile } = config;
|
|
2622
|
+
const { src: originalSrc, alt, innerLink, mobile } = config;
|
|
2623
|
+
// In dev mode, if there's no src, use the placeholder
|
|
2624
|
+
const src = devMode && !originalSrc
|
|
2625
|
+
? "https://placehold.co/300x200?text=select+an+image&font=poppins"
|
|
2626
|
+
: originalSrc;
|
|
2539
2627
|
// Resolve href and target from innerLink
|
|
2540
|
-
const href = buildLinkHref$
|
|
2628
|
+
const href = buildLinkHref$2(innerLink);
|
|
2541
2629
|
const target = (innerLink === null || innerLink === void 0 ? void 0 : innerLink.target) || "_blank";
|
|
2542
2630
|
const seed = src + (alt || "");
|
|
2543
2631
|
const instanceId = seed
|
|
@@ -2551,43 +2639,37 @@ function Image({ config, devNode, devMode }) {
|
|
|
2551
2639
|
const widthAttr = desktopWidth.replace("px", "");
|
|
2552
2640
|
const heightAttr = (_a = config.height) === null || _a === void 0 ? void 0 : _a.replace("px", "");
|
|
2553
2641
|
// Determine the table's "initial" width.
|
|
2554
|
-
// If it's 300px, the table should be 300px, not 100%.
|
|
2555
2642
|
const tableWidth = isPercent ? desktopWidth : `${widthAttr}px`;
|
|
2556
|
-
//
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2643
|
+
// Calculate width attribute for Outlook
|
|
2644
|
+
let imgWidthAttr;
|
|
2645
|
+
if (config.outlookWidth) {
|
|
2646
|
+
// Use explicit outlookWidth if provided
|
|
2647
|
+
imgWidthAttr = parseInt(config.outlookWidth, 10);
|
|
2648
|
+
}
|
|
2649
|
+
else if (isPercent) {
|
|
2650
|
+
// For percentage widths, use maxWidth as fallback for Outlook
|
|
2651
|
+
const maxWidthPx = ((_b = config.maxWidth) === null || _b === void 0 ? void 0 : _b.endsWith("px"))
|
|
2652
|
+
? parseInt(config.maxWidth, 10)
|
|
2653
|
+
: undefined;
|
|
2654
|
+
imgWidthAttr = maxWidthPx !== null && maxWidthPx !== void 0 ? maxWidthPx : undefined;
|
|
2655
|
+
}
|
|
2656
|
+
else {
|
|
2657
|
+
// For fixed pixel widths, use that value
|
|
2658
|
+
imgWidthAttr = widthAttr ? parseInt(widthAttr, 10) : undefined;
|
|
2659
|
+
}
|
|
2660
|
+
// 2. Mobile Overrides
|
|
2573
2661
|
let mobileCss = "";
|
|
2574
2662
|
if (mobile) {
|
|
2575
|
-
|
|
2576
|
-
const wrapRules = [
|
|
2577
|
-
// Always reset min-width so the px lock from desktop can be overridden
|
|
2578
|
-
"min-width: 0 !important;",
|
|
2579
|
-
];
|
|
2663
|
+
const wrapRules = ["min-width: 0 !important;"];
|
|
2580
2664
|
if (mobile.width !== undefined)
|
|
2581
2665
|
wrapRules.push(`width: ${mobile.width} !important;`);
|
|
2582
2666
|
if (mobile.maxWidth !== undefined)
|
|
2583
2667
|
wrapRules.push(`max-width: ${mobile.maxWidth} !important;`);
|
|
2584
|
-
// .td-${imgClass} rules
|
|
2585
2668
|
const tdRules = [];
|
|
2586
2669
|
if (mobile.padding !== undefined)
|
|
2587
2670
|
tdRules.push(`padding: ${mobile.padding} !important;`);
|
|
2588
2671
|
if (mobile.backgroundColor !== undefined)
|
|
2589
2672
|
tdRules.push(`background-color: ${mobile.backgroundColor} !important;`);
|
|
2590
|
-
// .${imgClass} rules
|
|
2591
2673
|
const imgRules = [];
|
|
2592
2674
|
if (mobile.width !== undefined)
|
|
2593
2675
|
imgRules.push(`width: ${mobile.width} !important;`);
|
|
@@ -2610,7 +2692,6 @@ function Image({ config, devNode, devMode }) {
|
|
|
2610
2692
|
mobileCss = `
|
|
2611
2693
|
@media screen and (max-width: 768px) {
|
|
2612
2694
|
.wrap-${imgClass} {
|
|
2613
|
-
/* This breaks the px lock from desktop and makes it fluid */
|
|
2614
2695
|
${wrapRules.join("\n ")}
|
|
2615
2696
|
}
|
|
2616
2697
|
.td-${imgClass} {
|
|
@@ -2636,9 +2717,27 @@ function Image({ config, devNode, devMode }) {
|
|
|
2636
2717
|
objectPosition: config.objectPosition,
|
|
2637
2718
|
};
|
|
2638
2719
|
const imageElement = (jsxRuntime.jsx("img", { src: src, alt: alt, width: imgWidthAttr, height: heightAttr !== "auto" ? heightAttr : undefined, className: imgClass, style: imgStyle, draggable: !devMode }));
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2720
|
+
// Outlook Classic wrapper - only applied when outlookWidth is explicitly set
|
|
2721
|
+
// OR when we need to constrain a percentage-width image in Outlook
|
|
2722
|
+
const needsOutlookWrapper = config.outlookWidth || (isPercent && imgWidthAttr);
|
|
2723
|
+
const finalImageElement = needsOutlookWrapper ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("style", { dangerouslySetInnerHTML: {
|
|
2724
|
+
__html: `</style>` +
|
|
2725
|
+
`<!--[if mso]>` +
|
|
2726
|
+
`<table cellpadding="0" cellspacing="0" border="0" style="width: ${imgWidthAttr}px;">` +
|
|
2727
|
+
`<tr>` +
|
|
2728
|
+
`<td style="padding: 0; margin: 0;" width="${imgWidthAttr}">` +
|
|
2729
|
+
`<img src="${src}" alt="${alt || ""}" width="${imgWidthAttr}" height="${heightAttr !== "auto" ? heightAttr : ""}" style="display: block; width: 100%; height: auto;" />` +
|
|
2730
|
+
`</td>` +
|
|
2731
|
+
`</tr>` +
|
|
2732
|
+
`</table>` +
|
|
2733
|
+
`<![endif]-->` +
|
|
2734
|
+
`<!--[if !mso]><!-->` +
|
|
2735
|
+
`<style>`,
|
|
2736
|
+
} }), imageElement, jsxRuntime.jsx("style", { dangerouslySetInnerHTML: {
|
|
2737
|
+
__html: `</style>` + `<!--<![endif]-->` + `<style>`,
|
|
2738
|
+
} })] })) : (imageElement);
|
|
2739
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [mobile && jsxRuntime.jsx("style", { dangerouslySetInnerHTML: { __html: mobileCss } }), jsxRuntime.jsxs("table", { role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, className: `wrap-${imgClass}`, align: "center", ...rootBindingProps(bindings), style: {
|
|
2740
|
+
width: tableWidth,
|
|
2642
2741
|
maxWidth: "100%",
|
|
2643
2742
|
borderCollapse: "collapse",
|
|
2644
2743
|
margin: "0 auto",
|
|
@@ -2647,10 +2746,10 @@ function Image({ config, devNode, devMode }) {
|
|
|
2647
2746
|
backgroundColor: config.backgroundColor,
|
|
2648
2747
|
fontSize: "0",
|
|
2649
2748
|
lineHeight: "0",
|
|
2650
|
-
width: tableWidth,
|
|
2749
|
+
width: tableWidth,
|
|
2651
2750
|
}, children: href && !devMode ? (jsxRuntime.jsx("a", { href: href, target: target, ...(target === "_blank"
|
|
2652
2751
|
? { rel: "noopener noreferrer" }
|
|
2653
|
-
: {}), style: { display: "block", width: "100%" }, children:
|
|
2752
|
+
: {}), style: { display: "block", width: "100%" }, children: finalImageElement })) : (finalImageElement) }) }) }), devMode && !!devNode && (jsxRuntime.jsx("tfoot", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { children: devNode }) }) }))] })] }));
|
|
2654
2753
|
}
|
|
2655
2754
|
var Image_default = React.memo(Image, arePropsEqual);
|
|
2656
2755
|
|
|
@@ -2719,7 +2818,21 @@ function getHrefFromInnerLink(innerLink) {
|
|
|
2719
2818
|
return undefined;
|
|
2720
2819
|
}
|
|
2721
2820
|
}
|
|
2722
|
-
|
|
2821
|
+
/**
|
|
2822
|
+
* Resolves the width for a child <td> at the given index based on layoutColumns.
|
|
2823
|
+
*
|
|
2824
|
+
* - "equal" → equal percentage share across all children
|
|
2825
|
+
* - string[] → explicit value at the matching index (px, %, or mixed)
|
|
2826
|
+
* - undefined → undefined, so no width attribute is set (retrocompat)
|
|
2827
|
+
*/
|
|
2828
|
+
function resolveChildColumnWidth(layoutColumns, index, numChildren) {
|
|
2829
|
+
if (!layoutColumns)
|
|
2830
|
+
return undefined;
|
|
2831
|
+
if (layoutColumns === "equal")
|
|
2832
|
+
return `${100 / numChildren}%`;
|
|
2833
|
+
return layoutColumns[index];
|
|
2834
|
+
}
|
|
2835
|
+
function Row({ children, config, devNode, devMode, bindings }) {
|
|
2723
2836
|
var _a, _b, _c, _d, _e, _f;
|
|
2724
2837
|
const childrenArray = (Array.isArray(children) ? children : [children]).filter((child) => child != null);
|
|
2725
2838
|
const numChildren = childrenArray.length;
|
|
@@ -2730,6 +2843,9 @@ function Row({ children, config, devNode, devMode }) {
|
|
|
2730
2843
|
// / mobile-gap-spacer class names so that stacking works via non-@media CSS
|
|
2731
2844
|
// rules that survive Gmail's stylesheet stripping.
|
|
2732
2845
|
const isStacking = ((_b = config.mobile) === null || _b === void 0 ? void 0 : _b.wrap) === true && numChildren > 1;
|
|
2846
|
+
// Whether layoutColumns is active. When true, table-layout:fixed is applied
|
|
2847
|
+
// to the content table so Outlook Classic honours the declared column widths.
|
|
2848
|
+
const hasLayoutColumns = config.layoutColumns !== undefined;
|
|
2733
2849
|
// 1. Outer TD: Background, Border Radius, Width, Height.
|
|
2734
2850
|
const backgroundTdStyle = {
|
|
2735
2851
|
backgroundColor: config.backgroundColor,
|
|
@@ -2770,24 +2886,34 @@ function Row({ children, config, devNode, devMode }) {
|
|
|
2770
2886
|
// Content table fills available space, giving Outlook Classic a hard
|
|
2771
2887
|
// boundary so text children get a constrained box and line wrapping
|
|
2772
2888
|
// triggers correctly. Use for rows containing text + image layouts.
|
|
2889
|
+
//
|
|
2890
|
+
// layoutColumns (any value) → additionally applies table-layout: fixed
|
|
2891
|
+
// so Outlook Classic honours the per-child width declarations.
|
|
2892
|
+
// Compatible with both fillWidth modes.
|
|
2773
2893
|
const contentTableStyle = {
|
|
2774
|
-
|
|
2894
|
+
// When layoutColumns is active, force 100% so Outlook Classic has a
|
|
2895
|
+
// concrete boundary to resolve percentage column widths against.
|
|
2896
|
+
// table-layout:fixed is meaningless without a fixed reference width.
|
|
2897
|
+
width: hasLayoutColumns || config.fillWidth ? "100%" : "auto",
|
|
2775
2898
|
height: "100%",
|
|
2776
2899
|
borderCollapse: "collapse",
|
|
2777
2900
|
minWidth: "1px",
|
|
2778
|
-
...(!config.fillWidth &&
|
|
2901
|
+
...(!config.fillWidth &&
|
|
2902
|
+
!hasLayoutColumns && { maxWidth: config.width || "100%" }),
|
|
2903
|
+
...(hasLayoutColumns && { tableLayout: "fixed" }),
|
|
2779
2904
|
};
|
|
2780
2905
|
// 5. Gap TD.
|
|
2781
2906
|
const gapTdStyle = {
|
|
2782
2907
|
width: config.gap || "0",
|
|
2783
2908
|
lineHeight: "1px",
|
|
2784
2909
|
fontSize: "1px",
|
|
2910
|
+
background: "transparent",
|
|
2785
2911
|
};
|
|
2786
2912
|
const tdAlign = config.justifyContent
|
|
2787
2913
|
? justifyMap$1[config.justifyContent]
|
|
2788
2914
|
: "left";
|
|
2789
2915
|
const tdValign = config.alignItems ? alignMap[config.alignItems] : "top";
|
|
2790
|
-
const content = (jsxRuntime.jsxs("table", { "aria-label": "Row Outer", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: {
|
|
2916
|
+
const content = (jsxRuntime.jsxs("table", { "aria-label": "Row Outer", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, ...(!href ? rootBindingProps(bindings) : {}), style: {
|
|
2791
2917
|
position: "relative",
|
|
2792
2918
|
width: config.width || "100%",
|
|
2793
2919
|
height: config.height,
|
|
@@ -2796,32 +2922,44 @@ function Row({ children, config, devNode, devMode }) {
|
|
|
2796
2922
|
width: "100%",
|
|
2797
2923
|
height: "100%",
|
|
2798
2924
|
borderCollapse: "collapse",
|
|
2799
|
-
}, children: jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { align: tdAlign, width: "100%", style: { width: "100%" }, children: jsxRuntime.jsx("table", { "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-wrap": ((_f = config.mobile) === null || _f === void 0 ? void 0 : _f.wrap) ? "true" : undefined, "data-gap": config.gap, children: jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { className: "content-tr", children: childrenArray.map((child, index) =>
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2925
|
+
}, children: jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { align: tdAlign, width: "100%", style: { width: "100%" }, children: jsxRuntime.jsx("table", { "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-wrap": ((_f = config.mobile) === null || _f === void 0 ? void 0 : _f.wrap) ? "true" : undefined, "data-gap": config.gap, children: jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { className: "content-tr", ...listBindingProps(bindings), children: childrenArray.map((child, index) => {
|
|
2926
|
+
// Resolve the column width for this child based on
|
|
2927
|
+
// layoutColumns. undefined when layoutColumns is not set,
|
|
2928
|
+
// preserving the original behaviour (retrocompat).
|
|
2929
|
+
const columnWidth = resolveChildColumnWidth(config.layoutColumns, index, numChildren);
|
|
2930
|
+
return (jsxRuntime.jsxs(React.Fragment, { children: [jsxRuntime.jsxs("td", { align: tdAlign, ...(columnWidth && {
|
|
2931
|
+
width: columnWidth,
|
|
2932
|
+
}), style: {
|
|
2933
|
+
verticalAlign: tdValign,
|
|
2934
|
+
textAlign: tdAlign,
|
|
2935
|
+
padding: "0",
|
|
2936
|
+
margin: "0",
|
|
2937
|
+
...(columnWidth && {
|
|
2938
|
+
width: columnWidth,
|
|
2939
|
+
}),
|
|
2940
|
+
},
|
|
2941
|
+
// Mirror of Container's stack-td pattern: when isStacking,
|
|
2942
|
+
// the non-@media .stack-td rule forces display:block +
|
|
2943
|
+
// width:100% on each child, which survives Gmail's
|
|
2944
|
+
// @media stripping and achieves true mobile stacking.
|
|
2945
|
+
className: `child-cell${isStacking ? " stack-td" : ""}`, children: [child, isStacking &&
|
|
2946
|
+
index < numChildren - 1 &&
|
|
2947
|
+
config.gap && (jsxRuntime.jsx("div", { className: "mobile-gap-spacer", style: {
|
|
2948
|
+
display: "none",
|
|
2949
|
+
fontSize: "0",
|
|
2950
|
+
lineHeight: "0",
|
|
2951
|
+
height: config.gap,
|
|
2952
|
+
background: "transparent",
|
|
2953
|
+
}, children: "\u00A0" }))] }), index < numChildren - 1 &&
|
|
2954
|
+
config.gap && (jsxRuntime.jsx("td", { width: config.gap, style: gapTdStyle,
|
|
2955
|
+
// Mirror of Container's desktop-gap-column pattern:
|
|
2956
|
+
// when isStacking, the non-@media .desktop-gap-column
|
|
2957
|
+
// rule collapses the between-column gap td so it does
|
|
2958
|
+
// not create phantom space while children are stacked.
|
|
2959
|
+
className: `row-gap-td${isStacking ? " desktop-gap-column" : ""}`, children: "\u00A0" }, `row-gap-${index}`))] }, `row-child-${index}`));
|
|
2960
|
+
}) }) }) }) }) }) }) }) }) }) }) }) }) }) }), devNode && (jsxRuntime.jsx("tfoot", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { children: devNode }) }) }))] }));
|
|
2823
2961
|
if (href && !devMode) {
|
|
2824
|
-
return (jsxRuntime.jsx("a", { href: href, ...({ target }), style: {
|
|
2962
|
+
return (jsxRuntime.jsx("a", { href: href, ...({ target }), ...rootBindingProps(bindings), style: {
|
|
2825
2963
|
textDecoration: "none",
|
|
2826
2964
|
color: "inherit",
|
|
2827
2965
|
display: "block",
|
|
@@ -2866,10 +3004,10 @@ function getBorderStyle$1(border) {
|
|
|
2866
3004
|
}
|
|
2867
3005
|
return style;
|
|
2868
3006
|
}
|
|
2869
|
-
const Section = ({ config, children, devNode, }) => {
|
|
3007
|
+
const Section = ({ config, children, devNode, bindings, }) => {
|
|
2870
3008
|
var _a, _b, _c;
|
|
2871
3009
|
const { sectionType, padding } = config;
|
|
2872
|
-
return (jsxRuntime.jsxs("table", { "aria-label": `Section |Table | ${sectionType}`, role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: {
|
|
3010
|
+
return (jsxRuntime.jsxs("table", { "aria-label": `Section |Table | ${sectionType}`, role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, ...rootBindingProps(bindings), style: {
|
|
2873
3011
|
position: "relative",
|
|
2874
3012
|
width: "100%",
|
|
2875
3013
|
backgroundColor: config.backgroundColor,
|
|
@@ -2882,58 +3020,84 @@ const Section = ({ config, children, devNode, }) => {
|
|
|
2882
3020
|
backgroundPosition: (_c = config.backgroundImage) === null || _c === void 0 ? void 0 : _c.position,
|
|
2883
3021
|
}, children: [jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { style: {
|
|
2884
3022
|
padding: padding,
|
|
2885
|
-
}, children: children }) }) }), devNode && (jsxRuntime.jsx("tfoot", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
3023
|
+
}, ...listBindingProps(bindings), children: children }) }) }), devNode && (jsxRuntime.jsx("tfoot", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { children: jsxRuntime.jsxs("span", { style: {
|
|
3024
|
+
backgroundColor: "black",
|
|
3025
|
+
color: "white",
|
|
3026
|
+
padding: "4px",
|
|
3027
|
+
fontSize: "14px",
|
|
3028
|
+
position: "absolute",
|
|
3029
|
+
left: 0,
|
|
3030
|
+
top: 0,
|
|
3031
|
+
}, children: ["Section | ", sectionType] }) }) }) }))] }));
|
|
2894
3032
|
};
|
|
2895
3033
|
var Section_default = React.memo(Section, arePropsEqual);
|
|
2896
3034
|
|
|
2897
|
-
function Spacer({ config, devNode }) {
|
|
2898
|
-
|
|
3035
|
+
function Spacer({ config, devNode, bindings }) {
|
|
3036
|
+
var _a, _b, _c;
|
|
3037
|
+
const { height, hideOnMobile, backgroundColor, backgroundImage } = config;
|
|
2899
3038
|
// 1. Spacer Table Style
|
|
2900
3039
|
const spacerTableStyle = {
|
|
2901
|
-
// Crucial for compatibility: Ensures no background or border interference
|
|
2902
|
-
backgroundColor: "transparent",
|
|
2903
3040
|
borderCollapse: "collapse",
|
|
2904
|
-
border: "0",
|
|
2905
3041
|
width: "100%",
|
|
2906
|
-
// Note the CSS standard dash convention: 'mso-table-lspace'
|
|
2907
|
-
// ["mso-table-lspace" as string]: "0pt",
|
|
2908
|
-
["msoTableLspace"]: "0pt",
|
|
2909
|
-
// ["mso-table-rspace" as string]: "0pt",
|
|
2910
|
-
["msoTableRspace"]: "0pt",
|
|
2911
3042
|
};
|
|
2912
3043
|
// 2. Spacer TD Style: The element that creates the actual vertical space
|
|
2913
3044
|
const spacerTdStyle = {
|
|
2914
3045
|
height: height,
|
|
2915
|
-
|
|
3046
|
+
maxHeight: height,
|
|
2916
3047
|
fontSize: "0",
|
|
2917
3048
|
lineHeight: "0",
|
|
2918
3049
|
padding: "0",
|
|
3050
|
+
margin: "0",
|
|
3051
|
+
border: "none",
|
|
3052
|
+
color: "transparent",
|
|
3053
|
+
// Background applied at TD level for Outlook Classic compatibility
|
|
3054
|
+
...(backgroundColor && { backgroundColor }),
|
|
3055
|
+
...(backgroundImage && {
|
|
3056
|
+
backgroundImage: `url(${backgroundImage.src})`,
|
|
3057
|
+
backgroundRepeat: (_a = backgroundImage.repeat) !== null && _a !== void 0 ? _a : "no-repeat",
|
|
3058
|
+
backgroundSize: (_b = backgroundImage.size) !== null && _b !== void 0 ? _b : "cover",
|
|
3059
|
+
backgroundPosition: (_c = backgroundImage.position) !== null && _c !== void 0 ? _c : "center",
|
|
3060
|
+
}),
|
|
2919
3061
|
};
|
|
2920
3062
|
// Parse height for the HTML attribute
|
|
2921
3063
|
const spacerHeightAttribute = parseInt(height, 10) || 1;
|
|
2922
|
-
return (
|
|
2923
|
-
// Outer table ensures the spacer spans the full width of its container
|
|
2924
|
-
jsxRuntime.jsxs("table", { "aria-label": "Vertical Spacer", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: {
|
|
3064
|
+
return (jsxRuntime.jsxs("table", { "aria-label": "Vertical Spacer", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, ...rootBindingProps(bindings), style: {
|
|
2925
3065
|
// --- Start dev
|
|
2926
3066
|
position: "relative",
|
|
2927
3067
|
// --- End dev
|
|
2928
3068
|
...spacerTableStyle,
|
|
2929
|
-
}, ...{ height: spacerHeightAttribute }, className: hideOnMobile ? "hide-on-mobile" : undefined, children: [jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { style: spacerTdStyle,
|
|
2930
|
-
|
|
2931
|
-
|
|
3069
|
+
}, ...{ height: spacerHeightAttribute }, className: hideOnMobile ? "hide-on-mobile" : undefined, children: [jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { style: spacerTdStyle, height: spacerHeightAttribute, ...(backgroundColor && !backgroundImage
|
|
3070
|
+
? { bgcolor: backgroundColor }
|
|
3071
|
+
: {}) }) }) }), devNode && (jsxRuntime.jsx("tfoot", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { children: devNode }) }) }))] }));
|
|
2932
3072
|
}
|
|
2933
3073
|
var Spacer_default = React.memo(Spacer, arePropsEqual);
|
|
2934
3074
|
|
|
2935
|
-
|
|
2936
|
-
|
|
3075
|
+
// Helper to build link href based on innerLink type
|
|
3076
|
+
function buildLinkHref$1(innerLink) {
|
|
3077
|
+
if (!innerLink || innerLink.type === "none")
|
|
3078
|
+
return null;
|
|
3079
|
+
switch (innerLink.type) {
|
|
3080
|
+
case "url":
|
|
3081
|
+
return innerLink.url || null;
|
|
3082
|
+
case "email":
|
|
3083
|
+
return innerLink.email ? `mailto:${innerLink.email}` : null;
|
|
3084
|
+
case "phone":
|
|
3085
|
+
return innerLink.phone ? `tel:${innerLink.phone}` : null;
|
|
3086
|
+
case "anchor":
|
|
3087
|
+
return innerLink.anchor ? `#${innerLink.anchor}` : null;
|
|
3088
|
+
case "page_top":
|
|
3089
|
+
return "#top";
|
|
3090
|
+
case "page_bottom":
|
|
3091
|
+
return "#bottom";
|
|
3092
|
+
default:
|
|
3093
|
+
return null;
|
|
3094
|
+
}
|
|
3095
|
+
}
|
|
3096
|
+
function Text({ config, devMode, children, bindings }) {
|
|
3097
|
+
const { text, padding, color, textAlign, fontFamily, fontSize, fontWeight, fontStyle, lineHeight, letterSpacing, textTransform, textDecoration, direction, verticalAlign, backgroundColor, opacity, whiteSpace, wordBreak = "break-all", maxWidth, innerLink, } = config;
|
|
3098
|
+
// Resolve href and target from innerLink
|
|
3099
|
+
const href = buildLinkHref$1(innerLink);
|
|
3100
|
+
const target = (innerLink === null || innerLink === void 0 ? void 0 : innerLink.target) || "_blank";
|
|
2937
3101
|
// 1. TD Style: Where padding and background are reliably applied.
|
|
2938
3102
|
// When maxWidth is set, this TD stays at width: 100% so it always fills
|
|
2939
3103
|
// its parent — the inner maxWidth table (see below) does the actual
|
|
@@ -2986,26 +3150,31 @@ function Text({ config, devMode, children }) {
|
|
|
2986
3150
|
? injectLinkStyles(content, contentStyle)
|
|
2987
3151
|
: "";
|
|
2988
3152
|
const innerContent = isString ? (jsxRuntime.jsx("div", { style: contentStyle, dangerouslySetInnerHTML: { __html: processedHtml } })) : (jsxRuntime.jsx("div", { style: contentStyle, children: content }));
|
|
2989
|
-
|
|
3153
|
+
const wrappedContent = maxWidth ? (
|
|
3154
|
+
/*
|
|
3155
|
+
* maxWidth wrapper — Outlook Classic compatibility pattern:
|
|
3156
|
+
*
|
|
3157
|
+
* <center> instructs the Word rendering engine to horizontally
|
|
3158
|
+
* centre its child block, equivalent to margin: 0 auto in CSS.
|
|
3159
|
+
*
|
|
3160
|
+
* The inner table carries the `width` HTML attribute set to the
|
|
3161
|
+
* maxWidth value. Outlook Classic reads `width` as a hard pixel
|
|
3162
|
+
* cap; it has no concept of max-width so this is the only lever
|
|
3163
|
+
* available. Modern clients receive the CSS max-width on the
|
|
3164
|
+
* same table and behave correctly.
|
|
3165
|
+
*
|
|
3166
|
+
* The outer TD remains at width: 100% so it always fills its
|
|
3167
|
+
* parent cell in every client — only the inner content is capped.
|
|
3168
|
+
*/
|
|
3169
|
+
jsxRuntime.jsx("center", { children: jsxRuntime.jsx("table", { "aria-label": "Text Max Width Wrapper", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, width: maxWidth, style: maxWidthTableStyle, children: jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { children: innerContent }) }) }) }) })) : (innerContent);
|
|
3170
|
+
return (jsxRuntime.jsx("table", { "aria-label": "Text Block Wrapper", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, ...rootBindingProps(bindings), style: {
|
|
2990
3171
|
width: "100%",
|
|
2991
3172
|
borderCollapse: "collapse",
|
|
2992
|
-
}, children: jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { style: tdStyle, align: textAlign, children:
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
* centre its child block, equivalent to margin: 0 auto in CSS.
|
|
2998
|
-
*
|
|
2999
|
-
* The inner table carries the `width` HTML attribute set to the
|
|
3000
|
-
* maxWidth value. Outlook Classic reads `width` as a hard pixel
|
|
3001
|
-
* cap; it has no concept of max-width so this is the only lever
|
|
3002
|
-
* available. Modern clients receive the CSS max-width on the
|
|
3003
|
-
* same table and behave correctly.
|
|
3004
|
-
*
|
|
3005
|
-
* The outer TD remains at width: 100% so it always fills its
|
|
3006
|
-
* parent cell in every client — only the inner content is capped.
|
|
3007
|
-
*/
|
|
3008
|
-
jsxRuntime.jsx("center", { children: jsxRuntime.jsx("table", { "aria-label": "Text Max Width Wrapper", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, width: maxWidth, style: maxWidthTableStyle, children: jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { children: innerContent }) }) }) }) })) : (innerContent) }) }) }) }));
|
|
3173
|
+
}, children: jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { style: tdStyle, align: textAlign, children: href && !devMode ? (jsxRuntime.jsx("a", { href: href, target: target, ...(target === "_blank" ? { rel: "noopener noreferrer" } : {}), style: {
|
|
3174
|
+
display: "block",
|
|
3175
|
+
textDecoration: "none",
|
|
3176
|
+
color: "inherit",
|
|
3177
|
+
}, children: wrappedContent })) : (wrappedContent) }) }) }) }));
|
|
3009
3178
|
}
|
|
3010
3179
|
var Text_default = React.memo(Text, arePropsEqual);
|
|
3011
3180
|
|
|
@@ -3131,7 +3300,7 @@ function buildLinkHref(innerLink) {
|
|
|
3131
3300
|
return null;
|
|
3132
3301
|
}
|
|
3133
3302
|
}
|
|
3134
|
-
function Icon({ config, devNode, devMode, children }) {
|
|
3303
|
+
function Icon({ config, devNode, devMode, children, bindings }) {
|
|
3135
3304
|
const {
|
|
3136
3305
|
// base64Source,
|
|
3137
3306
|
width, height, backgroundColor, padding = "0", borderRadius = "0", border, innerLink, justifyContent = "center", } = config;
|
|
@@ -3266,7 +3435,7 @@ function Icon({ config, devNode, devMode, children }) {
|
|
|
3266
3435
|
<!--<![endif]-->
|
|
3267
3436
|
`
|
|
3268
3437
|
: null;
|
|
3269
|
-
return (jsxRuntime.jsxs("table", { "aria-label": "Icon", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, align: align, style: {
|
|
3438
|
+
return (jsxRuntime.jsxs("table", { "aria-label": "Icon", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, align: align, ...rootBindingProps(bindings), style: {
|
|
3270
3439
|
// --- Start dev
|
|
3271
3440
|
position: "relative",
|
|
3272
3441
|
// --- End dev
|