@react-email/tailwind 0.0.8 → 0.0.11

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.
@@ -0,0 +1,10 @@
1
+ import * as React from 'react';
2
+ import { TailwindConfig } from 'tw-to-css';
3
+
4
+ interface TailwindProps {
5
+ children: React.ReactNode;
6
+ config?: TailwindConfig;
7
+ }
8
+ declare const Tailwind: React.FC<TailwindProps>;
9
+
10
+ export { Tailwind, TailwindProps };
package/dist/index.js CHANGED
@@ -1,10 +1,27 @@
1
1
  "use strict";
2
2
  var __create = Object.create;
3
3
  var __defProp = Object.defineProperty;
4
+ var __defProps = Object.defineProperties;
4
5
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
5
7
  var __getOwnPropNames = Object.getOwnPropertyNames;
8
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
6
9
  var __getProtoOf = Object.getPrototypeOf;
7
10
  var __hasOwnProp = Object.prototype.hasOwnProperty;
11
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
12
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
13
+ var __spreadValues = (a, b) => {
14
+ for (var prop in b || (b = {}))
15
+ if (__hasOwnProp.call(b, prop))
16
+ __defNormalProp(a, prop, b[prop]);
17
+ if (__getOwnPropSymbols)
18
+ for (var prop of __getOwnPropSymbols(b)) {
19
+ if (__propIsEnum.call(b, prop))
20
+ __defNormalProp(a, prop, b[prop]);
21
+ }
22
+ return a;
23
+ };
24
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
8
25
  var __export = (target, all) => {
9
26
  for (var name in all)
10
27
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -18,6 +35,10 @@ var __copyProps = (to, from, except, desc) => {
18
35
  return to;
19
36
  };
20
37
  var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
38
+ // If the importer is in node compatibility mode or this is not an ESM
39
+ // file that has been converted to a CommonJS file using a Babel-
40
+ // compatible transform (i.e. "__esModule" has not been set), then set
41
+ // "default" to the CommonJS "module.exports" for node compatibility.
21
42
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
22
43
  mod
23
44
  ));
@@ -33,111 +54,170 @@ module.exports = __toCommonJS(src_exports);
33
54
  // src/tailwind.tsx
34
55
  var React = __toESM(require("react"));
35
56
  var import_server = require("react-dom/server");
36
- var import_html_react_parser = __toESM(require("html-react-parser"));
37
57
  var import_tw_to_css = require("tw-to-css");
58
+
59
+ // src/utils/css-to-jsx-style.ts
60
+ var camelCase = (string) => string.replace(/-(\w|$)/g, (_, p1) => p1.toUpperCase());
61
+ var convertPropertyName = (prop) => {
62
+ let modifiedProp = prop;
63
+ modifiedProp = modifiedProp.toLowerCase();
64
+ if (modifiedProp === "float") {
65
+ return "cssFloat";
66
+ }
67
+ if (modifiedProp.startsWith("--")) {
68
+ return modifiedProp;
69
+ }
70
+ if (modifiedProp.startsWith("-ms-")) {
71
+ modifiedProp = modifiedProp.substr(1);
72
+ }
73
+ return camelCase(modifiedProp);
74
+ };
75
+ var splitDeclarations = (cssText) => {
76
+ const declarations = [];
77
+ let capturing;
78
+ let i = cssText.length;
79
+ let last = i;
80
+ while (i-- > -1) {
81
+ if ((cssText[i] === '"' || cssText[i] === "'") && cssText[i - 1] !== "\\") {
82
+ if (!capturing) {
83
+ capturing = cssText[i];
84
+ } else if (cssText[i] === capturing) {
85
+ capturing = false;
86
+ }
87
+ }
88
+ if (!capturing && cssText[i] === ")") {
89
+ capturing = cssText[i];
90
+ }
91
+ if (cssText[i] === "(" && capturing === ")") {
92
+ capturing = false;
93
+ }
94
+ if (i < 0 || !capturing && cssText[i] === ";") {
95
+ declarations.unshift(cssText.slice(i + 1, last));
96
+ last = i;
97
+ }
98
+ }
99
+ return declarations;
100
+ };
101
+ var splitDeclaration = (declaration) => {
102
+ const i = declaration.indexOf(":");
103
+ return [declaration.substr(0, i).trim(), declaration.substr(i + 1).trim()];
104
+ };
105
+ var cssToJsxStyle = (cssText) => splitDeclarations(cssText).map(splitDeclaration).reduce((styles, [name, value]) => {
106
+ if (name && value) {
107
+ styles[convertPropertyName(name)] = value;
108
+ }
109
+ return styles;
110
+ }, {});
111
+
112
+ // src/tailwind.tsx
38
113
  var import_jsx_runtime = require("react/jsx-runtime");
114
+ function processElement(element, headStyles, twi) {
115
+ let modifiedElement = element;
116
+ if (modifiedElement.props.className) {
117
+ const convertedStyles = [];
118
+ const responsiveStyles = [];
119
+ const classNames = modifiedElement.props.className.split(" ");
120
+ const customClassNames = classNames.filter((className) => {
121
+ const tailwindClassName = twi(className, { ignoreMediaQueries: true });
122
+ if (tailwindClassName) {
123
+ convertedStyles.push(tailwindClassName);
124
+ return false;
125
+ } else if (twi(className, { ignoreMediaQueries: false })) {
126
+ responsiveStyles.push(className);
127
+ return false;
128
+ }
129
+ return true;
130
+ });
131
+ const convertedResponsiveStyles = twi(responsiveStyles, {
132
+ ignoreMediaQueries: false,
133
+ merge: false
134
+ });
135
+ headStyles.push(
136
+ convertedResponsiveStyles.replace(/^\n+/, "").replace(/\n+$/, "")
137
+ );
138
+ modifiedElement = React.cloneElement(modifiedElement, __spreadProps(__spreadValues({}, modifiedElement.props), {
139
+ className: customClassNames.length ? customClassNames.join(" ") : void 0,
140
+ style: __spreadValues(__spreadValues({}, modifiedElement.props.style), cssToJsxStyle(convertedStyles.join(" ")))
141
+ }));
142
+ }
143
+ if (modifiedElement.props.children) {
144
+ const children = React.Children.toArray(modifiedElement.props.children);
145
+ const processedChildren = children.map((child) => {
146
+ if (React.isValidElement(child)) {
147
+ return processElement(child, headStyles, twi);
148
+ }
149
+ return child;
150
+ });
151
+ modifiedElement = React.cloneElement(
152
+ modifiedElement,
153
+ modifiedElement.props,
154
+ ...processedChildren
155
+ );
156
+ }
157
+ return modifiedElement;
158
+ }
159
+ function processHead(child, responsiveStyles) {
160
+ let modifiedChild = child;
161
+ if (modifiedChild.type === "head" || modifiedChild.type.displayName === "Head") {
162
+ const styleElement = /* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: responsiveStyles });
163
+ const headChildren = React.Children.toArray(modifiedChild.props.children);
164
+ headChildren.push(styleElement);
165
+ modifiedChild = React.cloneElement(
166
+ modifiedChild,
167
+ modifiedChild.props,
168
+ ...headChildren
169
+ );
170
+ }
171
+ if (modifiedChild.props.children) {
172
+ const children = React.Children.toArray(modifiedChild.props.children);
173
+ const processedChildren = children.map((processedChild) => {
174
+ if (React.isValidElement(processedChild)) {
175
+ return processHead(processedChild, responsiveStyles);
176
+ }
177
+ return processedChild;
178
+ });
179
+ modifiedChild = React.cloneElement(
180
+ modifiedChild,
181
+ modifiedChild.props,
182
+ ...processedChildren
183
+ );
184
+ }
185
+ return modifiedChild;
186
+ }
39
187
  var Tailwind = ({ children, config }) => {
188
+ const headStyles = [];
40
189
  const { twi } = (0, import_tw_to_css.tailwindToCSS)({
41
190
  config
42
191
  });
43
- const newChildren = React.Children.toArray(children);
44
- const fullHTML = (0, import_server.renderToStaticMarkup)(/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: newChildren }));
45
- const tailwindCss = twi(fullHTML, {
46
- merge: false,
47
- ignoreMediaQueries: false
192
+ const childrenWithInlineStyles = React.Children.map(children, (child) => {
193
+ if (React.isValidElement(child)) {
194
+ return processElement(child, headStyles, twi);
195
+ }
196
+ return child;
48
197
  });
49
- const css = cleanCss(tailwindCss);
50
- const cssMap = makeCssMap(css);
51
- const headStyle = getMediaQueryCss(css);
52
- const hasResponsiveStyles = /@media[^{]+\{(?<content>[\s\S]+?)\}\s*\}/gm.test(
53
- headStyle
198
+ if (!childrenWithInlineStyles)
199
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children });
200
+ const fullHTML = (0, import_server.renderToStaticMarkup)(/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: childrenWithInlineStyles }));
201
+ const hasResponsiveStyles = new RegExp("@media[^{]+\\{(?<content>[\\s\\S]+?)\\}\\s*\\}", "gm").test(
202
+ headStyles.join(" ")
54
203
  );
55
- const hasHTML = /<html[^>]*>/gm.test(fullHTML);
56
- const hasHead = /<head[^>]*>/gm.test(fullHTML);
57
- if (hasResponsiveStyles && (!hasHTML || !hasHead)) {
204
+ const hasHTMLAndHead = /<html[^>]*>(?=[\s\S]*<head[^>]*>)/gm.test(fullHTML);
205
+ if (hasResponsiveStyles && !hasHTMLAndHead) {
58
206
  throw new Error(
59
207
  "Tailwind: To use responsive styles you must have a <html> and <head> element in your template."
60
208
  );
61
209
  }
62
- const reactHTML = React.Children.map(newChildren, (child) => {
63
- if (!React.isValidElement(child))
64
- return child;
65
- const html = (0, import_server.renderToStaticMarkup)(child);
66
- const parsedHTML = (0, import_html_react_parser.default)(html, {
67
- replace: (domNode) => {
68
- var _a;
69
- if (domNode instanceof import_html_react_parser.Element) {
70
- if (hasResponsiveStyles && hasHead && domNode.name === "head") {
71
- let newDomNode = null;
72
- if (domNode.children) {
73
- const props = (0, import_html_react_parser.attributesToProps)(domNode.attribs);
74
- newDomNode = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("head", { ...props, children: [
75
- (0, import_html_react_parser.domToReact)(domNode.children),
76
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: headStyle })
77
- ] });
78
- }
79
- return newDomNode;
80
- }
81
- if ((_a = domNode.attribs) == null ? void 0 : _a.class) {
82
- const cleanRegex = /[:#\!\-[\]\/\.%]+/g;
83
- const cleanTailwindClasses = domNode.attribs.class.replace(cleanRegex, "_");
84
- const currentStyles = domNode.attribs.style ? `${domNode.attribs.style};` : "";
85
- const tailwindStyles = cleanTailwindClasses.split(" ").map((className) => {
86
- return cssMap[`.${className}`];
87
- }).join(";");
88
- domNode.attribs.style = `${currentStyles} ${tailwindStyles}`;
89
- domNode.attribs.class = domNode.attribs.class.split(" ").filter((className) => className.search(/^.{2}:/) !== -1).join(" ").replace(cleanRegex, "_");
90
- if (domNode.attribs.class === "")
91
- delete domNode.attribs.class;
92
- }
93
- }
210
+ const childrenWithInlineAndResponsiveStyles = React.Children.map(
211
+ childrenWithInlineStyles,
212
+ (child) => {
213
+ if (React.isValidElement(child)) {
214
+ return processHead(child, headStyles);
94
215
  }
95
- });
96
- return parsedHTML;
97
- });
98
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: reactHTML });
99
- };
100
- Tailwind.displayName = "Tailwind";
101
- function cleanCss(css) {
102
- let newCss = css.replace(/\\/g, "").replace(/[.\!\#\w\d\\:\-\[\]\/\.%\(\))]+(?=\s*?{[^{]*?\})\s*?{/g, (m) => {
103
- return m.replace(/(?<=.)[:#\!\-[\\\]\/\.%]+/g, "_");
104
- }).replace(/font-family(?<value>[^;\r\n]+)/g, (m, value) => {
105
- return `font-family${value.replace(/['"]+/g, "")}`;
106
- });
107
- return newCss;
108
- }
109
- function getMediaQueryCss(css) {
110
- var _a;
111
- const mediaQueryRegex = /@media[^{]+\{(?<content>[\s\S]+?)\}\s*\}/gm;
112
- return ((_a = css.replace(mediaQueryRegex, (m) => {
113
- return m.replace(
114
- /([^{]+\{)([\s\S]+?)(\}\s*\})/gm,
115
- (_, start, content, end) => {
116
- const newContent = content.replace(
117
- /(?:[\s\r\n]*)?(?<prop>[\w-]+)\s*:\s*(?<value>[^};\r\n]+)/gm,
118
- (_2, prop, value) => {
119
- return `${prop}: ${value} !important;`;
120
- }
121
- );
122
- return `${start}${newContent}${end}`;
123
- }
124
- );
125
- }).match(/@media\s*([^{]+)\{([^{}]*\{[^{}]*\})*[^{}]*\}/g)) == null ? void 0 : _a.join("")) ?? "";
126
- }
127
- function makeCssMap(css) {
128
- const cssNoMedia = css.replace(
129
- /@media[^{]+\{(?<content>[\s\S]+?)\}\s*\}/gm,
130
- ""
131
- );
132
- const cssMap = cssNoMedia.split("}").reduce((acc, cur) => {
133
- const [key, value] = cur.split("{");
134
- if (key && value) {
135
- acc[key] = value;
216
+ return child;
136
217
  }
137
- return acc;
138
- }, {});
139
- return cssMap;
140
- }
218
+ );
219
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: childrenWithInlineAndResponsiveStyles });
220
+ };
141
221
  // Annotate the CommonJS export names for ESM import in node:
142
222
  0 && (module.exports = {
143
223
  Tailwind
package/dist/index.mjs CHANGED
@@ -1,111 +1,190 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defProps = Object.defineProperties;
3
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
+ var __spreadValues = (a, b) => {
9
+ for (var prop in b || (b = {}))
10
+ if (__hasOwnProp.call(b, prop))
11
+ __defNormalProp(a, prop, b[prop]);
12
+ if (__getOwnPropSymbols)
13
+ for (var prop of __getOwnPropSymbols(b)) {
14
+ if (__propIsEnum.call(b, prop))
15
+ __defNormalProp(a, prop, b[prop]);
16
+ }
17
+ return a;
18
+ };
19
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
+
1
21
  // src/tailwind.tsx
2
22
  import * as React from "react";
3
23
  import { renderToStaticMarkup } from "react-dom/server";
4
- import htmlParser, { attributesToProps, domToReact, Element } from "html-react-parser";
5
24
  import { tailwindToCSS } from "tw-to-css";
6
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
25
+
26
+ // src/utils/css-to-jsx-style.ts
27
+ var camelCase = (string) => string.replace(/-(\w|$)/g, (_, p1) => p1.toUpperCase());
28
+ var convertPropertyName = (prop) => {
29
+ let modifiedProp = prop;
30
+ modifiedProp = modifiedProp.toLowerCase();
31
+ if (modifiedProp === "float") {
32
+ return "cssFloat";
33
+ }
34
+ if (modifiedProp.startsWith("--")) {
35
+ return modifiedProp;
36
+ }
37
+ if (modifiedProp.startsWith("-ms-")) {
38
+ modifiedProp = modifiedProp.substr(1);
39
+ }
40
+ return camelCase(modifiedProp);
41
+ };
42
+ var splitDeclarations = (cssText) => {
43
+ const declarations = [];
44
+ let capturing;
45
+ let i = cssText.length;
46
+ let last = i;
47
+ while (i-- > -1) {
48
+ if ((cssText[i] === '"' || cssText[i] === "'") && cssText[i - 1] !== "\\") {
49
+ if (!capturing) {
50
+ capturing = cssText[i];
51
+ } else if (cssText[i] === capturing) {
52
+ capturing = false;
53
+ }
54
+ }
55
+ if (!capturing && cssText[i] === ")") {
56
+ capturing = cssText[i];
57
+ }
58
+ if (cssText[i] === "(" && capturing === ")") {
59
+ capturing = false;
60
+ }
61
+ if (i < 0 || !capturing && cssText[i] === ";") {
62
+ declarations.unshift(cssText.slice(i + 1, last));
63
+ last = i;
64
+ }
65
+ }
66
+ return declarations;
67
+ };
68
+ var splitDeclaration = (declaration) => {
69
+ const i = declaration.indexOf(":");
70
+ return [declaration.substr(0, i).trim(), declaration.substr(i + 1).trim()];
71
+ };
72
+ var cssToJsxStyle = (cssText) => splitDeclarations(cssText).map(splitDeclaration).reduce((styles, [name, value]) => {
73
+ if (name && value) {
74
+ styles[convertPropertyName(name)] = value;
75
+ }
76
+ return styles;
77
+ }, {});
78
+
79
+ // src/tailwind.tsx
80
+ import { Fragment, jsx } from "react/jsx-runtime";
81
+ function processElement(element, headStyles, twi) {
82
+ let modifiedElement = element;
83
+ if (modifiedElement.props.className) {
84
+ const convertedStyles = [];
85
+ const responsiveStyles = [];
86
+ const classNames = modifiedElement.props.className.split(" ");
87
+ const customClassNames = classNames.filter((className) => {
88
+ const tailwindClassName = twi(className, { ignoreMediaQueries: true });
89
+ if (tailwindClassName) {
90
+ convertedStyles.push(tailwindClassName);
91
+ return false;
92
+ } else if (twi(className, { ignoreMediaQueries: false })) {
93
+ responsiveStyles.push(className);
94
+ return false;
95
+ }
96
+ return true;
97
+ });
98
+ const convertedResponsiveStyles = twi(responsiveStyles, {
99
+ ignoreMediaQueries: false,
100
+ merge: false
101
+ });
102
+ headStyles.push(
103
+ convertedResponsiveStyles.replace(/^\n+/, "").replace(/\n+$/, "")
104
+ );
105
+ modifiedElement = React.cloneElement(modifiedElement, __spreadProps(__spreadValues({}, modifiedElement.props), {
106
+ className: customClassNames.length ? customClassNames.join(" ") : void 0,
107
+ style: __spreadValues(__spreadValues({}, modifiedElement.props.style), cssToJsxStyle(convertedStyles.join(" ")))
108
+ }));
109
+ }
110
+ if (modifiedElement.props.children) {
111
+ const children = React.Children.toArray(modifiedElement.props.children);
112
+ const processedChildren = children.map((child) => {
113
+ if (React.isValidElement(child)) {
114
+ return processElement(child, headStyles, twi);
115
+ }
116
+ return child;
117
+ });
118
+ modifiedElement = React.cloneElement(
119
+ modifiedElement,
120
+ modifiedElement.props,
121
+ ...processedChildren
122
+ );
123
+ }
124
+ return modifiedElement;
125
+ }
126
+ function processHead(child, responsiveStyles) {
127
+ let modifiedChild = child;
128
+ if (modifiedChild.type === "head" || modifiedChild.type.displayName === "Head") {
129
+ const styleElement = /* @__PURE__ */ jsx("style", { children: responsiveStyles });
130
+ const headChildren = React.Children.toArray(modifiedChild.props.children);
131
+ headChildren.push(styleElement);
132
+ modifiedChild = React.cloneElement(
133
+ modifiedChild,
134
+ modifiedChild.props,
135
+ ...headChildren
136
+ );
137
+ }
138
+ if (modifiedChild.props.children) {
139
+ const children = React.Children.toArray(modifiedChild.props.children);
140
+ const processedChildren = children.map((processedChild) => {
141
+ if (React.isValidElement(processedChild)) {
142
+ return processHead(processedChild, responsiveStyles);
143
+ }
144
+ return processedChild;
145
+ });
146
+ modifiedChild = React.cloneElement(
147
+ modifiedChild,
148
+ modifiedChild.props,
149
+ ...processedChildren
150
+ );
151
+ }
152
+ return modifiedChild;
153
+ }
7
154
  var Tailwind = ({ children, config }) => {
155
+ const headStyles = [];
8
156
  const { twi } = tailwindToCSS({
9
157
  config
10
158
  });
11
- const newChildren = React.Children.toArray(children);
12
- const fullHTML = renderToStaticMarkup(/* @__PURE__ */ jsx(Fragment, { children: newChildren }));
13
- const tailwindCss = twi(fullHTML, {
14
- merge: false,
15
- ignoreMediaQueries: false
159
+ const childrenWithInlineStyles = React.Children.map(children, (child) => {
160
+ if (React.isValidElement(child)) {
161
+ return processElement(child, headStyles, twi);
162
+ }
163
+ return child;
16
164
  });
17
- const css = cleanCss(tailwindCss);
18
- const cssMap = makeCssMap(css);
19
- const headStyle = getMediaQueryCss(css);
20
- const hasResponsiveStyles = /@media[^{]+\{(?<content>[\s\S]+?)\}\s*\}/gm.test(
21
- headStyle
165
+ if (!childrenWithInlineStyles)
166
+ return /* @__PURE__ */ jsx(Fragment, { children });
167
+ const fullHTML = renderToStaticMarkup(/* @__PURE__ */ jsx(Fragment, { children: childrenWithInlineStyles }));
168
+ const hasResponsiveStyles = new RegExp("@media[^{]+\\{(?<content>[\\s\\S]+?)\\}\\s*\\}", "gm").test(
169
+ headStyles.join(" ")
22
170
  );
23
- const hasHTML = /<html[^>]*>/gm.test(fullHTML);
24
- const hasHead = /<head[^>]*>/gm.test(fullHTML);
25
- if (hasResponsiveStyles && (!hasHTML || !hasHead)) {
171
+ const hasHTMLAndHead = /<html[^>]*>(?=[\s\S]*<head[^>]*>)/gm.test(fullHTML);
172
+ if (hasResponsiveStyles && !hasHTMLAndHead) {
26
173
  throw new Error(
27
174
  "Tailwind: To use responsive styles you must have a <html> and <head> element in your template."
28
175
  );
29
176
  }
30
- const reactHTML = React.Children.map(newChildren, (child) => {
31
- if (!React.isValidElement(child))
32
- return child;
33
- const html = renderToStaticMarkup(child);
34
- const parsedHTML = htmlParser(html, {
35
- replace: (domNode) => {
36
- var _a;
37
- if (domNode instanceof Element) {
38
- if (hasResponsiveStyles && hasHead && domNode.name === "head") {
39
- let newDomNode = null;
40
- if (domNode.children) {
41
- const props = attributesToProps(domNode.attribs);
42
- newDomNode = /* @__PURE__ */ jsxs("head", { ...props, children: [
43
- domToReact(domNode.children),
44
- /* @__PURE__ */ jsx("style", { children: headStyle })
45
- ] });
46
- }
47
- return newDomNode;
48
- }
49
- if ((_a = domNode.attribs) == null ? void 0 : _a.class) {
50
- const cleanRegex = /[:#\!\-[\]\/\.%]+/g;
51
- const cleanTailwindClasses = domNode.attribs.class.replace(cleanRegex, "_");
52
- const currentStyles = domNode.attribs.style ? `${domNode.attribs.style};` : "";
53
- const tailwindStyles = cleanTailwindClasses.split(" ").map((className) => {
54
- return cssMap[`.${className}`];
55
- }).join(";");
56
- domNode.attribs.style = `${currentStyles} ${tailwindStyles}`;
57
- domNode.attribs.class = domNode.attribs.class.split(" ").filter((className) => className.search(/^.{2}:/) !== -1).join(" ").replace(cleanRegex, "_");
58
- if (domNode.attribs.class === "")
59
- delete domNode.attribs.class;
60
- }
61
- }
62
- }
63
- });
64
- return parsedHTML;
65
- });
66
- return /* @__PURE__ */ jsx(Fragment, { children: reactHTML });
67
- };
68
- Tailwind.displayName = "Tailwind";
69
- function cleanCss(css) {
70
- let newCss = css.replace(/\\/g, "").replace(/[.\!\#\w\d\\:\-\[\]\/\.%\(\))]+(?=\s*?{[^{]*?\})\s*?{/g, (m) => {
71
- return m.replace(/(?<=.)[:#\!\-[\\\]\/\.%]+/g, "_");
72
- }).replace(/font-family(?<value>[^;\r\n]+)/g, (m, value) => {
73
- return `font-family${value.replace(/['"]+/g, "")}`;
74
- });
75
- return newCss;
76
- }
77
- function getMediaQueryCss(css) {
78
- var _a;
79
- const mediaQueryRegex = /@media[^{]+\{(?<content>[\s\S]+?)\}\s*\}/gm;
80
- return ((_a = css.replace(mediaQueryRegex, (m) => {
81
- return m.replace(
82
- /([^{]+\{)([\s\S]+?)(\}\s*\})/gm,
83
- (_, start, content, end) => {
84
- const newContent = content.replace(
85
- /(?:[\s\r\n]*)?(?<prop>[\w-]+)\s*:\s*(?<value>[^};\r\n]+)/gm,
86
- (_2, prop, value) => {
87
- return `${prop}: ${value} !important;`;
88
- }
89
- );
90
- return `${start}${newContent}${end}`;
177
+ const childrenWithInlineAndResponsiveStyles = React.Children.map(
178
+ childrenWithInlineStyles,
179
+ (child) => {
180
+ if (React.isValidElement(child)) {
181
+ return processHead(child, headStyles);
91
182
  }
92
- );
93
- }).match(/@media\s*([^{]+)\{([^{}]*\{[^{}]*\})*[^{}]*\}/g)) == null ? void 0 : _a.join("")) ?? "";
94
- }
95
- function makeCssMap(css) {
96
- const cssNoMedia = css.replace(
97
- /@media[^{]+\{(?<content>[\s\S]+?)\}\s*\}/gm,
98
- ""
99
- );
100
- const cssMap = cssNoMedia.split("}").reduce((acc, cur) => {
101
- const [key, value] = cur.split("{");
102
- if (key && value) {
103
- acc[key] = value;
183
+ return child;
104
184
  }
105
- return acc;
106
- }, {});
107
- return cssMap;
108
- }
185
+ );
186
+ return /* @__PURE__ */ jsx(Fragment, { children: childrenWithInlineAndResponsiveStyles });
187
+ };
109
188
  export {
110
189
  Tailwind
111
190
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-email/tailwind",
3
- "version": "0.0.8",
3
+ "version": "0.0.11",
4
4
  "description": "A React component to wrap emails with Tailwind CSS",
5
5
  "sideEffects": false,
6
6
  "main": "./dist/index.js",
@@ -9,20 +9,30 @@
9
9
  "files": [
10
10
  "dist/**"
11
11
  ],
12
+ "exports": {
13
+ ".": {
14
+ "import": {
15
+ "types": "./dist/index.d.ts",
16
+ "default": "./dist/index.mjs"
17
+ },
18
+ "require": {
19
+ "types": "./dist/index.d.ts",
20
+ "default": "./dist/index.js"
21
+ }
22
+ }
23
+ },
12
24
  "license": "MIT",
13
25
  "scripts": {
14
26
  "build": "tsup src/index.ts --format esm,cjs --dts --external react",
15
- "dev": "tsup src/index.ts --format esm,cjs --dts --external react --watch",
16
- "lint": "eslint",
17
27
  "clean": "rm -rf dist",
18
- "test": "jest",
19
- "test:watch": "jest --watch",
20
- "format:check": "prettier --check \"**/*.{ts,tsx,md}\"",
21
- "format": "prettier --write \"**/*.{ts,tsx,md}\""
28
+ "dev": "tsup src/index.ts --format esm,cjs --dts --external react --watch",
29
+ "lint": "eslint .",
30
+ "test:watch": "vitest",
31
+ "test": "vitest run"
22
32
  },
23
33
  "repository": {
24
34
  "type": "git",
25
- "url": "https://github.com/zenorocha/react-email.git",
35
+ "url": "https://github.com/resendlabs/react-email.git",
26
36
  "directory": "packages/tailwind"
27
37
  },
28
38
  "keywords": [
@@ -31,29 +41,26 @@
31
41
  "tailwind"
32
42
  ],
33
43
  "engines": {
34
- "node": ">=16.0.0"
44
+ "node": ">=18.0.0"
35
45
  },
36
46
  "dependencies": {
37
- "html-react-parser": "3.0.9",
38
47
  "react": "18.2.0",
39
48
  "react-dom": "18.2.0",
40
49
  "tw-to-css": "0.0.11"
41
50
  },
51
+ "peerDependencies": {
52
+ "react": "18.2.0"
53
+ },
42
54
  "devDependencies": {
43
- "@babel/preset-react": "7.18.6",
44
- "@react-email/button": "0.0.7",
55
+ "@babel/core": "7.21.8",
56
+ "@babel/preset-react": "7.22.5",
57
+ "@react-email/hr": "workspace:*",
58
+ "@react-email/head": "workspace:*",
59
+ "@react-email/html": "workspace:*",
45
60
  "@testing-library/react": "14.0.0",
46
- "@types/jest": "29.5.0",
47
- "@types/react": "18.0.20",
48
- "@types/react-dom": "18.0.6",
49
- "babel-jest": "29.5.0",
50
- "eslint": "8.23.1",
51
- "jest": "29.5.0",
52
- "prettier": "2.8.4",
53
- "react": "18.2.0",
54
- "ts-jest": "29.0.5",
55
- "tsup": "6.2.3",
56
- "typescript": "4.8.3"
61
+ "eslint-config-custom": "workspace:*",
62
+ "tsconfig": "workspace:*",
63
+ "typescript": "5.1.6"
57
64
  },
58
65
  "publishConfig": {
59
66
  "access": "public"
package/readme.md CHANGED
@@ -65,7 +65,7 @@ This component was tested using the most popular email clients.
65
65
 
66
66
  | <img src="https://react.email/static/icons/gmail.svg" width="48px" height="48px" alt="Gmail logo"> | <img src="https://react.email/static/icons/apple-mail.svg" width="48px" height="48px" alt="Apple Mail"> | <img src="https://react.email/static/icons/outlook.svg" width="48px" height="48px" alt="Outlook logo"> | <img src="https://react.email/static/icons/yahoo-mail.svg" width="48px" height="48px" alt="Yahoo! Mail logo"> | <img src="https://react.email/static/icons/hey.svg" width="48px" height="48px" alt="HEY logo"> | <img src="https://react.email/static/icons/superhuman.svg" width="48px" height="48px" alt="Superhuman logo"> |
67
67
  | -------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
68
- | Gmail ✔ | Apple Mail ✔ | Outlook ✔ | Yahoo! Mail ✔ | HEY ✔ | Superhuman ✔ |
68
+ | Gmail ✔ | Apple Mail ✔ | Outlook ✔ | Yahoo! Mail ✔ | HEY ✔ | Superhuman ✔ |
69
69
 
70
70
  ## License
71
71