@react-email/preview-server 4.1.0-canary.10 → 4.1.0-canary.12

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.
Files changed (92) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-build-manifest.json +32 -32
  3. package/.next/build-manifest.json +14 -14
  4. package/.next/diagnostics/framework.json +1 -1
  5. package/.next/next-minimal-server.js.nft.json +1 -1
  6. package/.next/next-server.js.nft.json +1 -1
  7. package/.next/prerender-manifest.json +3 -3
  8. package/.next/required-server-files.json +1 -1
  9. package/.next/server/app/_not-found/page.js +1 -1
  10. package/.next/server/app/_not-found/page.js.nft.json +1 -1
  11. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  12. package/.next/server/app/favicon.ico/route.js +1 -1
  13. package/.next/server/app/favicon.ico/route.js.nft.json +1 -1
  14. package/.next/server/app/page.js +1 -1
  15. package/.next/server/app/page.js.nft.json +1 -1
  16. package/.next/server/app/page_client-reference-manifest.js +1 -1
  17. package/.next/server/app/preview/[...slug]/page.js +356 -174
  18. package/.next/server/app/preview/[...slug]/page.js.nft.json +1 -1
  19. package/.next/server/app/preview/[...slug]/page_client-reference-manifest.js +1 -1
  20. package/.next/server/chunks/151.js +1 -0
  21. package/.next/server/chunks/277.js +1 -0
  22. package/.next/server/chunks/{879.js → 532.js} +7 -7
  23. package/.next/server/chunks/550.js +6 -0
  24. package/.next/server/chunks/834.js +15 -0
  25. package/.next/server/chunks/851.js +20 -0
  26. package/.next/server/middleware-build-manifest.js +1 -1
  27. package/.next/server/pages/500.html +1 -1
  28. package/.next/server/pages/_app.js +1 -1
  29. package/.next/server/pages/_app.js.nft.json +1 -1
  30. package/.next/server/pages/_document.js +1 -1
  31. package/.next/server/pages/_document.js.nft.json +1 -1
  32. package/.next/server/pages/_error.js +1 -1
  33. package/.next/server/pages/_error.js.nft.json +1 -1
  34. package/.next/server/server-reference-manifest.js +1 -1
  35. package/.next/server/server-reference-manifest.json +1 -1
  36. package/.next/static/chunks/343-0aa226f42148dce4.js +1 -0
  37. package/.next/static/chunks/353-5e7d05b120b2e25f.js +1 -0
  38. package/.next/static/chunks/445-576b0c51a037fe4d.js +1 -0
  39. package/.next/static/chunks/483-33f8edd35a9abbac.js +1 -0
  40. package/.next/static/chunks/624-9d1650c8211771cd.js +1 -0
  41. package/.next/static/chunks/755-01456539a6894956.js +1 -0
  42. package/.next/static/chunks/app/_not-found/{page-aee2c5619f94a965.js → page-e9c9ee8e737ce3f8.js} +1 -1
  43. package/.next/static/chunks/app/layout-094f1db7cb89023e.js +1 -0
  44. package/.next/static/chunks/app/page-ee81303e36f65d71.js +1 -0
  45. package/.next/static/chunks/app/preview/[...slug]/page-17daf55202c7ed10.js +1 -0
  46. package/.next/static/chunks/{04c799b8-f2be86d6e75dbf29.js → e8809b48-6a73b3f51ba71e9c.js} +1 -1
  47. package/.next/static/chunks/{f33a14d2-188715a58266ac15.js → f33a14d2-13f6de3d216cf617.js} +1 -1
  48. package/.next/static/chunks/framework-4f208795521d076c.js +1 -0
  49. package/.next/static/chunks/main-0000d0a5ac74fec0.js +1 -0
  50. package/.next/static/chunks/main-app-5ba7fd8e7a976edb.js +1 -0
  51. package/.next/static/chunks/pages/_app-550e3587fddcaa19.js +1 -0
  52. package/.next/static/chunks/pages/_error-870af0ad63b0e49e.js +1 -0
  53. package/.next/static/chunks/{webpack-c09dcf4c47767be8.js → webpack-fc6f324c4c88f6e3.js} +1 -1
  54. package/.next/static/css/48dcea18d820a298.css +3 -0
  55. package/.next/static/{ur8mm-bO6uPtIDOFYtHum → hWjgzfxten__dpm6I5Okv}/_buildManifest.js +1 -1
  56. package/.next/trace +27 -27
  57. package/CHANGELOG.md +13 -0
  58. package/_index.js +4 -0
  59. package/package.json +2 -2
  60. package/src/actions/email-validation/__snapshots__/check-images.spec.tsx.snap +84 -0
  61. package/src/actions/email-validation/check-images.spec.tsx +1 -80
  62. package/src/app/preview/[...slug]/preview.tsx +1 -1
  63. package/src/components/code-container.tsx +3 -1
  64. package/src/components/code.tsx +60 -59
  65. package/src/components/logo.tsx +68 -63
  66. package/src/components/send.tsx +8 -5
  67. package/src/components/sidebar/file-tree-directory-children.tsx +4 -1
  68. package/src/components/toolbar.tsx +9 -5
  69. package/src/utils/__snapshots__/get-email-component.spec.ts.snap +183 -1
  70. package/src/utils/caniemail/ast/get-used-style-properties.ts +1 -0
  71. package/src/utils/get-email-component.spec.ts +3 -0
  72. package/.next/server/chunks/200.js +0 -1
  73. package/.next/server/chunks/3.js +0 -15
  74. package/.next/server/chunks/565.js +0 -1
  75. package/.next/server/chunks/784.js +0 -6
  76. package/.next/server/chunks/915.js +0 -20
  77. package/.next/static/chunks/188-e278e5f1e9c4067e.js +0 -1
  78. package/.next/static/chunks/336-0767fdc0ff1ceaa1.js +0 -1
  79. package/.next/static/chunks/551-d9ce0a77591e6bf7.js +0 -1
  80. package/.next/static/chunks/651-ca7523b84c3a84c4.js +0 -1
  81. package/.next/static/chunks/713-6c7607cb54b8278e.js +0 -1
  82. package/.next/static/chunks/834-e77d5196a2631efe.js +0 -1
  83. package/.next/static/chunks/app/layout-51e57d53a74eca29.js +0 -1
  84. package/.next/static/chunks/app/page-ddc5b5b5b8d2de0e.js +0 -1
  85. package/.next/static/chunks/app/preview/[...slug]/page-8ac2b346f388df3e.js +0 -1
  86. package/.next/static/chunks/framework-f71c687711cb40cc.js +0 -1
  87. package/.next/static/chunks/main-697e2f65b52ad05c.js +0 -1
  88. package/.next/static/chunks/main-app-deb9839bdc2bcbd4.js +0 -1
  89. package/.next/static/chunks/pages/_app-2e335329c12ac3e7.js +0 -1
  90. package/.next/static/chunks/pages/_error-73094c2ebe868f44.js +0 -1
  91. package/.next/static/css/ac3decd5d6736fbe.css +0 -3
  92. /package/.next/static/{ur8mm-bO6uPtIDOFYtHum → hWjgzfxten__dpm6I5Okv}/_ssgManifest.js +0 -0
@@ -38,6 +38,9 @@ export const Send = ({ markup }: { markup: string }) => {
38
38
  }
39
39
  };
40
40
 
41
+ const toId = React.useId();
42
+ const subjectId = React.useId();
43
+
41
44
  return (
42
45
  <Popover.Root
43
46
  onOpenChange={() => {
@@ -63,13 +66,13 @@ export const Send = ({ markup }: { markup: string }) => {
63
66
  <Popover.Portal>
64
67
  <Popover.Content
65
68
  align="end"
66
- className="-mt-10 w-80 rounded-lg border border-slate-6 bg-black/70 p-3 font-sans text-slate-11 shadow-md backdrop-blur-lg font-sans"
69
+ className="-mt-10 w-80 rounded-lg border border-slate-6 bg-black/70 p-3 text-slate-11 shadow-md backdrop-blur-lg font-sans"
67
70
  sideOffset={48}
68
71
  >
69
72
  <form className="mt-1" onSubmit={(e) => void onFormSubmit(e)}>
70
73
  <label
71
74
  className="mb-2 block text-xs uppercase text-slate-10"
72
- htmlFor="to"
75
+ htmlFor={toId}
73
76
  >
74
77
  Recipient
75
78
  </label>
@@ -77,7 +80,7 @@ export const Send = ({ markup }: { markup: string }) => {
77
80
  autoFocus
78
81
  className="mb-3 w-full appearance-none rounded-lg border border-slate-6 bg-slate-3 px-2 py-1 text-sm text-slate-12 placeholder-slate-10 outline-none transition duration-300 ease-in-out focus:ring-1 focus:ring-slate-10"
79
82
  defaultValue={to}
80
- id="to"
83
+ id={toId}
81
84
  onChange={(e) => {
82
85
  setTo(e.target.value);
83
86
  }}
@@ -87,14 +90,14 @@ export const Send = ({ markup }: { markup: string }) => {
87
90
  />
88
91
  <label
89
92
  className="mb-2 mt-1 block text-xs uppercase text-slate-10"
90
- htmlFor="subject"
93
+ htmlFor={subjectId}
91
94
  >
92
95
  Subject
93
96
  </label>
94
97
  <input
95
98
  className="mb-3 w-full appearance-none rounded-lg border border-slate-6 bg-slate-3 px-2 py-1 text-sm text-slate-12 placeholder-slate-10 outline-none transition duration-300 ease-in-out focus:ring-1 focus:ring-slate-10"
96
99
  defaultValue={subject}
97
- id="subject"
100
+ id={subjectId}
98
101
  onChange={(e) => {
99
102
  setSubject(e.target.value);
100
103
  }}
@@ -2,6 +2,7 @@ import * as Collapsible from '@radix-ui/react-collapsible';
2
2
  import { AnimatePresence, LayoutGroup, motion } from 'framer-motion';
3
3
  import Link from 'next/link';
4
4
  import { useRouter, useSearchParams } from 'next/navigation';
5
+ import * as React from 'react';
5
6
  import { cn } from '../../utils';
6
7
  import type { EmailsDirectory } from '../../utils/get-emails-directory-metadata';
7
8
  import { IconFile } from '../icons/icon-file';
@@ -16,6 +17,8 @@ export const FileTreeDirectoryChildren = (props: {
16
17
  const searchParams = useSearchParams();
17
18
  const router = useRouter();
18
19
 
20
+ const id = React.useId();
21
+
19
22
  return (
20
23
  <AnimatePresence initial={false}>
21
24
  {props.open ? (
@@ -33,7 +36,7 @@ export const FileTreeDirectoryChildren = (props: {
33
36
  <div className="line absolute left-2.5 h-full w-px bg-slate-6" />
34
37
  )}
35
38
  <div className="flex flex-col truncate">
36
- <LayoutGroup id="sidebar">
39
+ <LayoutGroup id={`sidebar-${id}`}>
37
40
  {props.emailsDirectoryMetadata.subDirectories.map(
38
41
  (subDirectory) => (
39
42
  <FileTreeDirectory
@@ -2,7 +2,7 @@
2
2
  import * as Tabs from '@radix-ui/react-tabs';
3
3
  import { LayoutGroup } from 'framer-motion';
4
4
  import { usePathname, useRouter, useSearchParams } from 'next/navigation';
5
- import { use, useEffect } from 'react';
5
+ import * as React from 'react';
6
6
  import type { CompatibilityCheckingResult } from '../actions/email-validation/check-compatibility';
7
7
  import { isBuilding } from '../app/env';
8
8
  import { PreviewContext } from '../contexts/preview';
@@ -105,7 +105,8 @@ const ToolbarInner = ({
105
105
 
106
106
  if (!isBuilding) {
107
107
  // biome-ignore lint/correctness/useHookAtTopLevel: This is fine since isBuilding does not change at runtime
108
- useEffect(() => {
108
+ // biome-ignore lint/correctness/useExhaustiveDependencies: Setters don't need dependencies
109
+ React.useEffect(() => {
109
110
  (async () => {
110
111
  const lintingRows = await loadLinting();
111
112
  setCachedLintingRows(lintingRows);
@@ -119,6 +120,8 @@ const ToolbarInner = ({
119
120
  }, []);
120
121
  }
121
122
 
123
+ const id = React.useId();
124
+
122
125
  return (
123
126
  <div
124
127
  data-toggled={toggled}
@@ -137,7 +140,7 @@ const ToolbarInner = ({
137
140
  >
138
141
  <div className="flex flex-col h-full">
139
142
  <Tabs.List className="flex gap-4 px-4 border-b border-solid border-slate-6 h-10 w-full flex-shrink-0">
140
- <LayoutGroup id="toolbar">
143
+ <LayoutGroup id={`toolbar-${id}`}>
141
144
  <Tabs.Trigger asChild value="linter">
142
145
  <ToolbarButton active={activeTab === 'linter'}>
143
146
  Linter
@@ -189,7 +192,7 @@ const ToolbarInner = ({
189
192
  <IconReload
190
193
  size={24}
191
194
  className={cn({
192
- 'animate-spin opacity-60 animate-spin-fast':
195
+ 'opacity-60 animate-spin-fast':
193
196
  lintLoading || spamLoading,
194
197
  })}
195
198
  />
@@ -329,7 +332,8 @@ export const Toolbar = ({
329
332
  serverSpamCheckingResult,
330
333
  serverCompatibilityResults,
331
334
  }: ToolbarProps) => {
332
- const { emailPath, emailSlug, renderedEmailMetadata } = use(PreviewContext)!;
335
+ const { emailPath, emailSlug, renderedEmailMetadata } =
336
+ React.use(PreviewContext)!;
333
337
 
334
338
  if (renderedEmailMetadata === undefined) return null;
335
339
  const { markup, plainText, reactMarkup } = renderedEmailMetadata;
@@ -1,3 +1,185 @@
1
1
  // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
2
 
3
- exports[`getEmailComponent() > with a demo email template 1`] = `"<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html dir="ltr" lang="en"><head><link rel="preload" as="image" href="/static/vercel-logo.png"/><link rel="preload" as="image" href="/static/vercel-user.png"/><link rel="preload" as="image" href="/static/vercel-arrow.png"/><link rel="preload" as="image" href="/static/vercel-team.png"/><meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/><meta name="x-apple-disable-message-reformatting"/><!--$--></head><body style="margin-left:auto;margin-right:auto;margin-top:auto;margin-bottom:auto;background-color:rgb(255,255,255);padding-left:0.5rem;padding-right:0.5rem;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 style="display:none;overflow:hidden;line-height:1px;opacity:0;max-height:0;max-width:0" data-skip-in-text="true">Join Alan on Vercel<div> ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏</div></div><table align="center" width="100%" border="0" cellPadding="0" cellSpacing="0" role="presentation" style="margin-left:auto;margin-right:auto;margin-top:40px;margin-bottom:40px;max-width:465px;border-radius:0.25rem;border-width:1px;border-color:rgb(234,234,234);border-style:solid;padding:20px"><tbody><tr style="width:100%"><td><table align="center" width="100%" border="0" cellPadding="0" cellSpacing="0" role="presentation" style="margin-top:32px"><tbody><tr><td><img alt="Vercel Logo" height="37" src="/static/vercel-logo.png" style="margin-left:auto;margin-right:auto;margin-top:0px;margin-bottom:0px;display:block;outline:none;border:none;text-decoration:none" width="40"/></td></tr></tbody></table><h1 style="margin-left:0px;margin-right:0px;margin-top:30px;margin-bottom:30px;padding:0px;text-align:center;font-weight:400;font-size:24px;color:rgb(0,0,0)">Join <strong>Enigma</strong> on <strong>Vercel</strong></h1><p style="font-size:14px;color:rgb(0,0,0);line-height:24px;margin-top:16px;margin-bottom:16px">Hello <!-- -->alanturing<!-- -->,</p><p style="font-size:14px;color:rgb(0,0,0);line-height:24px;margin-top:16px;margin-bottom:16px"><strong>Alan</strong> (<a href="mailto:alan.turing@example.com" style="color:rgb(37,99,235);text-decoration-line:none" target="_blank">alan.turing@example.com</a>) has invited you to the <strong>Enigma</strong> team on<!-- --> <strong>Vercel</strong>.</p><table align="center" width="100%" border="0" cellPadding="0" cellSpacing="0" role="presentation"><tbody><tr><td><table align="center" width="100%" border="0" cellPadding="0" cellSpacing="0" role="presentation"><tbody style="width:100%"><tr style="width:100%"><td align="right" data-id="__react-email-column"><img alt="alanturing&#x27;s profile picture" height="64" src="/static/vercel-user.png" style="border-radius:9999px;display:block;outline:none;border:none;text-decoration:none" width="64"/></td><td align="center" data-id="__react-email-column"><img alt="Arrow indicating invitation" height="9" src="/static/vercel-arrow.png" style="display:block;outline:none;border:none;text-decoration:none" width="12"/></td><td align="left" data-id="__react-email-column"><img alt="Enigma team logo" height="64" src="/static/vercel-team.png" style="border-radius:9999px;display:block;outline:none;border:none;text-decoration:none" width="64"/></td></tr></tbody></table></td></tr></tbody></table><table align="center" width="100%" border="0" cellPadding="0" cellSpacing="0" role="presentation" style="margin-top:32px;margin-bottom:32px;text-align:center"><tbody><tr><td><a href="https://vercel.com" style="border-radius:0.25rem;background-color:rgb(0,0,0);padding-left:20px;padding-right:20px;padding-top:12px;padding-bottom:12px;text-align:center;font-weight:600;font-size:12px;color:rgb(255,255,255);text-decoration-line:none;line-height:100%;text-decoration:none;display:inline-block;max-width:100%;mso-padding-alt:0px" target="_blank"><span><!--[if mso]><i style="mso-font-width:500%;mso-text-raise:18" hidden>&#8202;&#8202;</i><![endif]--></span><span style="max-width:100%;display:inline-block;line-height:120%;mso-padding-alt:0px;mso-text-raise:9px">Join the team</span><span><!--[if mso]><i style="mso-font-width:500%" hidden>&#8202;&#8202;&#8203;</i><![endif]--></span></a></td></tr></tbody></table><p style="font-size:14px;color:rgb(0,0,0);line-height:24px;margin-top:16px;margin-bottom:16px">or copy and paste this URL into your browser:<!-- --> <a href="https://vercel.com" style="color:rgb(37,99,235);text-decoration-line:none" target="_blank">https://vercel.com</a></p><hr style="margin-left:0px;margin-right:0px;margin-top:26px;margin-bottom:26px;width:100%;border-width:1px;border-color:rgb(234,234,234);border-style:solid;border:none;border-top:1px solid #eaeaea"/><p style="color:rgb(102,102,102);font-size:12px;line-height:24px;margin-top:16px;margin-bottom:16px">This invitation was intended for<!-- --> <span style="color:rgb(0,0,0)">alanturing</span>. This invite was sent from <span style="color:rgb(0,0,0)">204.13.186.218</span> <!-- -->located in<!-- --> <span style="color:rgb(0,0,0)">São Paulo, Brazil</span>. If you were not expecting this invitation, you can ignore this email. If you are concerned about your account&#x27;s safety, please reply to this email to get in touch with us.</p></td></tr></tbody></table><!--/$--></body></html>"`;
3
+ exports[`getEmailComponent() > with a demo email template 1`] = `
4
+ "<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
+ <html dir="ltr" lang="en">
6
+ <head>
7
+ <link rel="preload" as="image" href="/static/vercel-logo.png" />
8
+ <link rel="preload" as="image" href="/static/vercel-user.png" />
9
+ <link rel="preload" as="image" href="/static/vercel-arrow.png" />
10
+ <link rel="preload" as="image" href="/static/vercel-team.png" />
11
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
12
+ <meta name="x-apple-disable-message-reformatting" />
13
+ <!--$-->
14
+ </head>
15
+ <body
16
+ style='margin-left:auto;margin-right:auto;margin-top:auto;margin-bottom:auto;background-color:rgb(255,255,255);padding-left:0.5rem;padding-right:0.5rem;font-family:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"'>
17
+ <div
18
+ style="display:none;overflow:hidden;line-height:1px;opacity:0;max-height:0;max-width:0"
19
+ data-skip-in-text="true">
20
+ Join Alan on Vercel
21
+ <div>
22
+  ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏
23
+ </div>
24
+ </div>
25
+ <table
26
+ align="center"
27
+ width="100%"
28
+ border="0"
29
+ cellpadding="0"
30
+ cellspacing="0"
31
+ role="presentation"
32
+ style="margin-left:auto;margin-right:auto;margin-top:40px;margin-bottom:40px;max-width:465px;border-radius:0.25rem;border-width:1px;border-color:rgb(234,234,234);border-style:solid;padding:20px">
33
+ <tbody>
34
+ <tr style="width:100%">
35
+ <td>
36
+ <table
37
+ align="center"
38
+ width="100%"
39
+ border="0"
40
+ cellpadding="0"
41
+ cellspacing="0"
42
+ role="presentation"
43
+ style="margin-top:32px">
44
+ <tbody>
45
+ <tr>
46
+ <td>
47
+ <img
48
+ alt="Vercel Logo"
49
+ height="37"
50
+ src="/static/vercel-logo.png"
51
+ style="margin-left:auto;margin-right:auto;margin-top:0px;margin-bottom:0px;display:block;outline:none;border:none;text-decoration:none"
52
+ width="40" />
53
+ </td>
54
+ </tr>
55
+ </tbody>
56
+ </table>
57
+ <h1
58
+ style="margin-left:0px;margin-right:0px;margin-top:30px;margin-bottom:30px;padding:0px;text-align:center;font-weight:400;font-size:24px;color:rgb(0,0,0)">
59
+ Join <strong>Enigma</strong> on <strong>Vercel</strong>
60
+ </h1>
61
+ <p
62
+ style="font-size:14px;color:rgb(0,0,0);line-height:24px;margin-top:16px;margin-bottom:16px">
63
+ Hello
64
+ <!-- -->alanturing<!-- -->,
65
+ </p>
66
+ <p
67
+ style="font-size:14px;color:rgb(0,0,0);line-height:24px;margin-top:16px;margin-bottom:16px">
68
+ <strong>Alan</strong> (<a
69
+ href="mailto:alan.turing@example.com"
70
+ style="color:rgb(37,99,235);text-decoration-line:none"
71
+ target="_blank"
72
+ >alan.turing@example.com</a
73
+ >) has invited you to the <strong>Enigma</strong> team on<!-- -->
74
+ <strong>Vercel</strong>.
75
+ </p>
76
+ <table
77
+ align="center"
78
+ width="100%"
79
+ border="0"
80
+ cellpadding="0"
81
+ cellspacing="0"
82
+ role="presentation">
83
+ <tbody>
84
+ <tr>
85
+ <td>
86
+ <table
87
+ align="center"
88
+ width="100%"
89
+ border="0"
90
+ cellpadding="0"
91
+ cellspacing="0"
92
+ role="presentation">
93
+ <tbody style="width:100%">
94
+ <tr style="width:100%">
95
+ <td align="right" data-id="__react-email-column">
96
+ <img
97
+ alt="alanturing&#x27;s profile picture"
98
+ height="64"
99
+ src="/static/vercel-user.png"
100
+ style="border-radius:9999px;display:block;outline:none;border:none;text-decoration:none"
101
+ width="64" />
102
+ </td>
103
+ <td align="center" data-id="__react-email-column">
104
+ <img
105
+ alt="Arrow indicating invitation"
106
+ height="9"
107
+ src="/static/vercel-arrow.png"
108
+ style="display:block;outline:none;border:none;text-decoration:none"
109
+ width="12" />
110
+ </td>
111
+ <td align="left" data-id="__react-email-column">
112
+ <img
113
+ alt="Enigma team logo"
114
+ height="64"
115
+ src="/static/vercel-team.png"
116
+ style="border-radius:9999px;display:block;outline:none;border:none;text-decoration:none"
117
+ width="64" />
118
+ </td>
119
+ </tr>
120
+ </tbody>
121
+ </table>
122
+ </td>
123
+ </tr>
124
+ </tbody>
125
+ </table>
126
+ <table
127
+ align="center"
128
+ width="100%"
129
+ border="0"
130
+ cellpadding="0"
131
+ cellspacing="0"
132
+ role="presentation"
133
+ style="margin-top:32px;margin-bottom:32px;text-align:center">
134
+ <tbody>
135
+ <tr>
136
+ <td>
137
+ <a
138
+ href="https://vercel.com"
139
+ style="border-radius:0.25rem;background-color:rgb(0,0,0);padding-left:20px;padding-right:20px;padding-top:12px;padding-bottom:12px;text-align:center;font-weight:600;font-size:12px;color:rgb(255,255,255);text-decoration-line:none;line-height:100%;text-decoration:none;display:inline-block;max-width:100%;mso-padding-alt:0px"
140
+ target="_blank"
141
+ ><span
142
+ ><!--[if mso]><i style="mso-font-width:500%;mso-text-raise:18" hidden>&#8202;&#8202;</i><![endif]--></span
143
+ ><span
144
+ style="max-width:100%;display:inline-block;line-height:120%;mso-padding-alt:0px;mso-text-raise:9px"
145
+ >Join the team</span
146
+ ><span
147
+ ><!--[if mso]><i style="mso-font-width:500%" hidden>&#8202;&#8202;&#8203;</i><![endif]--></span
148
+ ></a
149
+ >
150
+ </td>
151
+ </tr>
152
+ </tbody>
153
+ </table>
154
+ <p
155
+ style="font-size:14px;color:rgb(0,0,0);line-height:24px;margin-top:16px;margin-bottom:16px">
156
+ or copy and paste this URL into your browser:<!-- -->
157
+ <a
158
+ href="https://vercel.com"
159
+ style="color:rgb(37,99,235);text-decoration-line:none"
160
+ target="_blank"
161
+ >https://vercel.com</a
162
+ >
163
+ </p>
164
+ <hr
165
+ style="margin-left:0px;margin-right:0px;margin-top:26px;margin-bottom:26px;width:100%;border-width:1px;border-color:rgb(234,234,234);border-style:solid;border:none;border-top:1px solid #eaeaea" />
166
+ <p
167
+ style="color:rgb(102,102,102);font-size:12px;line-height:24px;margin-top:16px;margin-bottom:16px">
168
+ This invitation was intended for<!-- -->
169
+ <span style="color:rgb(0,0,0)">alanturing</span>. This invite was
170
+ sent from <span style="color:rgb(0,0,0)">204.13.186.218</span>
171
+ <!-- -->located in<!-- -->
172
+ <span style="color:rgb(0,0,0)">São Paulo, Brazil</span>. If you
173
+ were not expecting this invitation, you can ignore this email. If
174
+ you are concerned about your account&#x27;s safety, please reply
175
+ to this email to get in touch with us.
176
+ </p>
177
+ </td>
178
+ </tr>
179
+ </tbody>
180
+ </table>
181
+ <!--/$-->
182
+ </body>
183
+ </html>
184
+ "
185
+ `;
@@ -1,3 +1,4 @@
1
+ /** biome-ignore-all lint/nursery/noNestedComponentDefinitions: There are no components here, just visitor functions */
1
2
  import traverse from '@babel/traverse';
2
3
  import type { AST } from '../../../actions/email-validation/check-compatibility';
3
4
  import { generateTailwindCssRules } from '../tailwind/generate-tailwind-rules';
@@ -34,6 +34,9 @@ describe('getEmailComponent()', () => {
34
34
  result.emailComponent,
35
35
  result.emailComponent.PreviewProps,
36
36
  ),
37
+ {
38
+ pretty: true,
39
+ },
37
40
  );
38
41
  expect(emailHtml).toMatchSnapshot();
39
42
  }