-
Notifications
You must be signed in to change notification settings - Fork 97
Expand file tree
/
Copy pathSandpack.tsx
More file actions
94 lines (84 loc) · 2.42 KB
/
Sandpack.tsx
File metadata and controls
94 lines (84 loc) · 2.42 KB
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
import { crawl } from '@/utils/docs'
import {
SandpackCodeEditor,
SandpackFileExplorer,
SandpackPreview,
type SandpackFiles,
type SandpackProviderProps,
} from '@codesandbox/sandpack-react'
import fs from 'node:fs'
import path from 'node:path'
import { ComponentProps } from 'react'
import { SandpackClient } from './SandpackClient'
import { SandpackCodeViewer } from './SandpackCodeViewer'
function getSandpackDependencies(folder: string) {
const pkgPath = `${folder}/package.json`
if (!fs.existsSync(pkgPath)) return null
const str = fs.readFileSync(pkgPath, 'utf-8')
return JSON.parse(str).dependencies as Record<string, string>
}
async function getSandpackFiles(
folder: string,
files: SandpackFiles = {},
extensions = ['js', 'ts', 'jsx', 'tsx', 'css'],
) {
const filepaths = await crawl(
folder,
(dir) =>
!dir.includes('node_modules') && extensions.map((ext) => dir.endsWith(ext)).some(Boolean),
)
return filepaths.reduce((acc, filepath) => {
const relativeFilepath = path.relative(folder, filepath)
const key = `/${relativeFilepath}`
const file = files[key]
return {
...acc,
[key]: {
...((typeof file !== 'string' && file) || undefined),
code: fs.readFileSync(filepath, 'utf-8'),
},
}
}, {} as SandpackFiles)
}
// https://sandpack.codesandbox.io/docs/getting-started/usage
export const Sandpack = async ({
className,
folder,
fileExplorer,
codeEditor,
codeViewer,
preview,
...props
}: SandpackProviderProps & {
className?: string
folder?: string
codeEditor?: ComponentProps<typeof SandpackCodeEditor>
codeViewer?: boolean | ComponentProps<typeof SandpackCodeViewer>
preview?: ComponentProps<typeof SandpackPreview>
fileExplorer?: boolean | ComponentProps<typeof SandpackFileExplorer>
}) => {
const _files = folder ? await getSandpackFiles(folder, props.files) : props.files
const pkgDeps = folder ? getSandpackDependencies(folder) : null
const dependencies = pkgDeps ?? props.customSetup?.dependencies
const customSetup = {
...props.customSetup,
dependencies,
}
const options = {
...props.options,
// editorHeight: 350
}
return (
<SandpackClient
className={className}
files={_files}
customSetup={customSetup}
options={options}
fileExplorer={fileExplorer}
codeEditor={codeEditor}
codeViewer={codeViewer}
preview={preview}
{...props}
/>
)
}