diff --git a/apps/web/.gitignore b/apps/web/.gitignore new file mode 100644 index 000000000..6240da8b1 --- /dev/null +++ b/apps/web/.gitignore @@ -0,0 +1,21 @@ +# build output +dist/ +# generated types +.astro/ + +# dependencies +node_modules/ + +# logs +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* + + +# environment variables +.env +.env.production + +# macOS-specific files +.DS_Store diff --git a/apps/web/.vitepress/config.mts b/apps/web/.vitepress/config.mts deleted file mode 100644 index e6be6801c..000000000 --- a/apps/web/.vitepress/config.mts +++ /dev/null @@ -1,77 +0,0 @@ -import { defineConfig } from 'vitepress'; - -import { sidebar } from './sidebar.mjs'; - -// TODO: make a vitepress plugins for pnpm, yarn, npm, etc based on -// https://github.com/vuejs/vitepress/blob/6edc588e5c1f01f50c1e158c705e04c1745db1e0/src/node/markdown/plugins/containers.ts#L56 - -// https://vitepress.dev/reference/site-config -export default defineConfig({ - appearance: 'force-dark', - base: '/', - cleanUrls: true, - description: 'Build emails with a delightful DX', - head: [ - [ - 'link', - { - rel: 'shortcut icon', - href: `data:image/svg+xml;charset=UTF-8,%3csvg width='126' height='113' viewBox='0 0 126 113' fill='none' xmlns='http://www.w3.org/2000/svg'%3e%3cpath fill-rule='evenodd' clip-rule='evenodd' d='M0.199951 50V109V113H4.19995H121.8H125.8V109V50H117.8V105H8.19995V50H0.199951Z' fill='%2364595C'/%3e%3cpath d='M0 53.429V47.4258L48.3069 22.8124V32.4176L11.2516 50.2773L11.5517 49.677V51.1778L11.2516 50.5775L48.3069 68.4372V78.0424L0 53.429Z' fill='%2364595C'/%3e%3cpath d='M79.4367 0L54.6832 92H46.582L71.3356 0H79.4367Z' fill='%2364595C'/%3e%3cpath d='M126 53.429L77.6931 78.0424V68.4372L114.748 50.5775L114.448 51.1778V49.677L114.748 50.2773L77.6931 32.4176V22.8124L126 47.4258V53.429Z' fill='%2364595C'/%3e%3c/svg%3e ` - } - ] - ], - ignoreDeadLinks: true, - markdown: { - theme: { - dark: 'slack-dark', - light: 'slack-ochin' - } - }, - outDir: './dist', - srcDir: 'src', - themeConfig: { - docFooter: { - prev: false, - next: false - }, - logo: '/logo.svg', - // https://vitepress.dev/reference/default-theme-config - nav: [ - { text: 'Documentation', link: '/docs/introduction' }, - { text: 'Quick Start', link: '/docs/quick-start' }, - { text: 'Changelog', link: '/changelog' }, - { text: 'Email Samples', link: 'http://samples.jsx.email' } - ], - search: { - provider: 'local' - // FIXME: We're waiting on DocSearch approval - // provider: 'algolia', - // options: { - // appId: '...', - // apiKey: '...', - // indexName: '...' - // } - }, - sidebar, - siteTitle: '', - socialLinks: [ - { icon: 'discord', link: 'https://discord.gg/FywZN57mTg' }, - { icon: 'github', link: 'https://github.com/shellscape/jsx-email' } - ] - }, - titleTemplate: 'JSX email • :title', - transformPageData(pageData) { - pageData.frontmatter.head ??= []; - pageData.frontmatter.head.push( - ['meta', { name: 'og:description', content: pageData.description }], - ['meta', { name: 'og:image', content: 'https://jsx.email/og.png' }], - ['meta', { name: 'og:site_name', content: 'JSX email' }], - ['meta', { name: 'og:title', content: pageData.title }], - ['meta', { name: 'og:type', content: 'website' }], - ['meta', { name: 'twitter:card', content: 'summary_large_image' }], - ['meta', { name: 'twitter:description', content: pageData.description }], - ['meta', { name: 'twitter:image', content: 'https://jsx.email/og.png' }], - ['meta', { name: 'twitter:title', content: pageData.title }] - ); - } -}); diff --git a/apps/web/.vitepress/sidebar.mts b/apps/web/.vitepress/sidebar.mts deleted file mode 100644 index 596e98546..000000000 --- a/apps/web/.vitepress/sidebar.mts +++ /dev/null @@ -1,50 +0,0 @@ -import { basename, resolve } from 'path'; - -import titleize from 'titleize'; -import globby from 'globby'; -import type { DefaultTheme } from 'vitepress'; - -const files = await globby(['**/*.md'], { cwd: resolve(__dirname, '../src/docs') }); -const nested = files.filter((file) => file.includes('/')).sort(); -const groups = nested.reduce((prev, file) => { - // Note: This assumes we'll only have one level of nesting - const [dirName, fileName] = file.split('/'); - const groupName = titleize(dirName); - const itemName = basename(fileName, '.md'); - let linkName = titleize(itemName).replace(/-/g, ''); - - if (linkName === 'Cli') linkName = 'CLI'; - - const item = { link: `/docs/${dirName}/${itemName}`, text: linkName }; - - if (prev[groupName]) { - prev[groupName].items.push(item); - } else { - prev[groupName] = { items: [item] }; - } - - return prev; -}, {} as Record | void); -const entries = Object.entries(groups!) - .map(([key, value]) => { - return { - text: key, - ...value - }; - }) - .reverse(); - -export const sidebar = [ - { - text: 'Meat and Potatoes', - items: [ - { text: 'Introduction', link: '/docs/introduction' }, - { text: 'Quick Start', link: '/docs/quick-start' }, - { text: 'Email Providers', link: '/docs/email-providers' }, - { text: 'Email Samples', link: 'https://samples.jsx.email' }, - { text: 'FAQ', link: '/docs/faq' }, - { text: 'Contributing', link: '/docs/contributing' } - ] - }, - ...entries -]; diff --git a/apps/web/.vitepress/theme/custom.css b/apps/web/.vitepress/theme/custom.css deleted file mode 100644 index 17924f939..000000000 --- a/apps/web/.vitepress/theme/custom.css +++ /dev/null @@ -1,218 +0,0 @@ -:root { - --vp-backdrop-bg-color: #2c2a2b; - --vp-button-alt-bg: #47504e; - --vp-button-alt-hover-bg: #61efce; - --vp-button-alt-hover-text: #343233; - --vp-button-alt-text: #78b0a0; - --vp-button-brand-bg: #ffd152; - --vp-button-brand-hover-bg: #ffc31f; - --vp-button-brand-hover-text: #343233; - --vp-button-brand-text: #343233; - --vp-c-bg: #343233; - --vp-c-bg-alt: #2c2a2b; - --vp-c-brand-1: #ffd152; - --vp-c-brand-2: #ebac00; - --vp-c-gutter: #565656; - --vp-c-text-1: #efdab9; - --vp-c-text-2: #8e8373; - --vp-code-block-bg: #2c2a2b; - --vp-code-tab-bg: #2c2a2b; - --vp-code-tab-divider: #00000033; - --vp-custom-block-tip-code-bg: #719bc4; - --vp-custom-block-tip-text: #719bc4; - --vp-custom-block-tip-bg: #434c56; - --vp-font-family-base: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, - 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; - --vp-home-hero-image-background-image: url(/home-hero.png); - --vp-nav-height: 80px; - --vp-nav-logo-height: 36px; - --vp-sidebar-bg-color: #343233; - --vp-sidebar-width: 200px; -} - -html > body { - line-height: 1.5; - font-style: normal; - font-variant-caps: normal; - font-variant-ligatures: normal; - font-variant-numeric: normal; - font-variant-east-asian: normal; - font-variant-alternates: normal; - font-kerning: auto; - font-optical-sizing: auto; - font-feature-settings: normal; - font-variation-settings: normal; - font-variant-position: normal; - font-stretch: normal; - -webkit-font-smoothing: auto; -} - -body { - font-weight: 300 !important; -} - -h2 { - font-size: 2em !important; - font-weight: 200 !important; -} -main h2 { - border: 0 !important; - letter-spacing: 1.6px !important; -} - -.custom-block.tip code { - color: #343233; -} -.content-container main { - background: #343233; -} -.header-anchor { - visibility: hidden; -} -img.brackets { - display: none; -} -svg.brackets { - display: inline-block; - vertical-align: sub; -} -img.clients { - filter: invert(0.8); -} -.prev-next { - border: 0 !important; -} -.vp-code-group .tabs label { - font-weight: 400 !important; -} -.vp-doc a { - font-weight: inherit !important; - text-decoration: none !important; -} - -.VPContent { - background-repeat: no-repeat; - background-image: url(/landing-bg.svg); - background-position: calc(100% + 800px) center; -} -.VPContent.is-home { - background-position: calc(100% + 570px) center; -} - -.VPDoc.has-aside .content-container { - max-width: none !important; -} -.VPDocAside { - background: #2c2a2b44; - border: 1px solid #2c2a2b44; - border-radius: 5px; -} -.VPDocAsideOutline.has-outline .content { - border-left: 1px solid var(--vp-c-bg) !important; -} -.VPDocAsideOutline.has-outline .outline-title { - color: #ebac00 !important; - font-size: 16px !important; - font-weight: 400 !important; -} - -.VPHomeHero .container { - margin: 0 !important; - padding-left: 3em !important; -} -.VPHomeHero .tagline { - font-weight: 200 !important; - max-width: 22em !important; -} -.VPHomeHero .text { - font-size: 2.3em; - font-weight: 200; - height: 2em; - letter-spacing: 0.05em; - max-width: none; -} -.VPHomeHero .text .hl { - color: #78b0a0; -} -.VPHomeHero .VPButton.medium { - border-radius: 5px !important; - font-size: inherit; - font-weight: 500; - padding: 0.1em 2em; -} -.VPHomeHero img.home-hero { - position: absolute; - right: -14%; - top: 60%; -} - -.VPNavBar { - margin-bottom: 30px !important; -} -.VPNavBarMenuLink { - font-size: 16px !important; - font-weight: 300 !important; -} -.VPNavBarTitle.has-sidebar { - background: var(--vp-c-bg); -} -.VPNav .title { - border: 0 !important; -} -.VPSidebar { - padding-right: 0 !important; -} -.VPSidebar .group { - border: 0 !important; -} - -.VPSidebarItem .items { - border-left: 2px solid #786f6333; - padding-left: 14px; -} -.VPSidebarItem.level-1 .text { - font-weight: 400 !important; -} -.VPSidebarItem a.VPLink.link:hover { - text-indent: -6px; -} -.VPSidebarItem a.VPLink.link:hover::before { - background: #786f6333; - border-radius: 9999px; - content: ''; - height: 6px; - left: -18px; - position: relative; - width: 6px; -} - -.VPSidebarItem.level-0 > .item > .text { - color: #78b0a0 !important; - font-size: 16px !important; - font-weight: 400 !important; - white-space: nowrap; -} - -.VPNavScreenAppearance.appearance { - display: none !important; -} -.VPNavScreenMenuLink { - font-size: 16px !important; - font-weight: 300 !important; -} - -@media (max-width: 960px) { - .VPHomeHero img.home-hero { - display: block; - margin-top: 1em; - position: relative; - right: auto; - top: auto; - } - .VPContent.is-home { - background-position: calc(100% + 800px) center; - } - .VPHomeHero .text { - height: auto; - } -} diff --git a/apps/web/.vitepress/theme/index.ts b/apps/web/.vitepress/theme/index.ts deleted file mode 100644 index 268bcb312..000000000 --- a/apps/web/.vitepress/theme/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -import DefaultTheme from 'vitepress/theme'; -import './custom.css'; - -export default DefaultTheme; \ No newline at end of file diff --git a/apps/web/.vscode/extensions.json b/apps/web/.vscode/extensions.json new file mode 100644 index 000000000..22a15055d --- /dev/null +++ b/apps/web/.vscode/extensions.json @@ -0,0 +1,4 @@ +{ + "recommendations": ["astro-build.astro-vscode"], + "unwantedRecommendations": [] +} diff --git a/apps/web/.vscode/launch.json b/apps/web/.vscode/launch.json new file mode 100644 index 000000000..d64220976 --- /dev/null +++ b/apps/web/.vscode/launch.json @@ -0,0 +1,11 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "command": "./node_modules/.bin/astro dev", + "name": "Development server", + "request": "launch", + "type": "node-terminal" + } + ] +} diff --git a/apps/web/astro.config.mjs b/apps/web/astro.config.mjs new file mode 100644 index 000000000..92765a740 --- /dev/null +++ b/apps/web/astro.config.mjs @@ -0,0 +1,109 @@ +// @ts-check +import { defineConfig } from 'astro/config'; +import starlight from '@astrojs/starlight'; + +// https://astro.build/config +export default defineConfig({ + site: 'https://jsx.email/', + integrations: [ + starlight({ + title: 'JSX email', + social: { + github: 'https://github.com/shellscape/jsx-email', + discord: 'https://discord.gg/FywZN57mTg' + }, + logo: { + replacesTitle: true, + light: '@assets/logo-hor-dark.svg', + dark: '@assets/logo-hor-light.svg' + }, + editLink: { + baseUrl: 'https://github.com/shellscape/jsx-email/edit/main/' + }, + tableOfContents: { + minHeadingLevel: 1, + maxHeadingLevel: 4 + }, + customCss: ['@css/style.css', '@fontsource/inter/400.css'], + sidebar: [ + { + label: 'Getting started', + autogenerate: { directory: 'getting-started' } + }, + { + label: 'Email Samples', + link: 'https://samples.jsx.email/', + badge: { + variant: 'tip', + text: 'External link' + } + }, + { + label: 'Upgrade to', + autogenerate: { directory: 'upgrade' } + }, + { + label: 'Core', + autogenerate: { directory: 'core' } + }, + { + label: 'Plugins', + autogenerate: { directory: 'plugins' }, + badge: { + variant: 'success', + text: 'New' + } + }, + { + label: 'Components', + autogenerate: { directory: 'components' } + } + ], + credits: true, + head: [ + { + tag: 'meta', + attrs: { + property: 'og:image', + content: 'https://jsx.email/og.png' + } + }, + { + tag: 'meta', + attrs: { + property: 'og:site_name', + content: 'JSX email' + } + }, + { + tag: 'meta', + attrs: { + name: 'twitter:card', + content: 'summary_large_image' + } + }, + { + tag: 'meta', + attrs: { + name: 'twitter:description', + content: 'Develop standards compliant emails with JSX or TSX' + } + }, + { + tag: 'meta', + attrs: { + name: 'twitter:image', + content: 'https://jsx.email/og.png' + } + }, + { + tag: 'meta', + attrs: { + name: 'twitter:title', + content: 'JSX email Docs' + } + } + ] + }) + ] +}); diff --git a/apps/web/moon.yml b/apps/web/moon.yml deleted file mode 100644 index d76094f85..000000000 --- a/apps/web/moon.yml +++ /dev/null @@ -1,41 +0,0 @@ -# https://moonrepo.dev/docs/config/tasks -$schema: 'https://moonrepo.dev/schemas/tasks.json' - -workspace: - inheritedTasks: - exclude: ['build', 'compile', 'release', 'test'] - -tasks: - build: - command: vitepress build - inputs: - - .vitepress - - markdown - - package.json - options: - cache: false - - cname: - command: mkdir -p dist && echo jsx.email > dist/CNAME && touch dist/.nojekyll - options: - cache: false - - dev: - command: vitepress dev - options: - cache: false - - preview: - command: vitepress preview - options: - cache: false - - publish: - command: gh-pages -d dist -u "Release Workflow " - deps: - - build - - cname - options: - cache: false - outputStyle: 'stream' - runDepsInParallel: false diff --git a/apps/web/package.json b/apps/web/package.json index 3769af551..3aab321aa 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -1,17 +1,20 @@ { - "name": "app-web", - "version": "0.0.0", - "private": true, - "description": "jsx.email", - "license": "MIT", - "engines": { - "node": ">=18.0.0" + "name": "docs", + "version": "1.1.0", + "type": "module", + "scripts": { + "astro": "astro", + "build": "astro check && astro build", + "dev": "astro dev", + "preview": "astro preview", + "upgradeEverything": "pnpm dlx @astrojs/upgrade && pnpm up" }, - "devDependencies": { - "@octokit/rest": "^20.0.2", - "globby": "11.0.4", - "titleize": "^4.0.0", - "vitepress": "1.0.0-rc.20", - "vue": "3.3.4" + "dependencies": { + "@astrojs/check": "^0.9.4", + "@astrojs/starlight": "^0.30.2", + "@fontsource/inter": "^5.1.0", + "astro": "^5.0.9", + "sharp": "^0.33.5", + "typescript": "^5.7.2" } } diff --git a/apps/web/public/favicon.png b/apps/web/public/favicon.png new file mode 100644 index 000000000..5e1f39b77 Binary files /dev/null and b/apps/web/public/favicon.png differ diff --git a/apps/web/public/favicon.svg b/apps/web/public/favicon.svg new file mode 100644 index 000000000..643780795 --- /dev/null +++ b/apps/web/public/favicon.svg @@ -0,0 +1,12 @@ + + + + + + + + + diff --git a/apps/web/src/api/contributions.data.ts b/apps/web/src/api/contributions.data.ts deleted file mode 100644 index ba238484c..000000000 --- a/apps/web/src/api/contributions.data.ts +++ /dev/null @@ -1,18 +0,0 @@ -// eslint-disable-next-line import/no-extraneous-dependencies -import { Octokit } from '@octokit/rest'; - -// eslint-disable-next-line import/no-default-export -export default { - async load() { - const octokit = new Octokit(); - - const { data: releases } = await octokit.rest.pulls.list({ - owner: 'shellscape', - per_page: 100, - repo: 'jsx-email', - state: 'closed' - }); - - return releases; - } -}; diff --git a/apps/web/src/assets/logo-hor-dark.svg b/apps/web/src/assets/logo-hor-dark.svg new file mode 100644 index 000000000..261517cf0 --- /dev/null +++ b/apps/web/src/assets/logo-hor-dark.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/apps/web/src/assets/logo-hor-light.svg b/apps/web/src/assets/logo-hor-light.svg new file mode 100644 index 000000000..c9d14d244 --- /dev/null +++ b/apps/web/src/assets/logo-hor-light.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/apps/web/src/assets/logo-hor.svg b/apps/web/src/assets/logo-hor.svg new file mode 100644 index 000000000..c7a759884 --- /dev/null +++ b/apps/web/src/assets/logo-hor.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/apps/web/src/assets/logo-vert-dark.svg b/apps/web/src/assets/logo-vert-dark.svg new file mode 100644 index 000000000..3aa6a5e07 --- /dev/null +++ b/apps/web/src/assets/logo-vert-dark.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/apps/web/src/assets/logo-vert-light.svg b/apps/web/src/assets/logo-vert-light.svg new file mode 100644 index 000000000..4a1f28c50 --- /dev/null +++ b/apps/web/src/assets/logo-vert-light.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/apps/web/src/assets/logo-vert.svg b/apps/web/src/assets/logo-vert.svg new file mode 100644 index 000000000..4357aa2ce --- /dev/null +++ b/apps/web/src/assets/logo-vert.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/apps/web/src/public/og.png b/apps/web/src/assets/og.png similarity index 100% rename from apps/web/src/public/og.png rename to apps/web/src/assets/og.png diff --git a/apps/web/src/public/preview-1.png b/apps/web/src/assets/preview-1.png similarity index 100% rename from apps/web/src/public/preview-1.png rename to apps/web/src/assets/preview-1.png diff --git a/apps/web/src/public/preview-2.png b/apps/web/src/assets/preview-2.png similarity index 100% rename from apps/web/src/public/preview-2.png rename to apps/web/src/assets/preview-2.png diff --git a/apps/web/src/public/preview-3.png b/apps/web/src/assets/preview-3.png similarity index 100% rename from apps/web/src/public/preview-3.png rename to apps/web/src/assets/preview-3.png diff --git a/apps/web/src/public/preview-4.png b/apps/web/src/assets/preview-4.png similarity index 100% rename from apps/web/src/public/preview-4.png rename to apps/web/src/assets/preview-4.png diff --git a/apps/web/src/changelog.md b/apps/web/src/changelog.md deleted file mode 100644 index c16ef45fc..000000000 --- a/apps/web/src/changelog.md +++ /dev/null @@ -1,317 +0,0 @@ ---- -# Inspired by: https://vuemail.net/releases -# https://vitepress.dev/reference/default-theme-home-page -layout: page -sidebar: false -title: Changes and Updates ---- - - - -
-
-
-
-

Changelog

-

Explore the latest contributions to jsx-email

- View on Github -
- -
- -
- - diff --git a/apps/web/src/components/Install.mdx b/apps/web/src/components/Install.mdx new file mode 100644 index 000000000..e0dbfc7e2 --- /dev/null +++ b/apps/web/src/components/Install.mdx @@ -0,0 +1,20 @@ +import { Tabs, TabItem, Code } from '@astrojs/starlight/components'; + +## Install + +{ props.type === 'component' ? 'Install the component' : 'Install the package' } from your command line + + + + + + + + + + + + + + + diff --git a/apps/web/src/content/config.ts b/apps/web/src/content/config.ts new file mode 100644 index 000000000..a0dc2fe4c --- /dev/null +++ b/apps/web/src/content/config.ts @@ -0,0 +1,7 @@ +/* eslint-disable import/no-unresolved */ +import { defineCollection } from 'astro:content'; +import { docsSchema } from '@astrojs/starlight/schema'; + +export const collections = { + docs: defineCollection({ schema: docsSchema() }) +}; diff --git a/apps/web/src/content/docs/components/background.mdx b/apps/web/src/content/docs/components/background.mdx new file mode 100644 index 000000000..1b5850236 --- /dev/null +++ b/apps/web/src/content/docs/components/background.mdx @@ -0,0 +1,87 @@ +--- +title: Background +description: A JSX email component for background images in your Email template +type: component +sidebar: + badge: + text: New + variant: success +--- +import Install from "@components/Install.mdx" + +

{ frontmatter.description }

+ + + +## Usage + +```jsx "Background" +// BackgroundExample.jsx +import { Background, Body, Column, Html, Row, Section } from 'jsx-email'; + +const Email = () => { + return ( + + + + + Content goes here + + + + + ); +}; +``` + +## Props + +### TypeScript Interface +```ts +interface BackgroundProps + extends Omit, 'height' | 'width' | 'bgcolor'> { + src: string; + bgColor?: string; + bgRepeat?: 'repeat' | 'no-repeat'; + height?: number; + width?: number; +} +``` + +### Required Props + +#### src +```ts +src: string; +``` +The path to the background image. + +### Optional Props + +#### bgColor +```ts +bgColor?: string; +``` +Fallback background color (hex code) if the image fails to load. + +#### bgRepeat +```ts +bgRepeat?: 'repeat' | 'no-repeat'; +``` +Background repeat behavior, uses `background-repeat`. Defaults to `no-repeat`. + +#### height +```ts +height?: number; +``` +Container height in pixels. + +#### width +```ts +width?: number; +``` +Container width in pixels. diff --git a/docs/components/body.md b/apps/web/src/content/docs/components/body.mdx similarity index 67% rename from docs/components/body.md rename to apps/web/src/content/docs/components/body.mdx index 304f28ccc..732274738 100644 --- a/docs/components/body.md +++ b/apps/web/src/content/docs/components/body.mdx @@ -1,19 +1,18 @@ --- -title: 'Body' -description: 'A JSX email component for using a React `Body` component to wrap email content' -slug: body +title: Body +description: A JSX email component for using a React `Body` component to wrap email content type: component --- +import Install from "@components/Install.mdx" - +

{ frontmatter.description }

- + ## Usage -Add the component to your email template. Include styles where needed. - -```jsx +```jsx "Body" +// BodyExample.jsx import { Body, Column, Html, Section } from 'jsx-email'; const Email = () => { @@ -30,6 +29,6 @@ const Email = () => { }; ``` -## Component Props +## Props 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'>`. diff --git a/apps/web/src/content/docs/components/butan.mdx b/apps/web/src/content/docs/components/butan.mdx new file mode 100644 index 000000000..4778af81b --- /dev/null +++ b/apps/web/src/content/docs/components/butan.mdx @@ -0,0 +1,59 @@ +--- +title: Butan +description: Deprecated. The v1 Button component. Please upgrade to the new Button component. +type: component +sidebar: + badge: + text: Deprecated + variant: caution +--- +import Install from "@components/Install.mdx" + +

{ frontmatter.description }

+ +:::warning[Deprecated Component] +This component is a fallback for v1 Button compatibility. Please migrate to the new [`Button`](/components/button) component. `Butan` will be removed in a future release. +::: + + + +## Usage + +```jsx "Butan" +// ButanExample.jsx +import { Butan } from 'jsx-email'; + +const Email = () => { + return ( + + Click me + + ); +}; +``` + +:::note[HTML Output] +Renders as an `` element styled to look like a button. +::: + +## Props + +### Required Props + +#### href +```ts +href: string; +``` +URL to navigate to when clicked. + +### Optional Props + +#### target +```ts +target?: string; +``` +Value for the HTML `target` attribute. + +### Additional Props + +This component also expresses all of the [Common Component Props](https://react.dev/reference/react-dom/components/common) for `ComponentProps<'a'>`. diff --git a/apps/web/src/content/docs/components/button.mdx b/apps/web/src/content/docs/components/button.mdx new file mode 100644 index 000000000..18cd9ce70 --- /dev/null +++ b/apps/web/src/content/docs/components/button.mdx @@ -0,0 +1,136 @@ +--- +title: Button +description: A JSX email component which styles an anchor element to appear as a button +type: component +sidebar: + badge: + text: Major update + variant: danger +--- +import Install from "@components/Install.mdx" + +

{ frontmatter.description }

+ + + +## Usage + +```jsx "Button" +// ButtonExample.jsx +import { Button } from 'jsx-email'; + +const Email = () => { + return ( + + ); +}; +``` + +:::note[HTML Output] +Renders as an `
` element styled to look like a button. +::: + +## Props + +### TypeScript Interface +```ts +export interface ButtonProps extends BaseProps<'a'> { + width: number; + height: number; + href?: string; + align?: 'left' | 'center' | 'right'; + backgroundColor?: string; + borderColor?: string; + borderRadius?: number; + borderSize?: number; + fontSize?: number; + textColor?: string; + withBackground?: boolean; +} +``` + +:::caution[Email Client Compatibility] +For optimal compatibility (especially with Outlook), use the component props below instead of CSS, `style` property, or [`Tailwind`](/components/tailwind) classes. +::: + +### Required Props + +#### width +```ts +width: number; +``` +Button width in pixels. + +#### height +```ts +height: number; +``` +Button height in pixels. + +### Optional Props + +#### href +```ts +href?: string; +``` +URL to navigate to when clicked. + +#### align +```ts +align?: 'left' | 'center' | 'right'; +``` +Horizontal alignment in container. Defaults to `left`. + +#### backgroundColor +```ts +backgroundColor?: string; +``` +Button background color (hex value). + +#### borderColor +```ts +borderColor?: string; +``` +Border color (hex value). + +#### borderRadius +```ts +borderRadius?: number; +``` +Border radius in pixels. + +#### borderSize +```ts +borderSize?: number; +``` +Border width in pixels. + +#### fontSize +```ts +fontSize?: number; +``` +Text size in pixels. + +#### target +```ts +target?: string; +``` +Value for the HTML `target` attribute. + +#### textColor +```ts +textColor?: string; +``` +Text color (hex value). + +#### withBackground +```ts +withBackground?: boolean; +``` +Set to `true` when nested in a `Background` component for Outlook compatibility. + +### Additional Props + +This component also expresses all of the [Common Component Props](https://react.dev/reference/react-dom/components/common) for `ComponentProps<'a'>`. diff --git a/apps/web/src/content/docs/components/code.mdx b/apps/web/src/content/docs/components/code.mdx new file mode 100644 index 000000000..d7d3229ce --- /dev/null +++ b/apps/web/src/content/docs/components/code.mdx @@ -0,0 +1,55 @@ +--- +title: Code +description: A JSX email component which displays a syntax-highlighted code block using Shiki +type: component +--- +import Install from "@components/Install.mdx" + +

{ frontmatter.description }

+ + + +## Usage + +```jsx "Code" +// CodeExample.jsx +import { Code } from 'jsx-email'; + +const Email = () => { + return ( + + {` + import { batman } from 'superheros'; + import { joker } from 'villains'; + + const henchmen = joker.help(); + + batman.fight(henchmen); + batman.arrest(joker); + `} + + ); +}; +``` + +## Props + +### Required Props + +#### language +```ts +language: string; +``` +Syntax highlighting language. See [`shiki` supported languages](https://github.com/shikijs/shiki/blob/main/docs/languages.md). + +### Optional Props + +#### theme +```ts +theme?: string; +``` +Color theme for syntax highlighting. Defaults to `'nord'`. See [`shiki` themes documentation](https://github.com/shikijs/shiki/blob/main/docs/themes.md). + +### Additional Props + +This component also expresses all of the [Common Component Props](https://react.dev/reference/react-dom/components/common) for `ComponentProps<'pre'>`. diff --git a/apps/web/src/content/docs/components/colorscheme.mdx b/apps/web/src/content/docs/components/colorscheme.mdx new file mode 100644 index 000000000..e594f276e --- /dev/null +++ b/apps/web/src/content/docs/components/colorscheme.mdx @@ -0,0 +1,82 @@ +--- +title: ColorScheme +description: A JSX email component which provides meta and style foundations for color scheme support +type: component +--- +import Install from "@components/Install.mdx" + +

{ frontmatter.description }

+ + + +:::tip[Dark Mode Support] +Read our [FAQ about Dark Mode](/getting-started/faq#dark-and-light-mode) in email templates. +::: + +## Usage + +```jsx "ColorScheme" +// ColorSchemeExample.jsx +import { Body, ColorScheme, Head, Html } from 'jsx-email'; + +const Email = () => { + return ( + + + + + + + ); +}; +``` + +:::note[HTML Output] +```html + + + + + + + + +``` +::: + +## Props + +### TypeScript Interface +```ts +export interface ColorSchemeProps { + mode?: Mode; +} +``` + +### Optional Props + +#### mode +```ts +mode?: ColorSchemeMode; +``` +Selects the color scheme mode. Defaults to `'normal'`. + +Available modes: +- `'dark'` - Dark mode +- `'dark only'` - Forces dark mode only +- `'light'` - Light mode +- `'light dark'` - Adapts to user preference +- `'light dark only'` - Forces adaptation to user preference +- `'light only'` - Forces light mode only +- `'normal'` - Uses page defaults or no specific scheme + +:::note[Mode Behavior] +- `only` suffix prevents client override +- `light dark` allows client to choose based on user preference +- `normal` respects page defaults +::: diff --git a/docs/components/column.md b/apps/web/src/content/docs/components/column.mdx similarity index 50% rename from docs/components/column.md rename to apps/web/src/content/docs/components/column.mdx index 19915f3e3..d4f10f117 100644 --- a/docs/components/column.md +++ b/apps/web/src/content/docs/components/column.mdx @@ -1,19 +1,18 @@ --- title: Column -description: A JSX email component which displays columns that separate content bounaries vertically -slug: column +description: A JSX email component which displays columns that separate content boundaries vertically type: component --- +import Install from "@components/Install.mdx" - +

{ frontmatter.description }

- + ## Usage -Add the component to your email template. Include styles where needed. - -```jsx +```jsx "Column" +// ColumnExample.jsx import { Column, Row } from 'jsx-email'; const Email = () => { @@ -27,27 +26,34 @@ const Email = () => { }; ``` -## Component Props +:::note[HTML Output] +Renders as a `` element within an email table structure. +::: + +## Props -```tsx +### TypeScript Interface +```ts export interface ColumnProps extends BaseProps<'td'> { bgColor?: string; bgImage?: string; } ``` -```tsx -bgColor: string; -``` +### Optional Props -Used to set the background color in HTML email by wrapping the `bgcolor` property of `` elements +#### bgColor +```ts +bgColor?: string; +``` +Sets the background color using HTML email's `bgcolor` property. -```tsx -bgImage: string; +#### bgImage +```ts +bgImage?: string; ``` +Sets the background image using HTML email's `background` property. -Used to set background images in HTML email by wrapping the `background` property of `` elements +### Additional Props -:::tip This component expresses all of the [Common Component Props](https://react.dev/reference/react-dom/components/common) for `ComponentProps<'td'>`. -::: diff --git a/apps/web/src/content/docs/components/conditional.mdx b/apps/web/src/content/docs/components/conditional.mdx new file mode 100644 index 000000000..c711410b9 --- /dev/null +++ b/apps/web/src/content/docs/components/conditional.mdx @@ -0,0 +1,75 @@ +--- +title: Conditional +description: Use HTML conditional comments effortlessly +type: component +--- +import Install from "@components/Install.mdx" + +

{ frontmatter.description }

+ + + +## Usage + +```jsx "Conditional" +// ConditionalExample.jsx +import { Conditional, Head } from 'jsx-email'; + +const Email = () => { + return ( + + {/* MSO-specific content */} + + + + + {/* Custom conditional */} + + + + + ); +}; +``` + +## Props + +### TypeScript Interface +```ts +interface ConditionalProps { + children?: React.ReactNode; + expression?: string; + mso?: boolean; +} +``` + +:::caution[Props Usage] +Either `expression` or `mso` must be defined, but not both simultaneously. +::: + +### Optional Props + +#### expression +```ts +expression?: string; +``` +Custom conditional expression for HTML comment. Example: `'lt ie 10'` produces ` ... ` + +### Children Props +```ts +children?: React.ReactNode; +``` +Content to be wrapped in the conditional comment. diff --git a/apps/web/src/content/docs/components/container.mdx b/apps/web/src/content/docs/components/container.mdx new file mode 100644 index 000000000..0b77931a4 --- /dev/null +++ b/apps/web/src/content/docs/components/container.mdx @@ -0,0 +1,51 @@ +--- +title: Container +description: Horizontally center child components and content +type: component +--- +import Install from "@components/Install.mdx" + +

{ frontmatter.description }

+ + + +## Usage + +```jsx "Container" +// ContainerExample.jsx +import { Button, Container } from 'jsx-email'; + +const Email = () => { + return ( + + + + ); +}; +``` + +:::caution[Table Usage] +While `Container` uses a `` element internally, it's designed for centering content. For table layouts, use [`Section`](/components/section) or [`Row`](/components/row) with [`Column`](/components/column). +::: + +## Props + +### Optional Props + +#### disableDefaultStyle +```ts +disableDefaultStyle?: boolean; +``` +When `true`, removes default styles. Useful when using [`Tailwind`](/components/tailwind) or custom classes. + +### Additional Props + +This component expresses all of the [Common Component Props](https://react.dev/reference/react-dom/components/common) for `ComponentProps<'table'>` except for: +- `cellPadding` +- `cellSpacing` diff --git a/apps/web/src/content/docs/components/font.mdx b/apps/web/src/content/docs/components/font.mdx new file mode 100644 index 000000000..cedb52c42 --- /dev/null +++ b/apps/web/src/content/docs/components/font.mdx @@ -0,0 +1,101 @@ +--- +title: Font +description: Sets up custom fonts for use in email +type: component +--- +import Install from "@components/Install.mdx" + +

{ frontmatter.description }

+ + + +:::caution[Web Font Support] +Not all email clients support web fonts. Check [email client compatibility](https://www.caniemail.com/features/css-at-font-face/) before implementation. +::: + +## Usage + +```jsx "Font" +// FontExample.jsx +import { Font, Head, Html } from 'jsx-email'; + +const Email = () => { + return ( + + + + + + ); +}; +``` + +## Props + +### TypeScript Interface +```ts +export interface FontProps { + fallbackFontFamily: FallbackFont | FallbackFont[]; + fontFamily: string; + fontStyle?: FontStyle; + fontWeight?: FontWeight; + webFont?: { + format: FontFormat; + url: string; + }; +} +``` + +### Required Props + +#### fontFamily +```ts +fontFamily: string; +``` +The primary font family name. Should match webFont name if using web fonts. + +#### fallbackFontFamily +```ts +fallbackFontFamily: FallbackFont | FallbackFont[]; +``` +Fallback font(s) to use when web fonts aren't supported or primary font is unavailable. + +### Optional Props + +#### fontStyle +```ts +fontStyle?: FontStyle; +``` +Font style variation. Defaults to `'normal'`. + +#### fontWeight +```ts +fontWeight?: FontWeight; +``` +Font weight value. Defaults to `400`. + +#### webFont +```ts +webFont?: { + format: FontFormat; + url: string; +} +``` +Web font configuration: +- `format`: Font file format (e.g., 'woff2') +- `url`: URL to font file + +:::note[Usage Tips] +- Use `fallbackFontFamily` for multiple fallback fonts +- Ensure web font URLs are publicly accessible +- Consider using system fonts for better compatibility +::: diff --git a/apps/web/src/content/docs/components/graph.mdx b/apps/web/src/content/docs/components/graph.mdx new file mode 100644 index 000000000..9812ace54 --- /dev/null +++ b/apps/web/src/content/docs/components/graph.mdx @@ -0,0 +1,98 @@ +--- +title: Graph +description: A JSX email component for displaying graphs in your Email template +type: component +sidebar: + badge: + text: New + variant: success +--- +import Install from "@components/Install.mdx" + +

{ frontmatter.description }

+ + + +:::note[API Integration] +This component uses [QuickChart API](https://quickchart.io/) to generate email-compatible charts. +::: + +## Usage + +```jsx "Graph" +// GraphExample.jsx +import { Html, Body, Section, Graph } from 'jsx-email'; + +const Email = () => { + return ( + + +
+ +
+ + + ); +}; +``` + +:::tip[Chart Configuration] +Test your chart configurations in the [QuickChart playground](https://quickchart.io/sandbox). +::: + +## Props + +### Required Props + +#### config +```ts +config: ChartConfiguration & Record; +``` +Chart configuration object following [Chart.js v2.9.4](https://www.chartjs.org/docs/2.9.4/charts/) format. + +#### title +```ts +title: string; +``` +Graph title. + +### Optional Props + +#### background +```ts +background?: string; +``` +Graph background color. + +#### className +```ts +className?: string; +``` +Custom CSS class for additional styling. + +#### height +```ts +height?: number; +``` +Graph height in pixels. + +#### width +```ts +width?: number; +``` +Graph width in pixels. diff --git a/apps/web/src/content/docs/components/head.mdx b/apps/web/src/content/docs/components/head.mdx new file mode 100644 index 000000000..12e74330b --- /dev/null +++ b/apps/web/src/content/docs/components/head.mdx @@ -0,0 +1,54 @@ +--- +title: Head +description: A JSX email component which creates an HTML head element +type: component +--- +import Install from "@components/Install.mdx" + +

{ frontmatter.description }

+ + + +:::note[Outlook Compatibility] +Required for VML compatibility in Outlook when using elements like ` +
batcave
+``` + +```html title="After" +
batcave
+``` + +## Performance Considerations + +:::caution[Size Impact] +Inlined CSS increases HTML size significantly. Monitor console output for size warnings to avoid email clipping in clients like Gmail. +::: + +## Resources +- [Source Code](https://github.com/shellscape/jsx-email/blob/main/packages/plugin-inline) +- [Understanding Inline Styles](https://www.codecademy.com/article/html-inline-styles) diff --git a/apps/web/src/content/docs/plugins/minify.mdx b/apps/web/src/content/docs/plugins/minify.mdx new file mode 100644 index 000000000..b1b3d6ba1 --- /dev/null +++ b/apps/web/src/content/docs/plugins/minify.mdx @@ -0,0 +1,30 @@ +--- +title: Minify Plugin +description: Reduce HTML size through minification for better email delivery +type: plugin +--- + +

{ frontmatter.description }

+ +## Overview + +The `@jsx-email/plugin-minify` plugin reduces HTML size by removing unnecessary whitespace and formatting. + +:::note[Automatic Loading] +This plugin is a `peerDependency` of `jsx-email` and loads automatically when the [`minify` render option](/core/render#method-options) is enabled. +::: + +## Benefits + +- Reduces email size +- Prevents email clipping in clients +- Improves delivery performance + +:::caution[Size Monitoring] +Monitor console output during rendering for size warnings to avoid email clipping in clients like Gmail. +::: + +## Resources + +- [Source Code](https://github.com/shellscape/jsx-email/blob/main/packages/plugin-minify) +- [About Minification]() diff --git a/apps/web/src/content/docs/plugins/pretty.mdx b/apps/web/src/content/docs/plugins/pretty.mdx new file mode 100644 index 000000000..a87097c41 --- /dev/null +++ b/apps/web/src/content/docs/plugins/pretty.mdx @@ -0,0 +1,30 @@ +--- +title: Pretty Plugin +description: Format HTML output for better readability during development +type: plugin +--- + +

{ frontmatter.description }

+ +## Overview + +The `@jsx-email/plugin-pretty` plugin formats HTML output for improved readability during development. + +:::note[Automatic Loading] +This plugin is a `peerDependency` of `jsx-email` and loads automatically when the [`pretty` render option](/core/render#method-options) is enabled. +::: + +## Use Cases + +- Debugging email templates +- Development environments +- Code review and inspection +- Template troubleshooting + +:::tip +While useful for development, disable this plugin in production for optimal performance. +::: + +## Resources + +- [Source Code](https://github.com/shellscape/jsx-email/blob/main/packages/plugin-pretty) diff --git a/apps/web/src/content/docs/upgrade/v2.mdx b/apps/web/src/content/docs/upgrade/v2.mdx new file mode 100644 index 000000000..19081f65a --- /dev/null +++ b/apps/web/src/content/docs/upgrade/v2.mdx @@ -0,0 +1,160 @@ +--- +title: V2 Upgrade Guide +description: Guide for upgrading to JSX-email version 2 +sidebar: + label: Version 2 +--- + +

{ frontmatter.description }

+ +## Overview + +Version 2 of JSX-email introduces significant improvements and breaking changes. This guide will help you upgrade your existing projects. + +## New Features + +### Components +- [`Background`](/components/background) ⭐️ New +- [`Button`](/components/button) Updates +- [`Graph`](/components/graph) ⭐️ New + +### Configuration File Support + +Added support for configuration files to: +- Disable default component styles globally +- Set rendering properties +- Configure logging levels +- Specify plugins + +See [Configuration](/core/config) documentation for details. + +### Plugin System + +New plugin system with lifecycle hooks for: +- Pre-render modifications +- During-render processing +- Post-render transformations + +Core features like minification and prettifying are now separate plugins, enabling: +- Smaller bundle sizes +- Better compatibility with restricted environments (e.g., Cloudflare) +- Custom rendering pipelines + +See [Plugins](/core/plugins) documentation for details. + +### Module Format Changes + +Moved to [`tshy`](https://github.com/isaacs/tshy) for package building + +## Breaking Changes + +### Named Exports + +Templates must now use named exports instead of default exports: + +```tsx title="Before" +export default function MyTemplate({ ... }) { + ... +}; + +MyTemplate.Name = 'MyTemplate'; +MyTemplate.PreviewProps = { ... }; +``` + +```tsx title="After" +export const previewProps = { ... }; +export const templateName = 'MyTemplate'; +export const Template = ({ ... }) => { + ... +}; +``` + +:::note[Why This Change?] +Default exports can negatively impact tree-shaking and bundle optimization. Named exports provide better consistency and simplify template validation. +::: + +### Button Component + +The `Button` component has been completely refactored for better email client compatibility. + +The [`Button`](/components/button) component received a mountain of updates thanks to [@lordelogos](https://github.com/lordelogos). Amoung the updates was a complete refactoring of the component source and the HTML that it generates. This was done to address nagging and persistent issues with rendering buttons effectively across many clients. No surprise, Outlook was the worst offender. While these updates provide a lot of new props, the `Button` component remains backwards compatible in most situations. + +However, one big potentially breaking change is around the `style` property. If you're using the `style` or `class` properties to style your buttons, there may be some visual differences. The updates to `Button` provide direct props for most of the styles that we've seen people use on buttons, in an effort to get to maximum compatibility across email clients. _This is something you won't find in other email templating tools!_ Please see the [props](/components/button#component-props) documentation for more info. + +#### Key Changes +- Original `Button` is now available as [`Butan`](/components/butan) +- New styling approach using props instead of CSS +- Better Outlook compatibility + +:::caution[Deprecation Notice] +The `Butan` component is deprecated and will be removed in v3. Migrate to the new `Button` component for future compatibility. +::: + +### Component Props + +To take full advantage of the new Button, we strongly recommend using the provided component props (see the Button docs or the details below) to set styles. Avoid using `CSS`, the `style` property, or `Tailwind` classes, as this ensures better compatibility with Outlook and older email clients. + +The Only required props are `width` and `height`. While the other props are optional, it is highly recommended to use them instead of relying on `style`, `CSS`, or `Tailwind` classes for styling. + +```tsx +width: number; +height: number; +href?: string; +align?: 'left' | 'center' | 'right'; +backgroundColor?: string; +borderColor?: string; +borderRadius?: number; +borderSize?: number; +fontSize?: number; +textColor?: string; +withBackground?: boolean; +``` + +#### Migration Example + +```tsx title="Before (now Butan)" + + Click Me! + +``` + +```tsx title="After (new Button)" + +``` + +### Preview System Changes + +Improvements: +- Faster pre-rendering +- Live updates via file watching +- Template exclusion support + +Current Limitations: +- Local relative asset imports temporarily unavailable, working on restoring this functionality + +:::tip[Need Help?] +If you encounter issues during migration, please [open an issue](https://github.com/shellscape/jsx-email/issues/new/choose). +::: diff --git a/apps/web/src/css/style.css b/apps/web/src/css/style.css new file mode 100644 index 000000000..1cd029732 --- /dev/null +++ b/apps/web/src/css/style.css @@ -0,0 +1,33 @@ +:root { + --sl-color-white: #ffffff; + --sl-color-black: #343233; + + --sl-color-accent-low: #434c56; + --sl-color-accent: #e6c12e; + --sl-color-accent-high: #ecc838; + + --sl-color-text: #ffffff; + --sl-color-text-accent: #e7c330; + --sl-color-text-invert: #343233; + --sl-color-bg: #242424; + --sl-color-bg-nav: #202020; + --sl-color-bg-sidebar: #343233; + --sl-color-bg-inline-code: #343233; +} + +:root[data-theme='light'] { + --sl-color-white: #000000; + --sl-color-black: #ffffff; + + --sl-color-accent-low: #fff3d6; + --sl-color-accent: #c68e00; + --sl-color-accent-high: #8b6300; + + --sl-color-text: #000000; + --sl-color-text-accent: #8b6300; + --sl-color-text-invert: #ffffff; + --sl-color-bg: #ffffff; + --sl-color-bg-nav: #dbdbdb; + --sl-color-bg-sidebar: #f0f0f0; + --sl-color-bg-inline-code: #f0f0f0; +} \ No newline at end of file diff --git a/apps/web/src/docs b/apps/web/src/docs deleted file mode 120000 index 48c4a0c02..000000000 --- a/apps/web/src/docs +++ /dev/null @@ -1 +0,0 @@ -../../../docs \ No newline at end of file diff --git a/apps/web/src/env.d.ts b/apps/web/src/env.d.ts new file mode 100644 index 000000000..acef35f17 --- /dev/null +++ b/apps/web/src/env.d.ts @@ -0,0 +1,2 @@ +/// +/// diff --git a/apps/web/src/include/CONTRIBUTING.md b/apps/web/src/include/CONTRIBUTING.md deleted file mode 120000 index 069558fad..000000000 --- a/apps/web/src/include/CONTRIBUTING.md +++ /dev/null @@ -1 +0,0 @@ -../../../../CONTRIBUTING.md \ No newline at end of file diff --git a/apps/web/src/include/README.md b/apps/web/src/include/README.md deleted file mode 120000 index ff5c79602..000000000 --- a/apps/web/src/include/README.md +++ /dev/null @@ -1 +0,0 @@ -../../../../README.md \ No newline at end of file diff --git a/apps/web/src/include/header.md b/apps/web/src/include/header.md deleted file mode 100644 index 0c5296408..000000000 --- a/apps/web/src/include/header.md +++ /dev/null @@ -1,3 +0,0 @@ -## {{ $frontmatter.title }} - -{{ $frontmatter.description }} \ No newline at end of file diff --git a/apps/web/src/include/install.md b/apps/web/src/include/install.md deleted file mode 100644 index 8d842e332..000000000 --- a/apps/web/src/include/install.md +++ /dev/null @@ -1,23 +0,0 @@ -## Install - -Install the {{ $frontmatter.type }} from your command line - -::: code-group - -```console-vue [pnpm] -pnpm add jsx-email -``` - -```console-vue [bun] -bun add jsx-email -``` - -```console-vue [npm] -npm add jsx-email -``` - -```console-vue [yarn] -yarn add jsx-email -``` - -::: \ No newline at end of file diff --git a/apps/web/src/index.md b/apps/web/src/index.md deleted file mode 100644 index 9d0c584ef..000000000 --- a/apps/web/src/index.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -# https://vitepress.dev/reference/default-theme-home-page -layout: home -title: Build Emails with a Delightful DX - -hero: - text: | - Build emails with a delightful Developer Experience - - tagline: Develop standards compliant emails with JSX or TSX — compatible with the most popular email clients - actions: - - theme: brand - text: Quick Start - link: /docs/quick-start - - theme: alt - text: View on Github - link: https://github.com/shellscape/jsx-email ---- diff --git a/apps/web/src/public/assets/demo/airbnb-logo.png b/apps/web/src/public/assets/demo/airbnb-logo.png deleted file mode 100644 index ed1bf2525..000000000 Binary files a/apps/web/src/public/assets/demo/airbnb-logo.png and /dev/null differ diff --git a/apps/web/src/public/assets/demo/apple-card-icon.png b/apps/web/src/public/assets/demo/apple-card-icon.png deleted file mode 100644 index 6a43d17bb..000000000 Binary files a/apps/web/src/public/assets/demo/apple-card-icon.png and /dev/null differ diff --git a/apps/web/src/public/assets/demo/apple-hbo-max-icon.jpeg b/apps/web/src/public/assets/demo/apple-hbo-max-icon.jpeg deleted file mode 100644 index 20efe12b1..000000000 Binary files a/apps/web/src/public/assets/demo/apple-hbo-max-icon.jpeg and /dev/null differ diff --git a/apps/web/src/public/assets/demo/apple-logo.png b/apps/web/src/public/assets/demo/apple-logo.png deleted file mode 100644 index 0bdfbbb77..000000000 Binary files a/apps/web/src/public/assets/demo/apple-logo.png and /dev/null differ diff --git a/apps/web/src/public/assets/demo/apple-wallet.png b/apps/web/src/public/assets/demo/apple-wallet.png deleted file mode 100644 index 38f8ac880..000000000 Binary files a/apps/web/src/public/assets/demo/apple-wallet.png and /dev/null differ diff --git a/apps/web/src/public/assets/demo/batman-adam.jpg b/apps/web/src/public/assets/demo/batman-adam.jpg deleted file mode 100644 index 35d5803e2..000000000 Binary files a/apps/web/src/public/assets/demo/batman-adam.jpg and /dev/null differ diff --git a/apps/web/src/public/assets/demo/batman-cartoon.jpg b/apps/web/src/public/assets/demo/batman-cartoon.jpg deleted file mode 100644 index 994de64ca..000000000 Binary files a/apps/web/src/public/assets/demo/batman-cartoon.jpg and /dev/null differ diff --git a/apps/web/src/public/assets/demo/batman-lego.webp b/apps/web/src/public/assets/demo/batman-lego.webp deleted file mode 100644 index 3ec2701bd..000000000 Binary files a/apps/web/src/public/assets/demo/batman-lego.webp and /dev/null differ diff --git a/apps/web/src/public/assets/demo/batman-twilight.jpg b/apps/web/src/public/assets/demo/batman-twilight.jpg deleted file mode 100644 index 6db64e19f..000000000 Binary files a/apps/web/src/public/assets/demo/batman-twilight.jpg and /dev/null differ diff --git a/apps/web/src/public/assets/demo/codepen-challengers.png b/apps/web/src/public/assets/demo/codepen-challengers.png deleted file mode 100644 index 2190f329b..000000000 Binary files a/apps/web/src/public/assets/demo/codepen-challengers.png and /dev/null differ diff --git a/apps/web/src/public/assets/demo/codepen-cube.png b/apps/web/src/public/assets/demo/codepen-cube.png deleted file mode 100644 index 2c112e902..000000000 Binary files a/apps/web/src/public/assets/demo/codepen-cube.png and /dev/null differ diff --git a/apps/web/src/public/assets/demo/codepen-pro.png b/apps/web/src/public/assets/demo/codepen-pro.png deleted file mode 100644 index dab587334..000000000 Binary files a/apps/web/src/public/assets/demo/codepen-pro.png and /dev/null differ diff --git a/apps/web/src/public/assets/demo/dropbox-logo.png b/apps/web/src/public/assets/demo/dropbox-logo.png deleted file mode 100644 index e899b7b3b..000000000 Binary files a/apps/web/src/public/assets/demo/dropbox-logo.png and /dev/null differ diff --git a/apps/web/src/public/assets/demo/github.png b/apps/web/src/public/assets/demo/github.png deleted file mode 100644 index ebd977fde..000000000 Binary files a/apps/web/src/public/assets/demo/github.png and /dev/null differ diff --git a/apps/web/src/public/assets/demo/google-play-academy.png b/apps/web/src/public/assets/demo/google-play-academy.png deleted file mode 100644 index e32ff2d7e..000000000 Binary files a/apps/web/src/public/assets/demo/google-play-academy.png and /dev/null differ diff --git a/apps/web/src/public/assets/demo/google-play-chat.png b/apps/web/src/public/assets/demo/google-play-chat.png deleted file mode 100644 index 11a06589e..000000000 Binary files a/apps/web/src/public/assets/demo/google-play-chat.png and /dev/null differ diff --git a/apps/web/src/public/assets/demo/google-play-footer.png b/apps/web/src/public/assets/demo/google-play-footer.png deleted file mode 100644 index f709d1ce3..000000000 Binary files a/apps/web/src/public/assets/demo/google-play-footer.png and /dev/null differ diff --git a/apps/web/src/public/assets/demo/google-play-header.png b/apps/web/src/public/assets/demo/google-play-header.png deleted file mode 100644 index 74a963d76..000000000 Binary files a/apps/web/src/public/assets/demo/google-play-header.png and /dev/null differ diff --git a/apps/web/src/public/assets/demo/google-play-icon.png b/apps/web/src/public/assets/demo/google-play-icon.png deleted file mode 100644 index ebab883ed..000000000 Binary files a/apps/web/src/public/assets/demo/google-play-icon.png and /dev/null differ diff --git a/apps/web/src/public/assets/demo/google-play-logo.png b/apps/web/src/public/assets/demo/google-play-logo.png deleted file mode 100644 index 6dfffb081..000000000 Binary files a/apps/web/src/public/assets/demo/google-play-logo.png and /dev/null differ diff --git a/apps/web/src/public/assets/demo/koala-logo.png b/apps/web/src/public/assets/demo/koala-logo.png deleted file mode 100644 index ea11f7da3..000000000 Binary files a/apps/web/src/public/assets/demo/koala-logo.png and /dev/null differ diff --git a/apps/web/src/public/assets/demo/linear-logo.png b/apps/web/src/public/assets/demo/linear-logo.png deleted file mode 100644 index 3eb2f84e7..000000000 Binary files a/apps/web/src/public/assets/demo/linear-logo.png and /dev/null differ diff --git a/apps/web/src/public/assets/demo/nike-logo.png b/apps/web/src/public/assets/demo/nike-logo.png deleted file mode 100644 index e7d2392a4..000000000 Binary files a/apps/web/src/public/assets/demo/nike-logo.png and /dev/null differ diff --git a/apps/web/src/public/assets/demo/nike-phone.png b/apps/web/src/public/assets/demo/nike-phone.png deleted file mode 100644 index 2890b0495..000000000 Binary files a/apps/web/src/public/assets/demo/nike-phone.png and /dev/null differ diff --git a/apps/web/src/public/assets/demo/nike-product.png b/apps/web/src/public/assets/demo/nike-product.png deleted file mode 100644 index 94adae8c6..000000000 Binary files a/apps/web/src/public/assets/demo/nike-product.png and /dev/null differ diff --git a/apps/web/src/public/assets/demo/nike-recomendation-1.png b/apps/web/src/public/assets/demo/nike-recomendation-1.png deleted file mode 100644 index 35a885eeb..000000000 Binary files a/apps/web/src/public/assets/demo/nike-recomendation-1.png and /dev/null differ diff --git a/apps/web/src/public/assets/demo/nike-recomendation-2.png b/apps/web/src/public/assets/demo/nike-recomendation-2.png deleted file mode 100644 index f533ddd59..000000000 Binary files a/apps/web/src/public/assets/demo/nike-recomendation-2.png and /dev/null differ diff --git a/apps/web/src/public/assets/demo/nike-recomendation-4 (1).png b/apps/web/src/public/assets/demo/nike-recomendation-4 (1).png deleted file mode 100644 index 3ca977b83..000000000 Binary files a/apps/web/src/public/assets/demo/nike-recomendation-4 (1).png and /dev/null differ diff --git a/apps/web/src/public/assets/demo/nike-recomendation-4.png b/apps/web/src/public/assets/demo/nike-recomendation-4.png deleted file mode 100644 index 3ca977b83..000000000 Binary files a/apps/web/src/public/assets/demo/nike-recomendation-4.png and /dev/null differ diff --git a/apps/web/src/public/assets/demo/notion-logo.png b/apps/web/src/public/assets/demo/notion-logo.png deleted file mode 100644 index 57cddee9b..000000000 Binary files a/apps/web/src/public/assets/demo/notion-logo.png and /dev/null differ diff --git a/apps/web/src/public/assets/demo/plaid-logo.png b/apps/web/src/public/assets/demo/plaid-logo.png deleted file mode 100644 index ce9d08cb2..000000000 Binary files a/apps/web/src/public/assets/demo/plaid-logo.png and /dev/null differ diff --git a/apps/web/src/public/assets/demo/raycast-logo.png b/apps/web/src/public/assets/demo/raycast-logo.png deleted file mode 100644 index d6b4024ee..000000000 Binary files a/apps/web/src/public/assets/demo/raycast-logo.png and /dev/null differ diff --git a/apps/web/src/public/assets/demo/slack-facebook.png b/apps/web/src/public/assets/demo/slack-facebook.png deleted file mode 100644 index 59cb467f0..000000000 Binary files a/apps/web/src/public/assets/demo/slack-facebook.png and /dev/null differ diff --git a/apps/web/src/public/assets/demo/slack-linkedin.png b/apps/web/src/public/assets/demo/slack-linkedin.png deleted file mode 100644 index a26df46f5..000000000 Binary files a/apps/web/src/public/assets/demo/slack-linkedin.png and /dev/null differ diff --git a/apps/web/src/public/assets/demo/slack-logo.png b/apps/web/src/public/assets/demo/slack-logo.png deleted file mode 100644 index 2fd7c9616..000000000 Binary files a/apps/web/src/public/assets/demo/slack-logo.png and /dev/null differ diff --git a/apps/web/src/public/assets/demo/slack-twitter.png b/apps/web/src/public/assets/demo/slack-twitter.png deleted file mode 100644 index a371d1896..000000000 Binary files a/apps/web/src/public/assets/demo/slack-twitter.png and /dev/null differ diff --git a/apps/web/src/public/assets/demo/stack-overflow-header.png b/apps/web/src/public/assets/demo/stack-overflow-header.png deleted file mode 100644 index 30ced2726..000000000 Binary files a/apps/web/src/public/assets/demo/stack-overflow-header.png and /dev/null differ diff --git a/apps/web/src/public/assets/demo/stack-overflow-logo-sm.png b/apps/web/src/public/assets/demo/stack-overflow-logo-sm.png deleted file mode 100644 index c6bae1a54..000000000 Binary files a/apps/web/src/public/assets/demo/stack-overflow-logo-sm.png and /dev/null differ diff --git a/apps/web/src/public/assets/demo/stack-overflow-logo.png b/apps/web/src/public/assets/demo/stack-overflow-logo.png deleted file mode 100644 index c4f8aafb3..000000000 Binary files a/apps/web/src/public/assets/demo/stack-overflow-logo.png and /dev/null differ diff --git a/apps/web/src/public/assets/demo/stripe-logo.png b/apps/web/src/public/assets/demo/stripe-logo.png deleted file mode 100644 index af4c7719a..000000000 Binary files a/apps/web/src/public/assets/demo/stripe-logo.png and /dev/null differ diff --git a/apps/web/src/public/assets/demo/twitch-icon-facebook.png b/apps/web/src/public/assets/demo/twitch-icon-facebook.png deleted file mode 100644 index fd3fab107..000000000 Binary files a/apps/web/src/public/assets/demo/twitch-icon-facebook.png and /dev/null differ diff --git a/apps/web/src/public/assets/demo/twitch-icon-twitter.png b/apps/web/src/public/assets/demo/twitch-icon-twitter.png deleted file mode 100644 index 10ecfe25a..000000000 Binary files a/apps/web/src/public/assets/demo/twitch-icon-twitter.png and /dev/null differ diff --git a/apps/web/src/public/assets/demo/twitch-logo.png b/apps/web/src/public/assets/demo/twitch-logo.png deleted file mode 100644 index 1ceb241e0..000000000 Binary files a/apps/web/src/public/assets/demo/twitch-logo.png and /dev/null differ diff --git a/apps/web/src/public/assets/demo/vercel-arrow.png b/apps/web/src/public/assets/demo/vercel-arrow.png deleted file mode 100644 index 018f64d2c..000000000 Binary files a/apps/web/src/public/assets/demo/vercel-arrow.png and /dev/null differ diff --git a/apps/web/src/public/assets/demo/vercel-logo.png b/apps/web/src/public/assets/demo/vercel-logo.png deleted file mode 100644 index 5b970948d..000000000 Binary files a/apps/web/src/public/assets/demo/vercel-logo.png and /dev/null differ diff --git a/apps/web/src/public/assets/demo/vercel-team.png b/apps/web/src/public/assets/demo/vercel-team.png deleted file mode 100644 index d3de7d938..000000000 Binary files a/apps/web/src/public/assets/demo/vercel-team.png and /dev/null differ diff --git a/apps/web/src/public/assets/demo/yelp-footer.png b/apps/web/src/public/assets/demo/yelp-footer.png deleted file mode 100644 index 9a02669b8..000000000 Binary files a/apps/web/src/public/assets/demo/yelp-footer.png and /dev/null differ diff --git a/apps/web/src/public/assets/demo/yelp-header.png b/apps/web/src/public/assets/demo/yelp-header.png deleted file mode 100644 index 75e6a23d0..000000000 Binary files a/apps/web/src/public/assets/demo/yelp-header.png and /dev/null differ diff --git a/apps/web/src/public/assets/demo/yelp-logo.png b/apps/web/src/public/assets/demo/yelp-logo.png deleted file mode 100644 index 297ba1694..000000000 Binary files a/apps/web/src/public/assets/demo/yelp-logo.png and /dev/null differ diff --git a/apps/web/src/public/home-hero.png b/apps/web/src/public/home-hero.png deleted file mode 100644 index 573da9cb9..000000000 Binary files a/apps/web/src/public/home-hero.png and /dev/null differ diff --git a/apps/web/src/public/landing-bg.svg b/apps/web/src/public/landing-bg.svg deleted file mode 100644 index 7a58c883e..000000000 --- a/apps/web/src/public/landing-bg.svg +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/apps/web/src/public/logo.svg b/apps/web/src/public/logo.svg deleted file mode 100644 index 9fd089f71..000000000 --- a/apps/web/src/public/logo.svg +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/apps/web/src/public/test/index.html b/apps/web/src/public/test/index.html deleted file mode 100644 index 3dc01874b..000000000 --- a/apps/web/src/public/test/index.html +++ /dev/null @@ -1,3 +0,0 @@ - - hello - \ No newline at end of file diff --git a/apps/web/tsconfig.json b/apps/web/tsconfig.json new file mode 100644 index 000000000..e4e7a9022 --- /dev/null +++ b/apps/web/tsconfig.json @@ -0,0 +1,12 @@ +// @ts-check +{ + "extends": "astro/tsconfigs/strict", + "compilerOptions": { + "baseUrl": ".", + "paths": { + "@assets/*": ["src/assets/*"], + "@components/*": ["src/components/*"], + "@css/*": ["src/css/*"] + } + } +} diff --git a/docs b/docs new file mode 120000 index 000000000..77d3c46f5 --- /dev/null +++ b/docs @@ -0,0 +1 @@ +apps/web/src/content/docs \ No newline at end of file diff --git a/docs/components/button.md b/docs/components/button.md deleted file mode 100644 index 635f39370..000000000 --- a/docs/components/button.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -title: 'Button' -description: A JSX email component which styles an anchor element to appear as a button -slug: button -type: component ---- - - - -::: tip -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 ` - ); -}; -``` - -## Component Props - -```ts -href: string; -``` - -The url to navigate to when the button is clicked. - -```ts -target?: string; -``` - -Specifies the value of the `"target"` attribute for the button `target`. - -:::tip -This component also expresses all of the [Common Component Props](https://react.dev/reference/react-dom/components/common) for `ComponentProps<'a'>`. -::: diff --git a/docs/components/code.md b/docs/components/code.md deleted file mode 100644 index 93de657a6..000000000 --- a/docs/components/code.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -title: Code -description: A JSX email component which displays a syntax-highlighted code block using Shiki -slug: code ---- - - - - - -## Usage - -Add the component to your email template. Include styles where needed. - -```jsx -import { Code } from 'jsx-email'; - -const Email = () => { - return ( - - {` - import { batman } from 'superheros'; - import { joker } from 'villains'; - - const henchmen = joker.help(); - - batman.fight(henchmen); - batman.arrest(joker); - `} - - ); -}; -``` - -## Component Props - -```ts -language: string; -``` - -Specifies the language to use for the highlighter. See the [`shiki` documentation](https://github.com/shikijs/shiki/blob/main/docs/languages.md) for more information on supported languages. - -```ts -theme?: string; -``` - -_Optional_. Defaults to `'nord'`. Specifies the theme to use for the highlighter. See the [`shiki` documentation](https://github.com/shikijs/shiki/blob/main/docs/themes.md) for more information on supported themes, modifying themes, and how to make your own. - -::: tip -This component also expresses all of the [Common Component Props](https://react.dev/reference/react-dom/components/common) for `ComponentProps<'pre'>`. -::: diff --git a/docs/components/color-scheme.md b/docs/components/color-scheme.md deleted file mode 100644 index 2b4654586..000000000 --- a/docs/components/color-scheme.md +++ /dev/null @@ -1,79 +0,0 @@ ---- -title: 'ColorScheme' -description: A JSX email component which provides meta and style foundations for color scheme support -slug: color-scheme -type: component ---- - - - -::: tip -Please be sure to read our FAQ about Dark Mode in the context of email templates: https://jsx.email/docs/faq#dark-and-light-mode -::: - - - -## Usage - -Add the component to your email template. - -```jsx -import { Body, ColorScheme, Head, Html } from 'jsx-email'; - -const Email = () => { - return ( - - - - - - - ); -}; -``` - -Which will produce the following HTML: - -```html - - - - - - - - -``` - -## Component Props - -```ts -export interface ColorSchemeProps { - mode?: Mode; -} -``` - -### Individual Props - -```ts -mode?: ColorSchemeMode; -``` - -Default: `'normal'`
- -Selects the color scheme mode that informs the email client which mode to render. - -Supported Values: - -- `'dark'` -- `'dark only'` The email client will only ever render the content in the dark color scheme and forbids the email client from overriding the color scheme. -- `'light'` -- `'light dark'` The email client will choose the light or dark theme to match the user’s preference. If the user’s preference does not match something in the list, the email client will choose which mode to display. -- `'light dark only'` The email client will choose the first of the listed schemes that it supports taking user preference into account and forbids the email client from overriding the color scheme. -- `'light only'` The email client will only ever render the content in the light color scheme and forbids the email client from overriding the color scheme. -- `'normal'` Indicates that the email supports the page's supported color schemes, if they are set, or that it supports no color schemes at all otherwise. diff --git a/docs/components/conditional.md b/docs/components/conditional.md deleted file mode 100644 index ac17c00aa..000000000 --- a/docs/components/conditional.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -title: 'Conditional' -description: Use HTML conditional comments effortlessly -slug: conditional -type: component ---- - - - - - -## Usage - -Add the component to your email template. Include styles where needed. - -```jsx -import { Conditional, Head } from 'jsx-email'; - -const Email = () => { - return ( - - - - - - ); -}; -``` - -## Component Props - -```ts -interface ConditionalProps { - children?: React.ReactNode; - expression?: string; - mso?: boolean; -} -``` - -::: info -The `expression` prop or the `mso` prop must be defined, but not both. -::: - -### Props - -```ts -expression?: string; -``` - -If provided, the string will be used as the conditional expression within the HTML comment. e.g. a value of `lt ie 10` would result in a conditional comment block starting with ` ... `. diff --git a/docs/components/container.md b/docs/components/container.md deleted file mode 100644 index 59f37d7ab..000000000 --- a/docs/components/container.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: 'Container' -description: Horizontally center child components and content -slug: container -type: component ---- - - - - - -## Usage - -Add the component to your email template. Include styles where needed. - -```jsx -import { Button, Container } from 'jsx-email'; - -const Email = () => { - return ( - - - - ); -}; -``` - -## Component Props - -```ts -disableDefaultStyle?: boolean; -``` - -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. - -::: tip -This component also expresses all of the [Common Component Props](https://react.dev/reference/react-dom/components/common) for `ComponentProps<'table'>`. -::: diff --git a/docs/components/font.md b/docs/components/font.md deleted file mode 100644 index 7e4289db1..000000000 --- a/docs/components/font.md +++ /dev/null @@ -1,93 +0,0 @@ ---- -title: Font -description: Sets up custom fonts for use in email -slug: font -type: component ---- - - - - - -## Usage - -Add the component to your email template. This applies your font to all tags inside your email. -Note, that not all email clients supports web fonts, this is why it is important to configure your `fallbackFontFamily`. -To view all email clients that supports web fonts [see](https://www.caniemail.com/features/css-at-font-face/) - -```jsx -import { Font, Head, Html } from 'jsx-email'; - -const Email = () => { - return ( - - - - - - ); -}; -``` - -## Component Props - -```ts -export interface FontProps { - fallbackFontFamily: FallbackFont | FallbackFont[]; - fontFamily: string; - fontStyle?: FontStyle; - fontWeight?: FontWeight; - webFont?: { - format: FontFormat; - url: string; - }; -} -``` - -### Props - -```ts -fallbackFontFamily: FallbackFont | FallbackFont[]; -``` - -The fallback font family the system should use, if web fonts are not supported or the chosen font is not installed on the system. - -```ts -fontFamily: string; -``` - -The font family you want to use. If the webFont property is configured, this should contain the name of that font. Note: Do not insert multiple fonts here, use `fallbackFontFamily` for that\_ - -```ts -fontStyle?: FontStyle;` -``` - -Default: `'normal'`
- -The style of the font. - -```ts -fontWeight?: FontWeight;` -``` - -Default: `400`
- -The weight of the font. - -```ts -webFont?: { - format: FontFormat; - url: string; -} -``` - -The webFont the supported email client should use. _Note: Not all clients support web fonts. For support check: [https://www.caniemail.com/features/css-at-font-face](https://www.caniemail.com/features/css-at-font-face)_ diff --git a/docs/components/head.md b/docs/components/head.md deleted file mode 100644 index 0b2750b72..000000000 --- a/docs/components/head.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: 'Head' -description: | - A JSX email component which creates an HTML head element -slug: head -type: component ---- - - - -::: tip -This component is required for adding elements such as `