├── .editorconfig ├── .eslintignore ├── .eslintrc.js ├── .github ├── ISSUE_TEMPLATE │ ├── BUG.md │ ├── DOCS.md │ ├── FEATURE.md │ ├── MODIFICATION.md │ ├── NEW_COMPONENT.md │ └── SUPPORT.md ├── actions │ └── setup │ │ └── action.yml ├── pull_request_template.md └── workflows │ ├── pr-title.yml │ ├── release.yml │ ├── test-cli.yml │ ├── test-smoke.yml │ ├── test-v18.yml │ ├── test.yml │ └── validate.yml ├── .gitignore ├── .husky └── pre-commit ├── .moon ├── tasks.yml ├── toolchain.yml └── workspace.yml ├── .npmrc ├── .nvmrc ├── .prettierrc.js ├── .vscode ├── settings.json └── tailwind.json ├── CONTRIBUTING.md ├── LICENSE.md ├── README.md ├── apps ├── demo │ ├── README.md │ ├── emails │ │ ├── airbnb-review.tsx │ │ ├── apple-receipt.tsx │ │ ├── codepen-challengers.tsx │ │ ├── credential emails │ │ │ ├── dropbox-reset-password.tsx │ │ │ ├── github-access-token.tsx │ │ │ ├── linear-login-code.tsx │ │ │ ├── magic links │ │ │ │ ├── notion-magic-link.tsx │ │ │ │ └── raycast-magic-link.tsx │ │ │ └── twitch-reset-password.tsx │ │ ├── google-play-policy-update.tsx │ │ ├── nike-receipt.tsx │ │ ├── plaid-verify-identity.tsx │ │ ├── slack-confirm.tsx │ │ ├── stack-overflow-tips.tsx │ │ ├── static │ │ │ ├── airbnb-logo.png │ │ │ ├── airbnb-review-user.jpg │ │ │ ├── amazon-book.jpg │ │ │ ├── amazon-facebook.jpg │ │ │ ├── amazon-instagram.jpg │ │ │ ├── amazon-logo.png │ │ │ ├── amazon-prime-logo.png │ │ │ ├── amazon-rating.gif │ │ │ ├── amazon-twitter.jpg │ │ │ ├── apple-card-icon.png │ │ │ ├── apple-hbo-max-icon.jpeg │ │ │ ├── apple-logo.png │ │ │ ├── apple-wallet.png │ │ │ ├── batman-twilight.jpg │ │ │ ├── cat.jpeg │ │ │ ├── codepen-challengers.png │ │ │ ├── codepen-cube.png │ │ │ ├── codepen-pro.png │ │ │ ├── dropbox-logo.png │ │ │ ├── github.png │ │ │ ├── google-play-academy.png │ │ │ ├── google-play-chat.png │ │ │ ├── google-play-footer.png │ │ │ ├── google-play-header.png │ │ │ ├── google-play-icon.png │ │ │ ├── google-play-logo.png │ │ │ ├── google-play-pl.png │ │ │ ├── google-play.png │ │ │ ├── koala-logo.png │ │ │ ├── linear-logo.png │ │ │ ├── netlify-logo.png │ │ │ ├── nike-logo.png │ │ │ ├── nike-phone.png │ │ │ ├── nike-product.png │ │ │ ├── nike-recomendation-1.png │ │ │ ├── nike-recomendation-2.png │ │ │ ├── nike-recomendation-3.png │ │ │ ├── nike-recomendation-4.png │ │ │ ├── notion-logo.png │ │ │ ├── plaid-logo.png │ │ │ ├── raycast-bg.png │ │ │ ├── raycast-logo.png │ │ │ ├── slack-facebook.png │ │ │ ├── slack-linkedin.png │ │ │ ├── slack-logo.png │ │ │ ├── slack-twitter.png │ │ │ ├── stack-overflow-header.png │ │ │ ├── stack-overflow-logo-sm.png │ │ │ ├── stack-overflow-logo.png │ │ │ ├── stripe-logo.png │ │ │ ├── twitch-icon-facebook.png │ │ │ ├── twitch-icon-twitter.png │ │ │ ├── twitch-logo.png │ │ │ ├── vercel-arrow.png │ │ │ ├── vercel-logo.png │ │ │ ├── vercel-team.png │ │ │ ├── vercel-user.png │ │ │ ├── yelp-footer.png │ │ │ ├── yelp-header.png │ │ │ └── yelp-logo.png │ │ ├── vercel-invite-user.tsx │ │ ├── welcome emails │ │ │ ├── koala-welcome.tsx │ │ │ ├── netlify-welcome.tsx │ │ │ └── stripe-welcome.tsx │ │ └── yelp-recent-login.tsx │ ├── moon.yml │ ├── package.json │ └── tsconfig.json ├── preview │ ├── .eslintrc.cjs │ ├── CHANGELOG.md │ ├── README.md │ ├── app │ │ ├── index.html │ │ ├── postcss.config.cjs │ │ ├── src │ │ │ ├── app.ts │ │ │ ├── components │ │ │ │ ├── code-container.tsx │ │ │ │ ├── code.tsx │ │ │ │ ├── icons.tsx │ │ │ │ ├── logo.tsx │ │ │ │ ├── mobile.tsx │ │ │ │ ├── nav-button.tsx │ │ │ │ ├── nav.tsx │ │ │ │ ├── send.tsx │ │ │ │ ├── shell.tsx │ │ │ │ └── sidebar.tsx │ │ │ ├── config.ts │ │ │ ├── devices.json │ │ │ ├── error.tsx │ │ │ ├── helpers.ts │ │ │ ├── home.tsx │ │ │ ├── index.css │ │ │ ├── main.tsx │ │ │ ├── preview.tsx │ │ │ ├── routes.tsx │ │ │ ├── templates.ts │ │ │ └── types.ts │ │ └── tailwind.config.cjs │ ├── moon.yml │ ├── package.json │ └── tsconfig.json └── web │ ├── .vitepress │ ├── config.mts │ ├── sidebar.mts │ └── theme │ │ ├── custom.css │ │ └── index.ts │ ├── moon.yml │ ├── package.json │ └── src │ ├── api │ └── contributions.data.ts │ ├── changelog.md │ ├── docs │ ├── include │ ├── CONTRIBUTING.md │ ├── README.md │ ├── header.md │ └── install.md │ ├── index.md │ └── public │ ├── assets │ └── demo │ │ ├── airbnb-logo.png │ │ ├── apple-card-icon.png │ │ ├── apple-hbo-max-icon.jpeg │ │ ├── apple-logo.png │ │ ├── apple-wallet.png │ │ ├── batman-adam.jpg │ │ ├── batman-cartoon.jpg │ │ ├── batman-lego.webp │ │ ├── batman-twilight.jpg │ │ ├── codepen-challengers.png │ │ ├── codepen-cube.png │ │ ├── codepen-pro.png │ │ ├── dropbox-logo.png │ │ ├── github.png │ │ ├── google-play-academy.png │ │ ├── google-play-chat.png │ │ ├── google-play-footer.png │ │ ├── google-play-header.png │ │ ├── google-play-icon.png │ │ ├── google-play-logo.png │ │ ├── koala-logo.png │ │ ├── linear-logo.png │ │ ├── netlify-logo.png │ │ ├── nike-logo.png │ │ ├── nike-phone.png │ │ ├── nike-product.png │ │ ├── nike-recomendation-1.png │ │ ├── nike-recomendation-2.png │ │ ├── nike-recomendation-4 (1).png │ │ ├── nike-recomendation-4.png │ │ ├── notion-logo.png │ │ ├── plaid-logo.png │ │ ├── raycast-logo.png │ │ ├── slack-facebook.png │ │ ├── slack-linkedin.png │ │ ├── slack-logo.png │ │ ├── slack-twitter.png │ │ ├── stack-overflow-header.png │ │ ├── stack-overflow-logo-sm.png │ │ ├── stack-overflow-logo.png │ │ ├── stripe-logo.png │ │ ├── twitch-icon-facebook.png │ │ ├── twitch-icon-twitter.png │ │ ├── twitch-logo.png │ │ ├── vercel-arrow.png │ │ ├── vercel-logo.png │ │ ├── vercel-team.png │ │ ├── yelp-footer.png │ │ ├── yelp-header.png │ │ └── yelp-logo.png │ ├── home-hero.png │ ├── landing-bg.svg │ ├── logo.svg │ ├── og.png │ ├── preview-1.png │ ├── preview-2.png │ ├── preview-3.png │ ├── preview-4.png │ └── test │ └── index.html ├── assets ├── brackets.svg ├── clients.svg ├── npm-header.svg └── templates │ └── email.mustache ├── docs ├── components │ ├── background.md │ ├── body.md │ ├── butan.md │ ├── button.md │ ├── code.md │ ├── color-scheme.md │ ├── column.md │ ├── conditional.md │ ├── container.md │ ├── font.md │ ├── graph.md │ ├── head.md │ ├── heading.md │ ├── hr.md │ ├── html.md │ ├── image.md │ ├── link.md │ ├── markdown.md │ ├── preview.md │ ├── raw.md │ ├── row.md │ ├── section.md │ ├── tailwind.md │ └── text.md ├── contributing.md ├── core │ ├── cli.md │ ├── compile.md │ ├── config.md │ ├── plugins.md │ └── render.md ├── email-providers.md ├── faq.md ├── introduction.md ├── plugins │ ├── inline.md │ ├── minify.md │ └── pretty.md ├── quick-start.md ├── recipes.md └── v2 │ ├── button.md │ └── migration.md ├── moon.yml ├── package.json ├── packages ├── create-jsx-email │ ├── CHANGELOG.md │ ├── README.md │ ├── bin │ │ └── create-jsx-email │ ├── generators │ │ ├── README.md │ │ ├── _.gitignore │ │ ├── _tsconfig.json │ │ ├── package.json.mustache │ │ └── templates │ ├── moon.yml │ ├── package.json │ ├── src │ │ ├── index.ts │ │ └── package-info.cts │ └── tsconfig.json ├── jsx-email │ ├── CHANGELOG.md │ ├── README.md │ ├── bin │ │ └── email │ ├── generators │ │ └── templates │ ├── moon.yml │ ├── package.json │ ├── src │ │ ├── cli │ │ │ ├── commands │ │ │ │ ├── build.mts │ │ │ │ ├── check.mts │ │ │ │ ├── create.mts │ │ │ │ ├── help.mts │ │ │ │ ├── preview.mts │ │ │ │ └── types.mts │ │ │ ├── helpers.mts │ │ │ ├── main.mts │ │ │ ├── vite-reload.mts │ │ │ ├── vite-static.mts │ │ │ └── watcher.mts │ │ ├── components │ │ │ ├── background.tsx │ │ │ ├── body.tsx │ │ │ ├── butan.tsx │ │ │ ├── button.tsx │ │ │ ├── code.tsx │ │ │ ├── color-scheme.tsx │ │ │ ├── column.tsx │ │ │ ├── conditional.tsx │ │ │ ├── container.tsx │ │ │ ├── font.tsx │ │ │ ├── graph.tsx │ │ │ ├── head.tsx │ │ │ ├── heading.tsx │ │ │ ├── hr.tsx │ │ │ ├── html.tsx │ │ │ ├── img.tsx │ │ │ ├── link.tsx │ │ │ ├── markdown.tsx │ │ │ ├── preview.tsx │ │ │ ├── raw.tsx │ │ │ ├── row.tsx │ │ │ ├── section.tsx │ │ │ ├── tailwind │ │ │ │ ├── color-functions.ts │ │ │ │ └── tailwind.tsx │ │ │ └── text.tsx │ │ ├── config.ts │ │ ├── debug.ts │ │ ├── helpers.ts │ │ ├── index.ts │ │ ├── log.ts │ │ ├── package-info.cts │ │ ├── plugins.ts │ │ ├── renderer │ │ │ ├── compat │ │ │ │ ├── context.ts │ │ │ │ └── hooks.ts │ │ │ ├── compile.ts │ │ │ ├── constants.ts │ │ │ ├── escape-string.ts │ │ │ ├── is-valid-element.ts │ │ │ ├── jsx-to-string.ts │ │ │ ├── move-style.ts │ │ │ ├── raw.ts │ │ │ ├── render.ts │ │ │ ├── stringify-styles.ts │ │ │ └── suspense.ts │ │ └── types.ts │ ├── test │ │ ├── .snapshots │ │ │ ├── background.test.tsx.snap │ │ │ ├── body.test.tsx.snap │ │ │ ├── button-legacy.test.tsx.snap │ │ │ ├── button.test.tsx.snap │ │ │ ├── code.test.tsx.snap │ │ │ ├── color-scheme.test.tsx.snap │ │ │ ├── column.test.tsx.snap │ │ │ ├── conditional.test.tsx.snap │ │ │ ├── container.test.tsx.snap │ │ │ ├── debug.test.tsx.snap │ │ │ ├── font.test.tsx.snap │ │ │ ├── graph.test.tsx.snap │ │ │ ├── head.test.tsx.snap │ │ │ ├── heading.test.tsx.snap │ │ │ ├── hr.test.tsx.snap │ │ │ ├── html.test.tsx.snap │ │ │ ├── img.test.tsx.snap │ │ │ ├── link.test.tsx.snap │ │ │ ├── markdown.test.tsx.snap │ │ │ ├── preview.test.tsx.snap │ │ │ ├── raw.test.tsx.snap │ │ │ ├── row.test.tsx.snap │ │ │ ├── section.test.tsx.snap │ │ │ ├── tailwind.test.tsx.snap │ │ │ └── text.test.tsx.snap │ │ ├── background.test.tsx │ │ ├── body.test.tsx │ │ ├── button.test.tsx │ │ ├── code.test.tsx │ │ ├── color-scheme.test.tsx │ │ ├── column.test.tsx │ │ ├── conditional.test.tsx │ │ ├── config │ │ │ ├── .snapshots │ │ │ │ ├── define-config.test.ts.snap │ │ │ │ └── merge-config.test.ts.snap │ │ │ ├── define-config.test.ts │ │ │ ├── load │ │ │ │ ├── dotdir │ │ │ │ │ ├── .config │ │ │ │ │ │ └── jsx-email.config.mjs │ │ │ │ │ ├── .snapshots │ │ │ │ │ │ └── load-dotdir.test.ts.snap │ │ │ │ │ └── load-dotdir.test.ts │ │ │ │ ├── mjs-json │ │ │ │ │ ├── .snapshots │ │ │ │ │ │ └── load-mjs-json.test.ts.snap │ │ │ │ │ ├── jsx-email.config.mjs │ │ │ │ │ └── load-mjs-json.test.ts │ │ │ │ ├── mjs │ │ │ │ │ ├── .snapshots │ │ │ │ │ │ └── load-mjs.test.ts.snap │ │ │ │ │ ├── jsx-email.config.mjs │ │ │ │ │ └── load-mjs.test.ts │ │ │ │ └── parent-dir │ │ │ │ │ ├── child-dir │ │ │ │ │ ├── .snapshots │ │ │ │ │ │ └── parent-dir.test.ts.snap │ │ │ │ │ └── parent-dir.test.ts │ │ │ │ │ └── jsx-email.config.mjs │ │ │ ├── merge-config.test.ts │ │ │ └── render │ │ │ │ ├── .snapshots │ │ │ │ └── config-render.test.tsx.snap │ │ │ │ ├── config-render.test.tsx │ │ │ │ └── jsx-email.config.mjs │ │ ├── container.test.tsx │ │ ├── debug.test.tsx │ │ ├── font.test.tsx │ │ ├── graph.test.tsx │ │ ├── head.test.tsx │ │ ├── heading-margins.test.ts │ │ ├── heading.test.tsx │ │ ├── hr.test.tsx │ │ ├── html.test.tsx │ │ ├── img.test.tsx │ │ ├── link.test.tsx │ │ ├── markdown.test.tsx │ │ ├── preview.test.tsx │ │ ├── raw.test.tsx │ │ ├── render │ │ │ ├── .snapshots │ │ │ │ ├── import-css.test.tsx.snap │ │ │ │ ├── issues.test.tsx.snap │ │ │ │ ├── jsx-to-string.test.tsx.snap │ │ │ │ ├── minify.test.tsx.snap │ │ │ │ ├── render.test.tsx.snap │ │ │ │ └── suspense.test.tsx.snap │ │ │ ├── compat │ │ │ │ ├── .snapshots │ │ │ │ │ └── context.test.tsx.snap │ │ │ │ └── context.test.tsx │ │ │ ├── fixtures │ │ │ │ ├── async-template.tsx │ │ │ │ ├── components.tsx │ │ │ │ ├── import-css.css │ │ │ │ ├── import-css.tsx │ │ │ │ ├── preview.tsx │ │ │ │ ├── tailwind.tsx │ │ │ │ └── template.tsx │ │ │ ├── import-css.test.tsx │ │ │ ├── issues.test.tsx │ │ │ ├── jsx-to-string.test.tsx │ │ │ ├── minify.test.tsx │ │ │ ├── render.test.tsx │ │ │ ├── render.tsx │ │ │ └── suspense.test.tsx │ │ ├── row.test.tsx │ │ ├── section.test.tsx │ │ ├── tailwind │ │ │ ├── .snapshots │ │ │ │ ├── color-functions.test.ts.snap │ │ │ │ ├── tailwind-head.test.tsx.snap │ │ │ │ └── tailwind.test.tsx.snap │ │ │ ├── color-functions.test.ts │ │ │ ├── tailwind-head.test.tsx │ │ │ └── tailwind.test.tsx │ │ ├── text.test.tsx │ │ └── tsconfig.json │ └── tsconfig.json ├── plugin-inline │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ ├── src │ │ └── index.ts │ └── tsconfig.json ├── plugin-minify │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ ├── src │ │ └── index.ts │ └── tsconfig.json └── plugin-pretty │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ ├── src │ └── index.ts │ └── tsconfig.json ├── pnpm-lock.yaml ├── pnpm-workspace.yaml ├── recipes └── import-css │ ├── .gitignore │ ├── README.md │ ├── package.json │ ├── templates │ ├── email.css │ └── email.tsx │ └── tsconfig.json ├── scripts ├── build-samples.ts ├── ci-preview-setup.sh ├── ci-preview-start.sh ├── test.tsx └── tester.tsx ├── shared ├── bootstrap.sh ├── tsconfig.base.json ├── tsconfig.eslint.json └── vitest.config.ts ├── test ├── cli │ ├── .npmrc │ ├── .snapshots │ │ ├── create-jsx-email.test.ts.snap │ │ └── create.test.ts.snap │ ├── create-jsx-email.test.ts │ ├── create.test.ts │ ├── esbuild │ │ ├── esbuild.test.ts │ │ └── jsx-email.config.mjs │ ├── moon.yml │ └── package.json └── smoke │ ├── fixtures │ ├── components │ │ └── text.tsx │ ├── templates │ │ ├── base.jsx │ │ ├── code.tsx │ │ ├── context.tsx │ │ ├── default-export-props-fn.tsx │ │ ├── env.tsx │ │ ├── issue-174.tsx │ │ ├── local-assets.tsx │ │ ├── props │ │ │ ├── preview-props-fn.tsx │ │ │ ├── preview-props-named.tsx │ │ │ └── preview-props.tsx │ │ ├── static │ │ │ └── cat.jpeg │ │ └── tailwind.tsx │ └── tsconfig.json │ ├── moon.yml │ ├── package.json │ ├── playwright.config.ts │ ├── playwright.dev.ts │ └── tests │ ├── .snapshots │ ├── smoke.test.ts-Base-chromium.snap │ ├── smoke.test.ts-Code-chromium.snap │ ├── smoke.test.ts-Context-chromium.snap │ ├── smoke.test.ts-Default-Export-Props-Fn-chromium.snap │ ├── smoke.test.ts-Default-Export-chromium.snap │ ├── smoke.test.ts-Env-chromium.snap │ ├── smoke.test.ts-Issue-174-chromium.snap │ ├── smoke.test.ts-Local-Assets-chromium.snap │ ├── smoke.test.ts-Paths-chromium.snap │ ├── smoke.test.ts-Preview-Props-Fn-chromium.snap │ ├── smoke.test.ts-Preview-Props-Named-chromium.snap │ ├── smoke.test.ts-Preview-Props-chromium.snap │ ├── smoke.test.ts-Tailwind-chromium.snap │ ├── smoke.test.ts-landing-1-chromium.txt │ ├── smoke.test.ts-page-Paths-1-chromium.txt │ └── smoke.test.ts-watcher-chromium.snap │ ├── helpers │ └── html.ts │ └── smoke.test.ts └── tsconfig.json /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | indent_size = 2 8 | indent_style = space 9 | insert_final_newline = true 10 | trim_trailing_whitespace = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | 15 | [*.{yml,yaml}] 16 | indent_size = 2 17 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | # Note: We're ignoring this while we get the rest of the repo setup 2 | .snapshots 3 | dist 4 | node_modules 5 | 6 | # Starter template files 7 | packages/create-jsx-email/starter 8 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/DOCS.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 📚 Documentation 3 | about: Are the docs lacking or missing something? Do they need some new 🔥 hotness? Tell us here. 4 | --- 5 | 6 | 18 | 19 | - Component or Package Name: 20 | - Component or Package Version: 21 | 22 | Documentation Is: 23 | 24 | 25 | 26 | - [ ] Missing 27 | - [ ] Needed 28 | - [ ] Confusing 29 | - [ ] Not Sure? 30 | 31 | ### Please Explain in Detail... 32 | 33 | ### Your Proposal for Changes 34 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/FEATURE.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: ✨ Feature Request 3 | about: Suggest an idea for this project 4 | --- 5 | 6 | 18 | 19 | - Component or Package Name: 20 | - Component or Package Version: 21 | 22 | ### Feature Use Case 23 | 24 | ### Feature Proposal 25 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/MODIFICATION.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🔧 Modification Request 3 | about: Would you like something work differently? Have an alternative approach? This is the template for you. 4 | --- 5 | 6 | 18 | 19 | - Component or Package Name: 20 | - Component or Package Version: 21 | 22 | ### Expected Behavior / Situation 23 | 24 | ### Actual Behavior / Situation 25 | 26 | ### Modification Proposal 27 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/NEW_COMPONENT.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🔌 New Component 3 | about: Request a new Component or Tools 4 | --- 5 | 6 | 18 | 19 | Request Checklist: 20 | 21 | 25 | 26 | - [ ] I have searched https://npmjs.com/ before opening this issue 27 | - [ ] I have searched https://jsx.email/docs before opening this issue 28 | 29 | ### New Component/Tool Use Case 30 | 31 | 39 | 40 | ### New Component/Tool Proposal 41 | 42 | 47 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/SUPPORT.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🆘 Support, Help, and Advice 3 | about: 👉🏽 Need help or tech support? Please don't open an issue! Head to https://discord.gg/FywZN57mTg or start a Discussion https://github.com/shellscape/jsx-email/discussions 4 | --- 5 | 6 | Hey there! If you need help or tech support then this is not the place to 7 | ask. Please head to our [Discord](https://discord.gg/FywZN57mTg) 8 | instead or start a Discussion https://github.com/shellscape/jsx-email/discussions. 9 | 10 | If you arrived here because you think JSX email's documentation is unclear, 11 | insufficient or wrong, please consider creating an issue for the documentation 12 | instead. 13 | -------------------------------------------------------------------------------- /.github/actions/setup/action.yml: -------------------------------------------------------------------------------- 1 | name: Setup 2 | description: Sets up the CI environment 3 | 4 | runs: 5 | using: 'composite' 6 | steps: 7 | - uses: actions/checkout@v2 8 | with: 9 | fetch-depth: 0 10 | 11 | - name: Setup Moon 12 | uses: moonrepo/setup-toolchain@v0 13 | 14 | - name: Setup Node 15 | uses: actions/setup-node@v3 16 | with: 17 | node-version: 20 18 | 19 | - name: Install PNPM 20 | uses: pnpm/action-setup@v4 21 | 22 | - name: Sanity Check 23 | shell: bash 24 | run: | 25 | echo $'.\n.\n============\nSanity Check\n============\n' 26 | echo git `git version`; 27 | echo branch `git branch --show-current`; 28 | echo `moon --version` 29 | echo node `node -v`; 30 | echo pnpm `pnpm -v` 31 | echo $'============\n.\n.' 32 | 33 | - name: pnpm install 34 | shell: bash 35 | run: pnpm install --frozen-lockfile 36 | -------------------------------------------------------------------------------- /.github/workflows/pr-title.yml: -------------------------------------------------------------------------------- 1 | name: Pull Request Title Format 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - '*' 7 | types: 8 | - opened 9 | - reopened 10 | - edited 11 | - synchronize 12 | 13 | jobs: 14 | prTitle: 15 | name: Check 16 | runs-on: ubuntu-latest 17 | steps: 18 | - name: Check PR Title 19 | uses: clowdhaus/actions/pr-title@main 20 | with: 21 | on-fail-message: "Your PR title doesn't match the required format. The title should be in the conventional commit (https://www.conventionalcommits.org/en/v1.0.0-beta.4/) format. e.g.\n\n```\nchore: add pr title workflow\n```. Note that scopes should not contain spaces." 22 | title-regex: '^(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test)(\(([*]|[\w|,|\-|\|]+)\))?(!)?\:\s.*' 23 | github-token: ${{ secrets.GITHUB_TOKEN }} 24 | -------------------------------------------------------------------------------- /.github/workflows/test-cli.yml: -------------------------------------------------------------------------------- 1 | name: CLI Tests 2 | 3 | on: 4 | workflow_dispatch: 5 | pull_request: 6 | types: 7 | - edited 8 | - opened 9 | - synchronize 10 | push: 11 | branches: 12 | - '*' 13 | - '!main' 14 | 15 | jobs: 16 | validate: 17 | runs-on: ubuntu-latest 18 | name: CLI Tests 19 | 20 | steps: 21 | - name: Checkout Commit 22 | uses: actions/checkout@v4 23 | with: 24 | fetch-depth: 10 25 | 26 | - name: Checkout Main 27 | run: | 28 | git fetch origin 29 | git branch -f main origin/main 30 | 31 | - name: Setup 32 | uses: ./.github/actions/setup 33 | 34 | - name: Build Projects 35 | run: | 36 | moon jsx-email:build 37 | moon create-jsx-email:build 38 | moon run :build --query "project~plugin-*" 39 | 40 | - name: Run Tests 41 | # Note: We're running `pnpm i` again so that pnpm places the `email` bin in root node_modules 42 | # We'll need that for the preview tests below 43 | run: | 44 | pnpm i 45 | moon test-cli:test.run 46 | -------------------------------------------------------------------------------- /.github/workflows/test-smoke.yml: -------------------------------------------------------------------------------- 1 | name: Smoke Test 2 | 3 | on: 4 | workflow_dispatch: 5 | pull_request: 6 | types: 7 | - edited 8 | - opened 9 | - synchronize 10 | push: 11 | branches: 12 | - '*' 13 | - '!main' 14 | 15 | jobs: 16 | validate: 17 | runs-on: ubuntu-latest 18 | name: Smoke Test 19 | 20 | steps: 21 | - name: Checkout Commit 22 | uses: actions/checkout@v4 23 | with: 24 | fetch-depth: 10 25 | 26 | - name: Checkout Main 27 | run: | 28 | git fetch origin 29 | git branch -f main origin/main 30 | 31 | - name: Setup 32 | uses: ./.github/actions/setup 33 | 34 | - name: Build Projects 35 | run: | 36 | moon jsx-email:build 37 | moon create-jsx-email:build 38 | moon run :build --query "project~plugin-*" 39 | 40 | - name: Smoke Test 41 | # Note: We're running `pnpm i` again so that pnpm places the `email` bin in root node_modules 42 | # We'll need that for the preview tests below 43 | run: | 44 | pnpm i 45 | moon test-smoke:run.ci 46 | -------------------------------------------------------------------------------- /.github/workflows/test-v18.yml: -------------------------------------------------------------------------------- 1 | name: Run Tests (React v18) 2 | 3 | on: 4 | workflow_dispatch: 5 | pull_request: 6 | types: 7 | - edited 8 | - opened 9 | - synchronize 10 | push: 11 | branches: 12 | - '*' 13 | - '!main' 14 | 15 | jobs: 16 | validate: 17 | runs-on: ubuntu-latest 18 | name: Run Tests (React v18) 19 | 20 | steps: 21 | - name: Checkout Commit 22 | uses: actions/checkout@v4 23 | with: 24 | fetch-depth: 10 25 | 26 | - name: Checkout Main 27 | run: | 28 | git fetch origin 29 | git branch -f main origin/main 30 | 31 | - name: Setup 32 | uses: ./.github/actions/setup 33 | 34 | - name: Install React v18 35 | run: | 36 | cd packages/jsx-email 37 | pnpm add react@^18 react-dom@18 38 | cd ../create-jsx-email 39 | pnpm add react@^18 react-dom@18 40 | 41 | - name: Build Projects 42 | run: | 43 | moon jsx-email:build 44 | moon create-jsx-email:build 45 | moon run :build --query "project~plugin-*" 46 | 47 | - name: Package Tests 48 | env: 49 | FORCE_COLOR: 1 50 | run: moon run :test --affected --concurrency 1 --remote 51 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Run Tests 2 | 3 | on: 4 | workflow_dispatch: 5 | pull_request: 6 | types: 7 | - edited 8 | - opened 9 | - synchronize 10 | push: 11 | branches: 12 | - '*' 13 | - '!main' 14 | 15 | jobs: 16 | validate: 17 | runs-on: ubuntu-latest 18 | name: Run Tests 19 | 20 | steps: 21 | - name: Checkout Commit 22 | uses: actions/checkout@v4 23 | with: 24 | fetch-depth: 10 25 | 26 | - name: Checkout Main 27 | run: | 28 | git fetch origin 29 | git branch -f main origin/main 30 | 31 | - name: Setup 32 | uses: ./.github/actions/setup 33 | 34 | - name: Build Projects 35 | run: | 36 | moon jsx-email:build 37 | moon create-jsx-email:build 38 | moon run :build --query "project~plugin-*" 39 | 40 | - name: Package Tests 41 | env: 42 | FORCE_COLOR: 1 43 | run: moon run :test --affected --concurrency 1 --remote 44 | -------------------------------------------------------------------------------- /.github/workflows/validate.yml: -------------------------------------------------------------------------------- 1 | name: Validate Monorepo 2 | 3 | on: 4 | workflow_dispatch: 5 | pull_request: 6 | types: 7 | - edited 8 | - opened 9 | - synchronize 10 | push: 11 | branches: 12 | - '*' 13 | - '!main' 14 | 15 | jobs: 16 | validate: 17 | runs-on: ubuntu-latest 18 | name: Validate 19 | 20 | steps: 21 | - name: Checkout Commit 22 | uses: actions/checkout@v4 23 | with: 24 | fetch-depth: 10 25 | 26 | - name: Checkout Main 27 | run: | 28 | git fetch origin 29 | git branch -f main origin/main 30 | 31 | - name: Setup 32 | uses: ./.github/actions/setup 33 | 34 | - name: Build Projects 35 | run: | 36 | moon jsx-email:build 37 | moon create-jsx-email:build 38 | moon run :build --query "project~plugin-*" 39 | 40 | - name: Lint Monorepo 41 | run: moon run repo:lint 42 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | .moon/cache 4 | .eslintcache 5 | .compiled 6 | .rendered 7 | .test 8 | node_modules 9 | dist 10 | .DS_Store 11 | .pnpm-debug.log* 12 | .env 13 | .nojekyll 14 | **/.vitepress/cache 15 | .idea/ 16 | .tshy 17 | .tshy-build 18 | 19 | test-results 20 | playwright-report 21 | blob-report 22 | playwright/.cache/ 23 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | 4 | pnpm exec lint-staged 5 | -------------------------------------------------------------------------------- /.moon/tasks.yml: -------------------------------------------------------------------------------- 1 | # https://moonrepo.dev/docs/config/tasks 2 | $schema: 'https://moonrepo.dev/schemas/tasks.json' 3 | 4 | fileGroups: 5 | configs: 6 | - '*.{js,json}' 7 | sources: 8 | - 'src/**/*' 9 | tests: 10 | - 'tests/**/*.test.*' 11 | 12 | tasks: 13 | build: 14 | command: echo "Build Complete ✓" 15 | deps: 16 | - ~:clean.dist 17 | - ~:compile 18 | inputs: 19 | - src 20 | - package.json 21 | options: 22 | cache: false 23 | outputStyle: 'stream' 24 | runDepsInParallel: false 25 | outputs: 26 | - dist 27 | 28 | clean.dist: 29 | command: rm -rf dist 30 | inputs: 31 | - src 32 | - package.json 33 | 34 | compile: 35 | command: tshy 36 | inputs: 37 | - src 38 | - package.json 39 | options: 40 | runDepsInParallel: false 41 | 42 | release: 43 | command: versioner --target $projectRoot 44 | deps: 45 | - ~:build 46 | options: 47 | cache: false 48 | outputStyle: 'stream' 49 | runDepsInParallel: false 50 | -------------------------------------------------------------------------------- /.moon/workspace.yml: -------------------------------------------------------------------------------- 1 | # https://moonrepo.dev/docs/config/workspace 2 | $schema: 'https://moonrepo.dev/schemas/workspace.json' 3 | 4 | projects: 5 | globs: 6 | - 'apps/*' 7 | - 'packages/*' 8 | - 'test/cli' 9 | - 'test/smoke' 10 | sources: 11 | root: '.' 12 | vcs: 13 | manager: 'git' 14 | defaultBranch: 'main' 15 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | //registry.npmjs.org/:_authToken=${NPM_TOKEN} 2 | 3 | # npm options 4 | auth-type=legacy 5 | 6 | # pnpm options 7 | always-auth = true 8 | auto-install-peers = true 9 | enable-pre-post-scripts = true 10 | link-workspace-packages = false 11 | shamefully-hoist = true 12 | shared-workspace-lockfile = true 13 | strict-peer-dependencies = false 14 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | 18 2 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | // Note: This file is necessary so that prettier writes which happen in hooks and scripts match the 2 | // same config that we're using from the eslint-config package. 3 | module.exports = require('eslint-config-shellscape/prettier'); 4 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "prettier.singleQuote": true, 3 | "typescript.tsdk": "node_modules/typescript/lib", 4 | "css.customData": [".vscode/tailwind.json"] 5 | } 6 | -------------------------------------------------------------------------------- /.vscode/tailwind.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1.1, 3 | "atDirectives": [ 4 | { 5 | "name": "@tailwind", 6 | "description": "Use the @tailwind directive to insert Tailwind's `base`, `components`, `utilities`, and `screens` styles into your CSS." 7 | } 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright 2022 Bu Kinoshita and Zeno Rocha 2 | Copyright 2023 Andrew Powell 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ./packages/jsx-email/README.md -------------------------------------------------------------------------------- /apps/demo/README.md: -------------------------------------------------------------------------------- 1 | [](https://discord.gg/FywZN57mTg) 2 | [](https://liberamanifesto.com) 3 | 4 |
Sorry, an unexpected error has occurred.
13 |14 | {err.statusText || err.message} 15 |
16 |