@react-email/tailwind
Advanced tools
Comparing version
@@ -8,4 +8,4 @@ import * as React from 'react'; | ||
} | ||
declare const Tailwind: React.FC<Readonly<TailwindProps>>; | ||
declare const Tailwind: React.FC<TailwindProps>; | ||
export { Tailwind, TailwindProps }; |
@@ -35,27 +35,88 @@ "use strict"; | ||
var React = __toESM(require("react")); | ||
var import_server = require("react-dom/server"); | ||
var import_html_react_parser = __toESM(require("html-react-parser")); | ||
var import_tw_to_css = require("tw-to-css"); | ||
var import_jsx_runtime = require("react/jsx-runtime"); | ||
var Tailwind = ({ | ||
children, | ||
config | ||
}) => { | ||
const { twj } = (0, import_tw_to_css.tailwindToCSS)({ config }); | ||
const replaceTailwindStyles = (child) => { | ||
if (!React.isValidElement(child)) { | ||
var Tailwind = ({ children, config }) => { | ||
const { twi } = (0, import_tw_to_css.tailwindToCSS)({ | ||
config | ||
}); | ||
const newChildren = React.Children.toArray(children); | ||
const fullHTML = (0, import_server.renderToStaticMarkup)(/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: newChildren })); | ||
const headStyle = getMediaQueryCSS( | ||
twi(fullHTML, { | ||
merge: false, | ||
ignoreMediaQueries: false | ||
}) | ||
); | ||
const hasResponsiveStyles = /@media[^{]+\{(?<content>[\s\S]+?)\}\s*\}/gm.test( | ||
headStyle | ||
); | ||
const hasHTML = /<html[^>]*>/gm.test(fullHTML); | ||
const hasHead = /<head[^>]*>/gm.test(fullHTML); | ||
if (hasResponsiveStyles && !hasHTML && !hasHead) { | ||
throw new Error( | ||
"Tailwind: To use responsive styles you must have a <html> and <head> element in your template." | ||
); | ||
} | ||
const reactHTML = React.Children.map(newChildren, (child) => { | ||
if (!React.isValidElement(child)) | ||
return child; | ||
} | ||
const { className, children: childChildren, style, ...rest } = child.props; | ||
return React.cloneElement(child, { | ||
...rest, | ||
children: React.Children.map(childChildren, replaceTailwindStyles), | ||
style: { ...style, ...className ? twj(className) : {} } | ||
const html = (0, import_server.renderToStaticMarkup)(child); | ||
const parsedHTML = (0, import_html_react_parser.default)(html, { | ||
replace: (domNode) => { | ||
var _a; | ||
if (domNode instanceof import_html_react_parser.Element) { | ||
if (hasResponsiveStyles && hasHead && domNode.name === "head") { | ||
let newDomNode = null; | ||
if (domNode.children) { | ||
const style = domNode.children.find( | ||
(child2) => child2 instanceof import_html_react_parser.Element && child2.name === "style" | ||
); | ||
const props = (0, import_html_react_parser.attributesToProps)(domNode.attribs); | ||
newDomNode = /* @__PURE__ */ (0, import_jsx_runtime.jsx)("head", { ...props, children: style && style instanceof import_html_react_parser.Element ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: `${style.children} ${headStyle}` }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: headStyle }) }); | ||
} | ||
return newDomNode; | ||
} | ||
if ((_a = domNode.attribs) == null ? void 0 : _a.class) { | ||
if (hasResponsiveStyles) { | ||
domNode.attribs.class = domNode.attribs.class.replace( | ||
/[:#\!\-[\]]+/g, | ||
"_" | ||
); | ||
} else { | ||
domNode.attribs.style = `${twi(domNode.attribs.class)} ${domNode.attribs.style || ""}`; | ||
delete domNode.attribs.class; | ||
} | ||
} | ||
} | ||
} | ||
}); | ||
}; | ||
const tailwindStylesToCSS = React.Children.map( | ||
children, | ||
replaceTailwindStyles | ||
); | ||
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: tailwindStylesToCSS }); | ||
return parsedHTML; | ||
}); | ||
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: reactHTML }); | ||
}; | ||
Tailwind.displayName = "Tailwind"; | ||
function getMediaQueryCSS(css) { | ||
const mediaQueryRegex = /@media[^{]+\{(?<content>[\s\S]+?)\}\s*\}/gm; | ||
let newCss = css.replace(mediaQueryRegex, (m) => { | ||
return m.replace( | ||
/([^{]+\{)([\s\S]+?)(\}\s*\})/gm, | ||
(_, start, content, end) => { | ||
const newcontent = content.replace( | ||
/(?:[\s\r\n]*)?(?<prop>[\w-]+)\s*:\s*(?<value>[^;\r\n]+)/gm, | ||
(_2, prop, value) => { | ||
return `${prop}: ${value} !important`; | ||
} | ||
); | ||
return `${start}${newcontent}${end}`; | ||
} | ||
); | ||
}).replace(/[.\!\#\w\d\\:\-\[\]]+\s*?{/g, (m) => { | ||
return m.replace(/[:#\!\-[\\\]]+/g, "_"); | ||
}).replace(/font-family(?<value>[^;\r\n]+)/g, (m, value) => { | ||
return `font-family${value.replace(/['"]+/g, "")}`; | ||
}); | ||
return newCss; | ||
} | ||
// Annotate the CommonJS export names for ESM import in node: | ||
@@ -62,0 +123,0 @@ 0 && (module.exports = { |
{ | ||
"name": "@react-email/tailwind", | ||
"version": "0.0.4", | ||
"version": "0.0.5", | ||
"description": "A React component to wrap emails with Tailwind CSS", | ||
@@ -18,2 +18,4 @@ "sideEffects": false, | ||
"clean": "rm -rf dist", | ||
"test": "jest", | ||
"test:watch": "jest --watch", | ||
"format:check": "prettier --ignore-path ./../../.prettierignore --check \"**/*.{ts,tsx,md}\"", | ||
@@ -36,5 +38,9 @@ "format": "prettier --ignore-path ./../../.prettierignore --write \"**/*.{ts,tsx,md}\"" | ||
"dependencies": { | ||
"tw-to-css": "0.0.9" | ||
"html-react-parser": "3.0.9", | ||
"react": "18.2.0", | ||
"react-dom": "18.2.0", | ||
"tw-to-css": "0.0.10" | ||
}, | ||
"devDependencies": { | ||
"@testing-library/react": "14.0.0", | ||
"@types/react": "18.0.20", | ||
@@ -41,0 +47,0 @@ "@types/react-dom": "18.0.6", |
Sorry, the diff of this file is not supported yet
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
14475
61.75%222
124.24%4
300%9
12.5%1
Infinity%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
Updated