-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Expand file tree
/
Copy pathCustomPreset.tsx
More file actions
145 lines (139 loc) · 4.29 KB
/
CustomPreset.tsx
File metadata and controls
145 lines (139 loc) · 4.29 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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import {memo, useRef, useState} from 'react';
import {flushSync} from 'react-dom';
import {
useSandpack,
useActiveCode,
SandpackCodeEditor,
SandpackLayout,
} from '@webcontainer/react';
import cn from 'classnames';
import {IconChevron} from 'components/Icon/IconChevron';
import {NavigationBar} from './NavigationBar';
import {Preview} from './Preview';
import {useSandpackLint} from './useSandpackLint';
export const CustomPreset = memo(function CustomPreset({
providedFiles,
showOpenInStackBlitz = true,
}: {
providedFiles: Array<string>;
showOpenInStackBlitz?: boolean;
}) {
const {lintErrors, lintExtensions} = useSandpackLint();
const {sandpack} = useSandpack();
const {code} = useActiveCode();
const {activeFile} = sandpack;
const lineCountRef = useRef<{[key: string]: number}>({});
if (!lineCountRef.current[activeFile]) {
// eslint-disable-next-line react-compiler/react-compiler
lineCountRef.current[activeFile] = code.split('\n').length;
}
const lineCount = lineCountRef.current[activeFile];
const isExpandable = lineCount > 16;
return (
<SandboxShell
providedFiles={providedFiles}
lintErrors={lintErrors}
lintExtensions={lintExtensions}
isExpandable={isExpandable}
showOpenInStackBlitz={showOpenInStackBlitz}
/>
);
});
const SandboxShell = memo(function SandboxShell({
providedFiles,
lintErrors,
lintExtensions,
isExpandable,
showOpenInStackBlitz,
}: {
providedFiles: Array<string>;
lintErrors: Array<any>;
lintExtensions: Array<any>;
isExpandable: boolean;
showOpenInStackBlitz: boolean;
}) {
const containerRef = useRef<HTMLDivElement>(null);
const [isExpanded, setIsExpanded] = useState(false);
return (
<>
<div
className="shadow-lg dark:shadow-lg-dark rounded-lg"
ref={containerRef}
style={{
contain: 'content',
}}>
<NavigationBar
providedFiles={providedFiles}
showOpenInStackBlitz={showOpenInStackBlitz}
/>
<SandpackLayout
className={cn(
!(isExpandable || isExpanded) && 'rounded-b-lg overflow-hidden',
isExpanded && 'sp-layout-expanded'
)}>
<Editor lintExtensions={lintExtensions} />
<Preview
className="order-last xl:order-2"
isExpanded={isExpanded}
lintErrors={lintErrors}
/>
{(isExpandable || isExpanded) && (
<button
translate="yes"
className="sandpack-expand flex text-base justify-between dark:border-card-dark bg-wash dark:bg-card-dark items-center z-10 p-1 w-full order-2 xl:order-last border-b-1 relative top-0"
onClick={() => {
const nextIsExpanded = !isExpanded;
flushSync(() => {
setIsExpanded(nextIsExpanded);
});
if (!nextIsExpanded && containerRef.current !== null) {
// @ts-ignore
if (containerRef.current.scrollIntoViewIfNeeded) {
// @ts-ignore
containerRef.current.scrollIntoViewIfNeeded();
} else {
containerRef.current.scrollIntoView({
block: 'nearest',
inline: 'nearest',
});
}
}
}}>
<span className="flex p-2 focus:outline-none text-primary dark:text-primary-dark leading-[20px]">
<IconChevron
className="inline me-1.5 text-xl"
displayDirection={isExpanded ? 'up' : 'down'}
/>
{isExpanded ? 'Show less' : 'Show more'}
</span>
</button>
)}
</SandpackLayout>
</div>
</>
);
});
const Editor = memo(function Editor({
lintExtensions,
}: {
lintExtensions: Array<any>;
}) {
return (
<SandpackCodeEditor
showLineNumbers
showInlineErrors
showTabs={false}
showRunButton={false}
extensions={lintExtensions}
/>
);
});