promote-email-templates 0.0.3 → 0.0.5
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/dist/index.d.mts +0 -10
- package/dist/index.d.ts +0 -10
- package/dist/index.js +4 -9
- package/dist/index.mjs +4 -9
- package/package.json +1 -1
- package/.react-email/.eslintrc.js +0 -52
- package/.react-email/.prettierignore +0 -3
- package/.react-email/.prettierrc.js +0 -8
- package/.react-email/license.md +0 -7
- package/.react-email/next.config.js +0 -36
- package/.react-email/package.json +0 -1
- package/.react-email/postcss.config.js +0 -8
- package/.react-email/readme.md +0 -44
- package/.react-email/src/actions/get-email-path-from-slug.ts +0 -26
- package/.react-email/src/actions/get-emails-directory-metadata.spec.ts +0 -73
- package/.react-email/src/actions/get-emails-directory-metadata.ts +0 -91
- package/.react-email/src/actions/render-email-by-path.tsx +0 -59
- package/.react-email/src/app/favicon.ico +0 -0
- package/.react-email/src/app/globals.css +0 -35
- package/.react-email/src/app/inter.ts +0 -7
- package/.react-email/src/app/layout.tsx +0 -36
- package/.react-email/src/app/logo.png +0 -0
- package/.react-email/src/app/page.tsx +0 -47
- package/.react-email/src/app/preview/[...slug]/page.tsx +0 -65
- package/.react-email/src/app/preview/[...slug]/preview.tsx +0 -141
- package/.react-email/src/app/preview/[...slug]/rendering-error.tsx +0 -40
- package/.react-email/src/components/button.tsx +0 -90
- package/.react-email/src/components/code-container.tsx +0 -145
- package/.react-email/src/components/code.tsx +0 -112
- package/.react-email/src/components/heading.tsx +0 -113
- package/.react-email/src/components/icons/icon-arrow-down.tsx +0 -16
- package/.react-email/src/components/icons/icon-base.tsx +0 -24
- package/.react-email/src/components/icons/icon-button.tsx +0 -23
- package/.react-email/src/components/icons/icon-check.tsx +0 -19
- package/.react-email/src/components/icons/icon-clipboard.tsx +0 -40
- package/.react-email/src/components/icons/icon-download.tsx +0 -19
- package/.react-email/src/components/icons/icon-file.tsx +0 -19
- package/.react-email/src/components/icons/icon-folder-open.tsx +0 -19
- package/.react-email/src/components/icons/icon-folder.tsx +0 -18
- package/.react-email/src/components/icons/icon-hide-sidebar.tsx +0 -23
- package/.react-email/src/components/icons/icon-monitor.tsx +0 -19
- package/.react-email/src/components/icons/icon-phone.tsx +0 -26
- package/.react-email/src/components/icons/icon-source.tsx +0 -19
- package/.react-email/src/components/index.ts +0 -7
- package/.react-email/src/components/logo.tsx +0 -64
- package/.react-email/src/components/send.tsx +0 -135
- package/.react-email/src/components/shell.tsx +0 -115
- package/.react-email/src/components/sidebar/index.ts +0 -1
- package/.react-email/src/components/sidebar/sidebar-directory-children.tsx +0 -134
- package/.react-email/src/components/sidebar/sidebar-directory.tsx +0 -106
- package/.react-email/src/components/sidebar/sidebar.tsx +0 -45
- package/.react-email/src/components/text.tsx +0 -99
- package/.react-email/src/components/tooltip-content.tsx +0 -32
- package/.react-email/src/components/tooltip.tsx +0 -19
- package/.react-email/src/components/topbar.tsx +0 -161
- package/.react-email/src/contexts/emails.tsx +0 -127
- package/.react-email/src/hooks/use-hot-reload.ts +0 -35
- package/.react-email/src/hooks/use-rendering-metadata.ts +0 -36
- package/.react-email/src/utils/cn.ts +0 -6
- package/.react-email/src/utils/constants.ts +0 -6
- package/.react-email/src/utils/copy-text-to-clipboard.ts +0 -7
- package/.react-email/src/utils/emails-directory-absolute-path.ts +0 -34
- package/.react-email/src/utils/get-email-component.ts +0 -108
- package/.react-email/src/utils/improve-error-with-sourcemap.ts +0 -55
- package/.react-email/src/utils/index.ts +0 -5
- package/.react-email/src/utils/language-map.ts +0 -7
- package/.react-email/src/utils/static-node-modules-for-vm.ts +0 -92
- package/.react-email/src/utils/types/as.ts +0 -26
- package/.react-email/src/utils/types/email-template.ts +0 -8
- package/.react-email/src/utils/types/error-object.ts +0 -11
- package/.react-email/src/utils/types/hot-reload-change.ts +0 -6
- package/.react-email/src/utils/types/hot-reload-event.ts +0 -6
- package/.react-email/src/utils/unreachable.ts +0 -8
- package/.react-email/tailwind.config.ts +0 -94
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
import * as React from 'react';
|
|
3
|
-
import { cn } from '../utils';
|
|
4
|
-
import { Logo } from './logo';
|
|
5
|
-
import { Sidebar } from './sidebar';
|
|
6
|
-
import { Topbar } from './topbar';
|
|
7
|
-
|
|
8
|
-
type RootProps = React.ComponentPropsWithoutRef<'div'>;
|
|
9
|
-
|
|
10
|
-
interface ShellProps extends RootProps {
|
|
11
|
-
markup?: string;
|
|
12
|
-
currentEmailOpenSlug?: string;
|
|
13
|
-
activeView?: string;
|
|
14
|
-
setActiveView?: (view: string) => void;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export const Shell = ({
|
|
18
|
-
currentEmailOpenSlug,
|
|
19
|
-
children,
|
|
20
|
-
markup,
|
|
21
|
-
activeView,
|
|
22
|
-
setActiveView,
|
|
23
|
-
}: ShellProps) => {
|
|
24
|
-
const [sidebarToggled, setSidebarToggled] = React.useState(false);
|
|
25
|
-
const [triggerTransition, setTriggerTransition] = React.useState(false);
|
|
26
|
-
|
|
27
|
-
return (
|
|
28
|
-
<div className="flex bg-black text-white flex-col h-screen overflow-x-hidden">
|
|
29
|
-
<div className="flex lg:hidden items-center px-6 justify-between h-[70px] border-b border-slate-6">
|
|
30
|
-
<div className="h-[70px] flex items-center">
|
|
31
|
-
<Logo />
|
|
32
|
-
</div>
|
|
33
|
-
|
|
34
|
-
<button
|
|
35
|
-
className="h-6 w-6 rounded flex items-center justify-center text-white"
|
|
36
|
-
onClick={() => {
|
|
37
|
-
setSidebarToggled((v) => !v);
|
|
38
|
-
}}
|
|
39
|
-
type="button"
|
|
40
|
-
>
|
|
41
|
-
<svg
|
|
42
|
-
fill="none"
|
|
43
|
-
height="16"
|
|
44
|
-
stroke="white"
|
|
45
|
-
viewBox="0 0 15 15"
|
|
46
|
-
width="16"
|
|
47
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
48
|
-
>
|
|
49
|
-
<path
|
|
50
|
-
clipRule="evenodd"
|
|
51
|
-
d="M1.5 3C1.22386 3 1 3.22386 1 3.5C1 3.77614 1.22386 4 1.5 4H13.5C13.7761 4 14 3.77614 14 3.5C14 3.22386 13.7761 3 13.5 3H1.5ZM1 7.5C1 7.22386 1.22386 7 1.5 7H13.5C13.7761 7 14 7.22386 14 7.5C14 7.77614 13.7761 8 13.5 8H1.5C1.22386 8 1 7.77614 1 7.5ZM1 11.5C1 11.2239 1.22386 11 1.5 11H13.5C13.7761 11 14 11.2239 14 11.5C14 11.7761 13.7761 12 13.5 12H1.5C1.22386 12 1 11.7761 1 11.5Z"
|
|
52
|
-
fill="currentColor"
|
|
53
|
-
fillRule="evenodd"
|
|
54
|
-
/>
|
|
55
|
-
</svg>
|
|
56
|
-
</button>
|
|
57
|
-
</div>
|
|
58
|
-
|
|
59
|
-
<div className="flex bg-slate-2">
|
|
60
|
-
<Sidebar
|
|
61
|
-
className={cn(
|
|
62
|
-
'w-screen max-w-full bg-black h-screen lg:h-auto z-50 lg:z-auto lg:max-w-[275px] fixed top-[70px] lg:top-0 left-0',
|
|
63
|
-
{
|
|
64
|
-
'translate-x-0 lg:-translate-x-full': sidebarToggled,
|
|
65
|
-
'-translate-x-full lg:translate-x-0': !sidebarToggled,
|
|
66
|
-
},
|
|
67
|
-
)}
|
|
68
|
-
currentEmailOpenSlug={currentEmailOpenSlug}
|
|
69
|
-
style={{
|
|
70
|
-
transition: triggerTransition ? 'transform 0.2s ease-in-out' : '',
|
|
71
|
-
}}
|
|
72
|
-
/>
|
|
73
|
-
|
|
74
|
-
<main
|
|
75
|
-
className={cn(
|
|
76
|
-
'absolute will-change-width h-screen w-[100vw] right-0',
|
|
77
|
-
{
|
|
78
|
-
'lg:translate-x-0 lg:w-[calc(100vw)]': sidebarToggled,
|
|
79
|
-
'lg:translate-x-0 lg:w-[calc(100vw-275px)]': !sidebarToggled,
|
|
80
|
-
},
|
|
81
|
-
)}
|
|
82
|
-
style={{
|
|
83
|
-
transition: triggerTransition
|
|
84
|
-
? 'width 0.2s ease-in-out, transform 0.2s ease-in-out'
|
|
85
|
-
: '',
|
|
86
|
-
}}
|
|
87
|
-
>
|
|
88
|
-
{currentEmailOpenSlug ? (
|
|
89
|
-
<Topbar
|
|
90
|
-
activeView={activeView}
|
|
91
|
-
currentEmailOpenSlug={currentEmailOpenSlug}
|
|
92
|
-
markup={markup}
|
|
93
|
-
onToggleSidebar={() => {
|
|
94
|
-
setTriggerTransition(true);
|
|
95
|
-
|
|
96
|
-
requestAnimationFrame(() => {
|
|
97
|
-
setSidebarToggled((v) => !v);
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
setTimeout(() => {
|
|
101
|
-
setTriggerTransition(false);
|
|
102
|
-
}, 300);
|
|
103
|
-
}}
|
|
104
|
-
setActiveView={setActiveView}
|
|
105
|
-
/>
|
|
106
|
-
) : null}
|
|
107
|
-
|
|
108
|
-
<div className="h-[calc(100vh_-_70px)] overflow-auto mx-auto">
|
|
109
|
-
{children}
|
|
110
|
-
</div>
|
|
111
|
-
</main>
|
|
112
|
-
</div>
|
|
113
|
-
</div>
|
|
114
|
-
);
|
|
115
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './sidebar';
|
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
import { AnimatePresence, LayoutGroup, motion } from 'framer-motion';
|
|
2
|
-
import * as Collapsible from '@radix-ui/react-collapsible';
|
|
3
|
-
import Link from 'next/link';
|
|
4
|
-
import { useSearchParams } from 'next/navigation';
|
|
5
|
-
import type { EmailsDirectory } from '../../actions/get-emails-directory-metadata';
|
|
6
|
-
import {
|
|
7
|
-
emailsDirectoryAbsolutePath,
|
|
8
|
-
pathSeparator,
|
|
9
|
-
} from '../../utils/emails-directory-absolute-path';
|
|
10
|
-
import { cn } from '../../utils';
|
|
11
|
-
import { IconFile } from '../icons/icon-file';
|
|
12
|
-
import { SidebarDirectory } from './sidebar-directory';
|
|
13
|
-
|
|
14
|
-
export const SidebarDirectoryChildren = (props: {
|
|
15
|
-
emailsDirectoryMetadata: EmailsDirectory;
|
|
16
|
-
currentEmailOpenSlug?: string;
|
|
17
|
-
open: boolean;
|
|
18
|
-
isRoot?: boolean;
|
|
19
|
-
}) => {
|
|
20
|
-
const searchParams = useSearchParams();
|
|
21
|
-
const directoryPathRelativeToEmailsDirectory =
|
|
22
|
-
props.emailsDirectoryMetadata.absolutePath
|
|
23
|
-
.replace(`${emailsDirectoryAbsolutePath}${pathSeparator}`, '')
|
|
24
|
-
.replace(emailsDirectoryAbsolutePath, '')
|
|
25
|
-
.trim();
|
|
26
|
-
const isBaseEmailsDirectory =
|
|
27
|
-
props.emailsDirectoryMetadata.absolutePath === emailsDirectoryAbsolutePath;
|
|
28
|
-
|
|
29
|
-
return (
|
|
30
|
-
<AnimatePresence initial={false}>
|
|
31
|
-
{props.open ? (
|
|
32
|
-
<Collapsible.Content
|
|
33
|
-
asChild
|
|
34
|
-
className="relative data-[root=true]:mt-2 overflow-y-hidden pl-1"
|
|
35
|
-
forceMount
|
|
36
|
-
>
|
|
37
|
-
<motion.div
|
|
38
|
-
animate={{ opacity: 1, height: 'auto' }}
|
|
39
|
-
exit={{ opacity: 0, height: 0 }}
|
|
40
|
-
initial={{ opacity: 0, height: 0 }}
|
|
41
|
-
>
|
|
42
|
-
{props.isRoot ? null : (
|
|
43
|
-
<div className="line absolute left-2.5 w-px h-full bg-slate-6" />
|
|
44
|
-
)}
|
|
45
|
-
|
|
46
|
-
<div className="data-[root=true]:py-2 flex flex-col truncate">
|
|
47
|
-
<LayoutGroup id="sidebar">
|
|
48
|
-
{props.emailsDirectoryMetadata.subDirectories.map(
|
|
49
|
-
(subDirectory) => (
|
|
50
|
-
<SidebarDirectory
|
|
51
|
-
className="pl-4 py-0"
|
|
52
|
-
currentEmailOpenSlug={props.currentEmailOpenSlug}
|
|
53
|
-
emailsDirectoryMetadata={subDirectory}
|
|
54
|
-
key={subDirectory.absolutePath}
|
|
55
|
-
/>
|
|
56
|
-
),
|
|
57
|
-
)}
|
|
58
|
-
|
|
59
|
-
{props.emailsDirectoryMetadata.emailFilenames.map(
|
|
60
|
-
(emailFilename, index) => {
|
|
61
|
-
const emailSlug = `${directoryPathRelativeToEmailsDirectory}${
|
|
62
|
-
!isBaseEmailsDirectory ? pathSeparator : ''
|
|
63
|
-
}${emailFilename}`;
|
|
64
|
-
const removeExtensionFrom = (path: string) => {
|
|
65
|
-
if (
|
|
66
|
-
path.split('.').pop() === 'tsx' ||
|
|
67
|
-
path.split('.').pop() === 'jsx' ||
|
|
68
|
-
path.split('.').pop() === 'js'
|
|
69
|
-
) {
|
|
70
|
-
return path.split('.').slice(0, -1).join('.');
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
return path;
|
|
74
|
-
};
|
|
75
|
-
const isCurrentPage = props.currentEmailOpenSlug
|
|
76
|
-
? removeExtensionFrom(props.currentEmailOpenSlug) ===
|
|
77
|
-
emailSlug
|
|
78
|
-
: false;
|
|
79
|
-
|
|
80
|
-
return (
|
|
81
|
-
<Link
|
|
82
|
-
href={{
|
|
83
|
-
pathname: `/preview/${emailSlug}`,
|
|
84
|
-
search: searchParams.toString(),
|
|
85
|
-
}}
|
|
86
|
-
key={emailSlug}
|
|
87
|
-
>
|
|
88
|
-
<motion.span
|
|
89
|
-
animate={{ x: 0, opacity: 1 }}
|
|
90
|
-
className={cn(
|
|
91
|
-
'text-[14px] flex items-center align-middle pl-3 h-8 max-w-full rounded-md text-slate-11 relative transition-colors',
|
|
92
|
-
{
|
|
93
|
-
'text-cyan-11': isCurrentPage,
|
|
94
|
-
'hover:text-slate-12':
|
|
95
|
-
props.currentEmailOpenSlug !== emailSlug,
|
|
96
|
-
},
|
|
97
|
-
)}
|
|
98
|
-
initial={{ x: -10 + -index * 1.5, opacity: 0 }}
|
|
99
|
-
transition={{
|
|
100
|
-
x: { delay: 0.03 * index, duration: 0.2 },
|
|
101
|
-
opacity: { delay: 0.03 * index, duration: 0.2 },
|
|
102
|
-
}}
|
|
103
|
-
>
|
|
104
|
-
{isCurrentPage ? (
|
|
105
|
-
<motion.span
|
|
106
|
-
animate={{ opacity: 1 }}
|
|
107
|
-
className="absolute left-0 right-0 top-0 bottom-0 rounded-md bg-cyan-5 opacity-0"
|
|
108
|
-
exit={{ opacity: 0 }}
|
|
109
|
-
initial={{ opacity: 0 }}
|
|
110
|
-
>
|
|
111
|
-
{!props.isRoot && (
|
|
112
|
-
<div className="bg-cyan-11 w-px absolute top-1 left-1.5 h-6" />
|
|
113
|
-
)}
|
|
114
|
-
</motion.span>
|
|
115
|
-
) : null}
|
|
116
|
-
<IconFile
|
|
117
|
-
className="absolute left-4 w-[24px] h-[24px]"
|
|
118
|
-
height="24"
|
|
119
|
-
width="24"
|
|
120
|
-
/>
|
|
121
|
-
<span className="truncate pl-8">{emailFilename}</span>
|
|
122
|
-
</motion.span>
|
|
123
|
-
</Link>
|
|
124
|
-
);
|
|
125
|
-
},
|
|
126
|
-
)}
|
|
127
|
-
</LayoutGroup>
|
|
128
|
-
</div>
|
|
129
|
-
</motion.div>
|
|
130
|
-
</Collapsible.Content>
|
|
131
|
-
) : null}
|
|
132
|
-
</AnimatePresence>
|
|
133
|
-
);
|
|
134
|
-
};
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
import * as Collapsible from '@radix-ui/react-collapsible';
|
|
3
|
-
import * as React from 'react';
|
|
4
|
-
import { cn } from '../../utils';
|
|
5
|
-
import {
|
|
6
|
-
emailsDirectoryAbsolutePath,
|
|
7
|
-
pathSeparator,
|
|
8
|
-
} from '../../utils/emails-directory-absolute-path';
|
|
9
|
-
import { type EmailsDirectory } from '../../actions/get-emails-directory-metadata';
|
|
10
|
-
import { Heading } from '../heading';
|
|
11
|
-
import { IconFolder } from '../icons/icon-folder';
|
|
12
|
-
import { IconFolderOpen } from '../icons/icon-folder-open';
|
|
13
|
-
import { IconArrowDown } from '../icons/icon-arrow-down';
|
|
14
|
-
import { SidebarDirectoryChildren } from './sidebar-directory-children';
|
|
15
|
-
|
|
16
|
-
interface SidebarDirectoryProps {
|
|
17
|
-
emailsDirectoryMetadata: EmailsDirectory;
|
|
18
|
-
className?: string;
|
|
19
|
-
currentEmailOpenSlug?: string;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const persistedOpenDirectories = new Set<string>();
|
|
23
|
-
|
|
24
|
-
export const SidebarDirectory = ({
|
|
25
|
-
emailsDirectoryMetadata: directoryMetadata,
|
|
26
|
-
className,
|
|
27
|
-
currentEmailOpenSlug,
|
|
28
|
-
}: SidebarDirectoryProps) => {
|
|
29
|
-
const isBaseEmailsDirectory =
|
|
30
|
-
directoryMetadata.absolutePath === emailsDirectoryAbsolutePath;
|
|
31
|
-
const directoryPathRelativeToBaseEmailsDirectory =
|
|
32
|
-
directoryMetadata.absolutePath
|
|
33
|
-
.replace(`${emailsDirectoryAbsolutePath}${pathSeparator}`, '')
|
|
34
|
-
.replace(emailsDirectoryAbsolutePath, '')
|
|
35
|
-
.trim();
|
|
36
|
-
const doesDirectoryContainCurrentEmailOpen = currentEmailOpenSlug
|
|
37
|
-
? currentEmailOpenSlug.includes(directoryPathRelativeToBaseEmailsDirectory)
|
|
38
|
-
: false;
|
|
39
|
-
|
|
40
|
-
const isEmpty =
|
|
41
|
-
directoryMetadata.emailFilenames.length > 0 ||
|
|
42
|
-
directoryMetadata.subDirectories.length > 0;
|
|
43
|
-
|
|
44
|
-
const [open, setOpen] = React.useState(
|
|
45
|
-
persistedOpenDirectories.has(directoryMetadata.absolutePath) ||
|
|
46
|
-
isBaseEmailsDirectory ||
|
|
47
|
-
doesDirectoryContainCurrentEmailOpen,
|
|
48
|
-
);
|
|
49
|
-
|
|
50
|
-
return (
|
|
51
|
-
<Collapsible.Root
|
|
52
|
-
className={cn('group', className)}
|
|
53
|
-
data-root={isBaseEmailsDirectory}
|
|
54
|
-
onOpenChange={(isOpening) => {
|
|
55
|
-
if (isOpening) {
|
|
56
|
-
persistedOpenDirectories.add(directoryMetadata.absolutePath);
|
|
57
|
-
} else {
|
|
58
|
-
persistedOpenDirectories.delete(directoryMetadata.absolutePath);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
setOpen(isOpening);
|
|
62
|
-
}}
|
|
63
|
-
open={open}
|
|
64
|
-
>
|
|
65
|
-
<Collapsible.Trigger
|
|
66
|
-
className={cn(
|
|
67
|
-
'text-[14px] flex items-center font-medium gap-2 justify-between w-full my-1',
|
|
68
|
-
{
|
|
69
|
-
'cursor-pointer': !isEmpty,
|
|
70
|
-
},
|
|
71
|
-
)}
|
|
72
|
-
>
|
|
73
|
-
<div className="flex items-center text-slate-11 transition ease-in-out duration-200 hover:text-slate-12 gap-1">
|
|
74
|
-
{open ? (
|
|
75
|
-
<IconFolderOpen height="24" width="24" />
|
|
76
|
-
) : (
|
|
77
|
-
<IconFolder height="24" width="24" />
|
|
78
|
-
)}
|
|
79
|
-
<Heading
|
|
80
|
-
as="h3"
|
|
81
|
-
className="transition ease-in-out duration-200 hover:text-slate-12"
|
|
82
|
-
color="gray"
|
|
83
|
-
size="2"
|
|
84
|
-
weight="medium"
|
|
85
|
-
>
|
|
86
|
-
{directoryMetadata.directoryName}
|
|
87
|
-
</Heading>
|
|
88
|
-
</div>
|
|
89
|
-
{isEmpty ? (
|
|
90
|
-
<IconArrowDown
|
|
91
|
-
className="data-[open=true]:rotate-180 transition-transform opacity-60 justify-self-end"
|
|
92
|
-
data-open={open}
|
|
93
|
-
/>
|
|
94
|
-
) : null}
|
|
95
|
-
</Collapsible.Trigger>
|
|
96
|
-
|
|
97
|
-
{isEmpty ? (
|
|
98
|
-
<SidebarDirectoryChildren
|
|
99
|
-
currentEmailOpenSlug={currentEmailOpenSlug}
|
|
100
|
-
emailsDirectoryMetadata={directoryMetadata}
|
|
101
|
-
open={open}
|
|
102
|
-
/>
|
|
103
|
-
) : null}
|
|
104
|
-
</Collapsible.Root>
|
|
105
|
-
);
|
|
106
|
-
};
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import * as React from 'react';
|
|
4
|
-
import * as Collapsible from '@radix-ui/react-collapsible';
|
|
5
|
-
import { useEmails } from '../../contexts/emails';
|
|
6
|
-
import { cn } from '../../utils';
|
|
7
|
-
import { Logo } from '../logo';
|
|
8
|
-
import { SidebarDirectoryChildren } from './sidebar-directory-children';
|
|
9
|
-
|
|
10
|
-
interface SidebarProps {
|
|
11
|
-
className?: string;
|
|
12
|
-
currentEmailOpenSlug?: string;
|
|
13
|
-
style?: React.CSSProperties;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export const Sidebar = ({
|
|
17
|
-
className,
|
|
18
|
-
currentEmailOpenSlug,
|
|
19
|
-
style,
|
|
20
|
-
}: SidebarProps) => {
|
|
21
|
-
const { emailsDirectoryMetadata } = useEmails();
|
|
22
|
-
|
|
23
|
-
return (
|
|
24
|
-
<aside
|
|
25
|
-
className={cn('border-r flex flex-col border-slate-6', className)}
|
|
26
|
-
style={{ ...style }}
|
|
27
|
-
>
|
|
28
|
-
<div className="p-4 h-[70px] flex-shrink items-center hidden lg:flex">
|
|
29
|
-
<Logo />
|
|
30
|
-
</div>
|
|
31
|
-
<nav className="p-4 flex-grow lg:pt-0 pl-0 w-screen h-[calc(100vh_-_70px)] lg:w-full lg:min-w-[275px] lg:max-w-[275px] flex flex-col overflow-y-auto">
|
|
32
|
-
<Collapsible.Root>
|
|
33
|
-
<React.Suspense>
|
|
34
|
-
<SidebarDirectoryChildren
|
|
35
|
-
currentEmailOpenSlug={currentEmailOpenSlug}
|
|
36
|
-
emailsDirectoryMetadata={emailsDirectoryMetadata}
|
|
37
|
-
isRoot
|
|
38
|
-
open
|
|
39
|
-
/>
|
|
40
|
-
</React.Suspense>
|
|
41
|
-
</Collapsible.Root>
|
|
42
|
-
</nav>
|
|
43
|
-
</aside>
|
|
44
|
-
);
|
|
45
|
-
};
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import * as SlotPrimitive from '@radix-ui/react-slot';
|
|
2
|
-
import * as React from 'react';
|
|
3
|
-
import { type As, unreachable, cn } from '../utils';
|
|
4
|
-
|
|
5
|
-
export type TextSize = '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9';
|
|
6
|
-
export type TextColor = 'gray' | 'white';
|
|
7
|
-
export type TextTransform = 'uppercase' | 'lowercase' | 'capitalize';
|
|
8
|
-
export type TextWeight = 'normal' | 'medium';
|
|
9
|
-
|
|
10
|
-
interface TextOwnProps {
|
|
11
|
-
size?: TextSize;
|
|
12
|
-
color?: TextColor;
|
|
13
|
-
transform?: TextTransform;
|
|
14
|
-
weight?: TextWeight;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
type TextProps = As<'span', 'div', 'p'> & TextOwnProps;
|
|
18
|
-
|
|
19
|
-
export const Text = React.forwardRef<HTMLSpanElement, Readonly<TextProps>>(
|
|
20
|
-
(
|
|
21
|
-
{
|
|
22
|
-
as: Tag = 'span',
|
|
23
|
-
size = '2',
|
|
24
|
-
color = 'gray',
|
|
25
|
-
transform,
|
|
26
|
-
weight = 'normal',
|
|
27
|
-
className,
|
|
28
|
-
children,
|
|
29
|
-
...props
|
|
30
|
-
},
|
|
31
|
-
forwardedRef,
|
|
32
|
-
) => (
|
|
33
|
-
<SlotPrimitive.Slot
|
|
34
|
-
className={cn(
|
|
35
|
-
className,
|
|
36
|
-
transform,
|
|
37
|
-
getSizesClassNames(size),
|
|
38
|
-
getColorClassNames(color),
|
|
39
|
-
getWeightClassNames(weight),
|
|
40
|
-
)}
|
|
41
|
-
ref={forwardedRef}
|
|
42
|
-
{...props}
|
|
43
|
-
>
|
|
44
|
-
<Tag>{children}</Tag>
|
|
45
|
-
</SlotPrimitive.Slot>
|
|
46
|
-
),
|
|
47
|
-
);
|
|
48
|
-
|
|
49
|
-
const getSizesClassNames = (size: TextSize | undefined) => {
|
|
50
|
-
switch (size) {
|
|
51
|
-
case '1':
|
|
52
|
-
return 'text-xs';
|
|
53
|
-
case undefined:
|
|
54
|
-
case '2':
|
|
55
|
-
return 'text-sm';
|
|
56
|
-
case '3':
|
|
57
|
-
return 'text-base';
|
|
58
|
-
case '4':
|
|
59
|
-
return 'text-lg';
|
|
60
|
-
case '5':
|
|
61
|
-
return ['text-17px', 'md:text-xl tracking-[-0.16px]'];
|
|
62
|
-
case '6':
|
|
63
|
-
return 'text-2xl tracking-[-0.288px]';
|
|
64
|
-
case '7':
|
|
65
|
-
return 'text-[28px] leading-[34px] tracking-[-0.416px]';
|
|
66
|
-
case '8':
|
|
67
|
-
return 'text-[35px] leading-[42px] tracking-[-0.64px]';
|
|
68
|
-
case '9':
|
|
69
|
-
return 'text-6xl leading-[73px] tracking-[-0.896px]';
|
|
70
|
-
default:
|
|
71
|
-
return unreachable(size);
|
|
72
|
-
}
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
const getColorClassNames = (color: TextColor | undefined) => {
|
|
76
|
-
switch (color) {
|
|
77
|
-
case 'white':
|
|
78
|
-
return 'text-slate-12';
|
|
79
|
-
case undefined:
|
|
80
|
-
case 'gray':
|
|
81
|
-
return 'text-slate-11';
|
|
82
|
-
default:
|
|
83
|
-
return unreachable(color);
|
|
84
|
-
}
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
const getWeightClassNames = (weight: TextWeight | undefined) => {
|
|
88
|
-
switch (weight) {
|
|
89
|
-
case undefined:
|
|
90
|
-
case 'normal':
|
|
91
|
-
return 'font-normal';
|
|
92
|
-
case 'medium':
|
|
93
|
-
return 'font-medium';
|
|
94
|
-
default:
|
|
95
|
-
return unreachable(weight);
|
|
96
|
-
}
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
Text.displayName = 'Text';
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import * as TooltipPrimitive from '@radix-ui/react-tooltip';
|
|
2
|
-
import * as React from 'react';
|
|
3
|
-
import { cn } from '../utils';
|
|
4
|
-
import { inter } from '../app/inter';
|
|
5
|
-
|
|
6
|
-
type ContentElement = React.ElementRef<typeof TooltipPrimitive.Content>;
|
|
7
|
-
type ContentProps = React.ComponentPropsWithoutRef<
|
|
8
|
-
typeof TooltipPrimitive.Content
|
|
9
|
-
>;
|
|
10
|
-
|
|
11
|
-
export type TooltipProps = ContentProps;
|
|
12
|
-
|
|
13
|
-
export const TooltipContent = React.forwardRef<
|
|
14
|
-
ContentElement,
|
|
15
|
-
Readonly<TooltipProps>
|
|
16
|
-
>(({ sideOffset = 6, children, ...props }, forwardedRef) => (
|
|
17
|
-
<TooltipPrimitive.Portal>
|
|
18
|
-
<TooltipPrimitive.Content
|
|
19
|
-
{...props}
|
|
20
|
-
className={cn(
|
|
21
|
-
'bg-black border border-slate-6 z-20 px-3 py-2 rounded-md text-xs',
|
|
22
|
-
`${inter.variable} font-sans`,
|
|
23
|
-
)}
|
|
24
|
-
ref={forwardedRef}
|
|
25
|
-
sideOffset={sideOffset}
|
|
26
|
-
>
|
|
27
|
-
{children}
|
|
28
|
-
</TooltipPrimitive.Content>
|
|
29
|
-
</TooltipPrimitive.Portal>
|
|
30
|
-
));
|
|
31
|
-
|
|
32
|
-
TooltipContent.displayName = 'TooltipContent';
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import * as TooltipPrimitive from '@radix-ui/react-tooltip';
|
|
2
|
-
import * as React from 'react';
|
|
3
|
-
import { TooltipContent } from './tooltip-content';
|
|
4
|
-
|
|
5
|
-
type RootProps = React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Root>;
|
|
6
|
-
|
|
7
|
-
export type TooltipProps = RootProps;
|
|
8
|
-
|
|
9
|
-
export const TooltipRoot: React.FC<Readonly<TooltipProps>> = ({
|
|
10
|
-
children,
|
|
11
|
-
...props
|
|
12
|
-
}) => <TooltipPrimitive.Root {...props}>{children}</TooltipPrimitive.Root>;
|
|
13
|
-
|
|
14
|
-
export const Tooltip = Object.assign(TooltipRoot, {
|
|
15
|
-
Arrow: TooltipPrimitive.TooltipArrow,
|
|
16
|
-
Provider: TooltipPrimitive.TooltipProvider,
|
|
17
|
-
Content: TooltipContent,
|
|
18
|
-
Trigger: TooltipPrimitive.TooltipTrigger,
|
|
19
|
-
});
|