react-email 4.0.0-alpha.5 → 4.0.0-alpha.7

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 (203) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/cli/index.js +1179 -2659
  3. package/dist/cli/index.mjs +17 -11
  4. package/dist/preview/.next/BUILD_ID +1 -1
  5. package/dist/preview/.next/app-build-manifest.json +32 -31
  6. package/dist/preview/.next/app-path-routes-manifest.json +6 -1
  7. package/dist/preview/.next/build-manifest.json +14 -14
  8. package/dist/preview/.next/cache/.rscinfo +1 -1
  9. package/dist/preview/.next/cache/webpack/client-production/0.pack +0 -0
  10. package/dist/preview/.next/cache/webpack/client-production/index.pack +0 -0
  11. package/dist/preview/.next/cache/webpack/edge-server-production/index.pack +0 -0
  12. package/dist/preview/.next/cache/webpack/server-production/0.pack +0 -0
  13. package/dist/preview/.next/cache/webpack/server-production/index.pack +0 -0
  14. package/dist/preview/.next/diagnostics/framework.json +1 -1
  15. package/dist/preview/.next/export-marker.json +6 -1
  16. package/dist/preview/.next/images-manifest.json +57 -1
  17. package/dist/preview/.next/next-minimal-server.js.nft.json +1 -1
  18. package/dist/preview/.next/next-server.js.nft.json +1 -1
  19. package/dist/preview/.next/prerender-manifest.json +41 -1
  20. package/dist/preview/.next/required-server-files.json +310 -1
  21. package/dist/preview/.next/routes-manifest.json +64 -1
  22. package/dist/preview/.next/server/app/_not-found/page.js +1 -1
  23. package/dist/preview/.next/server/app/_not-found/page.js.nft.json +1 -1
  24. package/dist/preview/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  25. package/dist/preview/.next/server/app/favicon.ico/route.js +1 -1
  26. package/dist/preview/.next/server/app/favicon.ico/route.js.nft.json +1 -1
  27. package/dist/preview/.next/server/app/page.js +1 -1
  28. package/dist/preview/.next/server/app/page.js.nft.json +1 -1
  29. package/dist/preview/.next/server/app/page_client-reference-manifest.js +1 -1
  30. package/dist/preview/.next/server/app/preview/[...slug]/page.js +51 -11
  31. package/dist/preview/.next/server/app/preview/[...slug]/page.js.nft.json +1 -1
  32. package/dist/preview/.next/server/app/preview/[...slug]/page_client-reference-manifest.js +1 -1
  33. package/dist/preview/.next/server/app-paths-manifest.json +1 -1
  34. package/dist/preview/.next/server/chunks/446.js +6 -0
  35. package/dist/preview/.next/server/chunks/600.js +8 -0
  36. package/dist/preview/.next/server/chunks/811.js +13 -0
  37. package/dist/preview/.next/server/chunks/816.js +14 -0
  38. package/dist/preview/.next/server/chunks/943.js +1 -0
  39. package/dist/preview/.next/server/functions-config-manifest.json +4 -1
  40. package/dist/preview/.next/server/middleware-build-manifest.js +1 -1
  41. package/dist/preview/.next/server/next-font-manifest.js +1 -1
  42. package/dist/preview/.next/server/next-font-manifest.json +1 -1
  43. package/dist/preview/.next/server/pages/500.html +1 -1
  44. package/dist/preview/.next/server/pages/_app.js +1 -1
  45. package/dist/preview/.next/server/pages/_app.js.nft.json +1 -1
  46. package/dist/preview/.next/server/pages/_document.js +1 -1
  47. package/dist/preview/.next/server/pages/_document.js.nft.json +1 -1
  48. package/dist/preview/.next/server/pages/_error.js +1 -1
  49. package/dist/preview/.next/server/pages/_error.js.nft.json +1 -1
  50. package/dist/preview/.next/server/pages-manifest.json +5 -1
  51. package/dist/preview/.next/server/server-reference-manifest.js +1 -1
  52. package/dist/preview/.next/server/server-reference-manifest.json +1 -1
  53. package/dist/preview/.next/server/webpack-runtime.js +1 -1
  54. package/dist/preview/.next/static/Pms2orsQgT5xpttCfZfH5/_buildManifest.js +1 -0
  55. package/dist/preview/.next/static/chunks/287-7864b805e6bdc854.js +1 -0
  56. package/dist/preview/.next/static/chunks/412-31817e53b50a3e73.js +1 -0
  57. package/dist/preview/.next/static/chunks/683-1fb40795502f6e63.js +1 -0
  58. package/dist/preview/.next/static/chunks/744-79730358b37b2212.js +1 -0
  59. package/dist/preview/.next/static/chunks/781-5f16c6bc9d9d4cc1.js +1 -0
  60. package/dist/preview/.next/static/chunks/832ad4be-cb988facfb8f955f.js +1 -0
  61. package/dist/preview/.next/static/chunks/880-9c0b721328117b8b.js +1 -0
  62. package/dist/preview/.next/static/chunks/{afa401a5-a600c227dacf3ab4.js → afa401a5-3e949a1cfd317dd3.js} +3 -3
  63. package/dist/preview/.next/static/chunks/app/_not-found/page-09d694081cc9d4dc.js +1 -0
  64. package/dist/preview/.next/static/chunks/app/layout-ffdee5cc1be30e7b.js +1 -0
  65. package/dist/preview/.next/static/chunks/app/page-9ea0bd45cd6294b0.js +1 -0
  66. package/dist/preview/.next/static/chunks/app/preview/[...slug]/page-9e22979a25c836c0.js +1 -0
  67. package/dist/preview/.next/static/chunks/framework-c2bd6d936e3077bc.js +1 -0
  68. package/dist/preview/.next/static/chunks/main-44463a8301435b64.js +1 -0
  69. package/dist/preview/.next/static/chunks/main-app-256b213b179a95cc.js +1 -0
  70. package/dist/preview/.next/static/chunks/pages/_app-f3011d3f00bb8dba.js +1 -0
  71. package/dist/preview/.next/static/chunks/pages/_error-39a87dee2e97a2a3.js +1 -0
  72. package/dist/preview/.next/static/chunks/{webpack-2eb145a20ee6cb77.js → webpack-41e2667c9f086a4f.js} +1 -1
  73. package/dist/preview/.next/static/css/eaae8ce545b295f9.css +3 -0
  74. package/dist/preview/.next/trace +26 -22
  75. package/dist/preview/.next/types/app/layout.ts +1 -1
  76. package/dist/preview/.next/types/app/page.ts +84 -0
  77. package/dist/preview/.next/types/app/preview/[...slug]/page.ts +1 -1
  78. package/dist/preview/.next/types/cache-life.d.ts +3 -3
  79. package/package.json +14 -9
  80. package/scripts/build-preview-server.mjs +32 -0
  81. package/scripts/fill-caniemail-data.mjs +36 -0
  82. package/src/actions/email-validation/caniemail-data.ts +85993 -0
  83. package/src/actions/email-validation/check-compatibility.ts +321 -0
  84. package/src/actions/email-validation/check-images.spec.tsx +15 -13
  85. package/src/actions/email-validation/check-images.ts +8 -2
  86. package/src/actions/email-validation/check-links.spec.tsx +27 -15
  87. package/src/actions/email-validation/check-links.ts +8 -2
  88. package/src/actions/email-validation/get-code-location-from-ast-element.ts +18 -0
  89. package/src/actions/get-email-path-from-slug.ts +1 -1
  90. package/src/actions/render-email-by-path.tsx +2 -1
  91. package/src/{utils/emails-directory-absolute-path.ts → app/env.ts} +5 -0
  92. package/src/app/layout.tsx +1 -1
  93. package/src/app/page.tsx +1 -1
  94. package/src/app/preview/[...slug]/page.tsx +89 -19
  95. package/src/app/preview/[...slug]/preview.tsx +25 -68
  96. package/src/components/code-container.tsx +90 -71
  97. package/src/components/code.tsx +106 -43
  98. package/src/components/icons/icon-info.tsx +18 -0
  99. package/src/components/icons/icon-reload.tsx +13 -14
  100. package/src/components/logo.tsx +3 -2
  101. package/src/components/resizable-wrapper.tsx +1 -4
  102. package/src/components/sidebar/file-tree-directory-children.tsx +1 -0
  103. package/src/components/sidebar/sidebar.tsx +2 -3
  104. package/src/components/toolbar/code-preview-line-link.tsx +40 -0
  105. package/src/components/toolbar/compatibility.tsx +113 -0
  106. package/src/components/toolbar/linter.tsx +226 -125
  107. package/src/components/toolbar/results.tsx +5 -2
  108. package/src/components/toolbar/spam-assassin.tsx +40 -43
  109. package/src/components/toolbar/toolbar-button.tsx +52 -0
  110. package/src/components/toolbar/use-cached-state.ts +33 -0
  111. package/src/components/toolbar.tsx +196 -110
  112. package/src/components/tooltip-content.tsx +1 -1
  113. package/src/components/topbar/view-size-controls.tsx +1 -1
  114. package/src/components/topbar.tsx +4 -29
  115. package/src/contexts/emails.tsx +2 -1
  116. package/src/contexts/fragment-identifier.tsx +46 -0
  117. package/src/contexts/preview.tsx +81 -0
  118. package/src/hooks/use-email-rendering-result.ts +2 -1
  119. package/src/hooks/use-fragment-identifier.ts +14 -0
  120. package/src/utils/__snapshots__/get-email-component.spec.ts.snap +1 -1
  121. package/src/utils/caniemail/all-css-properties.ts +358 -0
  122. package/src/utils/caniemail/ast/get-object-variables.ts +61 -0
  123. package/src/utils/caniemail/ast/get-used-style-properties.ts +91 -0
  124. package/src/utils/caniemail/get-compatibility-stats-for-entry.ts +118 -0
  125. package/src/utils/caniemail/get-css-functions.ts +25 -0
  126. package/src/utils/caniemail/get-css-property-names.ts +32 -0
  127. package/src/utils/caniemail/get-css-property-with-value.ts +14 -0
  128. package/src/utils/caniemail/get-css-unit.ts +3 -0
  129. package/src/utils/caniemail/get-element-attributes.ts +7 -0
  130. package/src/utils/caniemail/get-element-names.ts +20 -0
  131. package/src/utils/caniemail/tailwind/generate-tailwind-rules.ts +30 -0
  132. package/src/utils/caniemail/tailwind/get-tailwind-config.ts +203 -0
  133. package/src/utils/caniemail/tailwind/get-tailwind-metadata.spec.ts +25 -0
  134. package/src/utils/caniemail/tailwind/get-tailwind-metadata.ts +45 -0
  135. package/src/utils/caniemail/tailwind/setup-tailwind-context.ts +15 -0
  136. package/src/utils/get-email-component.ts +34 -67
  137. package/src/utils/get-line-and-column-from-offset.spec.ts +11 -0
  138. package/src/utils/get-line-and-column-from-offset.ts +11 -0
  139. package/src/utils/index.ts +1 -0
  140. package/src/utils/linting.ts +60 -0
  141. package/src/utils/load-stream.ts +15 -0
  142. package/src/utils/result.ts +49 -0
  143. package/src/utils/run-bundled-code.ts +64 -0
  144. package/src/utils/sanitize.ts +6 -0
  145. package/tailwind-internals.d.ts +133 -0
  146. package/tsconfig.json +9 -3
  147. package/build-preview-server.mjs +0 -25
  148. package/dist/preview/.next/cache/images/TcyzHbFXGFjrOu3wEMvDoSmqCh3qP3iiNqJf0QbED9Y/60.1741728556140.cQ5qicbpvoXZ7leVmWqG2ElLwXB1ynYeSv8MBSA-QeM.Vy8iMWM3MGUtMTk1ODcxYmIyNzMi.webp +0 -0
  149. package/dist/preview/.next/cache/webpack/client-development/0.pack.gz +0 -0
  150. package/dist/preview/.next/cache/webpack/client-development/1.pack.gz +0 -0
  151. package/dist/preview/.next/cache/webpack/client-development/10.pack.gz +0 -0
  152. package/dist/preview/.next/cache/webpack/client-development/11.pack.gz +0 -0
  153. package/dist/preview/.next/cache/webpack/client-development/12.pack.gz +0 -0
  154. package/dist/preview/.next/cache/webpack/client-development/13.pack.gz +0 -0
  155. package/dist/preview/.next/cache/webpack/client-development/2.pack.gz +0 -0
  156. package/dist/preview/.next/cache/webpack/client-development/3.pack.gz +0 -0
  157. package/dist/preview/.next/cache/webpack/client-development/4.pack.gz +0 -0
  158. package/dist/preview/.next/cache/webpack/client-development/5.pack.gz +0 -0
  159. package/dist/preview/.next/cache/webpack/client-development/6.pack.gz +0 -0
  160. package/dist/preview/.next/cache/webpack/client-development/7.pack.gz +0 -0
  161. package/dist/preview/.next/cache/webpack/client-development/8.pack.gz +0 -0
  162. package/dist/preview/.next/cache/webpack/client-development/9.pack.gz +0 -0
  163. package/dist/preview/.next/cache/webpack/client-development/index.pack.gz +0 -0
  164. package/dist/preview/.next/cache/webpack/client-development/index.pack.gz.old +0 -0
  165. package/dist/preview/.next/cache/webpack/server-development/0.pack.gz +0 -0
  166. package/dist/preview/.next/cache/webpack/server-development/1.pack.gz +0 -0
  167. package/dist/preview/.next/cache/webpack/server-development/2.pack.gz +0 -0
  168. package/dist/preview/.next/cache/webpack/server-development/3.pack.gz +0 -0
  169. package/dist/preview/.next/cache/webpack/server-development/4.pack.gz +0 -0
  170. package/dist/preview/.next/cache/webpack/server-development/5.pack.gz +0 -0
  171. package/dist/preview/.next/cache/webpack/server-development/6.pack.gz +0 -0
  172. package/dist/preview/.next/cache/webpack/server-development/7.pack.gz +0 -0
  173. package/dist/preview/.next/cache/webpack/server-development/8.pack.gz +0 -0
  174. package/dist/preview/.next/cache/webpack/server-development/9.pack.gz +0 -0
  175. package/dist/preview/.next/cache/webpack/server-development/index.pack.gz +0 -0
  176. package/dist/preview/.next/cache/webpack/server-development/index.pack.gz.old +0 -0
  177. package/dist/preview/.next/server/chunks/143.js +0 -6
  178. package/dist/preview/.next/server/chunks/409.js +0 -5
  179. package/dist/preview/.next/server/chunks/46.js +0 -1
  180. package/dist/preview/.next/server/chunks/478.js +0 -14
  181. package/dist/preview/.next/server/chunks/707.js +0 -13
  182. package/dist/preview/.next/static/B4EYZiVzdylEG9lAIl-aO/_buildManifest.js +0 -1
  183. package/dist/preview/.next/static/chunks/575-bc52750855c25df4.js +0 -2
  184. package/dist/preview/.next/static/chunks/684-0f1ef7361c499798.js +0 -1
  185. package/dist/preview/.next/static/chunks/684c6b30-0c65da32762fc4ee.js +0 -1
  186. package/dist/preview/.next/static/chunks/81-e7539b08d9d3fb4d.js +0 -1
  187. package/dist/preview/.next/static/chunks/883-70c8267c50bc4133.js +0 -1
  188. package/dist/preview/.next/static/chunks/921-d1dc8c63f49e85d6.js +0 -1
  189. package/dist/preview/.next/static/chunks/app/_not-found/page-03ce767859c36d4e.js +0 -1
  190. package/dist/preview/.next/static/chunks/app/layout-7cf14e28880544f1.js +0 -1
  191. package/dist/preview/.next/static/chunks/app/page-065cb49b0a078541.js +0 -1
  192. package/dist/preview/.next/static/chunks/app/preview/[...slug]/page-656510fd180c803c.js +0 -1
  193. package/dist/preview/.next/static/chunks/framework-2a724981073c3a29.js +0 -1
  194. package/dist/preview/.next/static/chunks/main-552b9719bbc3a274.js +0 -1
  195. package/dist/preview/.next/static/chunks/main-app-914a73336fd45af5.js +0 -1
  196. package/dist/preview/.next/static/chunks/pages/_app-77ca34bce25ac75c.js +0 -1
  197. package/dist/preview/.next/static/chunks/pages/_error-73f611c46abbb495.js +0 -1
  198. package/dist/preview/.next/static/css/2df96d9ee014e8de.css +0 -3
  199. package/src/actions/email-validation/get-line-and-column-from-index.spec.ts +0 -22
  200. package/src/actions/email-validation/get-line-and-column-from-index.ts +0 -43
  201. package/src/components/icons/icon-scanner.tsx +0 -19
  202. package/src/components/icons/icon-scissors.tsx +0 -19
  203. /package/dist/preview/.next/static/{B4EYZiVzdylEG9lAIl-aO → Pms2orsQgT5xpttCfZfH5}/_ssgManifest.js +0 -0
@@ -7,22 +7,16 @@ import { ShellContext } from './shell';
7
7
  import { Tooltip } from './tooltip';
8
8
 
9
9
  interface TopbarProps {
10
- currentEmailOpenSlug: string;
11
- pathSeparator: string;
12
-
10
+ emailTitle: string;
13
11
  children: React.ReactNode;
14
12
  }
15
13
 
16
- export const Topbar = ({
17
- currentEmailOpenSlug,
18
- pathSeparator,
19
- children,
20
- }: TopbarProps) => {
14
+ export const Topbar = ({ emailTitle, children }: TopbarProps) => {
21
15
  const { toggleSidebar } = use(ShellContext)!;
22
16
 
23
17
  return (
24
18
  <Tooltip.Provider>
25
- <header className="relative flex h-[3.3125rem] items-center justify-between gap-3 border-slate-6 border-b px-3">
19
+ <header className="relative flex h-[3.3125rem] items-center justify-between gap-3 border-slate-6 border-b px-3 py-2">
26
20
  <div className="relative flex w-fit items-center gap-3">
27
21
  <Tooltip>
28
22
  <Tooltip.Trigger asChild>
@@ -40,31 +34,12 @@ export const Topbar = ({
40
34
  </Tooltip>
41
35
  <div className="hidden items-center overflow-hidden text-center lg:flex">
42
36
  <Heading as="h2" className="truncate" size="2" weight="medium">
43
- {currentEmailOpenSlug.split(pathSeparator).pop()}
37
+ {emailTitle}
44
38
  </Heading>
45
39
  </div>
46
40
  </div>
47
41
  <div className="flex w-full items-center justify-between gap-3 lg:w-fit lg:justify-start">
48
42
  {children}
49
- {/* {setViewWidth && setViewHeight && viewWidth && viewHeight ? ( */}
50
- {/* <ViewSizeControls */}
51
- {/* setViewHeight={setViewHeight} */}
52
- {/* setViewWidth={setViewWidth} */}
53
- {/* viewHeight={viewHeight} */}
54
- {/* viewWidth={viewWidth} */}
55
- {/* /> */}
56
- {/* ) : null} */}
57
- {/* {activeView && setActiveView ? ( */}
58
- {/* <ActiveViewToggleGroup */}
59
- {/* activeView={activeView} */}
60
- {/* setActiveView={setActiveView} */}
61
- {/* /> */}
62
- {/* ) : null} */}
63
- {/* {markup ? ( */}
64
- {/* <div className="flex justify-end"> */}
65
- {/* <Send markup={markup} /> */}
66
- {/* </div> */}
67
- {/* ) : null} */}
68
43
  </div>
69
44
  </header>
70
45
  </Tooltip.Provider>
@@ -1,6 +1,7 @@
1
1
  'use client';
2
2
  import { createContext, useContext, useState } from 'react';
3
3
  import { getEmailsDirectoryMetadataAction } from '../actions/get-emails-directory-metadata-action';
4
+ import { isBuilding } from '../app/env';
4
5
  import { useHotreload } from '../hooks/use-hot-reload';
5
6
  import type { EmailsDirectory } from '../utils/get-emails-directory-metadata';
6
7
 
@@ -30,7 +31,7 @@ export const EmailsProvider = (props: {
30
31
  const [emailsDirectoryMetadata, setEmailsDirectoryMetadata] =
31
32
  useState<EmailsDirectory>(props.initialEmailsDirectoryMetadata);
32
33
 
33
- if (process.env.NEXT_PUBLIC_IS_BUILDING !== 'true') {
34
+ if (!isBuilding) {
34
35
  // this will not change on runtime so it doesn't violate
35
36
  // the rules of hooks
36
37
  // eslint-disable-next-line react-hooks/rules-of-hooks
@@ -0,0 +1,46 @@
1
+ 'use client';
2
+ import { usePathname, useSearchParams } from 'next/navigation';
3
+ import { createContext, use, useEffect, useState } from 'react';
4
+
5
+ export const FragmentIdentifierContext = createContext<
6
+ | {
7
+ identifier: string | undefined;
8
+
9
+ update(value: string): void;
10
+ }
11
+ | undefined
12
+ >(undefined);
13
+
14
+ export const useFragmentIdentifier = () => {
15
+ const value = use(FragmentIdentifierContext);
16
+ return value?.identifier;
17
+ };
18
+
19
+ export const FragmentIdentifierProvider = ({
20
+ children,
21
+ }: { children: React.ReactNode }) => {
22
+ const [fragmentIdentifier, setFragmentIdentifier] = useState<string>();
23
+ const pathname = usePathname();
24
+ const searchParams = useSearchParams();
25
+
26
+ const update = () => {
27
+ setFragmentIdentifier(location.hash);
28
+ };
29
+
30
+ useEffect(() => {
31
+ update();
32
+ }, [pathname, searchParams]);
33
+
34
+ return (
35
+ <FragmentIdentifierContext.Provider
36
+ value={{
37
+ identifier: fragmentIdentifier,
38
+ update(value: string) {
39
+ setFragmentIdentifier(value);
40
+ },
41
+ }}
42
+ >
43
+ {children}
44
+ </FragmentIdentifierContext.Provider>
45
+ );
46
+ };
@@ -0,0 +1,81 @@
1
+ 'use client';
2
+ import { useRouter } from 'next/navigation';
3
+ import { createContext } from 'react';
4
+ import type {
5
+ EmailRenderingResult,
6
+ RenderedEmailMetadata,
7
+ } from '../actions/render-email-by-path';
8
+ import { isBuilding } from '../app/env';
9
+ import { useEmailRenderingResult } from '../hooks/use-email-rendering-result';
10
+ import { useHotreload } from '../hooks/use-hot-reload';
11
+ import { useRenderingMetadata } from '../hooks/use-rendering-metadata';
12
+
13
+ export const PreviewContext = createContext<
14
+ | {
15
+ renderedEmailMetadata: RenderedEmailMetadata | undefined;
16
+ renderingResult: EmailRenderingResult;
17
+
18
+ emailSlug: string;
19
+ emailPath: string;
20
+ }
21
+ | undefined
22
+ >(undefined);
23
+
24
+ interface PreviewProvider {
25
+ emailSlug: string;
26
+ emailPath: string;
27
+
28
+ serverRenderingResult: EmailRenderingResult;
29
+
30
+ children: React.ReactNode;
31
+ }
32
+
33
+ export const PreviewProvider = ({
34
+ emailSlug,
35
+ emailPath,
36
+ serverRenderingResult,
37
+ children,
38
+ }: PreviewProvider) => {
39
+ const router = useRouter();
40
+
41
+ const renderingResult = useEmailRenderingResult(
42
+ emailPath,
43
+ serverRenderingResult,
44
+ );
45
+
46
+ const renderedEmailMetadata = useRenderingMetadata(
47
+ emailPath,
48
+ renderingResult,
49
+ serverRenderingResult,
50
+ );
51
+
52
+ if (!isBuilding) {
53
+ // this will not change on runtime so it doesn't violate
54
+ // the rules of hooks
55
+ // eslint-disable-next-line react-hooks/rules-of-hooks
56
+ useHotreload((changes) => {
57
+ const changeForThisEmail = changes.find((change) =>
58
+ change.filename.includes(emailSlug),
59
+ );
60
+
61
+ if (typeof changeForThisEmail !== 'undefined') {
62
+ if (changeForThisEmail.event === 'unlink') {
63
+ router.push('/');
64
+ }
65
+ }
66
+ });
67
+ }
68
+
69
+ return (
70
+ <PreviewContext.Provider
71
+ value={{
72
+ emailPath,
73
+ emailSlug,
74
+ renderedEmailMetadata,
75
+ renderingResult,
76
+ }}
77
+ >
78
+ {children}
79
+ </PreviewContext.Provider>
80
+ );
81
+ };
@@ -4,6 +4,7 @@ import {
4
4
  type EmailRenderingResult,
5
5
  renderEmailByPath,
6
6
  } from '../actions/render-email-by-path';
7
+ import { isBuilding } from '../app/env';
7
8
  import { useHotreload } from './use-hot-reload';
8
9
 
9
10
  export const useEmailRenderingResult = (
@@ -14,7 +15,7 @@ export const useEmailRenderingResult = (
14
15
  serverEmailRenderedResult,
15
16
  );
16
17
 
17
- if (process.env.NEXT_PUBLIC_IS_BUILDING !== 'true') {
18
+ if (!isBuilding) {
18
19
  // eslint-disable-next-line react-hooks/rules-of-hooks
19
20
  useHotreload(async (changes) => {
20
21
  for await (const change of changes) {
@@ -0,0 +1,14 @@
1
+ import { usePathname, useSearchParams } from 'next/navigation';
2
+ import { useEffect, useState } from 'react';
3
+
4
+ export const useFragmentIdentifier = () => {
5
+ const pathname = usePathname();
6
+ const searchParams = useSearchParams();
7
+ const [fragmentIdentifier, setFragmentIdentifier] = useState<string>();
8
+
9
+ useEffect(() => {
10
+ setFragmentIdentifier(global.location?.hash);
11
+ }, [pathname, searchParams]);
12
+
13
+ return fragmentIdentifier;
14
+ };
@@ -1,3 +1,3 @@
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="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;;padding-left:0.5rem;padding-right:0.5rem"><div style="display:none;overflow:hidden;line-height:1px;opacity:0;max-height:0;max-width:0">Join Alan on Vercel<div> ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏</div></div><table align="center" width="100%" border="0" cellPadding="0" cellSpacing="0" role="presentation" style="border-width:1px;border-style:solid;border-color:rgb(234,234,234);border-radius:0.25rem;margin-top:40px;margin-bottom:40px;margin-left:auto;margin-right:auto;padding:20px;max-width:465px"><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" height="37" src="/static/vercel-logo.png" style="margin-top:0px;margin-bottom:0px;margin-left:auto;margin-right:auto;display:block;outline:none;border:none;text-decoration:none" width="40"/></td></tr></tbody></table><h1 style="color:rgb(0,0,0);font-size:24px;font-weight:400;text-align:center;padding:0px;margin-top:30px;margin-bottom:30px;margin-left:0px;margin-right:0px">Join <strong>Enigma</strong> on <strong>Vercel</strong></h1><p style="color:rgb(0,0,0);font-size:14px;line-height:24px;margin:16px 0">Hello <!-- -->alanturing<!-- -->,</p><p style="color:rgb(0,0,0);font-size:14px;line-height:24px;margin:16px 0"><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 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="invited you to" 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 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="text-align:center;margin-top:32px;margin-bottom:32px"><tbody><tr><td><a href="https://vercel.com/teams/invite/foo" style="background-color:rgb(0,0,0);border-radius:0.25rem;color:rgb(255,255,255);font-size:12px;font-weight:600;text-decoration-line:none;text-align:center;padding-left:1.25rem;padding-right:1.25rem;padding-top:0.75rem;padding-bottom:0.75rem;line-height:100%;text-decoration:none;display:inline-block;max-width:100%;mso-padding-alt:0px;padding:12px 20px 12px 20px" 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="color:rgb(0,0,0);font-size:14px;line-height:24px;margin:16px 0">or copy and paste this URL into your browser:<!-- --> <a href="https://vercel.com/teams/invite/foo" style="color:rgb(37,99,235);text-decoration-line:none" target="_blank">https://vercel.com/teams/invite/foo</a></p><hr style="border-width:1px;border-style:solid;border-color:rgb(234,234,234);margin-top:26px;margin-bottom:26px;margin-left:0px;margin-right:0px;width:100%;border:none;border-top:1px solid #eaeaea"/><p style="color:rgb(102,102,102);font-size:12px;line-height:24px;margin:16px 0">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`] = `"<!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="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;;padding-left:0.5rem;padding-right:0.5rem"><div style="display:none;overflow:hidden;line-height:1px;opacity:0;max-height:0;max-width:0">Join Alan on Vercel<div> ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏</div></div><table align="center" width="100%" border="0" cellPadding="0" cellSpacing="0" role="presentation" style="border-width:1px;border-style:solid;border-color:rgb(234,234,234);border-radius:0.25rem;margin-top:40px;margin-bottom:40px;margin-left:auto;margin-right:auto;padding:20px;max-width:465px"><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" height="37" src="/static/vercel-logo.png" style="margin-top:0px;margin-bottom:0px;margin-left:auto;margin-right:auto;display:block;outline:none;border:none;text-decoration:none" width="40"/></td></tr></tbody></table><h1 style="color:rgb(0,0,0);font-size:24px;font-weight:400;text-align:center;padding:0px;margin-top:30px;margin-bottom:30px;margin-left:0px;margin-right:0px">Join <strong>Enigma</strong> on <strong>Vercel</strong></h1><p style="color:rgb(0,0,0);font-size:14px;line-height:24px;margin-bottom:16px;margin-top:16px">Hello <!-- -->alanturing<!-- -->,</p><p style="color:rgb(0,0,0);font-size:14px;line-height:24px;margin-bottom:16px;margin-top: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 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="invited you to" 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 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="text-align:center;margin-top:32px;margin-bottom:32px"><tbody><tr><td><a href="https://vercel.com/teams/invite/foo" style="background-color:rgb(0,0,0);border-radius:0.25rem;color:rgb(255,255,255);font-size:12px;font-weight:600;text-decoration-line:none;text-align:center;padding-left:1.25rem;padding-right:1.25rem;padding-top:0.75rem;padding-bottom:0.75rem;line-height:100%;text-decoration:none;display:inline-block;max-width:100%;mso-padding-alt:0px;padding:12px 20px 12px 20px" 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="color:rgb(0,0,0);font-size:14px;line-height:24px;margin-bottom:16px;margin-top:16px">or copy and paste this URL into your browser:<!-- --> <a href="https://vercel.com/teams/invite/foo" style="color:rgb(37,99,235);text-decoration-line:none" target="_blank">https://vercel.com/teams/invite/foo</a></p><hr style="border-width:1px;border-style:solid;border-color:rgb(234,234,234);margin-top:26px;margin-bottom:26px;margin-left:0px;margin-right:0px;width:100%;border:none;border-top:1px solid #eaeaea"/><p style="color:rgb(102,102,102);font-size:12px;line-height:24px;margin-bottom:16px;margin-top: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>"`;
@@ -0,0 +1,358 @@
1
+ // taken from https://www.w3schools.com/cssref/index.php
2
+ export const allCssProperties = [
3
+ 'accent-color',
4
+ 'align-content',
5
+ 'align-items',
6
+ 'align-self',
7
+ 'all',
8
+ 'animation',
9
+ 'animation-delay',
10
+ 'animation-direction',
11
+ 'animation-duration',
12
+ 'animation-fill-mode',
13
+ 'animation-iteration-count',
14
+ 'animation-name',
15
+ 'animation-play-state',
16
+ 'animation-timing-function',
17
+ 'aspect-ratio',
18
+ 'backdrop-filter',
19
+ 'backface-visibility',
20
+ 'background',
21
+ 'background-attachment',
22
+ 'background-blend-mode',
23
+ 'background-clip',
24
+ 'background-color',
25
+ 'background-image',
26
+ 'background-origin',
27
+ 'background-position',
28
+ 'background-position-x',
29
+ 'background-position-y',
30
+ 'background-repeat',
31
+ 'background-size',
32
+ 'block-size',
33
+ 'border',
34
+ 'border-block',
35
+ 'border-block-color',
36
+ 'border-block-end',
37
+ 'border-block-end-color',
38
+ 'border-block-end-style',
39
+ 'border-block-end-width',
40
+ 'border-block-start',
41
+ 'border-block-start-color',
42
+ 'border-block-start-style',
43
+ 'border-block-start-width',
44
+ 'border-block-style',
45
+ 'border-block-width',
46
+ 'border-bottom',
47
+ 'border-bottom-color',
48
+ 'border-bottom-left-radius',
49
+ 'border-bottom-right-radius',
50
+ 'border-bottom-style',
51
+ 'border-bottom-width',
52
+ 'border-collapse',
53
+ 'border-color',
54
+ 'border-end-end-radius',
55
+ 'border-end-start-radius',
56
+ 'border-image',
57
+ 'border-image-outset',
58
+ 'border-image-repeat',
59
+ 'border-image-slice',
60
+ 'border-image-source',
61
+ 'border-image-width',
62
+ 'border-inline',
63
+ 'border-inline-color',
64
+ 'border-inline-end',
65
+ 'border-inline-end-color',
66
+ 'border-inline-end-style',
67
+ 'border-inline-end-width',
68
+ 'border-inline-start',
69
+ 'border-inline-start-color',
70
+ 'border-inline-start-style',
71
+ 'border-inline-start-width',
72
+ 'border-inline-style',
73
+ 'border-inline-width',
74
+ 'border-left',
75
+ 'border-left-color',
76
+ 'border-left-style',
77
+ 'border-left-width',
78
+ 'border-radius',
79
+ 'border-right',
80
+ 'border-right-color',
81
+ 'border-right-style',
82
+ 'border-right-width',
83
+ 'border-spacing',
84
+ 'border-start-end-radius',
85
+ 'border-start-start-radius',
86
+ 'border-style',
87
+ 'border-top',
88
+ 'border-top-color',
89
+ 'border-top-left-radius',
90
+ 'border-top-right-radius',
91
+ 'border-top-style',
92
+ 'border-top-width',
93
+ 'border-width',
94
+ 'bottom',
95
+ 'box-decoration-break',
96
+ 'box-reflect',
97
+ 'box-shadow',
98
+ 'box-sizing',
99
+ 'break-after',
100
+ 'break-before',
101
+ 'break-inside',
102
+ 'caption-side',
103
+ 'caret-color',
104
+ '@charset',
105
+ 'clear',
106
+ 'clip',
107
+ 'clip-path',
108
+ 'color',
109
+ 'column-count',
110
+ 'column-fill',
111
+ 'column-gap',
112
+ 'column-rule',
113
+ 'column-rule-color',
114
+ 'column-rule-style',
115
+ 'column-rule-width',
116
+ 'column-span',
117
+ 'column-width',
118
+ 'columns',
119
+ 'content',
120
+ 'counter-increment',
121
+ 'counter-reset',
122
+ 'counter-set',
123
+ 'cursor',
124
+ 'direction',
125
+ 'display',
126
+ 'empty-cells',
127
+ 'filter',
128
+ 'flex',
129
+ 'flex-basis',
130
+ 'flex-direction',
131
+ 'flex-flow',
132
+ 'flex-grow',
133
+ 'flex-shrink',
134
+ 'flex-wrap',
135
+ 'float',
136
+ 'font',
137
+ '@font-face',
138
+ 'font-family',
139
+ 'font-feature-settings',
140
+ '@font-feature-values',
141
+ 'font-kerning',
142
+ 'font-language-override',
143
+ 'font-size',
144
+ 'font-size-adjust',
145
+ 'font-stretch',
146
+ 'font-style',
147
+ 'font-synthesis',
148
+ 'font-variant',
149
+ 'font-variant-alternates',
150
+ 'font-variant-caps',
151
+ 'font-variant-east-asian',
152
+ 'font-variant-ligatures',
153
+ 'font-variant-numeric',
154
+ 'font-variant-position',
155
+ 'font-weight',
156
+ 'gap',
157
+ 'grid',
158
+ 'grid-area',
159
+ 'grid-auto-columns',
160
+ 'grid-auto-flow',
161
+ 'grid-auto-rows',
162
+ 'grid-column',
163
+ 'grid-column-end',
164
+ 'grid-column-gap',
165
+ 'grid-column-start',
166
+ 'grid-gap',
167
+ 'grid-row',
168
+ 'grid-row-end',
169
+ 'grid-row-gap',
170
+ 'grid-row-start',
171
+ 'grid-template',
172
+ 'grid-template-areas',
173
+ 'grid-template-columns',
174
+ 'grid-template-rows',
175
+ 'hanging-punctuation',
176
+ 'height',
177
+ 'hyphens',
178
+ 'hypenate-character',
179
+ 'image-rendering',
180
+ '@import',
181
+ 'inline-size',
182
+ 'inset',
183
+ 'inset-block',
184
+ 'inset-block-end',
185
+ 'inset-block-start',
186
+ 'inset-inline',
187
+ 'inset-inline-end',
188
+ 'inset-inline-start',
189
+ 'isolation',
190
+ 'justify-content',
191
+ 'justify-items',
192
+ 'justify-self',
193
+ '@keyframes',
194
+ 'left',
195
+ 'letter-spacing',
196
+ 'line-break',
197
+ 'line-height',
198
+ 'list-style',
199
+ 'list-style-image',
200
+ 'list-style-position',
201
+ 'list-style-type',
202
+ 'margin',
203
+ 'shape-margin',
204
+ 'margin-block',
205
+ 'margin-block-end',
206
+ 'margin-block-start',
207
+ 'margin-bottom',
208
+ 'margin-inline',
209
+ 'margin-inline-end',
210
+ 'margin-inline-start',
211
+ 'margin-left',
212
+ 'margin-right',
213
+ 'margin-top',
214
+ 'mask',
215
+ 'mask-clip',
216
+ 'mask-composite',
217
+ 'mask-image',
218
+ 'mask-mode',
219
+ 'mask-origin',
220
+ 'mask-position',
221
+ 'mask-repeat',
222
+ 'mask-size',
223
+ 'mask-type',
224
+ 'max-height',
225
+ 'max-width',
226
+ '@media',
227
+ 'max-block-size',
228
+ 'max-inline-size',
229
+ 'min-block-size',
230
+ 'min-inline-size',
231
+ 'min-height',
232
+ 'min-width',
233
+ 'mix-blend-mode',
234
+ 'object-fit',
235
+ 'object-position',
236
+ 'offset',
237
+ 'offset-anchor',
238
+ 'offset-distance',
239
+ 'offset-path',
240
+ 'offset-rotate',
241
+ 'opacity',
242
+ 'order',
243
+ 'orphans',
244
+ 'outline',
245
+ 'outline-color',
246
+ 'outline-offset',
247
+ 'outline-style',
248
+ 'outline-width',
249
+ 'overflow',
250
+ 'overflow-anchor',
251
+ 'overflow-wrap',
252
+ 'overflow-x',
253
+ 'overflow-y',
254
+ 'overscroll-behavior',
255
+ 'overscroll-behavior-block',
256
+ 'overscroll-behavior-inline',
257
+ 'overscroll-behavior-x',
258
+ 'overscroll-behavior-y',
259
+ 'padding',
260
+ 'padding-block',
261
+ 'padding-block-end',
262
+ 'padding-block-start',
263
+ 'padding-bottom',
264
+ 'padding-inline',
265
+ 'padding-inline-end',
266
+ 'padding-inline-start',
267
+ 'padding-left',
268
+ 'padding-right',
269
+ 'padding-top',
270
+ 'page-break-after',
271
+ 'page-break-before',
272
+ 'page-break-inside',
273
+ 'paint-order',
274
+ 'perspective',
275
+ 'perspective-origin',
276
+ 'place-content',
277
+ 'place-items',
278
+ 'place-self',
279
+ 'pointer-events',
280
+ 'position',
281
+ 'quotes',
282
+ 'resize',
283
+ 'right',
284
+ 'rotate',
285
+ 'row-gap',
286
+ 'scale',
287
+ 'scroll-behavior',
288
+ 'scroll-margin',
289
+ 'scroll-margin-block',
290
+ 'scroll-margin-block-end',
291
+ 'scroll-margin-block-start',
292
+ 'scroll-margin-bottom',
293
+ 'scroll-margin-inline',
294
+ 'scroll-margin-inline-end',
295
+ 'scroll-margin-inline-start',
296
+ 'scroll-margin-left',
297
+ 'scroll-margin-right',
298
+ 'scroll-margin-top',
299
+ 'scroll-padding',
300
+ 'scroll-padding-block',
301
+ 'scroll-padding-block-end',
302
+ 'scroll-padding-block-start',
303
+ 'scroll-padding-bottom',
304
+ 'scroll-padding-inline',
305
+ 'scroll-padding-inline-end',
306
+ 'scroll-padding-inline-start',
307
+ 'scroll-padding-left',
308
+ 'scroll-padding-right',
309
+ 'scroll-padding-top',
310
+ 'scroll-snap-align',
311
+ 'scroll-snap-stop',
312
+ 'scroll-snap-type',
313
+ 'scrollbar-color',
314
+ 'tab-size',
315
+ 'table-layout',
316
+ 'text-align',
317
+ 'text-align-last',
318
+ 'text-combine-upright',
319
+ 'text-decoration',
320
+ 'text-decoration-color',
321
+ 'text-decoration-line',
322
+ 'text-decoration-style',
323
+ 'text-decoration-thickness',
324
+ 'text-emphasis',
325
+ 'text-emphasis-color',
326
+ 'text-emphasis-position',
327
+ 'text-emphasis-style',
328
+ 'text-indent',
329
+ 'text-justify',
330
+ 'text-orientation',
331
+ 'text-overflow',
332
+ 'text-shadow',
333
+ 'text-transform',
334
+ 'text-underline-offset',
335
+ 'text-underline-position',
336
+ 'top',
337
+ 'transform',
338
+ 'transform-origin',
339
+ 'transform-style',
340
+ 'transition',
341
+ 'transition-delay',
342
+ 'transition-duration',
343
+ 'transition-property',
344
+ 'transition-timing-function',
345
+ 'translate',
346
+ 'unicode-bidi',
347
+ 'user-select',
348
+ 'vertical-align',
349
+ 'visibility',
350
+ 'white-space',
351
+ 'widows',
352
+ 'width',
353
+ 'word-break',
354
+ 'word-spacing',
355
+ 'word-wrap',
356
+ 'writing-mode',
357
+ 'z-index',
358
+ ];