Skip to content

Commit dbfd242

Browse files
feat(tailwind): extract pseudo classes to stylesheet (#1864)
Co-authored-by: gabriel miranda <[email protected]>
1 parent fe139ef commit dbfd242

8 files changed

+275
-200
lines changed

.changeset/great-parrots-yell.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@react-email/tailwind": minor
3+
---
4+
5+
Extract tailwind pseudo classes to stylesheet

packages/tailwind/src/__snapshots__/tailwind.spec.tsx.snap

Lines changed: 36 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -14,42 +14,6 @@ exports[`Custom theme config > should be able to use custom spacing 1`] = `"<!DO
1414

1515
exports[`Custom theme config > should be able to use custom text alignment 1`] = `"<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><!--$--><div style="text-align:justify"></div><!--/$-->"`;
1616

17-
exports[`Responsive styles > should add css to <head/> and keep responsive class names 1`] = `"<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html lang="en"><head><!--$--><style>@media(min-width:640px){.sm_bg-red-300{background-color:rgb(252,165,165) !important}}@media(min-width:768px){.md_bg-red-400{background-color:rgb(248,113,113) !important}}@media(min-width:1024px){.lg_bg-red-500{background-color:rgb(239,68,68) !important}}</style></head><body><div class="sm_bg-red-300 md_bg-red-400 lg_bg-red-500" style="background-color:rgb(254,202,202)"></div><!--/$--></body></html>"`;
18-
19-
exports[`Responsive styles > should not have duplicate media queries 1`] = `"<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><head><meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/><meta name="x-apple-disable-message-reformatting"/><!--$--><style>@media(min-width:768px){.md_px-64px{padding-left:64px !important;padding-right:64px !important}}</style></head><body class="md_px-64px" style="background-color:rgb(255,255,255);margin-top:auto;margin-bottom:auto;margin-left:auto;margin-right:auto;font-family:ui-sans-serif, system-ui, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;, &quot;Noto Color Emoji&quot;"><div class="md_px-64px"></div><!--/$--></body>"`;
20-
21-
exports[`Responsive styles > should persist existing <head/> elements 1`] = `"<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html lang="en"><head><!--$--><style></style><link/><style>@media(min-width:640px){.sm_bg-red-500{background-color:rgb(239,68,68) !important}}</style></head><body><div class="sm_bg-red-500" style="background-color:rgb(254,202,202)"></div><!--/$--></body></html>"`;
22-
23-
exports[`Responsive styles > should throw an error when used without a <head/> 1`] = `
24-
[Error: You are trying to use the following Tailwind classes that cannot be inlined: sm:bg-red-500.
25-
For the media queries to work properly on rendering, they need to be added into a <style> tag inside of a <head> tag,
26-
the Tailwind component tried finding a <head> element but just wasn't able to find it.
27-
28-
Make sure that you have a <head> element at some point inside of the <Tailwind> component at any depth.
29-
This can also be our <Head> component.
30-
31-
If you do already have a <head> element at some depth,
32-
please file a bug https://github.com/resend/react-email/issues/new?assignees=&labels=Type%3A+Bug&projects=&template=1.bug_report.yml.]
33-
`;
34-
35-
exports[`Responsive styles > should throw error when used without the head and with media query class names only very deeply nested 1`] = `
36-
[Error: You are trying to use the following Tailwind classes that cannot be inlined: sm:h-10 sm:w-10.
37-
For the media queries to work properly on rendering, they need to be added into a <style> tag inside of a <head> tag,
38-
the Tailwind component tried finding a <head> element but just wasn't able to find it.
39-
40-
Make sure that you have a <head> element at some point inside of the <Tailwind> component at any depth.
41-
This can also be our <Head> component.
42-
43-
If you do already have a <head> element at some depth,
44-
please file a bug https://github.com/resend/react-email/issues/new?assignees=&labels=Type%3A+Bug&projects=&template=1.bug_report.yml.]
45-
`;
46-
47-
exports[`Responsive styles > should work with arbitrarily deep (in the React tree) <head> elements 1`] = `"<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html lang="en"><head><!--$--><style>@media(min-width:640px){.sm_bg-red-300{background-color:rgb(252,165,165) !important}}@media(min-width:768px){.md_bg-red-400{background-color:rgb(248,113,113) !important}}@media(min-width:1024px){.lg_bg-red-500{background-color:rgb(239,68,68) !important}}</style></head><body><div class="sm_bg-red-300 md_bg-red-400 lg_bg-red-500" style="background-color:rgb(254,202,202)"></div><!--/$--></body></html>"`;
48-
49-
exports[`Responsive styles > should work with arbitrarily deep (in the React tree) <head> elements 2`] = `"<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html lang="en"><head><!--$--><style>@media(min-width:640px){.sm_bg-red-300{background-color:rgb(252,165,165) !important}}@media(min-width:768px){.md_bg-red-400{background-color:rgb(248,113,113) !important}}@media(min-width:1024px){.lg_bg-red-500{background-color:rgb(239,68,68) !important}}</style></head><body><div class="sm_bg-red-300 md_bg-red-400 lg_bg-red-500" style="background-color:rgb(254,202,202)"></div><!--/$--></body></html>"`;
50-
51-
exports[`Responsive styles > should work with relatively complex media query utilities 1`] = `"<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><head><meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/><meta name="x-apple-disable-message-reformatting"/><!--$--><style>@media not all and(min-width:640px){.max-sm_text-red-600{color:rgb(220,38,38) !important}}</style></head><p class="max-sm_text-red-600" style="color:rgb(29,78,216)">I am some text</p><!--/$-->"`;
52-
5317
exports[`Tailwind component > <Button className="px-3 py-2 mt-8 text-sm text-gray-200 bg-blue-600 rounded-md"> 1`] = `"<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><!--$--><a style="padding-left:0.75rem;padding-right:0.75rem;padding-top:0.5rem;padding-bottom:0.5rem;margin-top:2rem;font-size:0.875rem;line-height:1.25rem;color:rgb(229,231,235);background-color:rgb(37,99,235);border-radius:0.375rem;text-decoration:none;display:inline-block;max-width:100%;mso-padding-alt:0px;padding:8px 12px 8px 12px" target="_blank"><span><!--[if mso]><i style="mso-font-width:300%;mso-text-raise:12" hidden>&#8202;&#8202;</i><![endif]--></span><span style="max-width:100%;display:inline-block;line-height:120%;mso-padding-alt:0px;mso-text-raise:6px">Testing button</span><span><!--[if mso]><i style="mso-font-width:300%" hidden>&#8202;&#8202;&#8203;</i><![endif]--></span></a>Testing<!--/$-->"`;
5418
5519
exports[`Tailwind component > it should not generate styles from text 1`] = `"<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><!--$-->container bg-red-500 bg-blue-300<!--/$-->"`;
@@ -77,3 +41,39 @@ exports[`Tailwind component > should work with components that return children 1
7741
exports[`Tailwind component > should work with components that use React.forwardRef 1`] = `"<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><!--$--><div style="font-size:50px;line-height:1;margin-top:100px">Hello world</div><div style="padding:20px"><p style="font-weight:700;font-size:50px">React Email</p></div><!--/$-->"`;
7842
7943
exports[`Tailwind component > should work with custom components with fragment at the root 1`] = `"<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><!--$--><div style="font-size:50px;line-height:1;margin-top:100px">Hello world</div><div style="padding:20px"><p style="font-weight:700;font-size:50px">React Email</p></div><div style="padding:20px"><p style="font-weight:700;font-size:50px">React Email</p></div><!--/$-->"`;
44+
45+
exports[`non-inlinable styles > should add css to <head/> and keep class names 1`] = `"<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html lang="en"><head><!--$--><style>@media(min-width:640px){.sm_bg-red-300{background-color:rgb(252,165,165) !important}.sm_hover_bg-red-200:hover{background-color:rgb(254,202,202) !important}}@media(min-width:768px){.md_bg-red-400{background-color:rgb(248,113,113) !important}}@media(min-width:1024px){.lg_bg-red-500{background-color:rgb(239,68,68) !important}}.hover_bg-red-600:hover{background-color:rgb(220,38,38) !important}.focus_bg-red-700:focus{background-color:rgb(185,28,28) !important}</style></head><body><div class="sm_bg-red-300 md_bg-red-400 lg_bg-red-500 hover_bg-red-600 focus_bg-red-700 sm_hover_bg-red-200" style="background-color:rgb(254,202,202)"></div><!--/$--></body></html>"`;
46+
47+
exports[`non-inlinable styles > should not have duplicate media queries 1`] = `"<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><head><meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/><meta name="x-apple-disable-message-reformatting"/><!--$--><style>@media(min-width:768px){.md_px-64px{padding-left:64px !important;padding-right:64px !important}}.hover_underline:hover{text-decoration-line:underline !important}</style></head><body class="md_px-64px hover_underline" style="background-color:rgb(255,255,255);margin-top:auto;margin-bottom:auto;margin-left:auto;margin-right:auto;font-family:ui-sans-serif, system-ui, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;, &quot;Noto Color Emoji&quot;"><div class="md_px-64px hover_underline"></div><!--/$--></body>"`;
48+
49+
exports[`non-inlinable styles > should persist existing <head/> elements 1`] = `"<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html lang="en"><head><!--$--><style></style><link/><style>@media(min-width:640px){.sm_bg-red-500{background-color:rgb(239,68,68) !important}}</style></head><body><div class="sm_bg-red-500" style="background-color:rgb(254,202,202)"></div><!--/$--></body></html>"`;
50+
51+
exports[`non-inlinable styles > should throw an error when used without a <head/> 1`] = `
52+
[Error: You are trying to use the following Tailwind classes that cannot be inlined: sm:bg-red-500.
53+
For the media queries to work properly on rendering, they need to be added into a <style> tag inside of a <head> tag,
54+
the Tailwind component tried finding a <head> element but just wasn't able to find it.
55+
56+
Make sure that you have a <head> element at some point inside of the <Tailwind> component at any depth.
57+
This can also be our <Head> component.
58+
59+
If you do already have a <head> element at some depth,
60+
please file a bug https://github.com/resend/react-email/issues/new?assignees=&labels=Type%3A+Bug&projects=&template=1.bug_report.yml.]
61+
`;
62+
63+
exports[`non-inlinable styles > should throw error when used without the head and with media query class names only very deeply nested 1`] = `
64+
[Error: You are trying to use the following Tailwind classes that cannot be inlined: sm:h-10 sm:w-10.
65+
For the media queries to work properly on rendering, they need to be added into a <style> tag inside of a <head> tag,
66+
the Tailwind component tried finding a <head> element but just wasn't able to find it.
67+
68+
Make sure that you have a <head> element at some point inside of the <Tailwind> component at any depth.
69+
This can also be our <Head> component.
70+
71+
If you do already have a <head> element at some depth,
72+
please file a bug https://github.com/resend/react-email/issues/new?assignees=&labels=Type%3A+Bug&projects=&template=1.bug_report.yml.]
73+
`;
74+
75+
exports[`non-inlinable styles > should work with arbitrarily deep (in the React tree) <head> elements 1`] = `"<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html lang="en"><head><!--$--><style>@media(min-width:640px){.sm_bg-red-300{background-color:rgb(252,165,165) !important}}@media(min-width:768px){.md_bg-red-400{background-color:rgb(248,113,113) !important}}@media(min-width:1024px){.lg_bg-red-500{background-color:rgb(239,68,68) !important}}</style></head><body><div class="sm_bg-red-300 md_bg-red-400 lg_bg-red-500" style="background-color:rgb(254,202,202)"></div><!--/$--></body></html>"`;
76+
77+
exports[`non-inlinable styles > should work with arbitrarily deep (in the React tree) <head> elements 2`] = `"<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html lang="en"><head><!--$--><style>@media(min-width:640px){.sm_bg-red-300{background-color:rgb(252,165,165) !important}}@media(min-width:768px){.md_bg-red-400{background-color:rgb(248,113,113) !important}}@media(min-width:1024px){.lg_bg-red-500{background-color:rgb(239,68,68) !important}}</style></head><body><div class="sm_bg-red-300 md_bg-red-400 lg_bg-red-500" style="background-color:rgb(254,202,202)"></div><!--/$--></body></html>"`;
78+
79+
exports[`non-inlinable styles > should work with relatively complex media query utilities 1`] = `"<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><head><meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/><meta name="x-apple-disable-message-reformatting"/><!--$--><style>@media not all and(min-width:640px){.max-sm_text-red-600{color:rgb(220,38,38) !important}}</style></head><p class="max-sm_text-red-600" style="color:rgb(29,78,216)">I am some text</p><!--/$-->"`;

packages/tailwind/src/tailwind.spec.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ describe('Tailwind component', () => {
338338
});
339339
});
340340

341-
describe('Responsive styles', () => {
341+
describe('non-inlinable styles', () => {
342342
/*
343343
This test is because of https://github.com/resend/react-email/issues/1112
344344
which was being caused because we required to, either have our <Head> component,
@@ -389,22 +389,22 @@ describe('Responsive styles', () => {
389389
const output = await render(
390390
<Tailwind>
391391
<Head />
392-
<Body className="bg-white my-auto mx-auto font-sans md:px-[64px]">
393-
<div className="md:px-[64px]" />
392+
<Body className="bg-white my-auto mx-auto font-sans md:px-[64px] hover:underline">
393+
<div className="md:px-[64px] hover:underline" />
394394
</Body>
395395
</Tailwind>,
396396
);
397397

398398
expect(output).toMatchSnapshot();
399399
});
400400

401-
it('should add css to <head/> and keep responsive class names', async () => {
401+
it('should add css to <head/> and keep class names', async () => {
402402
const actualOutput = await render(
403403
<html lang="en">
404404
<Tailwind>
405405
<head />
406406
<body>
407-
<div className="bg-red-200 sm:bg-red-300 md:bg-red-400 lg:bg-red-500" />
407+
<div className="bg-red-200 sm:bg-red-300 md:bg-red-400 lg:bg-red-500 hover:bg-red-600 focus:bg-red-700 sm:hover:bg-red-200" />
408408
</body>
409409
</Tailwind>
410410
</html>,

packages/tailwind/src/utils/css/media-queries/sanitize-media-queries.spec.ts

Lines changed: 0 additions & 88 deletions
This file was deleted.

packages/tailwind/src/utils/css/media-queries/sanitize-media-queries.ts

Lines changed: 0 additions & 64 deletions
This file was deleted.

0 commit comments

Comments
 (0)