@depup/react-email 6.9.3-depup.0 → 6.11.0-depup.0
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/CHANGELOG.md +24 -0
- package/README.md +8 -9
- package/changes.json +7 -11
- package/dist/cli/index.mjs +74 -33
- package/dist/components/container/container.cjs +18 -3
- package/dist/components/container/container.d.cts +3 -1
- package/dist/components/container/container.d.mts +3 -1
- package/dist/components/container/container.mjs +18 -3
- package/dist/components/element-marker.cjs +8 -2
- package/dist/components/element-marker.d.cts +14 -0
- package/dist/components/element-marker.d.mts +14 -0
- package/dist/components/element-marker.mjs +8 -3
- package/dist/components/index.d.cts +1 -0
- package/dist/components/index.d.mts +1 -0
- package/dist/components/section/section.cjs +18 -3
- package/dist/components/section/section.d.cts +3 -1
- package/dist/components/section/section.d.mts +3 -1
- package/dist/components/section/section.mjs +18 -3
- package/dist/components/tailwind/utils/tailwindcss/clone-element-with-inlined-styles.cjs +34 -21
- package/dist/components/tailwind/utils/tailwindcss/clone-element-with-inlined-styles.mjs +34 -21
- package/dist/index.cjs +2 -0
- package/dist/index.d.cts +2 -1
- package/dist/index.d.mts +2 -1
- package/dist/index.mjs +2 -1
- package/package.json +16 -20
- package/readme.md +8 -0
- package/src/components/container/container.tsx +66 -46
- package/src/components/element-marker.ts +25 -2
- package/src/components/index.ts +5 -0
- package/src/components/section/section.tsx +66 -46
- package/src/components/tailwind/tailwind.spec.tsx +13 -0
- package/src/components/tailwind/utils/tailwindcss/clone-element-with-inlined-styles.ts +46 -37
|
@@ -2,6 +2,8 @@ import * as React$1 from "react";
|
|
|
2
2
|
|
|
3
3
|
//#region src/components/section/section.d.ts
|
|
4
4
|
type SectionProps = Readonly<React$1.ComponentPropsWithoutRef<'table'>>;
|
|
5
|
-
declare const Section: React$1.ForwardRefExoticComponent<Readonly<Omit<React$1.DetailedHTMLProps<React$1.TableHTMLAttributes<HTMLTableElement>, HTMLTableElement>, "ref">> &
|
|
5
|
+
declare const Section: React$1.ForwardRefExoticComponent<Readonly<Omit<React$1.DetailedHTMLProps<React$1.TableHTMLAttributes<HTMLTableElement>, HTMLTableElement>, "ref">> & {
|
|
6
|
+
tdClassName?: string;
|
|
7
|
+
} & React$1.RefAttributes<HTMLTableElement>>;
|
|
6
8
|
//#endregion
|
|
7
9
|
export { Section, SectionProps };
|
|
@@ -2,14 +2,14 @@ import { markAsElement } from "../element-marker.mjs";
|
|
|
2
2
|
import * as React$1 from "react";
|
|
3
3
|
import { jsx } from "react/jsx-runtime";
|
|
4
4
|
//#region src/components/section/section.tsx
|
|
5
|
-
const Section = React$1.forwardRef(({ children, style = {}, ...props }, ref) => {
|
|
5
|
+
const Section = React$1.forwardRef(({ children, style = {}, tdClassName, ...props }, ref) => {
|
|
6
6
|
const tdStyle = {};
|
|
7
7
|
const tableStyle = {};
|
|
8
8
|
const styleRecord = style;
|
|
9
9
|
for (const key in styleRecord) {
|
|
10
10
|
if (!Object.hasOwn(styleRecord, key)) continue;
|
|
11
11
|
const value = styleRecord[key];
|
|
12
|
-
if (key
|
|
12
|
+
if (key.startsWith("padding")) tdStyle[key] = value;
|
|
13
13
|
else tableStyle[key] = value;
|
|
14
14
|
}
|
|
15
15
|
return /* @__PURE__ */ jsx("table", {
|
|
@@ -23,12 +23,27 @@ const Section = React$1.forwardRef(({ children, style = {}, ...props }, ref) =>
|
|
|
23
23
|
ref,
|
|
24
24
|
style: tableStyle,
|
|
25
25
|
children: /* @__PURE__ */ jsx("tbody", { children: /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx("td", {
|
|
26
|
+
className: tdClassName,
|
|
26
27
|
style: tdStyle,
|
|
27
28
|
children
|
|
28
29
|
}) }) })
|
|
29
30
|
});
|
|
30
31
|
});
|
|
31
32
|
Section.displayName = "Section";
|
|
32
|
-
markAsElement(Section)
|
|
33
|
+
markAsElement(Section, { resolveTailwind(props, { style, className, classProperties }) {
|
|
34
|
+
const tableClasses = [];
|
|
35
|
+
const tdClasses = props.tdClassName ? [props.tdClassName] : [];
|
|
36
|
+
for (const name of className?.split(" ") ?? []) {
|
|
37
|
+
const properties = classProperties[name];
|
|
38
|
+
if (properties && properties.length > 0 && properties.every((property) => property.startsWith("padding"))) tdClasses.push(name);
|
|
39
|
+
else tableClasses.push(name);
|
|
40
|
+
}
|
|
41
|
+
return {
|
|
42
|
+
...props,
|
|
43
|
+
style,
|
|
44
|
+
className: tableClasses.length > 0 ? tableClasses.join(" ") : void 0,
|
|
45
|
+
tdClassName: tdClasses.length > 0 ? tdClasses.join(" ") : void 0
|
|
46
|
+
};
|
|
47
|
+
} });
|
|
33
48
|
//#endregion
|
|
34
49
|
export { Section };
|
|
@@ -1,35 +1,48 @@
|
|
|
1
1
|
const require_runtime = require("../../../../_virtual/_rolldown/runtime.cjs");
|
|
2
|
+
const require_element_marker = require("../../../element-marker.cjs");
|
|
2
3
|
const require_make_inline_styles_for = require("../css/make-inline-styles-for.cjs");
|
|
3
4
|
const require_sanitize_class_name = require("../compatibility/sanitize-class-name.cjs");
|
|
4
5
|
const require_is_component = require("../react/is-component.cjs");
|
|
5
6
|
let react = require("react");
|
|
6
7
|
react = require_runtime.__toESM(react, 1);
|
|
8
|
+
let css_tree = require("css-tree");
|
|
7
9
|
//#region src/components/tailwind/utils/tailwindcss/clone-element-with-inlined-styles.ts
|
|
8
10
|
function cloneElementWithInlinedStyles(element, inlinableRules, nonInlinableRules, customProperties) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
11
|
+
if (!element.props.className || require_is_component.isComponent(element)) return react.default.cloneElement(element, element.props, element.props.children);
|
|
12
|
+
const classes = element.props.className.trim().split(/\s+/);
|
|
13
|
+
const residualClasses = [];
|
|
14
|
+
const classProperties = Object.create(null);
|
|
15
|
+
const rules = [];
|
|
16
|
+
for (const className of classes) {
|
|
17
|
+
const classRules = inlinableRules.get(className);
|
|
18
|
+
if (classRules) rules.push(...classRules);
|
|
19
|
+
const nonInlinable = nonInlinableRules.get(className);
|
|
20
|
+
if (nonInlinable) {
|
|
21
|
+
const sanitized = require_sanitize_class_name.sanitizeClassName(className);
|
|
22
|
+
residualClasses.push(sanitized);
|
|
23
|
+
const properties = [];
|
|
24
|
+
for (const rule of nonInlinable) (0, css_tree.walk)(rule, {
|
|
25
|
+
visit: "Declaration",
|
|
26
|
+
enter(declaration) {
|
|
27
|
+
properties.push(declaration.property);
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
classProperties[sanitized] = properties;
|
|
31
|
+
} else if (!classRules) residualClasses.push(className);
|
|
32
|
+
}
|
|
33
|
+
const resolved = {
|
|
34
|
+
style: {
|
|
21
35
|
...require_make_inline_styles_for.makeInlineStylesFor(rules, customProperties),
|
|
22
36
|
...element.props.style
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
const newProps = {
|
|
37
|
+
},
|
|
38
|
+
className: residualClasses.length > 0 ? residualClasses.join(" ") : void 0,
|
|
39
|
+
classProperties
|
|
40
|
+
};
|
|
41
|
+
const resolveTailwind = require_element_marker.getElementOptions(element.type)?.resolveTailwind;
|
|
42
|
+
const newProps = resolveTailwind ? resolveTailwind(element.props, resolved) : {
|
|
31
43
|
...element.props,
|
|
32
|
-
|
|
44
|
+
style: resolved.style,
|
|
45
|
+
className: resolved.className
|
|
33
46
|
};
|
|
34
47
|
return react.default.cloneElement(element, newProps, newProps.children);
|
|
35
48
|
}
|
|
@@ -1,33 +1,46 @@
|
|
|
1
|
+
import { getElementOptions } from "../../../element-marker.mjs";
|
|
1
2
|
import { makeInlineStylesFor } from "../css/make-inline-styles-for.mjs";
|
|
2
3
|
import { sanitizeClassName } from "../compatibility/sanitize-class-name.mjs";
|
|
3
4
|
import { isComponent } from "../react/is-component.mjs";
|
|
4
5
|
import React from "react";
|
|
6
|
+
import { walk } from "css-tree/dist/csstree.esm";
|
|
5
7
|
//#region src/components/tailwind/utils/tailwindcss/clone-element-with-inlined-styles.ts
|
|
6
8
|
function cloneElementWithInlinedStyles(element, inlinableRules, nonInlinableRules, customProperties) {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
9
|
+
if (!element.props.className || isComponent(element)) return React.cloneElement(element, element.props, element.props.children);
|
|
10
|
+
const classes = element.props.className.trim().split(/\s+/);
|
|
11
|
+
const residualClasses = [];
|
|
12
|
+
const classProperties = Object.create(null);
|
|
13
|
+
const rules = [];
|
|
14
|
+
for (const className of classes) {
|
|
15
|
+
const classRules = inlinableRules.get(className);
|
|
16
|
+
if (classRules) rules.push(...classRules);
|
|
17
|
+
const nonInlinable = nonInlinableRules.get(className);
|
|
18
|
+
if (nonInlinable) {
|
|
19
|
+
const sanitized = sanitizeClassName(className);
|
|
20
|
+
residualClasses.push(sanitized);
|
|
21
|
+
const properties = [];
|
|
22
|
+
for (const rule of nonInlinable) walk(rule, {
|
|
23
|
+
visit: "Declaration",
|
|
24
|
+
enter(declaration) {
|
|
25
|
+
properties.push(declaration.property);
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
classProperties[sanitized] = properties;
|
|
29
|
+
} else if (!classRules) residualClasses.push(className);
|
|
30
|
+
}
|
|
31
|
+
const resolved = {
|
|
32
|
+
style: {
|
|
19
33
|
...makeInlineStylesFor(rules, customProperties),
|
|
20
34
|
...element.props.style
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
28
|
-
const newProps = {
|
|
35
|
+
},
|
|
36
|
+
className: residualClasses.length > 0 ? residualClasses.join(" ") : void 0,
|
|
37
|
+
classProperties
|
|
38
|
+
};
|
|
39
|
+
const resolveTailwind = getElementOptions(element.type)?.resolveTailwind;
|
|
40
|
+
const newProps = resolveTailwind ? resolveTailwind(element.props, resolved) : {
|
|
29
41
|
...element.props,
|
|
30
|
-
|
|
42
|
+
style: resolved.style,
|
|
43
|
+
className: resolved.className
|
|
31
44
|
};
|
|
32
45
|
return React.cloneElement(element, newProps, newProps.children);
|
|
33
46
|
}
|
package/dist/index.cjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_element_marker = require("./components/element-marker.cjs");
|
|
2
3
|
const require_body = require("./components/body/body.cjs");
|
|
3
4
|
const require_button = require("./components/button/button.cjs");
|
|
4
5
|
const require_code_block = require("./components/code-block/code-block.cjs");
|
|
@@ -64,6 +65,7 @@ exports.hopscotch = require_themes.hopscotch;
|
|
|
64
65
|
exports.inlineStyles = require_inline_styles.inlineStyles;
|
|
65
66
|
exports.laserwave = require_themes.laserwave;
|
|
66
67
|
exports.lucario = require_themes.lucario;
|
|
68
|
+
exports.markAsElement = require_element_marker.markAsElement;
|
|
67
69
|
exports.materialDark = require_themes.materialDark;
|
|
68
70
|
exports.materialLight = require_themes.materialLight;
|
|
69
71
|
exports.materialOceanic = require_themes.materialOceanic;
|
package/dist/index.d.cts
CHANGED
|
@@ -6,6 +6,7 @@ import { CodeBlock, CodeBlockProps } from "./components/code-block/code-block.cj
|
|
|
6
6
|
import { CodeInline, CodeInlineProps } from "./components/code-inline/code-inline.cjs";
|
|
7
7
|
import { Column, ColumnProps } from "./components/column/column.cjs";
|
|
8
8
|
import { Container, ContainerProps } from "./components/container/container.cjs";
|
|
9
|
+
import { ElementOptions, ResolvedTailwind, markAsElement } from "./components/element-marker.cjs";
|
|
9
10
|
import { Font, FontProps } from "./components/font/font.cjs";
|
|
10
11
|
import { Head, HeadProps } from "./components/head/head.cjs";
|
|
11
12
|
import { Heading, HeadingAs, HeadingProps } from "./components/heading/heading.cjs";
|
|
@@ -23,4 +24,4 @@ import { EmailElementProps, Tailwind, TailwindConfig, TailwindProps, pixelBasedP
|
|
|
23
24
|
import { TailwindSetup, setupTailwind } from "./components/tailwind/utils/tailwindcss/setup-tailwind.cjs";
|
|
24
25
|
import { Text, TextProps } from "./components/text/text.cjs";
|
|
25
26
|
export * from "@react-email/render";
|
|
26
|
-
export { Body, BodyProps, Button, ButtonProps, CodeBlock, CodeBlockProps, CodeInline, CodeInlineProps, Column, ColumnProps, Container, ContainerProps, EmailElementProps, Font, FontProps, Head, HeadProps, Heading, HeadingAs, HeadingProps, Hr, HrProps, Html, HtmlProps, Img, ImgProps, Link, LinkProps, Markdown, MarkdownProps, Preview, PreviewProps, PrismLanguage, Row, RowProps, Section, SectionProps, Tailwind, TailwindConfig, TailwindProps, TailwindSetup, Text, TextProps, Theme, a11yDark, atomDark, baseAteliersulphurpoolLight, cb, coldarkCold, coldarkDark, coyWithoutShadows, darcula, dracula, duotoneDark, duotoneEarth, duotoneForest, duotoneLight, duotoneSea, duotoneSpace, ghcolors, gruvboxDark, gruvboxLight, holiTheme, hopscotch, inlineStyles, laserwave, lucario, materialDark, materialLight, materialOceanic, nightOwl, nord, oneDark, oneLight, pixelBasedPreset, pojoaque, renderWhiteSpace, sanitizeStyleSheet, setupTailwind, shadesOfPurple, solarizedDarkAtom, synthwave84, vesper, vs, vscDarkPlus, xonokai, zTouch };
|
|
27
|
+
export { Body, BodyProps, Button, ButtonProps, CodeBlock, CodeBlockProps, CodeInline, CodeInlineProps, Column, ColumnProps, Container, ContainerProps, ElementOptions, EmailElementProps, Font, FontProps, Head, HeadProps, Heading, HeadingAs, HeadingProps, Hr, HrProps, Html, HtmlProps, Img, ImgProps, Link, LinkProps, Markdown, MarkdownProps, Preview, PreviewProps, PrismLanguage, ResolvedTailwind, Row, RowProps, Section, SectionProps, Tailwind, TailwindConfig, TailwindProps, TailwindSetup, Text, TextProps, Theme, a11yDark, atomDark, baseAteliersulphurpoolLight, cb, coldarkCold, coldarkDark, coyWithoutShadows, darcula, dracula, duotoneDark, duotoneEarth, duotoneForest, duotoneLight, duotoneSea, duotoneSpace, ghcolors, gruvboxDark, gruvboxLight, holiTheme, hopscotch, inlineStyles, laserwave, lucario, markAsElement, materialDark, materialLight, materialOceanic, nightOwl, nord, oneDark, oneLight, pixelBasedPreset, pojoaque, renderWhiteSpace, sanitizeStyleSheet, setupTailwind, shadesOfPurple, solarizedDarkAtom, synthwave84, vesper, vs, vscDarkPlus, xonokai, zTouch };
|
package/dist/index.d.mts
CHANGED
|
@@ -6,6 +6,7 @@ import { CodeBlock, CodeBlockProps } from "./components/code-block/code-block.mj
|
|
|
6
6
|
import { CodeInline, CodeInlineProps } from "./components/code-inline/code-inline.mjs";
|
|
7
7
|
import { Column, ColumnProps } from "./components/column/column.mjs";
|
|
8
8
|
import { Container, ContainerProps } from "./components/container/container.mjs";
|
|
9
|
+
import { ElementOptions, ResolvedTailwind, markAsElement } from "./components/element-marker.mjs";
|
|
9
10
|
import { Font, FontProps } from "./components/font/font.mjs";
|
|
10
11
|
import { Head, HeadProps } from "./components/head/head.mjs";
|
|
11
12
|
import { Heading, HeadingAs, HeadingProps } from "./components/heading/heading.mjs";
|
|
@@ -23,4 +24,4 @@ import { EmailElementProps, Tailwind, TailwindConfig, TailwindProps, pixelBasedP
|
|
|
23
24
|
import { TailwindSetup, setupTailwind } from "./components/tailwind/utils/tailwindcss/setup-tailwind.mjs";
|
|
24
25
|
import { Text, TextProps } from "./components/text/text.mjs";
|
|
25
26
|
export * from "@react-email/render";
|
|
26
|
-
export { Body, BodyProps, Button, ButtonProps, CodeBlock, CodeBlockProps, CodeInline, CodeInlineProps, Column, ColumnProps, Container, ContainerProps, EmailElementProps, Font, FontProps, Head, HeadProps, Heading, HeadingAs, HeadingProps, Hr, HrProps, Html, HtmlProps, Img, ImgProps, Link, LinkProps, Markdown, MarkdownProps, Preview, PreviewProps, PrismLanguage, Row, RowProps, Section, SectionProps, Tailwind, TailwindConfig, TailwindProps, TailwindSetup, Text, TextProps, Theme, a11yDark, atomDark, baseAteliersulphurpoolLight, cb, coldarkCold, coldarkDark, coyWithoutShadows, darcula, dracula, duotoneDark, duotoneEarth, duotoneForest, duotoneLight, duotoneSea, duotoneSpace, ghcolors, gruvboxDark, gruvboxLight, holiTheme, hopscotch, inlineStyles, laserwave, lucario, materialDark, materialLight, materialOceanic, nightOwl, nord, oneDark, oneLight, pixelBasedPreset, pojoaque, renderWhiteSpace, sanitizeStyleSheet, setupTailwind, shadesOfPurple, solarizedDarkAtom, synthwave84, vesper, vs, vscDarkPlus, xonokai, zTouch };
|
|
27
|
+
export { Body, BodyProps, Button, ButtonProps, CodeBlock, CodeBlockProps, CodeInline, CodeInlineProps, Column, ColumnProps, Container, ContainerProps, ElementOptions, EmailElementProps, Font, FontProps, Head, HeadProps, Heading, HeadingAs, HeadingProps, Hr, HrProps, Html, HtmlProps, Img, ImgProps, Link, LinkProps, Markdown, MarkdownProps, Preview, PreviewProps, PrismLanguage, ResolvedTailwind, Row, RowProps, Section, SectionProps, Tailwind, TailwindConfig, TailwindProps, TailwindSetup, Text, TextProps, Theme, a11yDark, atomDark, baseAteliersulphurpoolLight, cb, coldarkCold, coldarkDark, coyWithoutShadows, darcula, dracula, duotoneDark, duotoneEarth, duotoneForest, duotoneLight, duotoneSea, duotoneSpace, ghcolors, gruvboxDark, gruvboxLight, holiTheme, hopscotch, inlineStyles, laserwave, lucario, markAsElement, materialDark, materialLight, materialOceanic, nightOwl, nord, oneDark, oneLight, pixelBasedPreset, pojoaque, renderWhiteSpace, sanitizeStyleSheet, setupTailwind, shadesOfPurple, solarizedDarkAtom, synthwave84, vesper, vs, vscDarkPlus, xonokai, zTouch };
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { markAsElement } from "./components/element-marker.mjs";
|
|
1
2
|
import { Body } from "./components/body/body.mjs";
|
|
2
3
|
import { Button } from "./components/button/button.mjs";
|
|
3
4
|
import { CodeBlock } from "./components/code-block/code-block.mjs";
|
|
@@ -22,4 +23,4 @@ import { setupTailwind } from "./components/tailwind/utils/tailwindcss/setup-tai
|
|
|
22
23
|
import { Tailwind, pixelBasedPreset } from "./components/tailwind/tailwind.mjs";
|
|
23
24
|
import { Text } from "./components/text/text.mjs";
|
|
24
25
|
export * from "@react-email/render";
|
|
25
|
-
export { Body, Button, CodeBlock, CodeInline, Column, Container, Font, Head, Heading, Hr, Html, Img, Link, Markdown, Preview, Row, Section, Tailwind, Text, a11yDark, atomDark, baseAteliersulphurpoolLight, cb, coldarkCold, coldarkDark, coyWithoutShadows, darcula, dracula, duotoneDark, duotoneEarth, duotoneForest, duotoneLight, duotoneSea, duotoneSpace, ghcolors, gruvboxDark, gruvboxLight, holiTheme, hopscotch, inlineStyles, laserwave, lucario, materialDark, materialLight, materialOceanic, nightOwl, nord, oneDark, oneLight, pixelBasedPreset, pojoaque, renderWhiteSpace, sanitizeStyleSheet, setupTailwind, shadesOfPurple, solarizedDarkAtom, synthwave84, vesper, vs, vscDarkPlus, xonokai, zTouch };
|
|
26
|
+
export { Body, Button, CodeBlock, CodeInline, Column, Container, Font, Head, Heading, Hr, Html, Img, Link, Markdown, Preview, Row, Section, Tailwind, Text, a11yDark, atomDark, baseAteliersulphurpoolLight, cb, coldarkCold, coldarkDark, coyWithoutShadows, darcula, dracula, duotoneDark, duotoneEarth, duotoneForest, duotoneLight, duotoneSea, duotoneSpace, ghcolors, gruvboxDark, gruvboxLight, holiTheme, hopscotch, inlineStyles, laserwave, lucario, markAsElement, materialDark, materialLight, materialOceanic, nightOwl, nord, oneDark, oneLight, pixelBasedPreset, pojoaque, renderWhiteSpace, sanitizeStyleSheet, setupTailwind, shadesOfPurple, solarizedDarkAtom, synthwave84, vesper, vs, vscDarkPlus, xonokai, zTouch };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@depup/react-email",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.11.0-depup.0",
|
|
4
4
|
"description": "A live preview of your emails right in your browser. (with updated dependencies)",
|
|
5
5
|
"bin": {
|
|
6
6
|
"email": "./dist/cli/index.mjs"
|
|
@@ -35,15 +35,15 @@
|
|
|
35
35
|
"email"
|
|
36
36
|
],
|
|
37
37
|
"engines": {
|
|
38
|
-
"node": ">=20.
|
|
38
|
+
"node": ">=20.19.0"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
|
41
41
|
"react": "^18.0 || ^19.0 || ^19.0.0-rc",
|
|
42
42
|
"react-dom": "^18.0 || ^19.0 || ^19.0.0-rc"
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@babel/parser": "^
|
|
46
|
-
"@babel/traverse": "^8.0.
|
|
45
|
+
"@babel/parser": "^7.29.9",
|
|
46
|
+
"@babel/traverse": "^8.0.6",
|
|
47
47
|
"@react-email/render": ">=2.1.0",
|
|
48
48
|
"chokidar": "^5.0.0",
|
|
49
49
|
"commander": "^15.0.0",
|
|
@@ -54,14 +54,14 @@
|
|
|
54
54
|
"glob": "^13.0.6",
|
|
55
55
|
"jiti": "^2.7.0",
|
|
56
56
|
"log-symbols": "^7.0.1",
|
|
57
|
-
"marked": "^18.0.
|
|
57
|
+
"marked": "^18.0.14",
|
|
58
58
|
"mime-types": "^3.0.2",
|
|
59
59
|
"normalize-path": "^3.0.0",
|
|
60
|
-
"nypm": "^0.6.
|
|
60
|
+
"nypm": "^0.6.10",
|
|
61
61
|
"picospinner": "^3.1.2",
|
|
62
62
|
"prismjs": "^1.30.0",
|
|
63
63
|
"prompts": "2.4.2",
|
|
64
|
-
"socket.io": "^4.8.
|
|
64
|
+
"socket.io": "^4.8.4",
|
|
65
65
|
"tailwindcss": "^4.3.3",
|
|
66
66
|
"tsconfig-paths": "4.2.0"
|
|
67
67
|
},
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
"@types/mime-types": "2.1.4",
|
|
74
74
|
"@types/prompts": "2.4.9",
|
|
75
75
|
"@types/shelljs": "0.10.0",
|
|
76
|
-
"next": "16.3.
|
|
76
|
+
"next": "16.3.3",
|
|
77
77
|
"react": "19.2.4",
|
|
78
78
|
"react-dom": "19.2.4",
|
|
79
79
|
"shelljs": "0.10.0",
|
|
@@ -96,15 +96,11 @@
|
|
|
96
96
|
"changes": {
|
|
97
97
|
"@babel/parser": {
|
|
98
98
|
"from": "7.29.2",
|
|
99
|
-
"to": "^
|
|
99
|
+
"to": "^7.29.9"
|
|
100
100
|
},
|
|
101
101
|
"@babel/traverse": {
|
|
102
102
|
"from": "7.29.0",
|
|
103
|
-
"to": "^8.0.
|
|
104
|
-
},
|
|
105
|
-
"chokidar": {
|
|
106
|
-
"from": "^4.0.3",
|
|
107
|
-
"to": "^5.0.0"
|
|
103
|
+
"to": "^8.0.6"
|
|
108
104
|
},
|
|
109
105
|
"commander": {
|
|
110
106
|
"from": "^13.0.0",
|
|
@@ -132,7 +128,7 @@
|
|
|
132
128
|
},
|
|
133
129
|
"marked": {
|
|
134
130
|
"from": "^15.0.12",
|
|
135
|
-
"to": "^18.0.
|
|
131
|
+
"to": "^18.0.14"
|
|
136
132
|
},
|
|
137
133
|
"mime-types": {
|
|
138
134
|
"from": "^3.0.0",
|
|
@@ -140,7 +136,7 @@
|
|
|
140
136
|
},
|
|
141
137
|
"nypm": {
|
|
142
138
|
"from": "0.6.6",
|
|
143
|
-
"to": "^0.6.
|
|
139
|
+
"to": "^0.6.10"
|
|
144
140
|
},
|
|
145
141
|
"picospinner": {
|
|
146
142
|
"from": "^3.0.0",
|
|
@@ -148,17 +144,17 @@
|
|
|
148
144
|
},
|
|
149
145
|
"socket.io": {
|
|
150
146
|
"from": "^4.8.1",
|
|
151
|
-
"to": "^4.8.
|
|
147
|
+
"to": "^4.8.4"
|
|
152
148
|
},
|
|
153
149
|
"tailwindcss": {
|
|
154
150
|
"from": "^4.1.18",
|
|
155
151
|
"to": "^4.3.3"
|
|
156
152
|
}
|
|
157
153
|
},
|
|
158
|
-
"depsUpdated":
|
|
154
|
+
"depsUpdated": 14,
|
|
159
155
|
"originalPackage": "react-email",
|
|
160
|
-
"originalVersion": "6.
|
|
161
|
-
"processedAt": "2026-
|
|
156
|
+
"originalVersion": "6.11.0",
|
|
157
|
+
"processedAt": "2026-09-27T01:01:23.007Z",
|
|
162
158
|
"smokeTest": "failed"
|
|
163
159
|
}
|
|
164
160
|
}
|
package/readme.md
CHANGED
|
@@ -30,6 +30,14 @@ Starts a local development server that will watch your files and automatically r
|
|
|
30
30
|
npx react-email dev
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
+
Templates are bundled with [esbuild](https://esbuild.github.io/). To run additional esbuild plugins, for example a compile-time transform your templates depend on, pass `--esbuild-plugins` with the path to a module whose default export is an array of plugins (or a function returning one):
|
|
34
|
+
|
|
35
|
+
```sh
|
|
36
|
+
npx react-email dev --esbuild-plugins ./esbuild-plugins.mjs
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
The same option is accepted by `email build` and `email export`.
|
|
40
|
+
|
|
33
41
|
### `email export`
|
|
34
42
|
|
|
35
43
|
Generates the plain HTML files of your emails into a `out` directory.
|
|
@@ -3,57 +3,77 @@ import { markAsElement } from '../element-marker.js';
|
|
|
3
3
|
|
|
4
4
|
export type ContainerProps = Readonly<React.ComponentPropsWithoutRef<'table'>>;
|
|
5
5
|
|
|
6
|
-
export const Container = React.forwardRef<
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
6
|
+
export const Container = React.forwardRef<
|
|
7
|
+
HTMLTableElement,
|
|
8
|
+
ContainerProps & { tdClassName?: string }
|
|
9
|
+
>(({ children, style = {}, tdClassName, ...props }, ref) => {
|
|
10
|
+
// Split padding styles to improve compatibility with Klaviyo and Outlook,
|
|
11
|
+
// while preserving user-provided style property order without allocating
|
|
12
|
+
// entry arrays on each render.
|
|
13
|
+
const tdStyle: React.CSSProperties = {};
|
|
14
|
+
const tableStyle: React.CSSProperties = {};
|
|
15
|
+
|
|
16
|
+
const styleRecord = style as Record<string, unknown>;
|
|
17
|
+
|
|
18
|
+
for (const key in styleRecord) {
|
|
19
|
+
if (!Object.hasOwn(styleRecord, key)) {
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const value = styleRecord[key];
|
|
20
24
|
|
|
21
|
-
|
|
25
|
+
if (key.startsWith('padding')) {
|
|
26
|
+
(tdStyle as Record<string, unknown>)[key] = value;
|
|
27
|
+
} else {
|
|
28
|
+
(tableStyle as Record<string, unknown>)[key] = value;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
22
31
|
|
|
32
|
+
return (
|
|
33
|
+
<table
|
|
34
|
+
align="center"
|
|
35
|
+
width="100%"
|
|
36
|
+
{...props}
|
|
37
|
+
border={0}
|
|
38
|
+
cellPadding="0"
|
|
39
|
+
cellSpacing="0"
|
|
40
|
+
ref={ref}
|
|
41
|
+
role="presentation"
|
|
42
|
+
style={{ maxWidth: '37.5em', ...tableStyle }}
|
|
43
|
+
>
|
|
44
|
+
<tbody>
|
|
45
|
+
<tr style={{ width: '100%' }}>
|
|
46
|
+
<td className={tdClassName} style={tdStyle}>
|
|
47
|
+
{children}
|
|
48
|
+
</td>
|
|
49
|
+
</tr>
|
|
50
|
+
</tbody>
|
|
51
|
+
</table>
|
|
52
|
+
);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
Container.displayName = 'Container';
|
|
56
|
+
markAsElement<ContainerProps & { tdClassName?: string }>(Container, {
|
|
57
|
+
resolveTailwind(props, { style, className, classProperties }) {
|
|
58
|
+
const tableClasses: string[] = [];
|
|
59
|
+
const tdClasses = props.tdClassName ? [props.tdClassName] : [];
|
|
60
|
+
for (const name of className?.split(' ') ?? []) {
|
|
61
|
+
const properties = classProperties[name];
|
|
23
62
|
if (
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
key === 'paddingBottom' ||
|
|
28
|
-
key === 'paddingLeft'
|
|
63
|
+
properties &&
|
|
64
|
+
properties.length > 0 &&
|
|
65
|
+
properties.every((property) => property.startsWith('padding'))
|
|
29
66
|
) {
|
|
30
|
-
(
|
|
67
|
+
tdClasses.push(name);
|
|
31
68
|
} else {
|
|
32
|
-
(
|
|
69
|
+
tableClasses.push(name);
|
|
33
70
|
}
|
|
34
71
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
border={0}
|
|
42
|
-
cellPadding="0"
|
|
43
|
-
cellSpacing="0"
|
|
44
|
-
ref={ref}
|
|
45
|
-
role="presentation"
|
|
46
|
-
style={{ maxWidth: '37.5em', ...tableStyle }}
|
|
47
|
-
>
|
|
48
|
-
<tbody>
|
|
49
|
-
<tr style={{ width: '100%' }}>
|
|
50
|
-
<td style={tdStyle}>{children}</td>
|
|
51
|
-
</tr>
|
|
52
|
-
</tbody>
|
|
53
|
-
</table>
|
|
54
|
-
);
|
|
72
|
+
return {
|
|
73
|
+
...props,
|
|
74
|
+
style,
|
|
75
|
+
className: tableClasses.length > 0 ? tableClasses.join(' ') : undefined,
|
|
76
|
+
tdClassName: tdClasses.length > 0 ? tdClasses.join(' ') : undefined,
|
|
77
|
+
};
|
|
55
78
|
},
|
|
56
|
-
);
|
|
57
|
-
|
|
58
|
-
Container.displayName = 'Container';
|
|
59
|
-
markAsElement(Container);
|
|
79
|
+
});
|
|
@@ -1,5 +1,28 @@
|
|
|
1
|
+
import type * as React from 'react';
|
|
2
|
+
|
|
1
3
|
export const elementMarker = Symbol.for('react-email.element');
|
|
2
4
|
|
|
3
|
-
export
|
|
4
|
-
|
|
5
|
+
export interface ResolvedTailwind {
|
|
6
|
+
style: React.CSSProperties;
|
|
7
|
+
className: string | undefined;
|
|
8
|
+
classProperties: Record<string, string[]>;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface ElementOptions<Props = object> {
|
|
12
|
+
resolveTailwind?: (props: Props, resolved: ResolvedTailwind) => Props;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const markAsElement = <Props>(
|
|
16
|
+
component: unknown,
|
|
17
|
+
options: ElementOptions<Props> = {},
|
|
18
|
+
) => {
|
|
19
|
+
(component as Record<symbol, ElementOptions<Props>>)[elementMarker] = options;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export const getElementOptions = (
|
|
23
|
+
type: unknown,
|
|
24
|
+
): ElementOptions | undefined => {
|
|
25
|
+
if (typeof type !== 'function' && typeof type !== 'object') return undefined;
|
|
26
|
+
if (type === null) return undefined;
|
|
27
|
+
return (type as Record<symbol, ElementOptions | undefined>)[elementMarker];
|
|
5
28
|
};
|
package/src/components/index.ts
CHANGED
|
@@ -4,6 +4,11 @@ export * from './code-block/index.js';
|
|
|
4
4
|
export * from './code-inline/index.js';
|
|
5
5
|
export * from './column/index.js';
|
|
6
6
|
export * from './container/index.js';
|
|
7
|
+
export {
|
|
8
|
+
type ElementOptions,
|
|
9
|
+
markAsElement,
|
|
10
|
+
type ResolvedTailwind,
|
|
11
|
+
} from './element-marker.js';
|
|
7
12
|
export * from './font/index.js';
|
|
8
13
|
export * from './head/index.js';
|
|
9
14
|
export * from './heading/index.js';
|