-
-
Notifications
You must be signed in to change notification settings - Fork 300
/
DemoSandbox.tsx
103 lines (90 loc) · 2.57 KB
/
DemoSandbox.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import type { ReactElement } from "react";
import { useCallback, useMemo } from "react";
import type { IFiles } from "codesandbox-import-utils/lib/api/define";
import { useRouter } from "next/router";
import { useJs } from "components/CodePreference";
import NotFoundPage from "components/NotFoundPage";
import { useTheme } from "components/Theme";
import type { SandboxQuery } from "utils/routes";
import { parseSandbox } from "utils/routes";
import SandboxModal from "./SandboxModal";
import useSandbox from "./useSandbox";
import useFiles from "./useFiles";
interface DemoSandboxProps {
sandbox: IFiles | null;
}
const EMPTY = {};
export default function DemoSandbox({
sandbox: defaultSandbox,
}: DemoSandboxProps): ReactElement {
const router = useRouter();
const { theme } = useTheme();
const isJs = useJs();
const { pkg, name, from, fileName } = parseSandbox(router.query, isJs);
const { sandbox, loading } = useSandbox(defaultSandbox, {
js: isJs,
pkg,
name,
theme,
pathname: router.pathname,
});
const files = useFiles(sandbox || EMPTY);
const folders = useMemo(
() =>
Object.values(files).reduce<string[]>(
(foldersPaths, { itemId }, _i, list) => {
if (list.find(({ parentId }) => itemId === parentId)) {
foldersPaths.push(itemId);
}
return foldersPaths;
},
[]
),
[files]
);
const onRequestClose = useCallback(() => {
if (from && from.startsWith("/packages")) {
router.push(from);
return;
}
router.push(router.pathname);
}, [from, router]);
const onFileChange = useCallback(
(nextFileName: string) => {
if (nextFileName === fileName || folders.includes(nextFileName)) {
return;
}
const query: SandboxQuery = { pkg, name };
if (from) {
query.from = from;
}
if (nextFileName !== "src/Demo.tsx") {
query.fileName = nextFileName;
}
router.replace({ pathname: router.pathname, query });
},
[folders, router, pkg, name, from, fileName]
);
if (!sandbox && !loading) {
if (process.env.NODE_ENV !== "production" && (pkg || name || from)) {
throw new Error(
"No sandbox found. Run `yarn sandbox` to generate demo sandboxes."
);
}
return <NotFoundPage />;
}
return (
<SandboxModal
pkg={pkg}
name={name}
fileName={fileName}
from={from}
files={files}
loading={loading}
folders={folders}
sandbox={sandbox}
onFileChange={onFileChange}
onRequestClose={onRequestClose}
/>
);
}