@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.
@@ -20,6 +20,7 @@ export interface RowConfig {
20
20
  mobile?: {
21
21
  justifyContent?: JustifyContent;
22
22
  alignItems?: AlignItems;
23
+ wrap?: boolean;
23
24
  };
24
25
  }
25
26
  export type RowProps = {
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$2 = {
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$2[justifyContent];
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$1 = {
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$1[config.justifyContent]
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: 600px) {
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: 600px) {
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: 600px) {
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
- /* We target the child cells if they are still side-by-side */
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 (like a <div> or <p>)
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", // Crucial: Remove default margin from <p> tags
2458
+ margin: "0",
2375
2459
  padding: "0",
2376
- fontFamily: "Arial, Helvetica, sans-serif", // Use a widely supported font stack
2460
+ fontFamily: "Arial, Helvetica, sans-serif",
2377
2461
  };
2378
- return (
2379
- // Wrap the text content in a table for padding/background/width management.
2380
- jsxRuntime.jsx("table", { "aria-label": "Text Block Wrapper", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: {
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: (_a = text !== null && text !== void 0 ? text : children) !== null && _a !== void 0 ? _a : "" } }) }) }) }) }));
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;