react-email 1.0.5 → 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/base/.next/cache/webpack/client-development/0.pack +0 -0
- package/base/.next/cache/webpack/client-development/1.pack +0 -0
- package/base/.next/cache/webpack/client-development/index.pack +0 -0
- package/base/.next/cache/webpack/client-development/index.pack.old +0 -0
- package/base/.next/cache/webpack/server-development/0.pack +0 -0
- package/base/.next/cache/webpack/server-development/1.pack +0 -0
- package/base/.next/cache/webpack/server-development/index.pack +0 -0
- package/base/.next/cache/webpack/server-development/index.pack.old +0 -0
- package/base/.next/server/emails_notion-magic-link_tsx.js +1 -91
- package/base/.next/server/emails_stripe-welcome_tsx.js +1 -81
- package/base/.next/server/emails_vercel-invite-user_tsx.js +1 -111
- package/base/.next/server/pages/[...path].js +168 -68
- package/base/.next/server/pages/_app.js +48 -81
- package/base/.next/server/pages/_document.js +36 -36
- package/base/.next/server/pages/_error.js +6 -6
- package/base/.next/server/pages/api/[...path].js +102 -215
- package/base/.next/server/pages-manifest.json +3 -1
- package/base/.next/server/webpack-api-runtime.js +0 -30
- package/base/.next/server/webpack-runtime.js +1 -1
- package/base/.next/static/chunks/amp.js +387 -387
- package/base/.next/static/chunks/main.js +522 -522
- package/base/.next/static/chunks/pages/[...path].js +467 -259
- package/base/.next/static/chunks/pages/_app.js +211 -243
- package/base/.next/static/chunks/pages/_error.js +6 -6
- package/base/.next/static/chunks/react-refresh.js +21 -21
- package/base/.next/static/chunks/webpack.js +1 -1
- package/base/.next/static/webpack/{118b91f318a0d84a.webpack.hot-update.json → 94b31eaefc86ea7b.webpack.hot-update.json} +0 -0
- package/base/.next/static/webpack/{webpack.f600aa1a5c634af4.hot-update.js → webpack.94b31eaefc86ea7b.hot-update.js} +6 -1
- package/base/.next/trace +5 -20
- package/base/package.json +5 -3
- package/base/src/components/code/code.tsx +152 -0
- package/base/src/components/code/index.ts +1 -0
- package/base/src/components/icon-button/icon-button.tsx +23 -0
- package/base/src/components/icon-button/index.ts +1 -0
- package/base/src/components/icons/icon-base.tsx +26 -0
- package/base/src/components/icons/icon-check.tsx +18 -0
- package/base/src/components/icons/icon-clipboard.tsx +39 -0
- package/base/src/components/icons/icon-download.tsx +18 -0
- package/base/src/components/icons/icon-loading.tsx +33 -0
- package/base/src/components/icons/index.ts +4 -0
- package/base/src/components/layout.tsx +8 -5
- package/base/src/components/tooltip/index.ts +1 -0
- package/base/src/components/tooltip/tooltip-arrow.tsx +1 -0
- package/base/src/components/tooltip/tooltip-content.tsx +26 -0
- package/base/src/components/tooltip/tooltip-provider.tsx +1 -0
- package/base/src/components/tooltip/tooltip-trigger.tsx +1 -0
- package/base/src/components/tooltip/tooltip.tsx +22 -0
- package/base/src/pages/[...path].tsx +16 -9
- package/base/src/pages/_app.tsx +1 -1
- package/base/src/utils/copy-text-to-clipboard.ts +7 -0
- package/package.json +4 -3
- package/src/index.js +6 -6
- package/base/.next/cache/webpack/client-development/2.pack +0 -0
- package/base/.next/cache/webpack/client-development/3.pack +0 -0
- package/base/.next/cache/webpack/client-development/4.pack +0 -0
- package/base/.next/cache/webpack/client-development/5.pack +0 -0
- package/base/.next/cache/webpack/client-development/6.pack +0 -0
- package/base/.next/cache/webpack/client-development/7.pack +0 -0
- package/base/.next/cache/webpack/client-development/8.pack +0 -0
- package/base/.next/cache/webpack/client-development/9.pack +0 -0
- package/base/.next/cache/webpack/server-development/10.pack +0 -0
- package/base/.next/cache/webpack/server-development/11.pack +0 -0
- package/base/.next/cache/webpack/server-development/12.pack +0 -0
- package/base/.next/cache/webpack/server-development/13.pack +0 -0
- package/base/.next/cache/webpack/server-development/2.pack +0 -0
- package/base/.next/cache/webpack/server-development/3.pack +0 -0
- package/base/.next/cache/webpack/server-development/4.pack +0 -0
- package/base/.next/cache/webpack/server-development/5.pack +0 -0
- package/base/.next/cache/webpack/server-development/6.pack +0 -0
- package/base/.next/cache/webpack/server-development/7.pack +0 -0
- package/base/.next/cache/webpack/server-development/8.pack +0 -0
- package/base/.next/cache/webpack/server-development/9.pack +0 -0
- package/base/.next/server/_error.js +0 -56
- package/base/.next/server/emails_package_json.js +0 -25
- package/base/.next/server/emails_packages_avatar-fallback_tsx.js +0 -55
- package/base/.next/server/emails_packages_avatar-image_tsx.js +0 -55
- package/base/.next/server/emails_packages_button_tsx.js +0 -55
- package/base/.next/server/emails_packages_code_tsx.js +0 -55
- package/base/.next/server/emails_packages_container_tsx.js +0 -55
- package/base/.next/server/emails_packages_heading_tsx.js +0 -55
- package/base/.next/server/emails_packages_hr_tsx.js +0 -55
- package/base/.next/server/emails_packages_img_tsx.js +0 -55
- package/base/.next/server/emails_packages_link_tsx.js +0 -55
- package/base/.next/server/emails_packages_ol_tsx.js +0 -55
- package/base/.next/server/emails_packages_pre_tsx.js +0 -55
- package/base/.next/server/emails_packages_text_tsx.js +0 -55
- package/base/.next/server/emails_packages_ul_tsx.js +0 -55
- package/base/.next/static/chunks/_error.js +0 -28
- package/base/.next/static/webpack/15a828ba327d9199.webpack.hot-update.json +0 -1
- package/base/.next/static/webpack/8922f8eea8c17006.webpack.hot-update.json +0 -1
- package/base/.next/static/webpack/b1bdf67f3279613d.webpack.hot-update.json +0 -1
- package/base/.next/static/webpack/bcfc06b028800b63.webpack.hot-update.json +0 -1
- package/base/.next/static/webpack/f600aa1a5c634af4.webpack.hot-update.json +0 -1
- package/base/.next/static/webpack/pages/[...path].b1bdf67f3279613d.hot-update.js +0 -22
- package/base/.next/static/webpack/webpack.118b91f318a0d84a.hot-update.js +0 -23
- package/base/.next/static/webpack/webpack.15a828ba327d9199.hot-update.js +0 -18
- package/base/.next/static/webpack/webpack.8922f8eea8c17006.hot-update.js +0 -18
- package/base/.next/static/webpack/webpack.b1bdf67f3279613d.hot-update.js +0 -18
- package/base/.next/static/webpack/webpack.bcfc06b028800b63.hot-update.js +0 -23
package/base/package.json
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
14
|
"@radix-ui/react-popover": "1.0.0",
|
|
15
|
+
"@radix-ui/react-tooltip": "1.0.0",
|
|
15
16
|
"@react-email/avatar": "*",
|
|
16
17
|
"@react-email/button": "*",
|
|
17
18
|
"@react-email/code": "*",
|
|
@@ -28,11 +29,12 @@
|
|
|
28
29
|
"@react-email/render": "*",
|
|
29
30
|
"@react-email/text": "*",
|
|
30
31
|
"@react-email/ul": "*",
|
|
31
|
-
"
|
|
32
|
+
"classnames": "2.3.2",
|
|
32
33
|
"lottie-react": "2.3.1",
|
|
33
34
|
"next": "12.2.3",
|
|
34
|
-
"react": "
|
|
35
|
-
"react-dom": "18.2.0"
|
|
35
|
+
"prism-react-renderer": "1.3.5",
|
|
36
|
+
"react-dom": "18.2.0",
|
|
37
|
+
"react": "18.2.0"
|
|
36
38
|
},
|
|
37
39
|
"devDependencies": {
|
|
38
40
|
"@babel/core": "7.19.1",
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import classnames from 'classnames';
|
|
2
|
+
import Highlight, { defaultProps, Language } from 'prism-react-renderer';
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { IconButton } from '../icon-button';
|
|
5
|
+
import { copyTextToClipboard } from '../../utils/copy-text-to-clipboard';
|
|
6
|
+
import { IconClipboard, IconCheck, IconDownload } from '../icons';
|
|
7
|
+
import { Tooltip } from '../tooltip';
|
|
8
|
+
|
|
9
|
+
interface CodeProps {
|
|
10
|
+
children: any;
|
|
11
|
+
className?: string;
|
|
12
|
+
language?: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const theme = {
|
|
16
|
+
plain: {
|
|
17
|
+
color: '#EDEDEF',
|
|
18
|
+
fontSize: 13,
|
|
19
|
+
fontFamily: 'MonoLisa, Menlo, monospace',
|
|
20
|
+
},
|
|
21
|
+
styles: [
|
|
22
|
+
{
|
|
23
|
+
types: ['comment'],
|
|
24
|
+
style: {
|
|
25
|
+
color: '#706F78',
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
types: ['atrule', 'keyword', 'attr-name', 'selector'],
|
|
30
|
+
style: {
|
|
31
|
+
color: '#7E7D86',
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
types: ['punctuation', 'operator'],
|
|
36
|
+
style: {
|
|
37
|
+
color: '#706F78',
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
types: ['class-name', 'function', 'tag', 'key-white'],
|
|
42
|
+
style: {
|
|
43
|
+
color: '#EDEDEF',
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
],
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export const Code: React.FC<Readonly<CodeProps>> = ({
|
|
50
|
+
children,
|
|
51
|
+
className,
|
|
52
|
+
language = 'html',
|
|
53
|
+
...props
|
|
54
|
+
}) => {
|
|
55
|
+
const [isCopied, setIsCopied] = React.useState(false);
|
|
56
|
+
const value = children.trim();
|
|
57
|
+
|
|
58
|
+
const file = new File([value], 'template.html', {
|
|
59
|
+
type: 'text/html',
|
|
60
|
+
});
|
|
61
|
+
const url = URL.createObjectURL(file);
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<Highlight
|
|
65
|
+
{...defaultProps}
|
|
66
|
+
theme={theme}
|
|
67
|
+
code={value}
|
|
68
|
+
language={language as Language}
|
|
69
|
+
>
|
|
70
|
+
{({ tokens, getLineProps, getTokenProps }) => (
|
|
71
|
+
<pre
|
|
72
|
+
className={classnames(
|
|
73
|
+
'relative my-8 w-full min-w-full max-w-full overflow-auto whitespace-pre rounded-md border border-gray-6 p-4 text-sm backdrop-blur-md',
|
|
74
|
+
className,
|
|
75
|
+
)}
|
|
76
|
+
style={{
|
|
77
|
+
lineHeight: '130%',
|
|
78
|
+
background:
|
|
79
|
+
'linear-gradient(145.37deg, rgba(255, 255, 255, 0.09) -8.75%, rgba(255, 255, 255, 0.027) 83.95%)',
|
|
80
|
+
boxShadow: 'rgb(0 0 0 / 10%) 0px 5px 30px -5px',
|
|
81
|
+
}}
|
|
82
|
+
>
|
|
83
|
+
<Tooltip>
|
|
84
|
+
<Tooltip.Trigger className="absolute top-3 right-3 hidden md:block">
|
|
85
|
+
<IconButton
|
|
86
|
+
onClick={async () => {
|
|
87
|
+
setIsCopied(true);
|
|
88
|
+
await copyTextToClipboard(value);
|
|
89
|
+
setTimeout(() => setIsCopied(false), 3000);
|
|
90
|
+
}}
|
|
91
|
+
>
|
|
92
|
+
{isCopied ? <IconCheck /> : <IconClipboard />}
|
|
93
|
+
</IconButton>
|
|
94
|
+
</Tooltip.Trigger>
|
|
95
|
+
<Tooltip.Content>Copy to Clipboard</Tooltip.Content>
|
|
96
|
+
</Tooltip>
|
|
97
|
+
|
|
98
|
+
<Tooltip>
|
|
99
|
+
<Tooltip.Trigger className="text-gray-11 absolute top-3 right-8 hidden md:block">
|
|
100
|
+
<a title="Download HTML" href={url} download={file.name}>
|
|
101
|
+
<IconDownload />
|
|
102
|
+
</a>
|
|
103
|
+
</Tooltip.Trigger>
|
|
104
|
+
<Tooltip.Content>Download HTML</Tooltip.Content>
|
|
105
|
+
</Tooltip>
|
|
106
|
+
|
|
107
|
+
<div
|
|
108
|
+
className="absolute right-0 top-0 h-px w-[300px]"
|
|
109
|
+
style={{
|
|
110
|
+
background:
|
|
111
|
+
'linear-gradient(90deg, rgba(56, 189, 248, 0) 0%, rgba(56, 189, 248, 0) 0%, rgba(232, 232, 232, 0.2) 33.02%, rgba(143, 143, 143, 0.6719) 64.41%, rgba(236, 72, 153, 0) 98.93%)',
|
|
112
|
+
}}
|
|
113
|
+
/>
|
|
114
|
+
{tokens.map((line, i) => {
|
|
115
|
+
return (
|
|
116
|
+
<div
|
|
117
|
+
key={i}
|
|
118
|
+
{...getLineProps({ line, key: i })}
|
|
119
|
+
className={classnames('whitespace-pre', {
|
|
120
|
+
"before:text-gray-11 before:mr-2 before:content-['$']":
|
|
121
|
+
language === 'bash' && tokens.length === 1,
|
|
122
|
+
})}
|
|
123
|
+
>
|
|
124
|
+
{line.map((token, key) => {
|
|
125
|
+
const isException =
|
|
126
|
+
token.content === 'from' && line[key + 1]?.content === ':';
|
|
127
|
+
const newTypes = isException
|
|
128
|
+
? [...token.types, 'key-white']
|
|
129
|
+
: token.types;
|
|
130
|
+
token.types = newTypes;
|
|
131
|
+
|
|
132
|
+
return (
|
|
133
|
+
<React.Fragment key={key}>
|
|
134
|
+
<span {...getTokenProps({ token, key })} />
|
|
135
|
+
</React.Fragment>
|
|
136
|
+
);
|
|
137
|
+
})}
|
|
138
|
+
</div>
|
|
139
|
+
);
|
|
140
|
+
})}
|
|
141
|
+
<div
|
|
142
|
+
className="absolute left-0 bottom-0 h-px w-[300px]"
|
|
143
|
+
style={{
|
|
144
|
+
background:
|
|
145
|
+
'linear-gradient(90deg, rgba(56, 189, 248, 0) 0%, rgba(56, 189, 248, 0) 0%, rgba(232, 232, 232, 0.2) 33.02%, rgba(143, 143, 143, 0.6719) 64.41%, rgba(236, 72, 153, 0) 98.93%)',
|
|
146
|
+
}}
|
|
147
|
+
/>
|
|
148
|
+
</pre>
|
|
149
|
+
)}
|
|
150
|
+
</Highlight>
|
|
151
|
+
);
|
|
152
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './code';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import classnames from 'classnames';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
|
|
4
|
+
export interface IconButtonProps
|
|
5
|
+
extends React.ComponentPropsWithoutRef<'button'> {}
|
|
6
|
+
|
|
7
|
+
export const IconButton = React.forwardRef<
|
|
8
|
+
HTMLButtonElement,
|
|
9
|
+
Readonly<IconButtonProps>
|
|
10
|
+
>(({ children, className, ...props }, forwardedRef) => (
|
|
11
|
+
<button
|
|
12
|
+
{...props}
|
|
13
|
+
ref={forwardedRef}
|
|
14
|
+
className={classnames(
|
|
15
|
+
'rounded text-gray-11 focus:text-gray-12 ease-in-out transition duration-200 focus:outline-none focus:ring-2 focus:ring-gray-8 hover:text-gray-12',
|
|
16
|
+
className,
|
|
17
|
+
)}
|
|
18
|
+
>
|
|
19
|
+
{children}
|
|
20
|
+
</button>
|
|
21
|
+
));
|
|
22
|
+
|
|
23
|
+
IconButton.displayName = 'IconButton';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './icon-button';
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
export interface IconProps {
|
|
4
|
+
size?: number;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export type IconElement = React.ElementRef<'svg'>;
|
|
8
|
+
export type RootProps = React.ComponentPropsWithoutRef<'svg'>;
|
|
9
|
+
|
|
10
|
+
export interface IconProps extends RootProps {}
|
|
11
|
+
|
|
12
|
+
export const IconBase = React.forwardRef<IconElement, Readonly<IconProps>>(
|
|
13
|
+
({ size = 20, ...props }, forwardedRef) => (
|
|
14
|
+
<svg
|
|
15
|
+
ref={forwardedRef}
|
|
16
|
+
width={size}
|
|
17
|
+
height={size}
|
|
18
|
+
viewBox="0 0 24 24"
|
|
19
|
+
fill="none"
|
|
20
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
21
|
+
{...props}
|
|
22
|
+
/>
|
|
23
|
+
),
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
IconBase.displayName = 'IconBase';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { IconBase, IconElement, IconProps } from './icon-base';
|
|
3
|
+
|
|
4
|
+
export const IconCheck = React.forwardRef<IconElement, Readonly<IconProps>>(
|
|
5
|
+
({ ...props }, forwardedRef) => (
|
|
6
|
+
<IconBase ref={forwardedRef} {...props}>
|
|
7
|
+
<path
|
|
8
|
+
d="M16.25 8.75L10.406 15.25L7.75 12.75"
|
|
9
|
+
stroke="currentColor"
|
|
10
|
+
strokeWidth="1.5"
|
|
11
|
+
strokeLinecap="round"
|
|
12
|
+
strokeLinejoin="round"
|
|
13
|
+
/>
|
|
14
|
+
</IconBase>
|
|
15
|
+
),
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
IconCheck.displayName = 'IconCheck';
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { IconBase, IconElement, IconProps } from './icon-base';
|
|
3
|
+
|
|
4
|
+
export const IconClipboard = React.forwardRef<IconElement, Readonly<IconProps>>(
|
|
5
|
+
({ ...props }, forwardedRef) => (
|
|
6
|
+
<IconBase ref={forwardedRef} {...props}>
|
|
7
|
+
<path
|
|
8
|
+
d="M9 6.75H7.75C6.64543 6.75 5.75 7.64543 5.75 8.75V17.25C5.75 18.3546 6.64543 19.25 7.75 19.25H16.25C17.3546 19.25 18.25 18.3546 18.25 17.25V8.75C18.25 7.64543 17.3546 6.75 16.25 6.75H15"
|
|
9
|
+
stroke="currentColor"
|
|
10
|
+
strokeWidth="1.5"
|
|
11
|
+
strokeLinecap="round"
|
|
12
|
+
strokeLinejoin="round"
|
|
13
|
+
/>
|
|
14
|
+
<path
|
|
15
|
+
d="M14 8.25H10C9.44772 8.25 9 7.80228 9 7.25V5.75C9 5.19772 9.44772 4.75 10 4.75H14C14.5523 4.75 15 5.19772 15 5.75V7.25C15 7.80228 14.5523 8.25 14 8.25Z"
|
|
16
|
+
stroke="currentColor"
|
|
17
|
+
strokeWidth="1.5"
|
|
18
|
+
strokeLinecap="round"
|
|
19
|
+
strokeLinejoin="round"
|
|
20
|
+
/>
|
|
21
|
+
<path
|
|
22
|
+
d="M9.75 12.25H14.25"
|
|
23
|
+
stroke="currentColor"
|
|
24
|
+
strokeWidth="1.5"
|
|
25
|
+
strokeLinecap="round"
|
|
26
|
+
strokeLinejoin="round"
|
|
27
|
+
/>
|
|
28
|
+
<path
|
|
29
|
+
d="M9.75 15.25H14.25"
|
|
30
|
+
stroke="currentColor"
|
|
31
|
+
strokeWidth="1.5"
|
|
32
|
+
strokeLinecap="round"
|
|
33
|
+
strokeLinejoin="round"
|
|
34
|
+
/>
|
|
35
|
+
</IconBase>
|
|
36
|
+
),
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
IconClipboard.displayName = 'IconClipboard';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { IconBase, IconElement, IconProps } from './icon-base';
|
|
3
|
+
|
|
4
|
+
export const IconDownload = React.forwardRef<IconElement, Readonly<IconProps>>(
|
|
5
|
+
({ ...props }, forwardedRef) => (
|
|
6
|
+
<IconBase ref={forwardedRef} {...props}>
|
|
7
|
+
<path
|
|
8
|
+
d="M4.75 14.75v1.5a3 3 0 0 0 3 3h8.5a3 3 0 0 0 3-3v-1.5M12 14.25v-9.5M8.75 10.75l3.25 3.5 3.25-3.5"
|
|
9
|
+
stroke="currentColor"
|
|
10
|
+
strokeWidth={1.5}
|
|
11
|
+
strokeLinecap="round"
|
|
12
|
+
strokeLinejoin="round"
|
|
13
|
+
/>
|
|
14
|
+
</IconBase>
|
|
15
|
+
),
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
IconDownload.displayName = 'IconDownload';
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import classnames from 'classnames';
|
|
3
|
+
import { IconBase, IconElement, IconProps } from './icon-base';
|
|
4
|
+
|
|
5
|
+
export const IconLoading = React.forwardRef<IconElement, Readonly<IconProps>>(
|
|
6
|
+
({ className, ...props }, forwardedRef) => (
|
|
7
|
+
<IconBase
|
|
8
|
+
ref={forwardedRef}
|
|
9
|
+
className={classnames('animate-spin', className)}
|
|
10
|
+
{...props}
|
|
11
|
+
>
|
|
12
|
+
<path
|
|
13
|
+
className="opacity-[15%]"
|
|
14
|
+
d="M5 12C5 8.13401 8.13401 5 12 5C15.866 5 19 8.13401 19 12C19 15.866 15.866 19 12 19C8.13401 19 5 15.866 5 12Z"
|
|
15
|
+
stroke="currentColor"
|
|
16
|
+
strokeWidth="2"
|
|
17
|
+
strokeLinecap="round"
|
|
18
|
+
strokeLinejoin="round"
|
|
19
|
+
/>
|
|
20
|
+
<circle
|
|
21
|
+
cx="12"
|
|
22
|
+
cy="12"
|
|
23
|
+
r="7"
|
|
24
|
+
stroke="currentColor"
|
|
25
|
+
strokeWidth="2"
|
|
26
|
+
strokeDasharray="150,200"
|
|
27
|
+
strokeDashoffset="-16"
|
|
28
|
+
/>
|
|
29
|
+
</IconBase>
|
|
30
|
+
),
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
IconLoading.displayName = 'IconLoading';
|
|
@@ -1,15 +1,18 @@
|
|
|
1
|
-
import { render } from '@react-email/render';
|
|
2
|
-
import dynamic from 'next/dynamic';
|
|
3
|
-
import Head from 'next/head';
|
|
4
1
|
import * as React from 'react';
|
|
5
2
|
import Logo from '../components/topbar/logo';
|
|
6
3
|
import External from '../components/topbar/external';
|
|
7
4
|
import Feedback from '../components/topbar/feedback';
|
|
8
5
|
import SendTest from '../components/topbar/send-test';
|
|
9
6
|
import ToggleView from '../components/topbar/toggle-view';
|
|
10
|
-
import { Code } from '
|
|
7
|
+
import { Code } from '../components/code';
|
|
11
8
|
|
|
12
|
-
export default function Layout({
|
|
9
|
+
export default function Layout({
|
|
10
|
+
markup,
|
|
11
|
+
path,
|
|
12
|
+
}: {
|
|
13
|
+
markup: string;
|
|
14
|
+
path: string;
|
|
15
|
+
}) {
|
|
13
16
|
const [isPreview, setIsPreview] = React.useState(true);
|
|
14
17
|
|
|
15
18
|
return (
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './tooltip';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { TooltipArrow } from '@radix-ui/react-tooltip';
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Arrow, Content, Portal } from '@radix-ui/react-tooltip';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
|
|
4
|
+
type ContentElement = React.ElementRef<typeof Content>;
|
|
5
|
+
type ContentProps = React.ComponentPropsWithoutRef<typeof Content>;
|
|
6
|
+
|
|
7
|
+
export interface TooltipProps extends ContentProps {}
|
|
8
|
+
|
|
9
|
+
export const TooltipContent = React.forwardRef<
|
|
10
|
+
ContentElement,
|
|
11
|
+
Readonly<TooltipProps>
|
|
12
|
+
>(({ className, sideOffset = 6, children, ...props }, forwardedRef) => (
|
|
13
|
+
<Portal>
|
|
14
|
+
<Content
|
|
15
|
+
{...props}
|
|
16
|
+
ref={forwardedRef}
|
|
17
|
+
className="bg-gray-2 border border-gray-7 z-20 px-2 py-1 rounded-md text-sm radix-side-top:animate-slide-down-fade radix-side-right:animate-slide-left-fade radix-side-bottom:animate-slide-up-fade radix-side-left:animate-slide-right-fade"
|
|
18
|
+
sideOffset={sideOffset}
|
|
19
|
+
>
|
|
20
|
+
{children}
|
|
21
|
+
<Arrow fill="#1c1c1f" />
|
|
22
|
+
</Content>
|
|
23
|
+
</Portal>
|
|
24
|
+
));
|
|
25
|
+
|
|
26
|
+
TooltipContent.displayName = 'TooltipContent';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { TooltipProvider } from '@radix-ui/react-tooltip';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { TooltipTrigger } from '@radix-ui/react-tooltip';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Root } from '@radix-ui/react-tooltip';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { TooltipArrow } from './tooltip-arrow';
|
|
4
|
+
import { TooltipContent } from './tooltip-content';
|
|
5
|
+
import { TooltipProvider } from './tooltip-provider';
|
|
6
|
+
import { TooltipTrigger } from './tooltip-trigger';
|
|
7
|
+
|
|
8
|
+
type RootProps = React.ComponentPropsWithoutRef<typeof Root>;
|
|
9
|
+
|
|
10
|
+
export interface TooltipProps extends RootProps {}
|
|
11
|
+
|
|
12
|
+
export const TooltipRoot: React.FC<Readonly<TooltipProps>> = ({
|
|
13
|
+
children,
|
|
14
|
+
...props
|
|
15
|
+
}) => <Root {...props}>{children}</Root>;
|
|
16
|
+
|
|
17
|
+
export const Tooltip = Object.assign(TooltipRoot, {
|
|
18
|
+
Arrow: TooltipArrow,
|
|
19
|
+
Provider: TooltipProvider,
|
|
20
|
+
Content: TooltipContent,
|
|
21
|
+
Trigger: TooltipTrigger,
|
|
22
|
+
});
|
|
@@ -7,21 +7,28 @@ export async function getServerSideProps({ params }: { params: any }) {
|
|
|
7
7
|
const resolvedPath = path.length > 0 ? path.join('/') : path;
|
|
8
8
|
|
|
9
9
|
try {
|
|
10
|
-
const req = await fetch(
|
|
11
|
-
|
|
10
|
+
const req = await fetch(
|
|
11
|
+
`http://localhost:3001/api/${resolvedPath}?json=true`,
|
|
12
|
+
);
|
|
13
|
+
const { markup } = await req.json();
|
|
12
14
|
|
|
13
15
|
return {
|
|
14
|
-
props: { markup, path }
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
catch(e) {
|
|
16
|
+
props: { markup, path },
|
|
17
|
+
};
|
|
18
|
+
} catch (e) {
|
|
18
19
|
return {
|
|
19
|
-
props: {}
|
|
20
|
-
}
|
|
20
|
+
props: {},
|
|
21
|
+
};
|
|
21
22
|
}
|
|
22
23
|
}
|
|
23
24
|
|
|
24
|
-
export default function Preview({
|
|
25
|
+
export default function Preview({
|
|
26
|
+
markup,
|
|
27
|
+
path,
|
|
28
|
+
}: {
|
|
29
|
+
markup: string;
|
|
30
|
+
path: string;
|
|
31
|
+
}) {
|
|
25
32
|
return (
|
|
26
33
|
<>
|
|
27
34
|
<Head>
|
package/base/src/pages/_app.tsx
CHANGED
package/package.json
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-email",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
4
4
|
"description": "A live preview of your emails right in your browser.",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"dependencies": {
|
|
8
8
|
"commander": "^9.4.1",
|
|
9
|
-
"
|
|
9
|
+
"copy": "^0.3.2",
|
|
10
10
|
"inquirer": "^9.1.4",
|
|
11
|
-
"prompts": "^2.4.2"
|
|
11
|
+
"prompts": "^2.4.2",
|
|
12
|
+
"shelljs": "^0.8.5"
|
|
12
13
|
},
|
|
13
14
|
"bin": {
|
|
14
15
|
"email": "src/index.js"
|
package/src/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
const { Command } = require('commander');
|
|
4
|
+
const copy = require('copy');
|
|
4
5
|
const path = require('path');
|
|
5
|
-
const fse = require('fs-extra');
|
|
6
6
|
const shell = require('shelljs');
|
|
7
7
|
const packageJson = require('../package.json');
|
|
8
8
|
|
|
@@ -14,13 +14,13 @@ program
|
|
|
14
14
|
.description(packageJson.description);
|
|
15
15
|
|
|
16
16
|
const dev = () => {
|
|
17
|
-
const currentPath = process.cwd()
|
|
17
|
+
const currentPath = `${process.cwd()}/*.tsx`;
|
|
18
18
|
const basePath = path.resolve(__dirname, '../base/emails');
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
copy(currentPath, basePath, () => {
|
|
21
|
+
shell.cd(path.join(__dirname, '../base'));
|
|
22
|
+
shell.exec('npm run dev', { async: true });
|
|
23
|
+
});
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
program
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|