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