@pagenflow/email 1.4.1 → 1.4.2
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/Body.d.ts +1 -0
- package/dist/components/Head.d.ts +1 -1
- package/dist/components/Image.d.ts +6 -8
- package/dist/components/Row.d.ts +10 -0
- package/dist/components/Text.d.ts +1 -0
- package/dist/index.cjs.js +120 -197
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +120 -197
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { ReactNode } from "react";
|
|
1
|
+
import { CSSProperties, ReactNode } from "react";
|
|
2
2
|
import { BorderConfig } from "../types";
|
|
3
|
-
/** Style-only mobile overrides. Content props (src, alt, href, target) are excluded. */
|
|
4
3
|
export interface ImageMobileConfig {
|
|
5
4
|
width?: string;
|
|
6
5
|
height?: string;
|
|
@@ -10,7 +9,8 @@ export interface ImageMobileConfig {
|
|
|
10
9
|
padding?: string;
|
|
11
10
|
borderRadius?: string;
|
|
12
11
|
border?: BorderConfig;
|
|
13
|
-
|
|
12
|
+
objectFit?: CSSProperties["objectFit"];
|
|
13
|
+
objectPosition?: string;
|
|
14
14
|
hidden?: boolean;
|
|
15
15
|
}
|
|
16
16
|
export interface ImageConfig {
|
|
@@ -26,17 +26,15 @@ export interface ImageConfig {
|
|
|
26
26
|
border?: BorderConfig;
|
|
27
27
|
href?: string;
|
|
28
28
|
target?: string;
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
* Only explicitly set properties override the desktop value on mobile.
|
|
32
|
-
* Unset properties fall back to the desktop value.
|
|
33
|
-
*/
|
|
29
|
+
objectFit?: CSSProperties["objectFit"];
|
|
30
|
+
objectPosition?: string;
|
|
34
31
|
mobile?: ImageMobileConfig;
|
|
35
32
|
}
|
|
36
33
|
export type ImageProps = {
|
|
37
34
|
config: ImageConfig;
|
|
38
35
|
devNode?: ReactNode;
|
|
39
36
|
devMode?: boolean;
|
|
37
|
+
previewMode?: boolean;
|
|
40
38
|
};
|
|
41
39
|
declare function Image({ config, devNode, devMode }: ImageProps): import("react/jsx-runtime").JSX.Element;
|
|
42
40
|
declare const _default: import("react").MemoExoticComponent<typeof Image>;
|
package/dist/components/Row.d.ts
CHANGED
|
@@ -13,6 +13,16 @@ export interface RowConfig {
|
|
|
13
13
|
alignItems?: AlignItems;
|
|
14
14
|
width?: string;
|
|
15
15
|
height?: string;
|
|
16
|
+
/**
|
|
17
|
+
* When true, the content table uses width:100% so Outlook Classic has a
|
|
18
|
+
* hard boundary and text children can wrap correctly.
|
|
19
|
+
* Use this for rows that contain text blocks alongside images.
|
|
20
|
+
*
|
|
21
|
+
* When false/undefined (default), the content table uses width:auto so
|
|
22
|
+
* children shrink-wrap to their natural sizes — preserving the original
|
|
23
|
+
* behavior. Use this for icon rows, button rows, social link rows.
|
|
24
|
+
*/
|
|
25
|
+
fillWidth?: boolean;
|
|
16
26
|
padding?: string;
|
|
17
27
|
backgroundColor?: string;
|
|
18
28
|
backgroundImage?: BackgroundImageType;
|
package/dist/index.cjs.js
CHANGED
|
@@ -10,20 +10,14 @@ function Body({ children, config = {} }) {
|
|
|
10
10
|
const globalFontSize = config.fontSize || "16px";
|
|
11
11
|
const globalBackgroundColor = config.backgroundColor || "#ffffff";
|
|
12
12
|
const globalLineHeight = config.lineHeight || "1.4";
|
|
13
|
+
const globalFontFamily = config.fontFamily || "Arial, Helvetica, sans-serif";
|
|
13
14
|
// Background image properties
|
|
14
15
|
const bgImage = ((_a = config.backgroundImage) === null || _a === void 0 ? void 0 : _a.src) || "";
|
|
15
16
|
const bgRepeat = ((_b = config.backgroundImage) === null || _b === void 0 ? void 0 : _b.repeat) || "no-repeat";
|
|
16
17
|
const bgSize = ((_c = config.backgroundImage) === null || _c === void 0 ? void 0 : _c.size) || "cover";
|
|
17
18
|
const bgPosition = ((_d = config.backgroundImage) === null || _d === void 0 ? void 0 : _d.position) || "center";
|
|
18
19
|
// 1. Style for the <body> tag inline
|
|
19
|
-
const bodyStyle = Object.assign({ backgroundColor: globalBackgroundColor, color: globalColor, fontSize: globalFontSize, lineHeight: globalLineHeight, padding: "0", margin: "0", WebkitTextSizeAdjust: "100%", overflowX: "hidden",
|
|
20
|
-
// ✅ FIX 1: Use string indexing for MSO property
|
|
21
|
-
// ['ms-text-size-adjust' as string]: '100%',
|
|
22
|
-
["msTextSizeAdjust"]: "100%",
|
|
23
|
-
// ["mso-line-height-rule" as string]: "exactly",
|
|
24
|
-
["msoLineHeightRule"]: "exactly",
|
|
25
|
-
// Base font for body
|
|
26
|
-
fontFamily: "Arial, Helvetica, sans-serif" }, (bgImage && {
|
|
20
|
+
const bodyStyle = Object.assign({ backgroundColor: globalBackgroundColor, color: globalColor, fontSize: globalFontSize, lineHeight: globalLineHeight, padding: "0", margin: "0", WebkitTextSizeAdjust: "100%", overflowX: "hidden", ["msTextSizeAdjust"]: "100%", ["msoLineHeightRule"]: "exactly", fontFamily: globalFontFamily }, (bgImage && {
|
|
27
21
|
backgroundImage: `url(${bgImage})`,
|
|
28
22
|
backgroundRepeat: bgRepeat,
|
|
29
23
|
backgroundSize: bgSize,
|
|
@@ -32,14 +26,10 @@ function Body({ children, config = {} }) {
|
|
|
32
26
|
// 2. Style for the top-level <table> wrapper
|
|
33
27
|
const outerTableStyle = {
|
|
34
28
|
width: "100%",
|
|
35
|
-
// ✅ FIX 1 (on table): Use string indexing for MSO property
|
|
36
29
|
["msoLineHeightRule"]: "exactly",
|
|
37
|
-
// ['mso-line-height-rule' as string]: 'exactly',
|
|
38
30
|
borderCollapse: "collapse",
|
|
39
31
|
};
|
|
40
|
-
return (
|
|
41
|
-
// The <body> tag with inline styles
|
|
42
|
-
jsxRuntime.jsxs("body", { style: bodyStyle, children: [jsxRuntime.jsx("center", { style: Object.assign({ width: "100%", background: globalBackgroundColor }, (bgImage && {
|
|
32
|
+
return (jsxRuntime.jsxs("body", { style: bodyStyle, children: [jsxRuntime.jsx("center", { style: Object.assign({ width: "100%", background: globalBackgroundColor }, (bgImage && {
|
|
43
33
|
backgroundImage: `url(${bgImage})`,
|
|
44
34
|
backgroundRepeat: bgRepeat,
|
|
45
35
|
backgroundSize: bgSize,
|
|
@@ -1681,9 +1671,12 @@ function Button({ config, devMode }) {
|
|
|
1681
1671
|
else {
|
|
1682
1672
|
vmlAlignStyle = `text-align:${textAlign};`;
|
|
1683
1673
|
}
|
|
1674
|
+
// Border radius is intentionally omitted (arcsize="0%") for Outlook Classic.
|
|
1675
|
+
// Outlook Classic does not reliably support rounded corners and the result
|
|
1676
|
+
// is inconsistent, so we render sharp corners there instead.
|
|
1684
1677
|
vmlButton = `
|
|
1685
1678
|
<!--[if mso]>
|
|
1686
|
-
<v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" href="${href}" style="height:${vmlHeight}px;width:${vmlWidth}px;" arcsize="
|
|
1679
|
+
<v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" href="${href}" style="height:${vmlHeight}px;width:${vmlWidth}px;" arcsize="0%" strokecolor="${vmlStrokeColor}" ${hasVmlStroke ? `strokeweight="${vmlStrokeWeight}px"` : 'stroke="f"'} fillcolor="${vmlFillColor}">
|
|
1687
1680
|
<w:anchorlock/>
|
|
1688
1681
|
<v:textbox inset="${horizontalPaddingValue}px,${numericPadding}px,${horizontalPaddingValue}px,${numericPadding}px">
|
|
1689
1682
|
<table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%" style="border-collapse:collapse;">
|
|
@@ -1716,6 +1709,9 @@ function Button({ config, devMode }) {
|
|
|
1716
1709
|
const directionProp = direction ? `direction: ${direction};` : "";
|
|
1717
1710
|
const opacityProp = opacity !== undefined ? `opacity: ${opacity};` : "";
|
|
1718
1711
|
const wordBreakProp = wordBreak !== "break-word" ? `word-break: ${wordBreak};` : "";
|
|
1712
|
+
// Border radius is intentionally omitted from the Outlook Classic table cell.
|
|
1713
|
+
// Outlook Classic ignores border-radius on table cells anyway, and including it
|
|
1714
|
+
// can cause unexpected rendering artifacts, so we explicitly leave it out.
|
|
1719
1715
|
simpleOutlookButton = `
|
|
1720
1716
|
<!--[if mso]>
|
|
1721
1717
|
<table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%" style="border-collapse: collapse;">
|
|
@@ -1723,7 +1719,7 @@ function Button({ config, devMode }) {
|
|
|
1723
1719
|
<td align="${align}" style="padding: 0;">
|
|
1724
1720
|
<table role="presentation" cellpadding="0" cellspacing="0" border="0" width="${width || "auto"}" style="border-collapse: collapse;">
|
|
1725
1721
|
<tr>
|
|
1726
|
-
<td bgcolor="${backgroundColor}" align="${textAlign}" style="padding: ${padding}; text-align: ${textAlign};
|
|
1722
|
+
<td bgcolor="${backgroundColor}" align="${textAlign}" style="padding: ${padding}; text-align: ${textAlign}; ${borderStyleString}">
|
|
1727
1723
|
<a href="${href}" target="_blank" rel="noopener noreferrer" style="color: ${color}; ${textDecorationStyle} display: block; font-family: ${safeFontFamily}; font-size: ${fontSize}; font-weight: ${fontWeight}; ${fontStyleProp} line-height: ${lineHeight}; ${letterSpacingProp} ${textTransformProp} text-align: ${textAlign}; ${whiteSpaceProp} ${directionProp} ${opacityProp} ${wordBreakProp} mso-line-height-rule: exactly;">
|
|
1728
1724
|
${typeof children === "string" ? children : ""}
|
|
1729
1725
|
</a>
|
|
@@ -2352,28 +2348,6 @@ function Html({ children, backgroundColor = "#ffffff", }) {
|
|
|
2352
2348
|
);
|
|
2353
2349
|
}
|
|
2354
2350
|
|
|
2355
|
-
/**
|
|
2356
|
-
* Content rendered by Outlook Classic only.
|
|
2357
|
-
* Outputs: <!--[if mso]> ... <![endif]-->
|
|
2358
|
-
*/
|
|
2359
|
-
function MsoOnly({ html }) {
|
|
2360
|
-
return (jsxRuntime.jsx("td", { dangerouslySetInnerHTML: {
|
|
2361
|
-
__html: `<!--[if mso]>${html}<![endif]-->`,
|
|
2362
|
-
} }));
|
|
2363
|
-
}
|
|
2364
|
-
/**
|
|
2365
|
-
* Content hidden from Outlook Classic, visible in all other clients.
|
|
2366
|
-
* Outputs: <!--[if !mso]><!--> ... <!--<![endif]-->
|
|
2367
|
-
*/
|
|
2368
|
-
function NonMso({ html }) {
|
|
2369
|
-
return (jsxRuntime.jsx("td", { dangerouslySetInnerHTML: {
|
|
2370
|
-
__html: `<!--[if !mso]><!-->${html}<!--<![endif]-->`,
|
|
2371
|
-
} }));
|
|
2372
|
-
}
|
|
2373
|
-
|
|
2374
|
-
// ---------------------------------------------------------------------------
|
|
2375
|
-
// Helpers
|
|
2376
|
-
// ---------------------------------------------------------------------------
|
|
2377
2351
|
function getBorderStyle$3(border) {
|
|
2378
2352
|
if (!border)
|
|
2379
2353
|
return {};
|
|
@@ -2381,15 +2355,6 @@ function getBorderStyle$3(border) {
|
|
|
2381
2355
|
if (border.width && border.style && border.color) {
|
|
2382
2356
|
style.border = `${border.width} ${border.style} ${border.color}`;
|
|
2383
2357
|
}
|
|
2384
|
-
else {
|
|
2385
|
-
const hasIndividual = border.top || border.right || border.bottom || border.left;
|
|
2386
|
-
if (hasIndividual) {
|
|
2387
|
-
style.borderTop = "none";
|
|
2388
|
-
style.borderRight = "none";
|
|
2389
|
-
style.borderBottom = "none";
|
|
2390
|
-
style.borderLeft = "none";
|
|
2391
|
-
}
|
|
2392
|
-
}
|
|
2393
2358
|
if (border.top)
|
|
2394
2359
|
style.borderTop = `${border.top.width} ${border.top.style} ${border.top.color}`;
|
|
2395
2360
|
if (border.right)
|
|
@@ -2404,143 +2369,87 @@ function getBorderStyleString$1(border) {
|
|
|
2404
2369
|
if (!border)
|
|
2405
2370
|
return "";
|
|
2406
2371
|
const styles = [];
|
|
2372
|
+
// Standard shorthand
|
|
2407
2373
|
if (border.width && border.style && border.color) {
|
|
2408
|
-
styles.push(`border:${border.width} ${border.style} ${border.color};`);
|
|
2374
|
+
styles.push(`border:${border.width} ${border.style} ${border.color} !important;`);
|
|
2409
2375
|
}
|
|
2410
2376
|
else {
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
styles.push("border-top:none;", "border-right:none;", "border-bottom:none;", "border-left:none;");
|
|
2414
|
-
}
|
|
2377
|
+
// If desktop had a border and mobile wants "none", we must explicitly kill it
|
|
2378
|
+
styles.push(`border: none !important;`);
|
|
2415
2379
|
}
|
|
2380
|
+
// Individual sides
|
|
2416
2381
|
if (border.top)
|
|
2417
|
-
styles.push(`border-top:${border.top.width} ${border.top.style} ${border.top.color};`);
|
|
2382
|
+
styles.push(`border-top:${border.top.width} ${border.top.style} ${border.top.color} !important;`);
|
|
2418
2383
|
if (border.right)
|
|
2419
|
-
styles.push(`border-right:${border.right.width} ${border.right.style} ${border.right.color};`);
|
|
2384
|
+
styles.push(`border-right:${border.right.width} ${border.right.style} ${border.right.color} !important;`);
|
|
2420
2385
|
if (border.bottom)
|
|
2421
|
-
styles.push(`border-bottom:${border.bottom.width} ${border.bottom.style} ${border.bottom.color};`);
|
|
2386
|
+
styles.push(`border-bottom:${border.bottom.width} ${border.bottom.style} ${border.bottom.color} !important;`);
|
|
2422
2387
|
if (border.left)
|
|
2423
|
-
styles.push(`border-left:${border.left.width} ${border.left.style} ${border.left.color};`);
|
|
2388
|
+
styles.push(`border-left:${border.left.width} ${border.left.style} ${border.left.color} !important;`);
|
|
2424
2389
|
return styles.join(" ");
|
|
2425
2390
|
}
|
|
2426
|
-
// ---------------------------------------------------------------------------
|
|
2427
|
-
// Merged styles helper — applies mobile overrides on top of desktop values
|
|
2428
|
-
// ---------------------------------------------------------------------------
|
|
2429
|
-
function mergeConfig(config, overrides) {
|
|
2430
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
2431
|
-
return {
|
|
2432
|
-
width: (_a = overrides === null || overrides === void 0 ? void 0 : overrides.width) !== null && _a !== void 0 ? _a : config.width,
|
|
2433
|
-
height: (_b = overrides === null || overrides === void 0 ? void 0 : overrides.height) !== null && _b !== void 0 ? _b : config.height,
|
|
2434
|
-
maxWidth: (_c = overrides === null || overrides === void 0 ? void 0 : overrides.maxWidth) !== null && _c !== void 0 ? _c : config.maxWidth,
|
|
2435
|
-
maxHeight: (_d = overrides === null || overrides === void 0 ? void 0 : overrides.maxHeight) !== null && _d !== void 0 ? _d : config.maxHeight,
|
|
2436
|
-
backgroundColor: (_e = overrides === null || overrides === void 0 ? void 0 : overrides.backgroundColor) !== null && _e !== void 0 ? _e : config.backgroundColor,
|
|
2437
|
-
padding: (_f = overrides === null || overrides === void 0 ? void 0 : overrides.padding) !== null && _f !== void 0 ? _f : config.padding,
|
|
2438
|
-
borderRadius: (_g = overrides === null || overrides === void 0 ? void 0 : overrides.borderRadius) !== null && _g !== void 0 ? _g : config.borderRadius,
|
|
2439
|
-
border: (_h = overrides === null || overrides === void 0 ? void 0 : overrides.border) !== null && _h !== void 0 ? _h : config.border,
|
|
2440
|
-
};
|
|
2441
|
-
}
|
|
2442
|
-
// ---------------------------------------------------------------------------
|
|
2443
|
-
// Desktop table — JSX (same as original)
|
|
2444
|
-
// ---------------------------------------------------------------------------
|
|
2445
|
-
function renderDesktopTable({ config, className, devNode, devMode, }) {
|
|
2446
|
-
const { src, alt, href, target } = config;
|
|
2447
|
-
const { width, height, maxWidth, maxHeight, backgroundColor, padding, borderRadius, border, } = mergeConfig(config);
|
|
2448
|
-
const borderStyle = getBorderStyle$3(border);
|
|
2449
|
-
const imgStyle = Object.assign({ display: "block", objectFit: "cover", width: width || "100%", height: height || "auto", maxWidth: maxWidth || "100%", maxHeight: maxHeight, border: "0", borderRadius: borderRadius }, borderStyle);
|
|
2450
|
-
const linkStyle = {
|
|
2451
|
-
display: "block",
|
|
2452
|
-
textDecoration: "none",
|
|
2453
|
-
border: "0",
|
|
2454
|
-
outline: "none",
|
|
2455
|
-
};
|
|
2456
|
-
const tdStyle = {
|
|
2457
|
-
padding: padding,
|
|
2458
|
-
backgroundColor: backgroundColor,
|
|
2459
|
-
fontSize: "0",
|
|
2460
|
-
lineHeight: "0",
|
|
2461
|
-
};
|
|
2462
|
-
const widthNum = (width === null || width === void 0 ? void 0 : width.endsWith("px")) ? parseInt(width, 10) : undefined;
|
|
2463
|
-
const maxWidthNum = (maxWidth === null || maxWidth === void 0 ? void 0 : maxWidth.endsWith("px"))
|
|
2464
|
-
? parseInt(maxWidth, 10)
|
|
2465
|
-
: undefined;
|
|
2466
|
-
const heightNum = (height === null || height === void 0 ? void 0 : height.endsWith("px")) ? parseInt(height, 10) : undefined;
|
|
2467
|
-
const imageElement = (jsxRuntime.jsx("img", { draggable: false, src: src, alt: alt, style: imgStyle, width: widthNum && maxWidthNum
|
|
2468
|
-
? Math.min(widthNum, maxWidthNum)
|
|
2469
|
-
: widthNum || maxWidthNum, height: heightNum, border: 0 }));
|
|
2470
|
-
const content = href && !devMode ? (jsxRuntime.jsx("a", Object.assign({ href: href, target: target, style: linkStyle }, (target === "_blank" ? { rel: "noopener noreferrer" } : {}), { children: imageElement }))) : (imageElement);
|
|
2471
|
-
return (jsxRuntime.jsxs("table", { "aria-label": `Image Wrapper for: ${alt}`, role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, className: className, style: {
|
|
2472
|
-
position: "relative",
|
|
2473
|
-
width: width || "100%",
|
|
2474
|
-
borderCollapse: "collapse",
|
|
2475
|
-
}, onClick: devMode ? (e) => e.preventDefault() : undefined, children: [jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { style: tdStyle, align: "center", children: content }) }) }), devMode && !!devNode && (jsxRuntime.jsx("tfoot", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { children: devNode }) }) }))] }));
|
|
2476
|
-
}
|
|
2477
|
-
// ---------------------------------------------------------------------------
|
|
2478
|
-
// Mobile table — HTML string (injected via NonMso, same pattern as Icon VML)
|
|
2479
|
-
// ---------------------------------------------------------------------------
|
|
2480
|
-
function buildMobileTableHTML({ config, overrides, className, }) {
|
|
2481
|
-
const { src, alt, href, target } = config;
|
|
2482
|
-
const { width, height, maxWidth, maxHeight, backgroundColor, padding, borderRadius, border, } = mergeConfig(config, overrides);
|
|
2483
|
-
const borderStyleStr = getBorderStyleString$1(border);
|
|
2484
|
-
const widthNum = (width === null || width === void 0 ? void 0 : width.endsWith("px")) ? parseInt(width, 10) : undefined;
|
|
2485
|
-
const maxWidthNum = (maxWidth === null || maxWidth === void 0 ? void 0 : maxWidth.endsWith("px"))
|
|
2486
|
-
? parseInt(maxWidth, 10)
|
|
2487
|
-
: undefined;
|
|
2488
|
-
const heightNum = (height === null || height === void 0 ? void 0 : height.endsWith("px")) ? parseInt(height, 10) : undefined;
|
|
2489
|
-
const resolvedWidth = widthNum && maxWidthNum
|
|
2490
|
-
? Math.min(widthNum, maxWidthNum)
|
|
2491
|
-
: widthNum || maxWidthNum;
|
|
2492
|
-
const imgTag = `<img
|
|
2493
|
-
draggable="false"
|
|
2494
|
-
src="${src}"
|
|
2495
|
-
alt="${alt}"
|
|
2496
|
-
${resolvedWidth ? `width="${resolvedWidth}"` : ""}
|
|
2497
|
-
${heightNum ? `height="${heightNum}"` : ""}
|
|
2498
|
-
border="0"
|
|
2499
|
-
style="display:block;object-fit:cover;width:${width || "100%"};height:${height || "auto"};max-width:${maxWidth || "100%"};${maxHeight ? `max-height:${maxHeight};` : ""}border:0;${borderRadius ? `border-radius:${borderRadius};` : ""}${borderStyleStr}"
|
|
2500
|
-
/>`;
|
|
2501
|
-
const content = href
|
|
2502
|
-
? `<a href="${href}" target="${target || "_self"}" style="display:block;text-decoration:none;border:0;outline:none;"${target === "_blank" ? ' rel="noopener noreferrer"' : ""}>${imgTag}</a>`
|
|
2503
|
-
: imgTag;
|
|
2504
|
-
return `
|
|
2505
|
-
<table
|
|
2506
|
-
aria-label="Image Wrapper for: ${alt}"
|
|
2507
|
-
role="presentation"
|
|
2508
|
-
cellpadding="0"
|
|
2509
|
-
cellspacing="0"
|
|
2510
|
-
border="0"
|
|
2511
|
-
class="${className}"
|
|
2512
|
-
style="position:relative;width:${width || "100%"};border-collapse:collapse;"
|
|
2513
|
-
>
|
|
2514
|
-
<tbody>
|
|
2515
|
-
<tr>
|
|
2516
|
-
<td
|
|
2517
|
-
align="center"
|
|
2518
|
-
style="padding:${padding || ""};background-color:${backgroundColor || ""};font-size:0;line-height:0;"
|
|
2519
|
-
>
|
|
2520
|
-
${content}
|
|
2521
|
-
</td>
|
|
2522
|
-
</tr>
|
|
2523
|
-
</tbody>
|
|
2524
|
-
</table>
|
|
2525
|
-
`;
|
|
2526
|
-
}
|
|
2527
|
-
// ---------------------------------------------------------------------------
|
|
2528
|
-
// Component
|
|
2529
|
-
// ---------------------------------------------------------------------------
|
|
2530
2391
|
function Image({ config, devNode, devMode }) {
|
|
2531
|
-
|
|
2532
|
-
const
|
|
2533
|
-
const
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2392
|
+
var _a;
|
|
2393
|
+
const { src, alt, href, target, mobile } = config;
|
|
2394
|
+
const seed = src + (alt || "");
|
|
2395
|
+
const instanceId = seed
|
|
2396
|
+
.split("")
|
|
2397
|
+
.reduce((acc, char) => acc + char.charCodeAt(0), 0)
|
|
2398
|
+
.toString(36);
|
|
2399
|
+
const imgClass = `img-${instanceId}`;
|
|
2400
|
+
// 1. Desktop Dimensional Logic
|
|
2401
|
+
const desktopWidth = config.width || "100%";
|
|
2402
|
+
const isPercent = desktopWidth.includes("%");
|
|
2403
|
+
const widthAttr = desktopWidth.replace("px", "");
|
|
2404
|
+
const heightAttr = (_a = config.height) === null || _a === void 0 ? void 0 : _a.replace("px", "");
|
|
2405
|
+
// Determine the table's "initial" width.
|
|
2406
|
+
// If it's 300px, the table should be 300px, not 100%.
|
|
2407
|
+
const tableWidth = isPercent ? desktopWidth : `${widthAttr}px`;
|
|
2408
|
+
// 2. Mobile Overrides (Every property used)
|
|
2409
|
+
let mobileCss = "";
|
|
2410
|
+
if (mobile) {
|
|
2411
|
+
mobileCss = `
|
|
2412
|
+
@media screen and (max-width: 768px) {
|
|
2413
|
+
.wrap-${imgClass} {
|
|
2414
|
+
/* This breaks the px lock from desktop and makes it fluid */
|
|
2415
|
+
width: ${mobile.width || "100%"} !important;
|
|
2416
|
+
max-width: ${mobile.maxWidth || "100%"} !important;
|
|
2417
|
+
min-width: 0 !important;
|
|
2418
|
+
}
|
|
2419
|
+
.td-${imgClass} {
|
|
2420
|
+
padding: ${mobile.padding || "0"} !important;
|
|
2421
|
+
background-color: ${mobile.backgroundColor || "transparent"} !important;
|
|
2422
|
+
width: 100% !important;
|
|
2423
|
+
}
|
|
2424
|
+
.${imgClass} {
|
|
2425
|
+
width: ${mobile.width || "100%"} !important;
|
|
2426
|
+
height: ${mobile.height || "auto"} !important;
|
|
2427
|
+
max-width: ${mobile.maxWidth || "100%"} !important;
|
|
2428
|
+
max-height: ${mobile.maxHeight || "none"} !important;
|
|
2429
|
+
border-radius: ${mobile.borderRadius || "0"} !important;
|
|
2430
|
+
display: ${mobile.hidden ? "none" : "block"} !important;
|
|
2431
|
+
object-fit: ${mobile.objectFit || "fill"} !important;
|
|
2432
|
+
object-position: ${mobile.objectPosition || "center"} !important;
|
|
2433
|
+
${getBorderStyleString$1(mobile.border)}
|
|
2434
|
+
}
|
|
2435
|
+
}
|
|
2436
|
+
`;
|
|
2437
|
+
}
|
|
2438
|
+
const imgStyle = Object.assign(Object.assign({ display: "block", width: isPercent ? "100%" : desktopWidth, height: config.height || "auto", maxWidth: config.maxWidth || "100%", maxHeight: config.maxHeight || "none", borderRadius: config.borderRadius || "0" }, getBorderStyle$3(config.border)), { outline: "none", textDecoration: "none", objectFit: config.objectFit, objectPosition: config.objectPosition });
|
|
2439
|
+
const imageElement = (jsxRuntime.jsx("img", { src: src, alt: alt, width: !isPercent ? widthAttr : undefined, height: heightAttr !== "auto" ? heightAttr : undefined, className: imgClass, style: imgStyle }));
|
|
2440
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [mobile && jsxRuntime.jsx("style", { dangerouslySetInnerHTML: { __html: mobileCss } }), jsxRuntime.jsxs("table", { role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, className: `wrap-${imgClass}`, align: "center" // Ensures a 300px image stays centered in its parent
|
|
2441
|
+
, style: {
|
|
2442
|
+
width: tableWidth, // Fixed px here prevents the 100% "ghost space"
|
|
2443
|
+
maxWidth: "100%",
|
|
2444
|
+
borderCollapse: "collapse",
|
|
2445
|
+
margin: "0 auto",
|
|
2446
|
+
}, children: [jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { className: `td-${imgClass}`, align: "center", style: {
|
|
2447
|
+
padding: config.padding,
|
|
2448
|
+
backgroundColor: config.backgroundColor,
|
|
2449
|
+
fontSize: "0",
|
|
2450
|
+
lineHeight: "0",
|
|
2451
|
+
width: tableWidth, // Lock the cell as well
|
|
2452
|
+
}, children: href && !devMode ? (jsxRuntime.jsx("a", { href: href, target: target, style: { display: "block", width: "100%" }, children: imageElement })) : (imageElement) }) }) }), devMode && !!devNode && (jsxRuntime.jsx("tfoot", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { children: devNode }) }) }))] })] }));
|
|
2544
2453
|
}
|
|
2545
2454
|
var Image_default = React.memo(Image, arePropsEqual);
|
|
2546
2455
|
|
|
@@ -2615,35 +2524,31 @@ function Row({ children, config, devNode, devMode }) {
|
|
|
2615
2524
|
const numChildren = childrenArray.length;
|
|
2616
2525
|
const href = getHrefFromInnerLink(config.innerLink);
|
|
2617
2526
|
const target = (_a = config.innerLink) === null || _a === void 0 ? void 0 : _a.target;
|
|
2618
|
-
// 1. Outer TD
|
|
2619
|
-
|
|
2620
|
-
const backgroundTdStyle = Object.assign({ backgroundColor: config.backgroundColor, borderRadius: config.borderRadius, width: config.width || "100%", height: config.height,
|
|
2621
|
-
// Background Image styles
|
|
2622
|
-
backgroundImage: config.backgroundImage
|
|
2527
|
+
// 1. Outer TD: Background, Border Radius, Width, Height.
|
|
2528
|
+
const backgroundTdStyle = Object.assign({ backgroundColor: config.backgroundColor, borderRadius: config.borderRadius, width: config.width || "100%", height: config.height, backgroundImage: config.backgroundImage
|
|
2623
2529
|
? `url(${config.backgroundImage.src})`
|
|
2624
2530
|
: undefined, backgroundRepeat: (_b = config.backgroundImage) === null || _b === void 0 ? void 0 : _b.repeat, backgroundSize: (_c = config.backgroundImage) === null || _c === void 0 ? void 0 : _c.size, backgroundPosition: (_d = config.backgroundImage) === null || _d === void 0 ? void 0 : _d.position }, (config.borderRadius && { overflow: "hidden" }));
|
|
2625
|
-
// 2. Inner Table
|
|
2626
|
-
// height: 100% so it stretches to fill the outer TD.
|
|
2531
|
+
// 2. Inner Table: Border and Border Radius.
|
|
2627
2532
|
const borderTableStyle = Object.assign({ width: "100%", height: "100%", borderCollapse: "separate", borderSpacing: 0, borderRadius: config.borderRadius }, getBorderStyle$2(config.border));
|
|
2628
|
-
// 3.
|
|
2629
|
-
// The outer TD owns the total height; setting height here would cause
|
|
2630
|
-
// browsers/email clients to treat it as content-box height and add
|
|
2631
|
-
// padding on top, making the row taller than the declared height.
|
|
2533
|
+
// 3. Padding TD.
|
|
2632
2534
|
const paddingTdStyle = {
|
|
2633
2535
|
padding: config.padding,
|
|
2634
2536
|
width: "100%",
|
|
2635
|
-
// height intentionally omitted — padding must be inner, not additive
|
|
2636
2537
|
verticalAlign: "top",
|
|
2637
2538
|
};
|
|
2638
|
-
// 4. Content Table
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
//
|
|
2539
|
+
// 4. Content Table.
|
|
2540
|
+
//
|
|
2541
|
+
// fillWidth: false/undefined (default) → width: "auto"
|
|
2542
|
+
// Original behavior. Children shrink-wrap to their natural sizes.
|
|
2543
|
+
// Use for icon rows, button rows, social link rows.
|
|
2544
|
+
// Centering works via the Justification Wrapper TD (align + width="100%").
|
|
2545
|
+
//
|
|
2546
|
+
// fillWidth: true → width: "100%"
|
|
2547
|
+
// Content table fills available space, giving Outlook Classic a hard
|
|
2548
|
+
// boundary so text children get a constrained box and line wrapping
|
|
2549
|
+
// triggers correctly. Use for rows containing text + image layouts.
|
|
2550
|
+
const contentTableStyle = Object.assign({ width: config.fillWidth ? "100%" : "auto", height: "100%", borderCollapse: "collapse", minWidth: "1px" }, (!config.fillWidth && { maxWidth: config.width || "100%" }));
|
|
2551
|
+
// 5. Gap TD.
|
|
2647
2552
|
const gapTdStyle = {
|
|
2648
2553
|
width: config.gap || "0",
|
|
2649
2554
|
lineHeight: "1px",
|
|
@@ -2653,7 +2558,6 @@ function Row({ children, config, devNode, devMode }) {
|
|
|
2653
2558
|
? justifyMap$1[config.justifyContent]
|
|
2654
2559
|
: "left";
|
|
2655
2560
|
const tdValign = config.alignItems ? alignMap[config.alignItems] : "top";
|
|
2656
|
-
// Content to render - wrapped in anchor if innerLink is defined
|
|
2657
2561
|
const content = (jsxRuntime.jsxs("table", Object.assign({ "aria-label": "Row Outer", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: {
|
|
2658
2562
|
position: "relative",
|
|
2659
2563
|
width: config.width || "100%",
|
|
@@ -2663,14 +2567,13 @@ function Row({ children, config, devNode, devMode }) {
|
|
|
2663
2567
|
width: "100%",
|
|
2664
2568
|
height: "100%",
|
|
2665
2569
|
borderCollapse: "collapse",
|
|
2666
|
-
}, children: jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { align: tdAlign, children: jsxRuntime.jsx("table", Object.assign({ "aria-label": "Row Content", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: contentTableStyle }, (config.height && { height: config.height }), { className: "content-table row-content-table", "data-mobile-justify": (_e = config.mobile) === null || _e === void 0 ? void 0 : _e.justifyContent, "data-mobile-align": (_f = config.mobile) === null || _f === void 0 ? void 0 : _f.alignItems, "data-mobile-wrap": ((_g = config.mobile) === null || _g === void 0 ? void 0 : _g.wrap) ? "true" : undefined, "data-gap": config.gap, children: jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { className: "content-tr", children: childrenArray.map((child, index) => (jsxRuntime.jsxs(React.Fragment, { children: [jsxRuntime.jsx("td", { valign: tdValign, style: {
|
|
2570
|
+
}, children: jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { align: tdAlign, width: "100%", style: { width: "100%" }, children: jsxRuntime.jsx("table", Object.assign({ "aria-label": "Row Content", role: "presentation", cellPadding: 0, cellSpacing: 0, border: 0, style: contentTableStyle }, (config.height && { height: config.height }), { className: "content-table row-content-table", "data-mobile-justify": (_e = config.mobile) === null || _e === void 0 ? void 0 : _e.justifyContent, "data-mobile-align": (_f = config.mobile) === null || _f === void 0 ? void 0 : _f.alignItems, "data-mobile-wrap": ((_g = config.mobile) === null || _g === void 0 ? void 0 : _g.wrap) ? "true" : undefined, "data-gap": config.gap, children: jsxRuntime.jsx("tbody", { children: jsxRuntime.jsx("tr", { className: "content-tr", children: childrenArray.map((child, index) => (jsxRuntime.jsxs(React.Fragment, { children: [jsxRuntime.jsx("td", { valign: tdValign, style: {
|
|
2667
2571
|
verticalAlign: tdValign,
|
|
2668
2572
|
textAlign: "left",
|
|
2669
2573
|
padding: "0",
|
|
2670
2574
|
margin: "0",
|
|
2671
2575
|
}, className: "child-cell", children: child }), index < numChildren - 1 &&
|
|
2672
2576
|
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 }) }) }))] })));
|
|
2673
|
-
// Wrap in anchor tag if innerLink is defined and NOT in dev mode
|
|
2674
2577
|
if (href && !devMode) {
|
|
2675
2578
|
return (jsxRuntime.jsx("a", Object.assign({ href: href }, (target && { target }), { style: {
|
|
2676
2579
|
textDecoration: "none",
|
|
@@ -2772,7 +2675,7 @@ function Spacer({ config, devNode }) {
|
|
|
2772
2675
|
var Spacer_default = React.memo(Spacer, arePropsEqual);
|
|
2773
2676
|
|
|
2774
2677
|
function Text({ config, devMode, children }) {
|
|
2775
|
-
const { text, padding, color, textAlign, fontFamily, fontSize, fontWeight, fontStyle, lineHeight, letterSpacing, textTransform, textDecoration, direction, verticalAlign, backgroundColor, opacity, whiteSpace, wordBreak = "break-all", } = config;
|
|
2678
|
+
const { text, padding, color, textAlign, fontFamily, fontSize, fontWeight, fontStyle, lineHeight, letterSpacing, textTransform, textDecoration, direction, verticalAlign, backgroundColor, opacity, whiteSpace, wordBreak = "break-all", maxWidth } = config;
|
|
2776
2679
|
// 1. TD Style: Where padding and background are reliably applied.
|
|
2777
2680
|
const tdStyle = {
|
|
2778
2681
|
padding: padding,
|
|
@@ -2799,6 +2702,7 @@ function Text({ config, devMode, children }) {
|
|
|
2799
2702
|
wordBreak: wordBreak,
|
|
2800
2703
|
margin: "0",
|
|
2801
2704
|
padding: "0",
|
|
2705
|
+
maxWidth
|
|
2802
2706
|
};
|
|
2803
2707
|
// Determine content to render
|
|
2804
2708
|
const content = text !== null && text !== void 0 ? text : children;
|
|
@@ -3078,6 +2982,25 @@ function Icon({ config, devNode, devMode, children }) {
|
|
|
3078
2982
|
}
|
|
3079
2983
|
var Icon_default = React.memo(Icon, arePropsEqual);
|
|
3080
2984
|
|
|
2985
|
+
/**
|
|
2986
|
+
* Content rendered by Outlook Classic only.
|
|
2987
|
+
* Outputs: <!--[if mso]> ... <![endif]-->
|
|
2988
|
+
*/
|
|
2989
|
+
function MsoOnly({ html }) {
|
|
2990
|
+
return (jsxRuntime.jsx("td", { dangerouslySetInnerHTML: {
|
|
2991
|
+
__html: `<!--[if mso]>${html}<![endif]-->`,
|
|
2992
|
+
} }));
|
|
2993
|
+
}
|
|
2994
|
+
/**
|
|
2995
|
+
* Content hidden from Outlook Classic, visible in all other clients.
|
|
2996
|
+
* Outputs: <!--[if !mso]><!--> ... <!--<![endif]-->
|
|
2997
|
+
*/
|
|
2998
|
+
function NonMso({ html }) {
|
|
2999
|
+
return (jsxRuntime.jsx("td", { dangerouslySetInnerHTML: {
|
|
3000
|
+
__html: `<!--[if !mso]><!-->${html}<!--<![endif]-->`,
|
|
3001
|
+
} }));
|
|
3002
|
+
}
|
|
3003
|
+
|
|
3081
3004
|
exports.Body = Body;
|
|
3082
3005
|
exports.Button = Button_default;
|
|
3083
3006
|
exports.Column = Column_default;
|