@pagenflow/email 1.3.3 → 1.3.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/Row.d.ts +1 -0
- package/dist/index.cjs.js +281 -27
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.esm.js +282 -29
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -1
package/dist/components/Row.d.ts
CHANGED
package/dist/index.cjs.js
CHANGED
|
@@ -1526,7 +1526,7 @@ function arePropsEqual(prevProps, nextProps) {
|
|
|
1526
1526
|
}
|
|
1527
1527
|
|
|
1528
1528
|
// Map alignment to HTML 'align' attribute
|
|
1529
|
-
const justifyMap$
|
|
1529
|
+
const justifyMap$3 = {
|
|
1530
1530
|
start: "left",
|
|
1531
1531
|
center: "center",
|
|
1532
1532
|
end: "right",
|
|
@@ -1549,7 +1549,7 @@ function Button({ config, devMode }) {
|
|
|
1549
1549
|
const vmlFillColor = backgroundColor.startsWith("#")
|
|
1550
1550
|
? backgroundColor
|
|
1551
1551
|
: `#${backgroundColor}`;
|
|
1552
|
-
const align = justifyMap$
|
|
1552
|
+
const align = justifyMap$3[justifyContent];
|
|
1553
1553
|
// Build VML font styles
|
|
1554
1554
|
const vmlFontWeight = fontWeight || "bold";
|
|
1555
1555
|
const vmlFontStyle = fontStyle === "italic" ? "font-style:italic;" : "";
|
|
@@ -1712,7 +1712,7 @@ const alignMap$1 = {
|
|
|
1712
1712
|
center: "middle",
|
|
1713
1713
|
end: "bottom",
|
|
1714
1714
|
};
|
|
1715
|
-
const justifyMap$
|
|
1715
|
+
const justifyMap$2 = {
|
|
1716
1716
|
start: "left",
|
|
1717
1717
|
center: "center",
|
|
1718
1718
|
end: "right",
|
|
@@ -1816,7 +1816,7 @@ function Container({ children, config, devMode, devNode }) {
|
|
|
1816
1816
|
fontSize: "1px",
|
|
1817
1817
|
};
|
|
1818
1818
|
const justifyAlign = config.justifyContent
|
|
1819
|
-
? justifyMap$
|
|
1819
|
+
? justifyMap$2[config.justifyContent]
|
|
1820
1820
|
: "center";
|
|
1821
1821
|
const containerWidthAttr = widthType === "fixed" ? containerWidthPx : undefined;
|
|
1822
1822
|
const isStacking = config.shouldWrap && numChildren > 1;
|
|
@@ -1926,14 +1926,14 @@ function Head({ children, backgroundColor = "#ffffff", title = "Email Preview",
|
|
|
1926
1926
|
}
|
|
1927
1927
|
`;
|
|
1928
1928
|
const globalStyles = `
|
|
1929
|
-
@media screen and (max-width:
|
|
1929
|
+
@media screen and (max-width: 768px) {
|
|
1930
1930
|
.container-fixed-width {
|
|
1931
1931
|
width: 100% !important;
|
|
1932
1932
|
max-width: 100% !important;
|
|
1933
1933
|
}
|
|
1934
1934
|
}
|
|
1935
1935
|
|
|
1936
|
-
@media screen and (max-width:
|
|
1936
|
+
@media screen and (max-width: 768px) {
|
|
1937
1937
|
.stack-td {
|
|
1938
1938
|
width: 100% !important;
|
|
1939
1939
|
display: block !important;
|
|
@@ -1957,8 +1957,8 @@ function Head({ children, backgroundColor = "#ffffff", title = "Email Preview",
|
|
|
1957
1957
|
}
|
|
1958
1958
|
}
|
|
1959
1959
|
|
|
1960
|
-
@media only screen and (max-width:
|
|
1961
|
-
/* 1. Handling Mobile Alignment (Justify) */
|
|
1960
|
+
@media only screen and (max-width: 768px) {
|
|
1961
|
+
/* 1. Handling Mobile Alignment (Justify) - Works for both wrapped and non-wrapped */
|
|
1962
1962
|
/* We target the inner table alignment */
|
|
1963
1963
|
.responsive-row[data-mobile-justify="center"] .content-table {
|
|
1964
1964
|
margin: 0 auto !important;
|
|
@@ -1973,17 +1973,104 @@ function Head({ children, backgroundColor = "#ffffff", title = "Email Preview",
|
|
|
1973
1973
|
float: right !important;
|
|
1974
1974
|
}
|
|
1975
1975
|
|
|
1976
|
+
/* Mobile justify for wrapped children - we need to target the outer wrapper td */
|
|
1977
|
+
.responsive-row[data-mobile-wrap="true"][data-mobile-justify="center"] td[align] {
|
|
1978
|
+
text-align: center !important;
|
|
1979
|
+
}
|
|
1980
|
+
.responsive-row[data-mobile-wrap="true"][data-mobile-justify="start"] td[align] {
|
|
1981
|
+
text-align: left !important;
|
|
1982
|
+
}
|
|
1983
|
+
.responsive-row[data-mobile-wrap="true"][data-mobile-justify="end"] td[align] {
|
|
1984
|
+
text-align: right !important;
|
|
1985
|
+
}
|
|
1986
|
+
|
|
1987
|
+
/* Also apply to child content tables for better support */
|
|
1988
|
+
.responsive-row[data-mobile-wrap="true"][data-mobile-justify="center"] .child-cell table {
|
|
1989
|
+
margin-left: auto !important;
|
|
1990
|
+
margin-right: auto !important;
|
|
1991
|
+
}
|
|
1992
|
+
.responsive-row[data-mobile-wrap="true"][data-mobile-justify="start"] .child-cell table {
|
|
1993
|
+
margin-left: 0 !important;
|
|
1994
|
+
margin-right: auto !important;
|
|
1995
|
+
}
|
|
1996
|
+
.responsive-row[data-mobile-wrap="true"][data-mobile-justify="end"] .child-cell table {
|
|
1997
|
+
margin-left: auto !important;
|
|
1998
|
+
margin-right: 0 !important;
|
|
1999
|
+
}
|
|
2000
|
+
|
|
1976
2001
|
/* 2. Handling Mobile Vertical Alignment (Align Items) */
|
|
1977
|
-
/*
|
|
1978
|
-
.responsive-row[data-mobile-align="center"] .child-cell {
|
|
2002
|
+
/* For non-wrapped rows - controls vertical alignment when cells are side-by-side */
|
|
2003
|
+
.responsive-row[data-mobile-align="center"]:not([data-mobile-wrap="true"]) .child-cell {
|
|
2004
|
+
vertical-align: middle !important;
|
|
2005
|
+
}
|
|
2006
|
+
.responsive-row[data-mobile-align="start"]:not([data-mobile-wrap="true"]) .child-cell {
|
|
2007
|
+
vertical-align: top !important;
|
|
2008
|
+
}
|
|
2009
|
+
.responsive-row[data-mobile-align="end"]:not([data-mobile-wrap="true"]) .child-cell {
|
|
2010
|
+
vertical-align: bottom !important;
|
|
2011
|
+
}
|
|
2012
|
+
|
|
2013
|
+
/* For wrapped rows - alignItems controls vertical alignment of content within each child cell */
|
|
2014
|
+
.responsive-row[data-mobile-wrap="true"][data-mobile-align="center"] .child-cell {
|
|
1979
2015
|
vertical-align: middle !important;
|
|
1980
2016
|
}
|
|
1981
|
-
.responsive-row[data-mobile-align="start"] .child-cell {
|
|
2017
|
+
.responsive-row[data-mobile-wrap="true"][data-mobile-align="start"] .child-cell {
|
|
1982
2018
|
vertical-align: top !important;
|
|
1983
2019
|
}
|
|
1984
|
-
.responsive-row[data-mobile-align="end"] .child-cell {
|
|
2020
|
+
.responsive-row[data-mobile-wrap="true"][data-mobile-align="end"] .child-cell {
|
|
1985
2021
|
vertical-align: bottom !important;
|
|
1986
2022
|
}
|
|
2023
|
+
|
|
2024
|
+
/* 3. Handling Mobile Wrap - Pure CSS Solution */
|
|
2025
|
+
/* Force table to act like block container */
|
|
2026
|
+
.responsive-row[data-mobile-wrap="true"] .content-table {
|
|
2027
|
+
width: 100% !important;
|
|
2028
|
+
max-width: 100% !important;
|
|
2029
|
+
}
|
|
2030
|
+
|
|
2031
|
+
/* Force table row to stack cells */
|
|
2032
|
+
.responsive-row[data-mobile-wrap="true"] .content-tr {
|
|
2033
|
+
display: block !important;
|
|
2034
|
+
}
|
|
2035
|
+
|
|
2036
|
+
/* Force each child cell to be full width block */
|
|
2037
|
+
.responsive-row[data-mobile-wrap="true"] .child-cell {
|
|
2038
|
+
display: block !important;
|
|
2039
|
+
width: 100% !important;
|
|
2040
|
+
box-sizing: border-box !important;
|
|
2041
|
+
}
|
|
2042
|
+
|
|
2043
|
+
/* Hide horizontal gap cells and create vertical spacing with padding */
|
|
2044
|
+
.responsive-row[data-mobile-wrap="true"] .row-gap-td {
|
|
2045
|
+
display: none !important;
|
|
2046
|
+
width: 0 !important;
|
|
2047
|
+
height: 0 !important;
|
|
2048
|
+
}
|
|
2049
|
+
|
|
2050
|
+
/* Add vertical spacing between stacked cells using margin */
|
|
2051
|
+
.responsive-row[data-mobile-wrap="true"] .child-cell:not(:last-child) {
|
|
2052
|
+
margin-bottom: 20px !important;
|
|
2053
|
+
}
|
|
2054
|
+
|
|
2055
|
+
/* Dynamic gap support - common values */
|
|
2056
|
+
.responsive-row[data-mobile-wrap="true"][data-gap="10px"] .child-cell:not(:last-child) {
|
|
2057
|
+
margin-bottom: 10px !important;
|
|
2058
|
+
}
|
|
2059
|
+
.responsive-row[data-mobile-wrap="true"][data-gap="15px"] .child-cell:not(:last-child) {
|
|
2060
|
+
margin-bottom: 15px !important;
|
|
2061
|
+
}
|
|
2062
|
+
.responsive-row[data-mobile-wrap="true"][data-gap="20px"] .child-cell:not(:last-child) {
|
|
2063
|
+
margin-bottom: 20px !important;
|
|
2064
|
+
}
|
|
2065
|
+
.responsive-row[data-mobile-wrap="true"][data-gap="24px"] .child-cell:not(:last-child) {
|
|
2066
|
+
margin-bottom: 24px !important;
|
|
2067
|
+
}
|
|
2068
|
+
.responsive-row[data-mobile-wrap="true"][data-gap="30px"] .child-cell:not(:last-child) {
|
|
2069
|
+
margin-bottom: 30px !important;
|
|
2070
|
+
}
|
|
2071
|
+
.responsive-row[data-mobile-wrap="true"][data-gap="40px"] .child-cell:not(:last-child) {
|
|
2072
|
+
margin-bottom: 40px !important;
|
|
2073
|
+
}
|
|
1987
2074
|
}
|
|
1988
2075
|
|
|
1989
2076
|
/* ================================================= */
|
|
@@ -2181,7 +2268,7 @@ function Image({ config, devNode, devMode }) {
|
|
|
2181
2268
|
}
|
|
2182
2269
|
var Image_default = React.memo(Image, arePropsEqual);
|
|
2183
2270
|
|
|
2184
|
-
const justifyMap = {
|
|
2271
|
+
const justifyMap$1 = {
|
|
2185
2272
|
start: "left",
|
|
2186
2273
|
center: "center",
|
|
2187
2274
|
end: "right",
|
|
@@ -2213,7 +2300,7 @@ function getBorderStyle$1(border) {
|
|
|
2213
2300
|
return style;
|
|
2214
2301
|
}
|
|
2215
2302
|
function Row({ children, config, devNode }) {
|
|
2216
|
-
var _a, _b, _c, _d, _e;
|
|
2303
|
+
var _a, _b, _c, _d, _e, _f;
|
|
2217
2304
|
const childrenArray = (Array.isArray(children) ? children : [children]).filter((child) => child != null);
|
|
2218
2305
|
const numChildren = childrenArray.length;
|
|
2219
2306
|
// 1. Outer TD for Background and Border Radius (no border here)
|
|
@@ -2246,7 +2333,7 @@ function Row({ children, config, devNode }) {
|
|
|
2246
2333
|
fontSize: "1px",
|
|
2247
2334
|
};
|
|
2248
2335
|
const tdAlign = config.justifyContent
|
|
2249
|
-
? justifyMap[config.justifyContent]
|
|
2336
|
+
? justifyMap$1[config.justifyContent]
|
|
2250
2337
|
: "left";
|
|
2251
2338
|
const tdValign = config.alignItems ? alignMap[config.alignItems] : "top";
|
|
2252
2339
|
return (jsxRuntime.jsxs("table", Object.assign({ "aria-label": "Row Outer", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: {
|
|
@@ -2254,7 +2341,7 @@ function Row({ children, config, devNode }) {
|
|
|
2254
2341
|
width: config.width || "100%",
|
|
2255
2342
|
height: config.height,
|
|
2256
2343
|
borderCollapse: "collapse",
|
|
2257
|
-
} }, (config.height && { height: config.height }), { "data-mobile-justify": (_d = config.mobile) === null || _d === void 0 ? void 0 : _d.justifyContent, "data-mobile-align": (_e = config.mobile) === null || _e === void 0 ? void 0 : _e.alignItems, className: "responsive-row", children: [jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", Object.assign({ style: backgroundTdStyle }, (config.height && { height: config.height }), { children: jsxRuntime.jsx("table", { "aria-label": "Row Border Wrapper", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: borderTableStyle, children: jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { style: paddingTdStyle, children: jsxRuntime.jsx("table", { "aria-label": "Row Justification Wrapper", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: {
|
|
2344
|
+
} }, (config.height && { height: config.height }), { "data-mobile-justify": (_d = config.mobile) === null || _d === void 0 ? void 0 : _d.justifyContent, "data-mobile-align": (_e = config.mobile) === null || _e === void 0 ? void 0 : _e.alignItems, "data-mobile-wrap": ((_f = config.mobile) === null || _f === void 0 ? void 0 : _f.wrap) ? "true" : undefined, "data-gap": config.gap, className: "responsive-row", children: [jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", Object.assign({ style: backgroundTdStyle }, (config.height && { height: config.height }), { children: jsxRuntime.jsx("table", { "aria-label": "Row Border Wrapper", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: borderTableStyle, children: jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { style: paddingTdStyle, children: jsxRuntime.jsx("table", { "aria-label": "Row Justification Wrapper", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: {
|
|
2258
2345
|
width: "100%",
|
|
2259
2346
|
height: "100%",
|
|
2260
2347
|
borderCollapse: "collapse",
|
|
@@ -2264,7 +2351,7 @@ function Row({ children, config, devNode }) {
|
|
|
2264
2351
|
padding: "0",
|
|
2265
2352
|
margin: "0",
|
|
2266
2353
|
}, className: "child-cell", children: child }), index < numChildren - 1 &&
|
|
2267
|
-
config.gap && (jsxRuntime.jsx("td", { width: config.gap, style: gapTdStyle, children: "\u00A0" }, `row-gap-${index}`))] }, `row-child-${index}`))) }) }) })) }) }) }) }) }) }) }) }) })) }) }), devNode && (jsxRuntime.jsx("tfoot", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { children: devNode }) }) }))] })));
|
|
2354
|
+
config.gap && (jsxRuntime.jsx("td", { width: config.gap, style: gapTdStyle, className: "row-gap-td", children: "\u00A0" }, `row-gap-${index}`))] }, `row-child-${index}`))) }) }) })) }) }) }) }) }) }) }) }) })) }) }), devNode && (jsxRuntime.jsx("tfoot", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { children: devNode }) }) }))] })));
|
|
2268
2355
|
}
|
|
2269
2356
|
var Row_default = React.memo(Row, arePropsEqual);
|
|
2270
2357
|
|
|
@@ -2345,7 +2432,6 @@ function Spacer({ config, devNode }) {
|
|
|
2345
2432
|
var Spacer_default = React.memo(Spacer, arePropsEqual);
|
|
2346
2433
|
|
|
2347
2434
|
function Text({ config, devMode, children }) {
|
|
2348
|
-
var _a;
|
|
2349
2435
|
const { text, padding, color, textAlign, fontSize, fontWeight, fontStyle, lineHeight, letterSpacing, textTransform, textDecoration, direction, verticalAlign, backgroundColor, opacity, whiteSpace, } = config;
|
|
2350
2436
|
// 1. TD Style: Where padding and background are reliably applied.
|
|
2351
2437
|
const tdStyle = {
|
|
@@ -2354,9 +2440,7 @@ function Text({ config, devMode, children }) {
|
|
|
2354
2440
|
width: "100%",
|
|
2355
2441
|
verticalAlign: "top",
|
|
2356
2442
|
};
|
|
2357
|
-
// 2. Content Style: Applied directly to a wrapper element
|
|
2358
|
-
// or inherited by the children. For max compatibility, we apply core styles
|
|
2359
|
-
// directly to the TD or a wrapper <p> (if children is just a string).
|
|
2443
|
+
// 2. Content Style: Applied directly to a wrapper element
|
|
2360
2444
|
const contentStyle = {
|
|
2361
2445
|
color: color,
|
|
2362
2446
|
textAlign: textAlign,
|
|
@@ -2371,19 +2455,188 @@ function Text({ config, devMode, children }) {
|
|
|
2371
2455
|
verticalAlign: verticalAlign,
|
|
2372
2456
|
opacity: opacity,
|
|
2373
2457
|
whiteSpace: whiteSpace,
|
|
2374
|
-
margin: "0",
|
|
2458
|
+
margin: "0",
|
|
2375
2459
|
padding: "0",
|
|
2376
|
-
fontFamily: "Arial, Helvetica, sans-serif",
|
|
2460
|
+
fontFamily: "Arial, Helvetica, sans-serif",
|
|
2377
2461
|
};
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2462
|
+
// Determine content to render
|
|
2463
|
+
const content = text !== null && text !== void 0 ? text : children;
|
|
2464
|
+
const isString = typeof content === "string";
|
|
2465
|
+
return (jsxRuntime.jsx("table", { "aria-label": "Text Block Wrapper", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: {
|
|
2381
2466
|
width: "100%",
|
|
2382
2467
|
borderCollapse: "collapse",
|
|
2383
|
-
}, children: jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { style: tdStyle, align: textAlign, children: jsxRuntime.jsx("div", { style: contentStyle, dangerouslySetInnerHTML: { __html:
|
|
2468
|
+
}, children: jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { style: tdStyle, align: textAlign, children: isString ? (jsxRuntime.jsx("div", { style: contentStyle, dangerouslySetInnerHTML: { __html: content } })) : (jsxRuntime.jsx("div", { style: contentStyle, children: content })) }) }) }) }));
|
|
2384
2469
|
}
|
|
2385
2470
|
var Text_default = React.memo(Text, arePropsEqual);
|
|
2386
2471
|
|
|
2472
|
+
// Map alignment to HTML 'align' attribute
|
|
2473
|
+
const justifyMap = {
|
|
2474
|
+
start: "left",
|
|
2475
|
+
center: "center",
|
|
2476
|
+
end: "right",
|
|
2477
|
+
};
|
|
2478
|
+
// Helper to build Iconify API URL
|
|
2479
|
+
function buildIconifyUrl(config) {
|
|
2480
|
+
const { iconIdentifier, height = 24, color = "000000", rotate = 0, rotateOrientation = "cw", } = config;
|
|
2481
|
+
if (!iconIdentifier)
|
|
2482
|
+
return null;
|
|
2483
|
+
// Remove # from color if present
|
|
2484
|
+
const cleanColor = color.replace("#", "");
|
|
2485
|
+
// Build URL from template
|
|
2486
|
+
const template = process.env.ICONIFY_API_IMAGE_URI ||
|
|
2487
|
+
"https://iconify.pagenflow.com/api/image/{{height}}/{{color}}/{{rotate}}-{{rotate-orientation}}/{{icon-full-name}}.png";
|
|
2488
|
+
return template
|
|
2489
|
+
.replace("{{height}}", String(Number(height) * Number(2)))
|
|
2490
|
+
.replace("{{color}}", cleanColor)
|
|
2491
|
+
.replace("{{rotate}}", String(rotate))
|
|
2492
|
+
.replace("{{rotate-orientation}}", rotateOrientation)
|
|
2493
|
+
.replace("{{icon-full-name}}", iconIdentifier);
|
|
2494
|
+
}
|
|
2495
|
+
// Helper to build link href based on innerLink type
|
|
2496
|
+
function buildLinkHref(innerLink) {
|
|
2497
|
+
if (!innerLink || innerLink.type === "none")
|
|
2498
|
+
return null;
|
|
2499
|
+
switch (innerLink.type) {
|
|
2500
|
+
case "url":
|
|
2501
|
+
return innerLink.url || null;
|
|
2502
|
+
case "email":
|
|
2503
|
+
return innerLink.email ? `mailto:${innerLink.email}` : null;
|
|
2504
|
+
case "phone":
|
|
2505
|
+
return innerLink.phone ? `tel:${innerLink.phone}` : null;
|
|
2506
|
+
case "anchor":
|
|
2507
|
+
return innerLink.anchor ? `#${innerLink.anchor}` : null;
|
|
2508
|
+
case "page_top":
|
|
2509
|
+
return "#top";
|
|
2510
|
+
case "page_bottom":
|
|
2511
|
+
return "#bottom";
|
|
2512
|
+
default:
|
|
2513
|
+
return null;
|
|
2514
|
+
}
|
|
2515
|
+
}
|
|
2516
|
+
function Icon({ config, devNode, devMode, children }) {
|
|
2517
|
+
const {
|
|
2518
|
+
// base64Source,
|
|
2519
|
+
width, height, backgroundColor, padding = "0", borderRadius = "0", innerLink, justifyContent = "center", } = config;
|
|
2520
|
+
// Determine icon source
|
|
2521
|
+
const iconSrc = buildIconifyUrl(config);
|
|
2522
|
+
const href = buildLinkHref(innerLink);
|
|
2523
|
+
const target = (innerLink === null || innerLink === void 0 ? void 0 : innerLink.target) || "_self";
|
|
2524
|
+
const align = justifyMap[justifyContent];
|
|
2525
|
+
// Convert width/height to string with px if number
|
|
2526
|
+
const widthStr = typeof width === "number" ? `${width}px` : width;
|
|
2527
|
+
const heightStr = typeof height === "number" ? `${height}px` : height;
|
|
2528
|
+
// Parse numeric values for HTML attributes
|
|
2529
|
+
const widthNum = typeof width === "number"
|
|
2530
|
+
? width
|
|
2531
|
+
: typeof width === "string" && width.endsWith("px")
|
|
2532
|
+
? parseInt(width, 10)
|
|
2533
|
+
: undefined;
|
|
2534
|
+
const heightNum = typeof height === "number"
|
|
2535
|
+
? height
|
|
2536
|
+
: typeof height === "string" && height.endsWith("px")
|
|
2537
|
+
? parseInt(height, 10)
|
|
2538
|
+
: undefined;
|
|
2539
|
+
// 1. Image Style: Critical for compatibility
|
|
2540
|
+
const imgStyle = {
|
|
2541
|
+
display: "block", // Prevents extra vertical space
|
|
2542
|
+
border: 0, // No default border
|
|
2543
|
+
width: widthStr || "auto",
|
|
2544
|
+
height: heightStr || "auto",
|
|
2545
|
+
};
|
|
2546
|
+
// 2. Link Style: No underline or color changes
|
|
2547
|
+
const linkStyle = {
|
|
2548
|
+
display: "block",
|
|
2549
|
+
textDecoration: "none",
|
|
2550
|
+
border: 0,
|
|
2551
|
+
outline: "none",
|
|
2552
|
+
};
|
|
2553
|
+
// 3. TD Style: Padding and background
|
|
2554
|
+
const tdStyle = {
|
|
2555
|
+
padding: padding,
|
|
2556
|
+
backgroundColor: backgroundColor,
|
|
2557
|
+
fontSize: "0", // CRITICAL: Collapses extra space
|
|
2558
|
+
lineHeight: "0", // CRITICAL: Collapses extra space7
|
|
2559
|
+
borderRadius: borderRadius,
|
|
2560
|
+
overflow: "hidden",
|
|
2561
|
+
};
|
|
2562
|
+
// --- VML Calculation for Outlook Compatibility ---
|
|
2563
|
+
const numericPadding = parseInt(padding.split(" ")[0] || "0", 10);
|
|
2564
|
+
const vmlWidth = (widthNum || 24) + numericPadding * 2;
|
|
2565
|
+
const vmlHeight = (heightNum || 24) + numericPadding * 2;
|
|
2566
|
+
// VML colors must use full hex format
|
|
2567
|
+
const vmlFillColor = (backgroundColor === null || backgroundColor === void 0 ? void 0 : backgroundColor.startsWith("#"))
|
|
2568
|
+
? backgroundColor
|
|
2569
|
+
: backgroundColor
|
|
2570
|
+
? `#${backgroundColor}`
|
|
2571
|
+
: "#ffffff";
|
|
2572
|
+
// Calculate arcsize percentage for VML
|
|
2573
|
+
const numericBorderRadius = parseInt(borderRadius || "0", 10);
|
|
2574
|
+
const arcsize = numericBorderRadius > 0
|
|
2575
|
+
? Math.min((numericBorderRadius / Math.min(vmlWidth, vmlHeight)) * 100, 100)
|
|
2576
|
+
: 0;
|
|
2577
|
+
// Build VML code for Outlook
|
|
2578
|
+
const vmlIcon = backgroundColor && numericBorderRadius > 0
|
|
2579
|
+
? `
|
|
2580
|
+
<!--[if mso]>
|
|
2581
|
+
<v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" ${href && !devMode ? `href="${href}"` : ""} style="height:${vmlHeight}px;width:${vmlWidth}px;v-text-anchor:middle;" arcsize="${arcsize}%" stroke="false" fillcolor="${vmlFillColor}">
|
|
2582
|
+
<w:anchorlock/>
|
|
2583
|
+
<v:textbox inset="0,0,0,0" style="text-align: center;">
|
|
2584
|
+
<center style="padding:${padding};">
|
|
2585
|
+
<img src="${iconSrc || ""}" alt="" width="${widthNum || 24}" height="${heightNum || 24}" border="0" style="display:block;border:0;" />
|
|
2586
|
+
</center>
|
|
2587
|
+
</v:textbox>
|
|
2588
|
+
</v:roundrect>
|
|
2589
|
+
<![endif]-->
|
|
2590
|
+
`
|
|
2591
|
+
: "";
|
|
2592
|
+
// If no icon source, return empty
|
|
2593
|
+
if (!iconSrc && !devMode) {
|
|
2594
|
+
return null;
|
|
2595
|
+
}
|
|
2596
|
+
// Icon image element
|
|
2597
|
+
const iconElement = devMode && !!children ? (children) : iconSrc ? (jsxRuntime.jsx("img", { draggable: false, src: iconSrc, alt: "" // Icons are decorative, empty alt is appropriate
|
|
2598
|
+
, style: imgStyle, width: widthNum, height: heightNum, border: 0 })) : (jsxRuntime.jsx(jsxRuntime.Fragment, {}));
|
|
2599
|
+
// Wrap in link if href exists and not in dev mode
|
|
2600
|
+
const content = href && !devMode ? (jsxRuntime.jsx("a", Object.assign({ href: href, target: target, style: linkStyle }, (target === "_blank" ? { rel: "noopener noreferrer" } : {}), { children: iconElement }))) : (iconElement);
|
|
2601
|
+
// Build the HTML content with VML support (only when NOT in dev mode)
|
|
2602
|
+
const useVML = !devMode && backgroundColor && numericBorderRadius > 0;
|
|
2603
|
+
const htmlContent = useVML
|
|
2604
|
+
? `
|
|
2605
|
+
${vmlIcon}
|
|
2606
|
+
<!--[if !mso]><!-->
|
|
2607
|
+
<table role="presentation" cellpadding="0" cellspacing="0" border="0" style="border-collapse: collapse; width: 100%;">
|
|
2608
|
+
<tbody>
|
|
2609
|
+
<tr>
|
|
2610
|
+
<td style="background-color: ${backgroundColor}; border-radius: ${borderRadius}; padding: ${padding}; font-size: 0; line-height: 0; overflow: hidden;">
|
|
2611
|
+
${href
|
|
2612
|
+
? `<a href="${href}" target="${target}" style="display:block;text-decoration:none;border:0;outline:none;" ${target === "_blank" ? 'rel="noopener noreferrer"' : ""}>
|
|
2613
|
+
<img draggable="false" src="${iconSrc}" alt="" width="${widthNum || 24}" height="${heightNum || 24}" border="0" style="display:block;border:0;width:${widthStr || "auto"};height:${heightStr || "auto"};" />
|
|
2614
|
+
</a>`
|
|
2615
|
+
: `<img draggable="false" src="${iconSrc}" alt="" width="${widthNum || 24}" height="${heightNum || 24}" border="0" style="display:block;border:0;width:${widthStr || "auto"};height:${heightStr || "auto"};" />`}
|
|
2616
|
+
</td>
|
|
2617
|
+
</tr>
|
|
2618
|
+
</tbody>
|
|
2619
|
+
</table>
|
|
2620
|
+
<!--<![endif]-->
|
|
2621
|
+
`
|
|
2622
|
+
: null;
|
|
2623
|
+
return (jsxRuntime.jsxs("table", { "aria-label": "Icon", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, align: align, style: {
|
|
2624
|
+
// --- Start dev
|
|
2625
|
+
position: "relative",
|
|
2626
|
+
// --- End dev
|
|
2627
|
+
width: widthStr || "auto",
|
|
2628
|
+
borderCollapse: "collapse",
|
|
2629
|
+
// base
|
|
2630
|
+
boxSizing: "border-box",
|
|
2631
|
+
border: 0,
|
|
2632
|
+
margin: 0,
|
|
2633
|
+
padding: 0,
|
|
2634
|
+
}, onClick: devMode ? (e) => e.preventDefault() : undefined, children: [jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: useVML ? (jsxRuntime.jsx("td", { dangerouslySetInnerHTML: {
|
|
2635
|
+
__html: htmlContent !== null && htmlContent !== void 0 ? htmlContent : "",
|
|
2636
|
+
} })) : (jsxRuntime.jsx("td", { style: tdStyle, align: align, children: content })) }) }), devMode && !!devNode && (jsxRuntime.jsx("tfoot", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { children: devNode }) }) }))] }));
|
|
2637
|
+
}
|
|
2638
|
+
var Icon_default = React.memo(Icon, arePropsEqual);
|
|
2639
|
+
|
|
2387
2640
|
exports.Body = Body;
|
|
2388
2641
|
exports.Button = Button_default;
|
|
2389
2642
|
exports.Column = Column_default;
|
|
@@ -2392,6 +2645,7 @@ exports.Divider = Divider_default;
|
|
|
2392
2645
|
exports.Head = Head;
|
|
2393
2646
|
exports.Heading = Heading_default;
|
|
2394
2647
|
exports.Html = Html;
|
|
2648
|
+
exports.Icon = Icon_default;
|
|
2395
2649
|
exports.Image = Image_default;
|
|
2396
2650
|
exports.Row = Row_default;
|
|
2397
2651
|
exports.Section = Section_default;
|