├── .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 | [![Join our Discord](https://img.shields.io/badge/join_our-Discord-5a64ea)](https://discord.gg/FywZN57mTg) 2 | [![libera manifesto](https://img.shields.io/badge/libera-manifesto-lightgrey.svg)](https://liberamanifesto.com) 3 | 4 |
5 | JSX email

6 |
7 | 8 | # Demo App 9 | 10 |
11 | JSX email 12 | A project to demo and test the `email preview` CLI command 13 |
14 |
15 | 16 | The intent of this app is to provide a likely real-world scenario on which users might use `jsx-email` and its commands. Specifically the `preview` command, which starts a live-preview server. 17 | 18 | ## Requirements 19 | 20 | This package requires an [LTS](https://github.com/nodejs/Release) Node version (v18.0.0+) and React v18.2.0+. 21 | 22 | ## Testing 23 | 24 | To begin, you'll need to be setup to work within this repo. Please see _Getting Started_ in the [CONTRIBUTING.md](../../CONTRIBUTING.md) guide before continuing. 25 | 26 | To start the preview server locally, run: 27 | 28 | ```console 29 | $ moon run demo:dev 30 | ``` 31 | 32 | Open up the preview server [http://localhost:55420/](http://localhost:55420/) 33 | -------------------------------------------------------------------------------- /apps/demo/emails/static/airbnb-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/airbnb-logo.png -------------------------------------------------------------------------------- /apps/demo/emails/static/airbnb-review-user.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/airbnb-review-user.jpg -------------------------------------------------------------------------------- /apps/demo/emails/static/amazon-book.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/amazon-book.jpg -------------------------------------------------------------------------------- /apps/demo/emails/static/amazon-facebook.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/amazon-facebook.jpg -------------------------------------------------------------------------------- /apps/demo/emails/static/amazon-instagram.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/amazon-instagram.jpg -------------------------------------------------------------------------------- /apps/demo/emails/static/amazon-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/amazon-logo.png -------------------------------------------------------------------------------- /apps/demo/emails/static/amazon-prime-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/amazon-prime-logo.png -------------------------------------------------------------------------------- /apps/demo/emails/static/amazon-rating.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/amazon-rating.gif -------------------------------------------------------------------------------- /apps/demo/emails/static/amazon-twitter.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/amazon-twitter.jpg -------------------------------------------------------------------------------- /apps/demo/emails/static/apple-card-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/apple-card-icon.png -------------------------------------------------------------------------------- /apps/demo/emails/static/apple-hbo-max-icon.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/apple-hbo-max-icon.jpeg -------------------------------------------------------------------------------- /apps/demo/emails/static/apple-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/apple-logo.png -------------------------------------------------------------------------------- /apps/demo/emails/static/apple-wallet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/apple-wallet.png -------------------------------------------------------------------------------- /apps/demo/emails/static/batman-twilight.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/batman-twilight.jpg -------------------------------------------------------------------------------- /apps/demo/emails/static/cat.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/cat.jpeg -------------------------------------------------------------------------------- /apps/demo/emails/static/codepen-challengers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/codepen-challengers.png -------------------------------------------------------------------------------- /apps/demo/emails/static/codepen-cube.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/codepen-cube.png -------------------------------------------------------------------------------- /apps/demo/emails/static/codepen-pro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/codepen-pro.png -------------------------------------------------------------------------------- /apps/demo/emails/static/dropbox-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/dropbox-logo.png -------------------------------------------------------------------------------- /apps/demo/emails/static/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/github.png -------------------------------------------------------------------------------- /apps/demo/emails/static/google-play-academy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/google-play-academy.png -------------------------------------------------------------------------------- /apps/demo/emails/static/google-play-chat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/google-play-chat.png -------------------------------------------------------------------------------- /apps/demo/emails/static/google-play-footer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/google-play-footer.png -------------------------------------------------------------------------------- /apps/demo/emails/static/google-play-header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/google-play-header.png -------------------------------------------------------------------------------- /apps/demo/emails/static/google-play-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/google-play-icon.png -------------------------------------------------------------------------------- /apps/demo/emails/static/google-play-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/google-play-logo.png -------------------------------------------------------------------------------- /apps/demo/emails/static/google-play-pl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/google-play-pl.png -------------------------------------------------------------------------------- /apps/demo/emails/static/google-play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/google-play.png -------------------------------------------------------------------------------- /apps/demo/emails/static/koala-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/koala-logo.png -------------------------------------------------------------------------------- /apps/demo/emails/static/linear-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/linear-logo.png -------------------------------------------------------------------------------- /apps/demo/emails/static/netlify-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/netlify-logo.png -------------------------------------------------------------------------------- /apps/demo/emails/static/nike-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/nike-logo.png -------------------------------------------------------------------------------- /apps/demo/emails/static/nike-phone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/nike-phone.png -------------------------------------------------------------------------------- /apps/demo/emails/static/nike-product.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/nike-product.png -------------------------------------------------------------------------------- /apps/demo/emails/static/nike-recomendation-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/nike-recomendation-1.png -------------------------------------------------------------------------------- /apps/demo/emails/static/nike-recomendation-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/nike-recomendation-2.png -------------------------------------------------------------------------------- /apps/demo/emails/static/nike-recomendation-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/nike-recomendation-3.png -------------------------------------------------------------------------------- /apps/demo/emails/static/nike-recomendation-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/nike-recomendation-4.png -------------------------------------------------------------------------------- /apps/demo/emails/static/notion-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/notion-logo.png -------------------------------------------------------------------------------- /apps/demo/emails/static/plaid-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/plaid-logo.png -------------------------------------------------------------------------------- /apps/demo/emails/static/raycast-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/raycast-bg.png -------------------------------------------------------------------------------- /apps/demo/emails/static/raycast-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/raycast-logo.png -------------------------------------------------------------------------------- /apps/demo/emails/static/slack-facebook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/slack-facebook.png -------------------------------------------------------------------------------- /apps/demo/emails/static/slack-linkedin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/slack-linkedin.png -------------------------------------------------------------------------------- /apps/demo/emails/static/slack-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/slack-logo.png -------------------------------------------------------------------------------- /apps/demo/emails/static/slack-twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/slack-twitter.png -------------------------------------------------------------------------------- /apps/demo/emails/static/stack-overflow-header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/stack-overflow-header.png -------------------------------------------------------------------------------- /apps/demo/emails/static/stack-overflow-logo-sm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/stack-overflow-logo-sm.png -------------------------------------------------------------------------------- /apps/demo/emails/static/stack-overflow-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/stack-overflow-logo.png -------------------------------------------------------------------------------- /apps/demo/emails/static/stripe-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/stripe-logo.png -------------------------------------------------------------------------------- /apps/demo/emails/static/twitch-icon-facebook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/twitch-icon-facebook.png -------------------------------------------------------------------------------- /apps/demo/emails/static/twitch-icon-twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/twitch-icon-twitter.png -------------------------------------------------------------------------------- /apps/demo/emails/static/twitch-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/twitch-logo.png -------------------------------------------------------------------------------- /apps/demo/emails/static/vercel-arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/vercel-arrow.png -------------------------------------------------------------------------------- /apps/demo/emails/static/vercel-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/vercel-logo.png -------------------------------------------------------------------------------- /apps/demo/emails/static/vercel-team.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/vercel-team.png -------------------------------------------------------------------------------- /apps/demo/emails/static/vercel-user.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/vercel-user.png -------------------------------------------------------------------------------- /apps/demo/emails/static/yelp-footer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/yelp-footer.png -------------------------------------------------------------------------------- /apps/demo/emails/static/yelp-header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/yelp-header.png -------------------------------------------------------------------------------- /apps/demo/emails/static/yelp-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/demo/emails/static/yelp-logo.png -------------------------------------------------------------------------------- /apps/demo/moon.yml: -------------------------------------------------------------------------------- 1 | # https://moonrepo.dev/docs/config/tasks 2 | $schema: 'https://moonrepo.dev/schemas/tasks.json' 3 | 4 | workspace: 5 | inheritedTasks: 6 | exclude: ['build', 'compile', 'release', 'test'] 7 | 8 | tasks: 9 | dev: 10 | command: email preview emails 11 | options: 12 | cache: false 13 | -------------------------------------------------------------------------------- /apps/demo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app-demo", 3 | "version": "0.0.0", 4 | "private": true, 5 | "description": "A project to demo and test the `email preview` CLI command", 6 | "license": "MIT", 7 | "peerDependencies": { 8 | "react": "^18.2.0 || ^19" 9 | }, 10 | "dependencies": { 11 | "jsx-email": "workspace:*" 12 | }, 13 | "devDependencies": { 14 | "@types/node": "20.10.5" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /apps/demo/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../shared/tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "ESNext", 5 | "types": ["vite/client", "@types/node"] 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /apps/preview/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | rules: { 3 | 'import/extensions': 'off', 4 | 'import/no-extraneous-dependencies': 'off' 5 | } 6 | }; 7 | -------------------------------------------------------------------------------- /apps/preview/README.md: -------------------------------------------------------------------------------- 1 | # app-preview 2 | 3 | This package contains the components and vite app which power the [`jsx-email`](https://github.com/shellscape/jsx-email) preview app. It is copied to the distribution directory before publishing. 4 | -------------------------------------------------------------------------------- /apps/preview/app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 10 | jsx-email 11 | 12 | 13 |
14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /apps/preview/app/postcss.config.cjs: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | module.exports = { 3 | plugins: { 4 | tailwindcss: {}, 5 | autoprefixer: {} 6 | } 7 | }; 8 | -------------------------------------------------------------------------------- /apps/preview/app/src/app.ts: -------------------------------------------------------------------------------- 1 | export const setup = () => { 2 | // Note: Disables annoying key errors. We're static so we don't need to worry about this. 3 | /* eslint-disable no-console */ 4 | const og = console.error; 5 | const re = 6 | /^Warning: Each child in an array or iterator should have a unique "key" prop|^Warning: Each child in a list should have a unique "key" prop/; 7 | console.error = (...args) => { 8 | const [line] = args; 9 | if (!re.test(line)) og(...args); 10 | }; 11 | }; 12 | -------------------------------------------------------------------------------- /apps/preview/app/src/components/nav-button.tsx: -------------------------------------------------------------------------------- 1 | import * as ToggleGroup from '@radix-ui/react-toggle-group'; 2 | import classnames from 'classnames'; 3 | import { motion } from 'framer-motion'; 4 | 5 | import type { Views } from '../types.js'; 6 | 7 | const button = 'text-sm font-medium px-3 py-2 transition ease-in-out duration-200 relative'; 8 | const motionSpan = 'absolute left-0 right-0 top-0 bottom-0 bg-cta-bg'; 9 | const span = 'capitalize relative'; 10 | 11 | interface NavButtonProps extends React.ComponentPropsWithoutRef<'header'> { 12 | activeView?: Views; 13 | addClassNames?: string; 14 | label: string; 15 | } 16 | 17 | const variants = { 18 | active: { opacity: 1 }, 19 | inactive: { opacity: 0 } 20 | }; 21 | 22 | export const NavButton = ({ activeView, addClassNames, label }: NavButtonProps) => ( 23 | 24 | 25 | 33 | {label} 34 | 35 | 36 | ); 37 | 38 | NavButton.displayName = 'NavButton'; 39 | -------------------------------------------------------------------------------- /apps/preview/app/src/config.ts: -------------------------------------------------------------------------------- 1 | interface AppConfig { 2 | buildPath: string; 3 | relativePath: string; 4 | } 5 | 6 | export const config: AppConfig = { 7 | buildPath: import.meta.env.VITE_JSXEMAIL_BUILD_PATH, 8 | relativePath: import.meta.env.VITE_JSXEMAIL_RELATIVE_PATH 9 | }; 10 | -------------------------------------------------------------------------------- /apps/preview/app/src/error.tsx: -------------------------------------------------------------------------------- 1 | import { useRouteError } from 'react-router-dom'; 2 | 3 | const { error } = console; 4 | 5 | export const Error = () => { 6 | const err: any = useRouteError(); 7 | error(err); 8 | 9 | return ( 10 |
11 |

Oops!

12 |

Sorry, an unexpected error has occurred.

13 |

14 | {err.statusText || err.message} 15 |

16 |
17 | ); 18 | }; 19 | -------------------------------------------------------------------------------- /apps/preview/app/src/helpers.ts: -------------------------------------------------------------------------------- 1 | import titleize from 'titleize'; 2 | 3 | export const addSpacesForCamelCaseName = (str: string) => str.replace(/([a-z])([A-Z])/g, '$1 $2'); 4 | 5 | export const parseName = (path: string) => { 6 | const chunks = path.replace('\\', '/').split('/'); 7 | const segment = chunks.at(-1); 8 | const [basename] = segment!.split(/\.[^.]+$/); 9 | 10 | return titleize(addSpacesForCamelCaseName(basename)); 11 | }; 12 | 13 | export const { warn } = console; 14 | -------------------------------------------------------------------------------- /apps/preview/app/src/main.tsx: -------------------------------------------------------------------------------- 1 | import { StrictMode } from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import { RouterProvider } from 'react-router-dom'; 4 | 5 | import './index.css'; 6 | import { setup } from './app'; 7 | import { getRouter } from './routes'; 8 | import { gather } from './templates'; 9 | 10 | setup(); 11 | 12 | // if (import.meta.hot) { 13 | // import.meta.hot.accept((mod) => { 14 | // console.log(mod); 15 | // }); 16 | // } 17 | 18 | const router = getRouter(await gather()); 19 | const rootElement = document.getElementById('root'); 20 | const root = ReactDOM.createRoot(rootElement); 21 | 22 | root.render( 23 | 24 | 25 | 26 | ); 27 | -------------------------------------------------------------------------------- /apps/preview/app/src/types.ts: -------------------------------------------------------------------------------- 1 | // Note: This should match the same declaration in jsx-email/src/cli/preview.mts 2 | export interface PreviewImportContent { 3 | html: string; 4 | plain: string; 5 | source: string; 6 | sourceFile: string; 7 | templateName: string; 8 | } 9 | 10 | export enum Views { 11 | Desktop = 'desktop', 12 | Html = 'html', 13 | Jsx = 'jsx', 14 | Mobile = 'mobile', 15 | Plain = 'plain' 16 | } 17 | 18 | export interface TemplateData { 19 | html: string; 20 | path?: string; 21 | plain: string; 22 | source: string; 23 | templateName: string; 24 | } 25 | 26 | export interface TemplatePart { 27 | children?: TemplatePart[]; 28 | name: string; 29 | path?: string; 30 | template?: TemplateData; 31 | } 32 | -------------------------------------------------------------------------------- /apps/preview/moon.yml: -------------------------------------------------------------------------------- 1 | # https://moonrepo.dev/docs/config/tasks 2 | $schema: 'https://moonrepo.dev/schemas/tasks.json' 3 | 4 | workspace: 5 | inheritedTasks: 6 | exclude: ['build', 'compile', 'release', 'test'] 7 | -------------------------------------------------------------------------------- /apps/preview/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app-preview", 3 | "version": "3.0.0", 4 | "private": true, 5 | "description": "The preview app source for jsx-email", 6 | "type": "module", 7 | "devDependencies": { 8 | "@radix-ui/colors": "3.0.0", 9 | "@radix-ui/react-collapsible": "1.1.1", 10 | "@radix-ui/react-icons": "^1.3.0", 11 | "@radix-ui/react-popover": "1.1.2", 12 | "@radix-ui/react-select": "^2.0.0", 13 | "@radix-ui/react-slot": "1.1.0", 14 | "@radix-ui/react-toggle-group": "1.1.0", 15 | "autoprefixer": "^10.4.16", 16 | "classnames": "2.5.1", 17 | "framer-motion": "11.12.0", 18 | "postcss": "^8.4.32", 19 | "react": "^19", 20 | "react-dom": "^19", 21 | "react-router-dom": "7.5.2", 22 | "shiki": "^1.18.0", 23 | "tailwindcss": "3.4.15", 24 | "titleize": "^4.0.0", 25 | "vite": "^5.2.11" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /apps/preview/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowImportingTsExtensions": true, 4 | "allowSyntheticDefaultImports": true, 5 | "composite": false, 6 | "jsx": "react-jsx", 7 | "module": "ESNext", 8 | "moduleResolution": "bundler", 9 | "noEmit": true, 10 | "skipLibCheck": true, 11 | "target": "ESNext", 12 | "types": ["vite/client"] 13 | }, 14 | "include": ["app", "src", "src/devices.json"] 15 | } 16 | -------------------------------------------------------------------------------- /apps/web/.vitepress/theme/index.ts: -------------------------------------------------------------------------------- 1 | import DefaultTheme from 'vitepress/theme'; 2 | import './custom.css'; 3 | 4 | export default DefaultTheme; -------------------------------------------------------------------------------- /apps/web/moon.yml: -------------------------------------------------------------------------------- 1 | # https://moonrepo.dev/docs/config/tasks 2 | $schema: 'https://moonrepo.dev/schemas/tasks.json' 3 | 4 | workspace: 5 | inheritedTasks: 6 | exclude: ['build', 'compile', 'release', 'test'] 7 | 8 | tasks: 9 | build: 10 | command: vitepress build 11 | inputs: 12 | - .vitepress 13 | - markdown 14 | - package.json 15 | options: 16 | cache: false 17 | 18 | cname: 19 | command: mkdir -p dist && echo jsx.email > dist/CNAME && touch dist/.nojekyll 20 | options: 21 | cache: false 22 | 23 | dev: 24 | command: vitepress dev 25 | options: 26 | cache: false 27 | 28 | preview: 29 | command: vitepress preview 30 | options: 31 | cache: false 32 | 33 | publish: 34 | command: gh-pages -d dist -u "Release Workflow " 35 | deps: 36 | - build 37 | - cname 38 | options: 39 | cache: false 40 | outputStyle: 'stream' 41 | runDepsInParallel: false 42 | -------------------------------------------------------------------------------- /apps/web/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app-web", 3 | "version": "0.0.0", 4 | "private": true, 5 | "description": "jsx.email", 6 | "license": "MIT", 7 | "engines": { 8 | "node": ">=18.0.0" 9 | }, 10 | "devDependencies": { 11 | "@octokit/rest": "^20.0.2", 12 | "globby": "11.0.4", 13 | "titleize": "^4.0.0", 14 | "vitepress": "1.0.0-rc.20", 15 | "vue": "3.3.4" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /apps/web/src/api/contributions.data.ts: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line import/no-extraneous-dependencies 2 | import { Octokit } from '@octokit/rest'; 3 | 4 | // eslint-disable-next-line import/no-default-export 5 | export default { 6 | async load() { 7 | const octokit = new Octokit(); 8 | 9 | const { data: releases } = await octokit.rest.pulls.list({ 10 | owner: 'shellscape', 11 | per_page: 100, 12 | repo: 'jsx-email', 13 | state: 'closed' 14 | }); 15 | 16 | return releases; 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /apps/web/src/docs: -------------------------------------------------------------------------------- 1 | ../../../docs -------------------------------------------------------------------------------- /apps/web/src/include/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ../../../../CONTRIBUTING.md -------------------------------------------------------------------------------- /apps/web/src/include/README.md: -------------------------------------------------------------------------------- 1 | ../../../../README.md -------------------------------------------------------------------------------- /apps/web/src/include/header.md: -------------------------------------------------------------------------------- 1 | ## {{ $frontmatter.title }} 2 | 3 | {{ $frontmatter.description }} -------------------------------------------------------------------------------- /apps/web/src/include/install.md: -------------------------------------------------------------------------------- 1 | ## Install 2 | 3 | Install the {{ $frontmatter.type }} from your command line 4 | 5 | ::: code-group 6 | 7 | ```console-vue [pnpm] 8 | pnpm add jsx-email 9 | ``` 10 | 11 | ```console-vue [bun] 12 | bun add jsx-email 13 | ``` 14 | 15 | ```console-vue [npm] 16 | npm add jsx-email 17 | ``` 18 | 19 | ```console-vue [yarn] 20 | yarn add jsx-email 21 | ``` 22 | 23 | ::: -------------------------------------------------------------------------------- /apps/web/src/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | # https://vitepress.dev/reference/default-theme-home-page 3 | layout: home 4 | title: Build Emails with a Delightful DX 5 | 6 | hero: 7 | text: | 8 | Build emails with a delightful Developer Experience 9 | 10 | tagline: Develop standards compliant emails with JSX or TSX — compatible with the most popular email clients 11 | actions: 12 | - theme: brand 13 | text: Quick Start 14 | link: /docs/quick-start 15 | - theme: alt 16 | text: View on Github 17 | link: https://github.com/shellscape/jsx-email 18 | --- 19 | -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/airbnb-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/airbnb-logo.png -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/apple-card-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/apple-card-icon.png -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/apple-hbo-max-icon.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/apple-hbo-max-icon.jpeg -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/apple-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/apple-logo.png -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/apple-wallet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/apple-wallet.png -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/batman-adam.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/batman-adam.jpg -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/batman-cartoon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/batman-cartoon.jpg -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/batman-lego.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/batman-lego.webp -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/batman-twilight.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/batman-twilight.jpg -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/codepen-challengers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/codepen-challengers.png -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/codepen-cube.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/codepen-cube.png -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/codepen-pro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/codepen-pro.png -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/dropbox-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/dropbox-logo.png -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/github.png -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/google-play-academy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/google-play-academy.png -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/google-play-chat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/google-play-chat.png -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/google-play-footer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/google-play-footer.png -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/google-play-header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/google-play-header.png -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/google-play-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/google-play-icon.png -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/google-play-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/google-play-logo.png -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/koala-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/koala-logo.png -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/linear-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/linear-logo.png -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/netlify-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/netlify-logo.png -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/nike-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/nike-logo.png -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/nike-phone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/nike-phone.png -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/nike-product.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/nike-product.png -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/nike-recomendation-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/nike-recomendation-1.png -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/nike-recomendation-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/nike-recomendation-2.png -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/nike-recomendation-4 (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/nike-recomendation-4 (1).png -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/nike-recomendation-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/nike-recomendation-4.png -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/notion-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/notion-logo.png -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/plaid-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/plaid-logo.png -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/raycast-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/raycast-logo.png -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/slack-facebook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/slack-facebook.png -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/slack-linkedin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/slack-linkedin.png -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/slack-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/slack-logo.png -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/slack-twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/slack-twitter.png -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/stack-overflow-header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/stack-overflow-header.png -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/stack-overflow-logo-sm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/stack-overflow-logo-sm.png -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/stack-overflow-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/stack-overflow-logo.png -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/stripe-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/stripe-logo.png -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/twitch-icon-facebook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/twitch-icon-facebook.png -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/twitch-icon-twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/twitch-icon-twitter.png -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/twitch-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/twitch-logo.png -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/vercel-arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/vercel-arrow.png -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/vercel-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/vercel-logo.png -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/vercel-team.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/vercel-team.png -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/yelp-footer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/yelp-footer.png -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/yelp-header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/yelp-header.png -------------------------------------------------------------------------------- /apps/web/src/public/assets/demo/yelp-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/assets/demo/yelp-logo.png -------------------------------------------------------------------------------- /apps/web/src/public/home-hero.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/home-hero.png -------------------------------------------------------------------------------- /apps/web/src/public/og.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/og.png -------------------------------------------------------------------------------- /apps/web/src/public/preview-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/preview-1.png -------------------------------------------------------------------------------- /apps/web/src/public/preview-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/preview-2.png -------------------------------------------------------------------------------- /apps/web/src/public/preview-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/preview-3.png -------------------------------------------------------------------------------- /apps/web/src/public/preview-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shellscape/jsx-email/36e0bbead81c0fa35cee0888183a7ec5880ca394/apps/web/src/public/preview-4.png -------------------------------------------------------------------------------- /apps/web/src/public/test/index.html: -------------------------------------------------------------------------------- 1 | 2 | hello 3 | -------------------------------------------------------------------------------- /assets/brackets.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /docs/components/body.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Body' 3 | description: 'A JSX email component for using a React `Body` component to wrap email content' 4 | slug: body 5 | type: component 6 | --- 7 | 8 | 9 | 10 | 11 | 12 | ## Usage 13 | 14 | Add the component to your email template. Include styles where needed. 15 | 16 | ```jsx 17 | import { Body, Column, Html, Section } from 'jsx-email'; 18 | 19 | const Email = () => { 20 | return ( 21 | 22 | 23 |
24 | {/* First column */} 25 | {/* Second column */} 26 |
27 | 28 | 29 | ); 30 | }; 31 | ``` 32 | 33 | ## Component Props 34 | 35 | This component has no custom props, but expresses all of the [Common Component Props](https://react.dev/reference/react-dom/components/common) for `ComponentProps<'body'>`. 36 | -------------------------------------------------------------------------------- /docs/components/butan.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Butan' 3 | description: Deprecated. The v1 Button component. Please upgrade to the new Button component. 4 | slug: butan 5 | type: component 6 | --- 7 | 8 | 9 | 10 | ::: warning 11 | This component is DEPRECATED and serves as a fallback for folks still wanting to use the v1 Button component. Please upgrade your templates to use the v2 Button. `Butan` will be removed in a future release. 12 | ::: 13 | 14 | ::: tip 15 | Semantics: Quite often in the email world we talk about buttons when we actually mean links. Behind the scenes this component is a `` element which is styled like a ` 25 | 26 | ); 27 | }; 28 | ``` 29 | 30 | ::: info 31 | Though the `Container` component wraps a `` element, it has a specific use-case and does not support setting `cellPadding` or `cellSpacing`. If attempting to use `Container` as a table, please consider using a `Section` component or a combination of `Row` and `Column`. 32 | ::: 33 | 34 | ## Component Props 35 | 36 | ```ts 37 | disableDefaultStyle?: boolean; 38 | ``` 39 | 40 | If `true`, instructs the component _not to add_ default `style` properties to the component. This can be useful when attempting to override default styles with `Tailwind` or class names. 41 | 42 | ::: tip 43 | This component also expresses all of the [Common Component Props](https://react.dev/reference/react-dom/components/common) for `ComponentProps<'table'>` except for `cellPadding` and `cellSpacing`. 44 | ::: 45 | -------------------------------------------------------------------------------- /docs/components/head.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Head' 3 | description: | 4 | A JSX email component which creates an HTML head element 5 | slug: head 6 | type: component 7 | --- 8 | 9 | 10 | 11 | ::: tip 12 | This component is required VML in outlook compatibility for adding elements such as `" 17 | `; 18 | -------------------------------------------------------------------------------- /packages/jsx-email/test/.snapshots/graph.test.tsx.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 | 3 | exports[`
component > renders correctly 1`] = `"\\"Basic"`; 4 | -------------------------------------------------------------------------------- /packages/jsx-email/test/.snapshots/heading.test.tsx.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 | 3 | exports[`render > renders the component 1`] = `"

Lorem ipsum

"`; 4 | -------------------------------------------------------------------------------- /packages/jsx-email/test/.snapshots/hr.test.tsx.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 | 3 | exports[`
component > disables the default styles 1`] = `"
"`; 4 | 5 | exports[`
component > renders correctly 1`] = `"
"`; 6 | -------------------------------------------------------------------------------- /packages/jsx-email/test/.snapshots/html.test.tsx.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 | 3 | exports[` component > renders correctly 1`] = `""`; 4 | -------------------------------------------------------------------------------- /packages/jsx-email/test/.snapshots/img.test.tsx.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 | 3 | exports[` component > renders correctly 1`] = `"\\"Cat\\""`; 4 | -------------------------------------------------------------------------------- /packages/jsx-email/test/.snapshots/link.test.tsx.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 | 3 | exports[` component > renders correctly 1`] = `"Example"`; 4 | -------------------------------------------------------------------------------- /packages/jsx-email/test/.snapshots/raw.test.tsx.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 | 3 | exports[` component > Should preserve content on plainText render 1`] = `"<#if firstname & lastname>Ola!"`; 4 | 5 | exports[` component > Should render without escaping 1`] = `"<#if firstname & lastname>Ola!"`; 6 | 7 | exports[` component > Should work correctly with a comment as a content 1`] = `"Ola!"`; 8 | 9 | exports[` component > disablePlainTextOutput > Should not output to the plain text when enabled 1`] = `"Ola!"`; 10 | 11 | exports[` component > disablePlainTextOutput > Should output to html when enabled 1`] = `"Ola!"`; 12 | -------------------------------------------------------------------------------- /packages/jsx-email/test/.snapshots/row.test.tsx.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 | 3 | exports[` component > doesn't override cellPadding and cellSpacing 1`] = `"
"`; 4 | 5 | exports[` component > renders correctly 1`] = `"
"`; 6 | -------------------------------------------------------------------------------- /packages/jsx-email/test/.snapshots/section.test.tsx.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 | 3 | exports[`
component > doesn't override cellPadding and cellSpacing 1`] = `"
Lorem ipsum
"`; 4 | 5 | exports[`
component > renders correctly 1`] = `"
Lorem ipsum
"`; 6 | -------------------------------------------------------------------------------- /packages/jsx-email/test/.snapshots/text.test.tsx.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 | 3 | exports[` component > disables the default styles 1`] = `"

Test message

"`; 4 | 5 | exports[` component > renders correctly 1`] = `"

Lorem ipsum

"`; 6 | -------------------------------------------------------------------------------- /packages/jsx-email/test/background.test.tsx: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | import React from 'react'; 3 | 4 | import { jsxToString } from '../src/renderer/jsx-to-string.js'; 5 | import { Background } from '../src/index.js'; 6 | 7 | describe('
component', () => { 8 | beforeEach(() => { 9 | vi.restoreAllMocks(); 10 | vi.resetModules(); 11 | }); 12 | 13 | it('passes styles and other props correctly', async () => { 14 | const html = await jsxToString( 15 | 16 | Hello World 17 | 18 | ); 19 | expect(html).toContain('width="600"'); 20 | expect(html).toContain('height="400"'); 21 | expect(html).toContain('height="400"'); 22 | }); 23 | 24 | it('renders VML elements conditionally', async () => { 25 | const html = await jsxToString( 26 | 27 | Hello World 28 | 29 | ); 30 | expect(html).toContain('Test message" 11 | `; 12 | -------------------------------------------------------------------------------- /packages/jsx-email/test/render/.snapshots/suspense.test.tsx.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 | 3 | exports[`render > processes an async component 1`] = `"
donezo

Welcome, Jim!

\\"test\\"/

Thanks for trying our product. We're thrilled to have you on board!

"`; 4 | 5 | exports[`render > renders an async component 1`] = `"
donezo

Welcome, Jim!

\\"test\\"

Thanks for trying our product. We're thrilled to have you on board!

"`; 6 | -------------------------------------------------------------------------------- /packages/jsx-email/test/render/compat/.snapshots/context.test.tsx.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 | 3 | exports[`context > renders the Consumer 1`] = `"123"`; 4 | 5 | exports[`context > renders the Provider 1`] = `""`; 6 | -------------------------------------------------------------------------------- /packages/jsx-email/test/render/fixtures/async-template.tsx: -------------------------------------------------------------------------------- 1 | import React, { Suspense } from 'react'; 2 | 3 | import { useData } from '../../../src/renderer/suspense.js'; 4 | 5 | interface TemplateProps { 6 | firstName: string; 7 | } 8 | 9 | const Async = (props: any) => { 10 | const res = useData( 11 | props, 12 | () => 13 | new Promise((resolve) => { 14 | setTimeout(() => { 15 | resolve('donezo'); 16 | }, 2000); 17 | }) 18 | ); 19 | 20 | return
{res}
; 21 | }; 22 | 23 | export const Template: React.FC> = ({ firstName }) => ( 24 | <> 25 | waiting
}> 26 | 27 | 28 | 29 |

Welcome, {firstName}!

30 | test 31 |

Thanks for trying our product. We're thrilled to have you on board!

32 | 33 | ); 34 | -------------------------------------------------------------------------------- /packages/jsx-email/test/render/fixtures/components.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import { Link } from '../../../dist/esm'; 4 | 5 | export const Template: React.FC = () => ( 6 | <> 7 | 8 | 9 | ); 10 | -------------------------------------------------------------------------------- /packages/jsx-email/test/render/fixtures/import-css.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: #000; 3 | } 4 | -------------------------------------------------------------------------------- /packages/jsx-email/test/render/fixtures/import-css.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import css from './import-css.css'; 4 | 5 | export const Template: React.FC = () => ( 6 | <> 7 | 8 | 9 | ); 10 | -------------------------------------------------------------------------------- /packages/jsx-email/test/render/fixtures/preview.tsx: -------------------------------------------------------------------------------- 1 | interface PreviewProps {} 2 | 3 | export const Template: React.FC> = () => ( 4 | <> 5 |
This should be hidden from plain text
6 | ` 9 | }} 10 | /> 11 |

This should be rendered in plain text

12 | 13 | 14 | 15 | 16 | ); 17 | -------------------------------------------------------------------------------- /packages/jsx-email/test/render/fixtures/template.tsx: -------------------------------------------------------------------------------- 1 | interface TemplateProps { 2 | firstName: string; 3 | } 4 | 5 | export const Template: React.FC> = ({ firstName }) => ( 6 | <> 7 |

Welcome, {firstName}!

8 | test 9 |

Thanks for trying our product. We're thrilled to have you on board!

10 | 11 | ); 12 | -------------------------------------------------------------------------------- /packages/jsx-email/test/render/import-css.test.tsx: -------------------------------------------------------------------------------- 1 | import { join, resolve } from 'node:path'; 2 | 3 | // @ts-ignore 4 | import React from 'react'; 5 | 6 | import { compile } from '../../src/renderer/compile.js'; 7 | import { render } from '../../src/renderer/render.js'; 8 | 9 | describe('import css', () => { 10 | it('simple', async () => { 11 | const filePath = resolve(__dirname, './fixtures/import-css.js'); 12 | const outDir = resolve(__dirname, '.compiled'); 13 | 14 | await compile({ files: [filePath], hashFiles: false, outDir }); 15 | 16 | const { Template } = await import(join(outDir, 'import-css.js')); 17 | 18 | expect(await render(