@pagenflow/email 1.3.3 → 1.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/Heading.d.ts +14 -7
- package/dist/components/Row.d.ts +1 -0
- package/dist/index.cjs.js +285 -30
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.esm.js +286 -32
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -1
|
@@ -15,15 +15,22 @@ export interface HeadingConfig {
|
|
|
15
15
|
fontSize?: string;
|
|
16
16
|
/** Font weight (e.g., 'normal', 'bold', or '700'). */
|
|
17
17
|
fontWeight?: string;
|
|
18
|
-
/** Font style (e.g., 'italic'). */
|
|
18
|
+
/** Font style (e.g., 'italic'). */
|
|
19
|
+
fontStyle?: string;
|
|
19
20
|
/** Line height (e.g., '1.3' or '30px'). */
|
|
20
21
|
lineHeight?: string;
|
|
21
|
-
/** Letter spacing (e.g., '0.5px', '1px'). */
|
|
22
|
-
|
|
23
|
-
/** Text
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
|
|
22
|
+
/** Letter spacing (e.g., '0.5px', '1px'). */
|
|
23
|
+
letterSpacing?: string;
|
|
24
|
+
/** Text transform (e.g., 'uppercase', 'lowercase', 'capitalize'). */
|
|
25
|
+
textTransform?: string;
|
|
26
|
+
/** Text decoration (e.g., 'underline', 'line-through'). */
|
|
27
|
+
textDecoration?: string;
|
|
28
|
+
/** Text direction (e.g., 'ltr', 'rtl'). */
|
|
29
|
+
direction?: string;
|
|
30
|
+
/** Vertical alignment (e.g., 'sub', 'super'). Applied to content wrapper in Text, applied to TD here for alignment. */
|
|
31
|
+
verticalAlign?: string;
|
|
32
|
+
/** Background color of the heading block. */
|
|
33
|
+
backgroundColor?: string;
|
|
27
34
|
}
|
|
28
35
|
export type HeadingProps = {
|
|
29
36
|
config: HeadingConfig;
|
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
|
/* ================================================= */
|
|
@@ -2063,8 +2150,10 @@ function Head({ children, backgroundColor = "#ffffff", title = "Email Preview",
|
|
|
2063
2150
|
}
|
|
2064
2151
|
|
|
2065
2152
|
function Heading({ config, devMode, children }) {
|
|
2066
|
-
var _a;
|
|
2067
2153
|
const { text, level = "h1", padding, color, textAlign, fontSize, fontWeight, fontStyle, lineHeight, letterSpacing, textTransform, textDecoration, direction, verticalAlign, backgroundColor, } = config;
|
|
2154
|
+
// Determine the content to render
|
|
2155
|
+
const content = text !== null && text !== void 0 ? text : children;
|
|
2156
|
+
const isString = typeof content === "string";
|
|
2068
2157
|
// 1. TD Style: Where padding, background, width, and verticalAlign are applied.
|
|
2069
2158
|
const tdStyle = {
|
|
2070
2159
|
padding: padding,
|
|
@@ -2091,7 +2180,6 @@ function Heading({ config, devMode, children }) {
|
|
|
2091
2180
|
fontFamily: "Arial, Helvetica, sans-serif",
|
|
2092
2181
|
// Outlook specific fixes (using string indexing)
|
|
2093
2182
|
["msoLineHeightRule"]: "exactly",
|
|
2094
|
-
// ["mso-line-height-rule" as string]: "exactly",
|
|
2095
2183
|
};
|
|
2096
2184
|
// Dynamically create the Heading element
|
|
2097
2185
|
const HeadingTag = level;
|
|
@@ -2100,7 +2188,7 @@ function Heading({ config, devMode, children }) {
|
|
|
2100
2188
|
jsxRuntime.jsx("table", { "aria-label": "Heading Block Wrapper", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: {
|
|
2101
2189
|
width: "100%",
|
|
2102
2190
|
borderCollapse: "collapse",
|
|
2103
|
-
}, children: jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { style: tdStyle, align: textAlign, children: jsxRuntime.jsx(HeadingTag, { style: headingStyle, dangerouslySetInnerHTML: { __html:
|
|
2191
|
+
}, children: jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { style: tdStyle, align: textAlign, children: isString ? (jsxRuntime.jsx(HeadingTag, { style: headingStyle, dangerouslySetInnerHTML: { __html: content } })) : (jsxRuntime.jsx(HeadingTag, { style: headingStyle, children: content })) }) }) }) }));
|
|
2104
2192
|
}
|
|
2105
2193
|
var Heading_default = React.memo(Heading, arePropsEqual);
|
|
2106
2194
|
|
|
@@ -2181,7 +2269,7 @@ function Image({ config, devNode, devMode }) {
|
|
|
2181
2269
|
}
|
|
2182
2270
|
var Image_default = React.memo(Image, arePropsEqual);
|
|
2183
2271
|
|
|
2184
|
-
const justifyMap = {
|
|
2272
|
+
const justifyMap$1 = {
|
|
2185
2273
|
start: "left",
|
|
2186
2274
|
center: "center",
|
|
2187
2275
|
end: "right",
|
|
@@ -2213,7 +2301,7 @@ function getBorderStyle$1(border) {
|
|
|
2213
2301
|
return style;
|
|
2214
2302
|
}
|
|
2215
2303
|
function Row({ children, config, devNode }) {
|
|
2216
|
-
var _a, _b, _c, _d, _e;
|
|
2304
|
+
var _a, _b, _c, _d, _e, _f;
|
|
2217
2305
|
const childrenArray = (Array.isArray(children) ? children : [children]).filter((child) => child != null);
|
|
2218
2306
|
const numChildren = childrenArray.length;
|
|
2219
2307
|
// 1. Outer TD for Background and Border Radius (no border here)
|
|
@@ -2246,7 +2334,7 @@ function Row({ children, config, devNode }) {
|
|
|
2246
2334
|
fontSize: "1px",
|
|
2247
2335
|
};
|
|
2248
2336
|
const tdAlign = config.justifyContent
|
|
2249
|
-
? justifyMap[config.justifyContent]
|
|
2337
|
+
? justifyMap$1[config.justifyContent]
|
|
2250
2338
|
: "left";
|
|
2251
2339
|
const tdValign = config.alignItems ? alignMap[config.alignItems] : "top";
|
|
2252
2340
|
return (jsxRuntime.jsxs("table", Object.assign({ "aria-label": "Row Outer", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: {
|
|
@@ -2254,7 +2342,7 @@ function Row({ children, config, devNode }) {
|
|
|
2254
2342
|
width: config.width || "100%",
|
|
2255
2343
|
height: config.height,
|
|
2256
2344
|
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: {
|
|
2345
|
+
} }, (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
2346
|
width: "100%",
|
|
2259
2347
|
height: "100%",
|
|
2260
2348
|
borderCollapse: "collapse",
|
|
@@ -2264,7 +2352,7 @@ function Row({ children, config, devNode }) {
|
|
|
2264
2352
|
padding: "0",
|
|
2265
2353
|
margin: "0",
|
|
2266
2354
|
}, 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 }) }) }))] })));
|
|
2355
|
+
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
2356
|
}
|
|
2269
2357
|
var Row_default = React.memo(Row, arePropsEqual);
|
|
2270
2358
|
|
|
@@ -2345,7 +2433,6 @@ function Spacer({ config, devNode }) {
|
|
|
2345
2433
|
var Spacer_default = React.memo(Spacer, arePropsEqual);
|
|
2346
2434
|
|
|
2347
2435
|
function Text({ config, devMode, children }) {
|
|
2348
|
-
var _a;
|
|
2349
2436
|
const { text, padding, color, textAlign, fontSize, fontWeight, fontStyle, lineHeight, letterSpacing, textTransform, textDecoration, direction, verticalAlign, backgroundColor, opacity, whiteSpace, } = config;
|
|
2350
2437
|
// 1. TD Style: Where padding and background are reliably applied.
|
|
2351
2438
|
const tdStyle = {
|
|
@@ -2354,9 +2441,7 @@ function Text({ config, devMode, children }) {
|
|
|
2354
2441
|
width: "100%",
|
|
2355
2442
|
verticalAlign: "top",
|
|
2356
2443
|
};
|
|
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).
|
|
2444
|
+
// 2. Content Style: Applied directly to a wrapper element
|
|
2360
2445
|
const contentStyle = {
|
|
2361
2446
|
color: color,
|
|
2362
2447
|
textAlign: textAlign,
|
|
@@ -2371,19 +2456,188 @@ function Text({ config, devMode, children }) {
|
|
|
2371
2456
|
verticalAlign: verticalAlign,
|
|
2372
2457
|
opacity: opacity,
|
|
2373
2458
|
whiteSpace: whiteSpace,
|
|
2374
|
-
margin: "0",
|
|
2459
|
+
margin: "0",
|
|
2375
2460
|
padding: "0",
|
|
2376
|
-
fontFamily: "Arial, Helvetica, sans-serif",
|
|
2461
|
+
fontFamily: "Arial, Helvetica, sans-serif",
|
|
2377
2462
|
};
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2463
|
+
// Determine content to render
|
|
2464
|
+
const content = text !== null && text !== void 0 ? text : children;
|
|
2465
|
+
const isString = typeof content === "string";
|
|
2466
|
+
return (jsxRuntime.jsx("table", { "aria-label": "Text Block Wrapper", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: {
|
|
2381
2467
|
width: "100%",
|
|
2382
2468
|
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:
|
|
2469
|
+
}, 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
2470
|
}
|
|
2385
2471
|
var Text_default = React.memo(Text, arePropsEqual);
|
|
2386
2472
|
|
|
2473
|
+
// Map alignment to HTML 'align' attribute
|
|
2474
|
+
const justifyMap = {
|
|
2475
|
+
start: "left",
|
|
2476
|
+
center: "center",
|
|
2477
|
+
end: "right",
|
|
2478
|
+
};
|
|
2479
|
+
// Helper to build Iconify API URL
|
|
2480
|
+
function buildIconifyUrl(config) {
|
|
2481
|
+
const { iconIdentifier, height = 24, color = "000000", rotate = 0, rotateOrientation = "cw", } = config;
|
|
2482
|
+
if (!iconIdentifier)
|
|
2483
|
+
return null;
|
|
2484
|
+
// Remove # from color if present
|
|
2485
|
+
const cleanColor = color.replace("#", "");
|
|
2486
|
+
// Build URL from template
|
|
2487
|
+
const template = process.env.ICONIFY_API_IMAGE_URI ||
|
|
2488
|
+
"https://iconify.pagenflow.com/api/image/{{height}}/{{color}}/{{rotate}}-{{rotate-orientation}}/{{icon-full-name}}.png";
|
|
2489
|
+
return template
|
|
2490
|
+
.replace("{{height}}", String(Number(height) * Number(2)))
|
|
2491
|
+
.replace("{{color}}", cleanColor)
|
|
2492
|
+
.replace("{{rotate}}", String(rotate))
|
|
2493
|
+
.replace("{{rotate-orientation}}", rotateOrientation)
|
|
2494
|
+
.replace("{{icon-full-name}}", iconIdentifier);
|
|
2495
|
+
}
|
|
2496
|
+
// Helper to build link href based on innerLink type
|
|
2497
|
+
function buildLinkHref(innerLink) {
|
|
2498
|
+
if (!innerLink || innerLink.type === "none")
|
|
2499
|
+
return null;
|
|
2500
|
+
switch (innerLink.type) {
|
|
2501
|
+
case "url":
|
|
2502
|
+
return innerLink.url || null;
|
|
2503
|
+
case "email":
|
|
2504
|
+
return innerLink.email ? `mailto:${innerLink.email}` : null;
|
|
2505
|
+
case "phone":
|
|
2506
|
+
return innerLink.phone ? `tel:${innerLink.phone}` : null;
|
|
2507
|
+
case "anchor":
|
|
2508
|
+
return innerLink.anchor ? `#${innerLink.anchor}` : null;
|
|
2509
|
+
case "page_top":
|
|
2510
|
+
return "#top";
|
|
2511
|
+
case "page_bottom":
|
|
2512
|
+
return "#bottom";
|
|
2513
|
+
default:
|
|
2514
|
+
return null;
|
|
2515
|
+
}
|
|
2516
|
+
}
|
|
2517
|
+
function Icon({ config, devNode, devMode, children }) {
|
|
2518
|
+
const {
|
|
2519
|
+
// base64Source,
|
|
2520
|
+
width, height, backgroundColor, padding = "0", borderRadius = "0", innerLink, justifyContent = "center", } = config;
|
|
2521
|
+
// Determine icon source
|
|
2522
|
+
const iconSrc = buildIconifyUrl(config);
|
|
2523
|
+
const href = buildLinkHref(innerLink);
|
|
2524
|
+
const target = (innerLink === null || innerLink === void 0 ? void 0 : innerLink.target) || "_self";
|
|
2525
|
+
const align = justifyMap[justifyContent];
|
|
2526
|
+
// Convert width/height to string with px if number
|
|
2527
|
+
const widthStr = typeof width === "number" ? `${width}px` : width;
|
|
2528
|
+
const heightStr = typeof height === "number" ? `${height}px` : height;
|
|
2529
|
+
// Parse numeric values for HTML attributes
|
|
2530
|
+
const widthNum = typeof width === "number"
|
|
2531
|
+
? width
|
|
2532
|
+
: typeof width === "string" && width.endsWith("px")
|
|
2533
|
+
? parseInt(width, 10)
|
|
2534
|
+
: undefined;
|
|
2535
|
+
const heightNum = typeof height === "number"
|
|
2536
|
+
? height
|
|
2537
|
+
: typeof height === "string" && height.endsWith("px")
|
|
2538
|
+
? parseInt(height, 10)
|
|
2539
|
+
: undefined;
|
|
2540
|
+
// 1. Image Style: Critical for compatibility
|
|
2541
|
+
const imgStyle = {
|
|
2542
|
+
display: "block", // Prevents extra vertical space
|
|
2543
|
+
border: 0, // No default border
|
|
2544
|
+
width: widthStr || "auto",
|
|
2545
|
+
height: heightStr || "auto",
|
|
2546
|
+
};
|
|
2547
|
+
// 2. Link Style: No underline or color changes
|
|
2548
|
+
const linkStyle = {
|
|
2549
|
+
display: "block",
|
|
2550
|
+
textDecoration: "none",
|
|
2551
|
+
border: 0,
|
|
2552
|
+
outline: "none",
|
|
2553
|
+
};
|
|
2554
|
+
// 3. TD Style: Padding and background
|
|
2555
|
+
const tdStyle = {
|
|
2556
|
+
padding: padding,
|
|
2557
|
+
backgroundColor: backgroundColor,
|
|
2558
|
+
fontSize: "0", // CRITICAL: Collapses extra space
|
|
2559
|
+
lineHeight: "0", // CRITICAL: Collapses extra space7
|
|
2560
|
+
borderRadius: borderRadius,
|
|
2561
|
+
overflow: "hidden",
|
|
2562
|
+
};
|
|
2563
|
+
// --- VML Calculation for Outlook Compatibility ---
|
|
2564
|
+
const numericPadding = parseInt(padding.split(" ")[0] || "0", 10);
|
|
2565
|
+
const vmlWidth = (widthNum || 24) + numericPadding * 2;
|
|
2566
|
+
const vmlHeight = (heightNum || 24) + numericPadding * 2;
|
|
2567
|
+
// VML colors must use full hex format
|
|
2568
|
+
const vmlFillColor = (backgroundColor === null || backgroundColor === void 0 ? void 0 : backgroundColor.startsWith("#"))
|
|
2569
|
+
? backgroundColor
|
|
2570
|
+
: backgroundColor
|
|
2571
|
+
? `#${backgroundColor}`
|
|
2572
|
+
: "#ffffff";
|
|
2573
|
+
// Calculate arcsize percentage for VML
|
|
2574
|
+
const numericBorderRadius = parseInt(borderRadius || "0", 10);
|
|
2575
|
+
const arcsize = numericBorderRadius > 0
|
|
2576
|
+
? Math.min((numericBorderRadius / Math.min(vmlWidth, vmlHeight)) * 100, 100)
|
|
2577
|
+
: 0;
|
|
2578
|
+
// Build VML code for Outlook
|
|
2579
|
+
const vmlIcon = backgroundColor && numericBorderRadius > 0
|
|
2580
|
+
? `
|
|
2581
|
+
<!--[if mso]>
|
|
2582
|
+
<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}">
|
|
2583
|
+
<w:anchorlock/>
|
|
2584
|
+
<v:textbox inset="0,0,0,0" style="text-align: center;">
|
|
2585
|
+
<center style="padding:${padding};">
|
|
2586
|
+
<img src="${iconSrc || ""}" alt="" width="${widthNum || 24}" height="${heightNum || 24}" border="0" style="display:block;border:0;" />
|
|
2587
|
+
</center>
|
|
2588
|
+
</v:textbox>
|
|
2589
|
+
</v:roundrect>
|
|
2590
|
+
<![endif]-->
|
|
2591
|
+
`
|
|
2592
|
+
: "";
|
|
2593
|
+
// If no icon source, return empty
|
|
2594
|
+
if (!iconSrc && !devMode) {
|
|
2595
|
+
return null;
|
|
2596
|
+
}
|
|
2597
|
+
// Icon image element
|
|
2598
|
+
const iconElement = devMode && !!children ? (children) : iconSrc ? (jsxRuntime.jsx("img", { draggable: false, src: iconSrc, alt: "" // Icons are decorative, empty alt is appropriate
|
|
2599
|
+
, style: imgStyle, width: widthNum, height: heightNum, border: 0 })) : (jsxRuntime.jsx(jsxRuntime.Fragment, {}));
|
|
2600
|
+
// Wrap in link if href exists and not in dev mode
|
|
2601
|
+
const content = href && !devMode ? (jsxRuntime.jsx("a", Object.assign({ href: href, target: target, style: linkStyle }, (target === "_blank" ? { rel: "noopener noreferrer" } : {}), { children: iconElement }))) : (iconElement);
|
|
2602
|
+
// Build the HTML content with VML support (only when NOT in dev mode)
|
|
2603
|
+
const useVML = !devMode && backgroundColor && numericBorderRadius > 0;
|
|
2604
|
+
const htmlContent = useVML
|
|
2605
|
+
? `
|
|
2606
|
+
${vmlIcon}
|
|
2607
|
+
<!--[if !mso]><!-->
|
|
2608
|
+
<table role="presentation" cellpadding="0" cellspacing="0" border="0" style="border-collapse: collapse; width: 100%;">
|
|
2609
|
+
<tbody>
|
|
2610
|
+
<tr>
|
|
2611
|
+
<td style="background-color: ${backgroundColor}; border-radius: ${borderRadius}; padding: ${padding}; font-size: 0; line-height: 0; overflow: hidden;">
|
|
2612
|
+
${href
|
|
2613
|
+
? `<a href="${href}" target="${target}" style="display:block;text-decoration:none;border:0;outline:none;" ${target === "_blank" ? 'rel="noopener noreferrer"' : ""}>
|
|
2614
|
+
<img draggable="false" src="${iconSrc}" alt="" width="${widthNum || 24}" height="${heightNum || 24}" border="0" style="display:block;border:0;width:${widthStr || "auto"};height:${heightStr || "auto"};" />
|
|
2615
|
+
</a>`
|
|
2616
|
+
: `<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"};" />`}
|
|
2617
|
+
</td>
|
|
2618
|
+
</tr>
|
|
2619
|
+
</tbody>
|
|
2620
|
+
</table>
|
|
2621
|
+
<!--<![endif]-->
|
|
2622
|
+
`
|
|
2623
|
+
: null;
|
|
2624
|
+
return (jsxRuntime.jsxs("table", { "aria-label": "Icon", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, align: align, style: {
|
|
2625
|
+
// --- Start dev
|
|
2626
|
+
position: "relative",
|
|
2627
|
+
// --- End dev
|
|
2628
|
+
width: widthStr || "auto",
|
|
2629
|
+
borderCollapse: "collapse",
|
|
2630
|
+
// base
|
|
2631
|
+
boxSizing: "border-box",
|
|
2632
|
+
border: 0,
|
|
2633
|
+
margin: 0,
|
|
2634
|
+
padding: 0,
|
|
2635
|
+
}, onClick: devMode ? (e) => e.preventDefault() : undefined, children: [jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: useVML ? (jsxRuntime.jsx("td", { dangerouslySetInnerHTML: {
|
|
2636
|
+
__html: htmlContent !== null && htmlContent !== void 0 ? htmlContent : "",
|
|
2637
|
+
} })) : (jsxRuntime.jsx("td", { style: tdStyle, align: align, children: content })) }) }), devMode && !!devNode && (jsxRuntime.jsx("tfoot", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { children: devNode }) }) }))] }));
|
|
2638
|
+
}
|
|
2639
|
+
var Icon_default = React.memo(Icon, arePropsEqual);
|
|
2640
|
+
|
|
2387
2641
|
exports.Body = Body;
|
|
2388
2642
|
exports.Button = Button_default;
|
|
2389
2643
|
exports.Column = Column_default;
|
|
@@ -2392,6 +2646,7 @@ exports.Divider = Divider_default;
|
|
|
2392
2646
|
exports.Head = Head;
|
|
2393
2647
|
exports.Heading = Heading_default;
|
|
2394
2648
|
exports.Html = Html;
|
|
2649
|
+
exports.Icon = Icon_default;
|
|
2395
2650
|
exports.Image = Image_default;
|
|
2396
2651
|
exports.Row = Row_default;
|
|
2397
2652
|
exports.Section = Section_default;
|