@react-email/preview-server 4.1.0-canary.9 → 4.1.0
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/.next/BUILD_ID +1 -1
- package/.next/app-build-manifest.json +32 -32
- package/.next/app-path-routes-manifest.json +1 -1
- package/.next/build-manifest.json +14 -14
- package/.next/diagnostics/framework.json +1 -1
- package/.next/next-minimal-server.js.nft.json +1 -1
- package/.next/next-server.js.nft.json +1 -1
- package/.next/prerender-manifest.json +3 -3
- package/.next/required-server-files.json +5 -5
- package/.next/server/app/_not-found/page.js +1 -1
- package/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/favicon.ico/route.js +1 -1
- package/.next/server/app/favicon.ico/route.js.nft.json +1 -1
- package/.next/server/app/page.js +1 -1
- package/.next/server/app/page.js.nft.json +1 -1
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app/preview/[...slug]/page.js +356 -174
- package/.next/server/app/preview/[...slug]/page.js.nft.json +1 -1
- package/.next/server/app/preview/[...slug]/page_client-reference-manifest.js +1 -1
- package/.next/server/app-paths-manifest.json +1 -1
- package/.next/server/chunks/277.js +1 -0
- package/.next/server/chunks/{879.js → 532.js} +7 -7
- package/.next/server/chunks/550.js +6 -0
- package/.next/server/chunks/834.js +15 -0
- package/.next/server/chunks/851.js +20 -0
- package/.next/server/chunks/905.js +1 -0
- package/.next/server/middleware-build-manifest.js +1 -1
- package/.next/server/next-font-manifest.js +1 -1
- package/.next/server/next-font-manifest.json +1 -1
- package/.next/server/pages/500.html +1 -1
- package/.next/server/pages/_app.js +1 -1
- package/.next/server/pages/_app.js.nft.json +1 -1
- package/.next/server/pages/_document.js +1 -1
- package/.next/server/pages/_document.js.nft.json +1 -1
- package/.next/server/pages/_error.js +1 -1
- package/.next/server/pages/_error.js.nft.json +1 -1
- package/.next/server/server-reference-manifest.js +1 -1
- package/.next/server/server-reference-manifest.json +1 -1
- package/.next/static/{pT9c18D6E8gNsHAfpxTUA → K0QONxIGIQiCTm2sc3hH-}/_buildManifest.js +1 -1
- package/.next/static/chunks/343-0aa226f42148dce4.js +1 -0
- package/.next/static/chunks/353-5e7d05b120b2e25f.js +1 -0
- package/.next/static/chunks/445-576b0c51a037fe4d.js +1 -0
- package/.next/static/chunks/483-03a4518fac962ed2.js +1 -0
- package/.next/static/chunks/624-9d1650c8211771cd.js +1 -0
- package/.next/static/chunks/755-01456539a6894956.js +1 -0
- package/.next/static/chunks/app/_not-found/{page-aee2c5619f94a965.js → page-e9c9ee8e737ce3f8.js} +1 -1
- package/.next/static/chunks/app/layout-a5cce4132e5e62fa.js +1 -0
- package/.next/static/chunks/app/page-88bd6f22b758e157.js +1 -0
- package/.next/static/chunks/app/preview/[...slug]/page-65586b6a48695068.js +1 -0
- package/.next/static/chunks/{04c799b8-f2be86d6e75dbf29.js → e8809b48-6a73b3f51ba71e9c.js} +1 -1
- package/.next/static/chunks/{f33a14d2-188715a58266ac15.js → f33a14d2-13f6de3d216cf617.js} +1 -1
- package/.next/static/chunks/framework-4f208795521d076c.js +1 -0
- package/.next/static/chunks/main-0000d0a5ac74fec0.js +1 -0
- package/.next/static/chunks/main-app-5d960817b9651318.js +1 -0
- package/.next/static/chunks/pages/_app-550e3587fddcaa19.js +1 -0
- package/.next/static/chunks/pages/_error-870af0ad63b0e49e.js +1 -0
- package/.next/static/chunks/{webpack-c09dcf4c47767be8.js → webpack-fc6f324c4c88f6e3.js} +1 -1
- package/.next/static/css/48dcea18d820a298.css +3 -0
- package/.next/trace +27 -27
- package/.next/types/app/layout.ts +1 -1
- package/.next/types/app/page.ts +1 -1
- package/.next/types/app/preview/[...slug]/page.ts +1 -1
- package/CHANGELOG.md +27 -0
- package/package.json +6 -4
- package/readme.md +35 -0
- package/scripts/dev.mts +47 -0
- package/scripts/{fill-caniemail-data.mjs → fill-caniemail-data.mts} +0 -5
- package/scripts/seed.mts +21 -0
- package/scripts/utils/default-seed/auth/account-confirmation.tsx +68 -0
- package/scripts/utils/default-seed/auth/forgot-password.tsx +71 -0
- package/scripts/utils/default-seed/communications/payment-overdue.tsx +82 -0
- package/scripts/utils/default-seed/communications/team-invite.tsx +78 -0
- package/scripts/utils/default-seed/communications/webhooks-failed.tsx +89 -0
- package/scripts/utils/default-seed/feedback-request.tsx +78 -0
- package/scripts/utils/default-seed/marketing/changelog.tsx +98 -0
- package/src/actions/email-validation/__snapshots__/check-images.spec.tsx.snap +84 -0
- package/src/actions/email-validation/check-images.spec.tsx +1 -80
- package/src/app/layout.tsx +2 -2
- package/src/app/preview/[...slug]/preview.tsx +1 -1
- package/src/components/code-container.tsx +3 -1
- package/src/components/code.tsx +60 -59
- package/src/components/logo.tsx +68 -63
- package/src/components/send.tsx +8 -5
- package/src/components/shell.tsx +4 -1
- package/src/components/sidebar/file-tree-directory-children.tsx +4 -1
- package/src/components/toolbar.tsx +9 -5
- package/src/contexts/emails.tsx +2 -2
- package/src/contexts/preview.tsx +2 -2
- package/src/hooks/use-email-rendering-result.ts +2 -2
- package/src/utils/__snapshots__/get-email-component.spec.ts.snap +183 -1
- package/src/utils/caniemail/ast/get-used-style-properties.ts +1 -0
- package/src/utils/contains-email-template.spec.ts +12 -0
- package/src/utils/contains-email-template.ts +26 -9
- package/src/utils/get-email-component.spec.ts +3 -0
- package/.next/server/chunks/200.js +0 -1
- package/.next/server/chunks/3.js +0 -15
- package/.next/server/chunks/784.js +0 -6
- package/.next/server/chunks/823.js +0 -1
- package/.next/server/chunks/915.js +0 -20
- package/.next/static/chunks/188-e278e5f1e9c4067e.js +0 -1
- package/.next/static/chunks/336-0767fdc0ff1ceaa1.js +0 -1
- package/.next/static/chunks/551-d9ce0a77591e6bf7.js +0 -1
- package/.next/static/chunks/651-337b0388fdb8c85c.js +0 -1
- package/.next/static/chunks/713-6c7607cb54b8278e.js +0 -1
- package/.next/static/chunks/834-e77d5196a2631efe.js +0 -1
- package/.next/static/chunks/app/layout-4403d8068fbec772.js +0 -1
- package/.next/static/chunks/app/page-ddc5b5b5b8d2de0e.js +0 -1
- package/.next/static/chunks/app/preview/[...slug]/page-873416b81678fe6b.js +0 -1
- package/.next/static/chunks/framework-f71c687711cb40cc.js +0 -1
- package/.next/static/chunks/main-697e2f65b52ad05c.js +0 -1
- package/.next/static/chunks/main-app-deb9839bdc2bcbd4.js +0 -1
- package/.next/static/chunks/pages/_app-2e335329c12ac3e7.js +0 -1
- package/.next/static/chunks/pages/_error-73094c2ebe868f44.js +0 -1
- package/.next/static/css/692fd92effde156a.css +0 -3
- /package/.next/static/{pT9c18D6E8gNsHAfpxTUA → K0QONxIGIQiCTm2sc3hH-}/_ssgManifest.js +0 -0
- /package/scripts/{build-preview-server.mjs → build-preview-server.mts} +0 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Body,
|
|
3
|
+
Container,
|
|
4
|
+
Head,
|
|
5
|
+
Heading,
|
|
6
|
+
Hr,
|
|
7
|
+
Html,
|
|
8
|
+
Preview,
|
|
9
|
+
Section,
|
|
10
|
+
Tailwind,
|
|
11
|
+
Text,
|
|
12
|
+
} from '@react-email/components';
|
|
13
|
+
|
|
14
|
+
interface ChangelogProps {
|
|
15
|
+
receiver: string;
|
|
16
|
+
changes: Partial<Record<'features' | 'fixes' | 'improvements', string[]>>;
|
|
17
|
+
date: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
interface ChangesProps {
|
|
21
|
+
title: React.ReactNode;
|
|
22
|
+
content: string[];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function Changes({ title, content }: ChangesProps) {
|
|
26
|
+
return (
|
|
27
|
+
<Section>
|
|
28
|
+
<Heading as="h2" className="my-[12px]">
|
|
29
|
+
{title}
|
|
30
|
+
</Heading>
|
|
31
|
+
<ul className="list-disc pl-6">
|
|
32
|
+
{content.map((feature, index) => (
|
|
33
|
+
<li key={index} className="mb-2">
|
|
34
|
+
{feature}
|
|
35
|
+
</li>
|
|
36
|
+
))}
|
|
37
|
+
</ul>
|
|
38
|
+
</Section>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export default function Changelog({ receiver, date, changes }: ChangelogProps) {
|
|
43
|
+
return (
|
|
44
|
+
<Html>
|
|
45
|
+
<Head />
|
|
46
|
+
<Tailwind>
|
|
47
|
+
<Body className="bg-black text-white">
|
|
48
|
+
<Preview>
|
|
49
|
+
The changes as of {date} particularly tailored to you
|
|
50
|
+
</Preview>
|
|
51
|
+
<Container className="mx-auto">
|
|
52
|
+
<Heading className="font-bold text-center my-[48px] text-[32px]">
|
|
53
|
+
Hello {receiver},
|
|
54
|
+
</Heading>
|
|
55
|
+
<Text>
|
|
56
|
+
We've been hard at work making improvements to our service, and we
|
|
57
|
+
wanted to share the latest changes as of{' '}
|
|
58
|
+
<span className="font-bold">{date}</span> with you.
|
|
59
|
+
</Text>
|
|
60
|
+
{changes.features && changes.features.length > 0 ? (
|
|
61
|
+
<Changes title="Features" content={changes.features} />
|
|
62
|
+
) : null}
|
|
63
|
+
{changes.improvements && changes.improvements.length > 0 ? (
|
|
64
|
+
<Changes title="Improvements" content={changes.improvements} />
|
|
65
|
+
) : null}
|
|
66
|
+
{changes.fixes && changes.fixes.length > 0 ? (
|
|
67
|
+
<Changes title="Fixes" content={changes.fixes} />
|
|
68
|
+
) : null}
|
|
69
|
+
<Text className="mt-6">- React Email team</Text>
|
|
70
|
+
<Hr style={{ borderTopColor: '#404040' }} />
|
|
71
|
+
<Text className="text-[#606060] font-bold">
|
|
72
|
+
React Email, 999 React St, Email City, EC 12345
|
|
73
|
+
</Text>
|
|
74
|
+
</Container>
|
|
75
|
+
</Body>
|
|
76
|
+
</Tailwind>
|
|
77
|
+
</Html>
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
Changelog.PreviewProps = {
|
|
82
|
+
receiver: 'user',
|
|
83
|
+
changes: {
|
|
84
|
+
features: [
|
|
85
|
+
'Added a new feature to enhance user experience',
|
|
86
|
+
'Introduced a dark mode option for better accessibility',
|
|
87
|
+
],
|
|
88
|
+
fixes: [
|
|
89
|
+
'Fixed a bug that caused the app to crash on startup',
|
|
90
|
+
'Resolved an issue with email notifications not being sent',
|
|
91
|
+
],
|
|
92
|
+
improvements: [
|
|
93
|
+
'Improved performance of the application by optimizing database queries',
|
|
94
|
+
'Enhanced security measures to protect user data',
|
|
95
|
+
],
|
|
96
|
+
},
|
|
97
|
+
date: 'June 4th, 2025',
|
|
98
|
+
} satisfies ChangelogProps;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
|
+
|
|
3
|
+
exports[`checkImages() 1`] = `
|
|
4
|
+
[
|
|
5
|
+
{
|
|
6
|
+
"checks": [
|
|
7
|
+
{
|
|
8
|
+
"metadata": {
|
|
9
|
+
"alt": undefined,
|
|
10
|
+
},
|
|
11
|
+
"passed": false,
|
|
12
|
+
"type": "accessibility",
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"passed": true,
|
|
16
|
+
"type": "syntax",
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"passed": true,
|
|
20
|
+
"type": "security",
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"metadata": {
|
|
24
|
+
"fetchStatusCode": 200,
|
|
25
|
+
},
|
|
26
|
+
"passed": true,
|
|
27
|
+
"type": "fetch_attempt",
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"metadata": {
|
|
31
|
+
"byteCount": 26808,
|
|
32
|
+
},
|
|
33
|
+
"passed": true,
|
|
34
|
+
"type": "image_size",
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
"codeLocation": {
|
|
38
|
+
"column": 3,
|
|
39
|
+
"line": 2,
|
|
40
|
+
},
|
|
41
|
+
"source": "https://resend.com/static/brand/resend-icon-white.png",
|
|
42
|
+
"status": "warning",
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"checks": [
|
|
46
|
+
{
|
|
47
|
+
"metadata": {
|
|
48
|
+
"alt": "codepen challenges",
|
|
49
|
+
},
|
|
50
|
+
"passed": true,
|
|
51
|
+
"type": "accessibility",
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"passed": true,
|
|
55
|
+
"type": "syntax",
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"passed": true,
|
|
59
|
+
"type": "security",
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"metadata": {
|
|
63
|
+
"fetchStatusCode": 200,
|
|
64
|
+
},
|
|
65
|
+
"passed": true,
|
|
66
|
+
"type": "fetch_attempt",
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"metadata": {
|
|
70
|
+
"byteCount": 111922,
|
|
71
|
+
},
|
|
72
|
+
"passed": true,
|
|
73
|
+
"type": "image_size",
|
|
74
|
+
},
|
|
75
|
+
],
|
|
76
|
+
"codeLocation": {
|
|
77
|
+
"column": 3,
|
|
78
|
+
"line": 3,
|
|
79
|
+
},
|
|
80
|
+
"source": "/static/codepen-challengers.png",
|
|
81
|
+
"status": "success",
|
|
82
|
+
},
|
|
83
|
+
]
|
|
84
|
+
`;
|
|
@@ -17,84 +17,5 @@ test('checkImages()', async () => {
|
|
|
17
17
|
break;
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
|
-
expect(results).
|
|
21
|
-
{
|
|
22
|
-
source: 'https://resend.com/static/brand/resend-icon-white.png',
|
|
23
|
-
codeLocation: {
|
|
24
|
-
line: 2,
|
|
25
|
-
column: 3,
|
|
26
|
-
},
|
|
27
|
-
checks: [
|
|
28
|
-
{
|
|
29
|
-
passed: false,
|
|
30
|
-
type: 'accessibility',
|
|
31
|
-
metadata: {
|
|
32
|
-
alt: undefined,
|
|
33
|
-
},
|
|
34
|
-
},
|
|
35
|
-
{
|
|
36
|
-
passed: true,
|
|
37
|
-
type: 'syntax',
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
passed: true,
|
|
41
|
-
type: 'security',
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
passed: true,
|
|
45
|
-
type: 'fetch_attempt',
|
|
46
|
-
metadata: {
|
|
47
|
-
fetchStatusCode: 200,
|
|
48
|
-
},
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
passed: true,
|
|
52
|
-
type: 'image_size',
|
|
53
|
-
metadata: {
|
|
54
|
-
byteCount: 23_138,
|
|
55
|
-
},
|
|
56
|
-
},
|
|
57
|
-
],
|
|
58
|
-
status: 'warning',
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
codeLocation: {
|
|
62
|
-
line: 3,
|
|
63
|
-
column: 3,
|
|
64
|
-
},
|
|
65
|
-
checks: [
|
|
66
|
-
{
|
|
67
|
-
metadata: {
|
|
68
|
-
alt: 'codepen challenges',
|
|
69
|
-
},
|
|
70
|
-
passed: true,
|
|
71
|
-
type: 'accessibility',
|
|
72
|
-
},
|
|
73
|
-
{
|
|
74
|
-
passed: true,
|
|
75
|
-
type: 'syntax',
|
|
76
|
-
},
|
|
77
|
-
{
|
|
78
|
-
passed: true,
|
|
79
|
-
type: 'security',
|
|
80
|
-
},
|
|
81
|
-
{
|
|
82
|
-
metadata: {
|
|
83
|
-
fetchStatusCode: 200,
|
|
84
|
-
},
|
|
85
|
-
passed: true,
|
|
86
|
-
type: 'fetch_attempt',
|
|
87
|
-
},
|
|
88
|
-
{
|
|
89
|
-
metadata: {
|
|
90
|
-
byteCount: 111_922,
|
|
91
|
-
},
|
|
92
|
-
passed: true,
|
|
93
|
-
type: 'image_size',
|
|
94
|
-
},
|
|
95
|
-
],
|
|
96
|
-
source: '/static/codepen-challengers.png',
|
|
97
|
-
status: 'success',
|
|
98
|
-
},
|
|
99
|
-
] satisfies ImageCheckingResult[]);
|
|
20
|
+
expect(results).toMatchSnapshot();
|
|
100
21
|
});
|
package/src/app/layout.tsx
CHANGED
|
@@ -27,8 +27,8 @@ const RootLayout = async ({ children }: { children: React.ReactNode }) => {
|
|
|
27
27
|
className={`${inter.variable} ${sfMono.variable} font-sans`}
|
|
28
28
|
lang="en"
|
|
29
29
|
>
|
|
30
|
-
<body className="relative
|
|
31
|
-
<div className="bg-gradient-to-t from-slate-3 flex">
|
|
30
|
+
<body className="relative h-screen bg-black text-slate-11 leading-loose selection:bg-cyan-5 selection:text-cyan-12">
|
|
31
|
+
<div className="bg-gradient-to-t from-slate-3 flex flex-col">
|
|
32
32
|
<EmailsProvider
|
|
33
33
|
initialEmailsDirectoryMetadata={emailsDirectoryMetadata}
|
|
34
34
|
>
|
|
@@ -162,7 +162,7 @@ const Preview = ({ emailTitle, className, ...props }: PreviewProps) => {
|
|
|
162
162
|
width={width}
|
|
163
163
|
>
|
|
164
164
|
<iframe
|
|
165
|
-
className="
|
|
165
|
+
className="max-h-full rounded-lg bg-white [color-scheme:auto]"
|
|
166
166
|
ref={(iframe) => {
|
|
167
167
|
if (iframe) {
|
|
168
168
|
return makeIframeDocumentBubbleEvents(iframe);
|
|
@@ -37,6 +37,8 @@ export const CodeContainer: React.FC<Readonly<CodeContainerProps>> = ({
|
|
|
37
37
|
});
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
+
const codeId = React.useId();
|
|
41
|
+
|
|
40
42
|
return (
|
|
41
43
|
<div
|
|
42
44
|
className="relative max-h-[650px] w-full h-full whitespace-pre rounded-md border border-slate-6 text-sm"
|
|
@@ -49,7 +51,7 @@ export const CodeContainer: React.FC<Readonly<CodeContainerProps>> = ({
|
|
|
49
51
|
>
|
|
50
52
|
<div className="h-9 border-b border-slate-6">
|
|
51
53
|
<div className="flex">
|
|
52
|
-
<LayoutGroup id=
|
|
54
|
+
<LayoutGroup id={codeId}>
|
|
53
55
|
{markups.map(({ language }) => {
|
|
54
56
|
const isCurrentLang = activeLang === language;
|
|
55
57
|
return (
|
package/src/components/code.tsx
CHANGED
|
@@ -105,78 +105,79 @@ export const Code: React.FC<Readonly<CodeProps>> = ({
|
|
|
105
105
|
/>
|
|
106
106
|
<div
|
|
107
107
|
ref={scrollerRef}
|
|
108
|
-
className="
|
|
108
|
+
className="max-h-[650px] h-full p-4 after:w-full after:static after:block after:h-4 after:content-[''] overflow-auto"
|
|
109
109
|
>
|
|
110
|
-
<div className="
|
|
111
|
-
{tokens.map((_, i) => (
|
|
112
|
-
<Link
|
|
113
|
-
id={`L${i + 1}`}
|
|
114
|
-
key={i}
|
|
115
|
-
href={{
|
|
116
|
-
hash: `#L${i + 1}`,
|
|
117
|
-
search: searchParams.toString(),
|
|
118
|
-
}}
|
|
119
|
-
scroll={false}
|
|
120
|
-
className={cn(
|
|
121
|
-
'align-middle block scroll-mt-[325px] rounded-l-sm select-none pr-3 cursor-pointer hover:text-slate-12',
|
|
122
|
-
isHighlighting(i + 1) &&
|
|
123
|
-
'text-cyan-11 hover:text-cyan-11 bg-cyan-5',
|
|
124
|
-
)}
|
|
125
|
-
type="button"
|
|
126
|
-
>
|
|
127
|
-
{i + 1}
|
|
128
|
-
</Link>
|
|
129
|
-
))}
|
|
130
|
-
</div>
|
|
131
|
-
<pre>
|
|
110
|
+
<div className="grid grid-cols-[auto_1fr] w-full">
|
|
132
111
|
{tokens.map((line, i) => {
|
|
133
112
|
const lineProps = getLineProps({
|
|
134
113
|
line,
|
|
135
114
|
key: i,
|
|
136
115
|
});
|
|
116
|
+
const isHighlighted = isHighlighting(i + 1);
|
|
117
|
+
const isHighlightStart = highlight && highlight[0] === i + 1;
|
|
118
|
+
const isHighlightEnd = highlight && highlight[1] === i + 1;
|
|
119
|
+
|
|
137
120
|
return (
|
|
138
|
-
<
|
|
139
|
-
{
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
121
|
+
<Fragment key={i}>
|
|
122
|
+
{/* Line number cell */}
|
|
123
|
+
<Link
|
|
124
|
+
id={`L${i + 1}`}
|
|
125
|
+
href={{
|
|
126
|
+
hash: `#L${i + 1}`,
|
|
127
|
+
search: searchParams.toString(),
|
|
128
|
+
}}
|
|
129
|
+
scroll={false}
|
|
130
|
+
aria-selected={isHighlighted}
|
|
131
|
+
className={cn(
|
|
132
|
+
'text-[#49494f] relative text-[13px] font-light font-[MonoLisa,_Menlo,_monospace] align-middle scroll-mt-[325px] select-none pr-3 cursor-pointer hover:text-slate-12 transition-colors',
|
|
133
|
+
'aria-selected:text-cyan-11 aria-selected:hover:text-cyan-11 aria-selected:bg-cyan-5 [&+*]:aria-selected:bg-cyan-5',
|
|
134
|
+
isHighlightStart && 'rounded-tl-sm',
|
|
135
|
+
isHighlightEnd && 'rounded-bl-sm',
|
|
136
|
+
)}
|
|
137
|
+
type="button"
|
|
138
|
+
>
|
|
139
|
+
{i + 1}
|
|
140
|
+
</Link>
|
|
141
|
+
|
|
142
|
+
{/* Code content cell */}
|
|
143
|
+
<div
|
|
144
|
+
{...lineProps}
|
|
145
|
+
className={cn('whitespace-pre transition-colors', {
|
|
144
146
|
"before:mr-2 before:text-slate-11 before:content-['$']":
|
|
145
147
|
language === 'bash' && tokens.length === 1,
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
: token.types;
|
|
160
|
-
token.types = newTypes;
|
|
148
|
+
})}
|
|
149
|
+
>
|
|
150
|
+
{line.map((token, key) => {
|
|
151
|
+
const tokenProps = getTokenProps({
|
|
152
|
+
token,
|
|
153
|
+
});
|
|
154
|
+
const isException =
|
|
155
|
+
token.content === 'from' &&
|
|
156
|
+
line[key + 1]?.content === ':';
|
|
157
|
+
const newTypes = isException
|
|
158
|
+
? [...token.types, 'key-white']
|
|
159
|
+
: token.types;
|
|
160
|
+
token.types = newTypes;
|
|
161
161
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
162
|
+
return (
|
|
163
|
+
<Fragment key={key}>
|
|
164
|
+
<span {...tokenProps} />
|
|
165
|
+
</Fragment>
|
|
166
|
+
);
|
|
167
|
+
})}
|
|
168
|
+
</div>
|
|
169
|
+
</Fragment>
|
|
169
170
|
);
|
|
170
171
|
})}
|
|
171
|
-
</
|
|
172
|
-
<div
|
|
173
|
-
className="absolute bottom-0 left-0 h-px w-[200px]"
|
|
174
|
-
style={{
|
|
175
|
-
background:
|
|
176
|
-
'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%)',
|
|
177
|
-
}}
|
|
178
|
-
/>
|
|
172
|
+
</div>
|
|
179
173
|
</div>
|
|
174
|
+
<div
|
|
175
|
+
className="absolute bottom-0 left-0 h-px w-[200px]"
|
|
176
|
+
style={{
|
|
177
|
+
background:
|
|
178
|
+
'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%)',
|
|
179
|
+
}}
|
|
180
|
+
/>
|
|
180
181
|
</>
|
|
181
182
|
)}
|
|
182
183
|
</Highlight>
|