Skip to content

Commit ad3c21a

Browse files
committed
fix: Playground Run button (runSandpack), hard-coded toolbar colors, add vercel.json
1 parent 97f8d51 commit ad3c21a

2 files changed

Lines changed: 112 additions & 80 deletions

File tree

docs-site/components/Playground.tsx

Lines changed: 111 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -5,42 +5,27 @@ import {
55
SandpackProvider,
66
SandpackLayout,
77
SandpackCodeEditor,
8-
SandpackPreview,
98
SandpackConsole,
9+
SandpackPreview,
1010
useSandpack,
1111
} from '@codesandbox/sandpack-react'
12-
// sandpackDark is bundled with sandpack-react
13-
const sandpackDark = 'dark' as const
1412

15-
function RunButton() {
16-
const { dispatch, sandpack } = useSandpack()
17-
const isLoading = sandpack.status === 'initial' || sandpack.status === 'timeout'
18-
return (
19-
<button
20-
onClick={() => dispatch({ type: 'refresh' })}
21-
disabled={isLoading}
22-
style={{
23-
display: 'flex',
24-
alignItems: 'center',
25-
gap: '6px',
26-
padding: '4px 14px',
27-
borderRadius: '4px',
28-
border: 'none',
29-
cursor: isLoading ? 'not-allowed' : 'pointer',
30-
fontFamily: 'var(--sp-font-mono)',
31-
fontSize: '12px',
32-
fontWeight: 600,
33-
background: isLoading ? 'var(--sp-colors-surface2)' : '#22c55e',
34-
color: isLoading ? 'var(--sp-colors-fg-inactive)' : '#fff',
35-
transition: 'background 0.15s',
36-
}}
37-
>
38-
▶ Run
39-
</button>
40-
)
41-
}
13+
// Hard-coded dark toolbar colors — CSS vars are only scoped inside SandpackLayout
14+
const T = {
15+
bg: '#1c1c1e',
16+
border: '#3a3a3c',
17+
muted: '#888',
18+
text: '#ccc',
19+
activeBg: '#0070f3',
20+
activeText: '#fff',
21+
pillBg: '#2a2a2c',
22+
runBg: '#22c55e',
23+
runText: '#fff',
24+
runDisabledBg: '#2a2a2c',
25+
runDisabledText: '#666',
26+
} as const
4227

43-
// Conflux network configs
28+
// ── Conflux network configs ──────────────────────────────────────────────────
4429
const NETWORKS = {
4530
testnet: {
4631
label: 'Testnet',
@@ -58,25 +43,40 @@ const NETWORKS = {
5843

5944
type Network = keyof typeof NETWORKS
6045

61-
interface PlaygroundProps {
62-
/** The active code file name, e.g. "index.ts" */
63-
file?: string
64-
/** Record of filename → code content */
65-
files?: Record<string, string>
66-
/** Template: "vanilla-ts" | "nextjs" | "node" */
67-
template?: 'vanilla-ts' | 'node'
68-
/** Show console instead of preview */
69-
showConsole?: boolean
70-
/** Extra npm dependencies beyond the defaults */
71-
extraDeps?: Record<string, string>
72-
}
46+
// ── Run button — must be inside SandpackProvider ─────────────────────────────
47+
function RunButton() {
48+
const { sandpack } = useSandpack()
49+
const busy =
50+
sandpack.status === 'initial' ||
51+
sandpack.status === 'timeout'
7352

74-
const DEFAULT_DEPS: Record<string, string> = {
75-
viem: '^2.0.0',
76-
'@cfxdevkit/core': 'latest',
77-
'@cfxdevkit/contracts': 'latest',
53+
return (
54+
<button
55+
onClick={() => sandpack.runSandpack()}
56+
disabled={busy}
57+
style={{
58+
display: 'flex',
59+
alignItems: 'center',
60+
gap: '5px',
61+
padding: '4px 14px',
62+
borderRadius: '4px',
63+
border: 'none',
64+
cursor: busy ? 'not-allowed' : 'pointer',
65+
fontFamily: 'ui-monospace, monospace',
66+
fontSize: '12px',
67+
fontWeight: 600,
68+
background: busy ? T.runDisabledBg : T.runBg,
69+
color: busy ? T.runDisabledText : T.runText,
70+
transition: 'background 0.15s',
71+
flexShrink: 0,
72+
}}
73+
>
74+
▶ Run
75+
</button>
76+
)
7877
}
7978

79+
// ── Network toggle ────────────────────────────────────────────────────────────
8080
function NetworkToggle({
8181
network,
8282
onChange,
@@ -85,33 +85,67 @@ function NetworkToggle({
8585
onChange: (n: Network) => void
8686
}) {
8787
return (
88-
<div style={{ display: 'flex', alignItems: 'center', gap: '8px', fontSize: '12px', fontFamily: 'var(--sp-font-mono)' }}>
89-
<span style={{ color: 'var(--sp-colors-fg-inactive)' }}>network:</span>
88+
<div
89+
style={{
90+
display: 'flex',
91+
alignItems: 'center',
92+
gap: '6px',
93+
fontSize: '12px',
94+
fontFamily: 'ui-monospace, monospace',
95+
color: T.muted,
96+
minWidth: 0,
97+
overflow: 'hidden',
98+
}}
99+
>
100+
<span style={{ whiteSpace: 'nowrap' }}>network:</span>
90101
{(Object.keys(NETWORKS) as Network[]).map((key) => (
91102
<button
92103
key={key}
93104
onClick={() => onChange(key)}
94105
style={{
95-
padding: '2px 10px',
106+
padding: '2px 9px',
96107
borderRadius: '4px',
97108
border: 'none',
98109
cursor: 'pointer',
99110
fontFamily: 'inherit',
100111
fontSize: '11px',
101-
background: network === key ? 'var(--sp-colors-accent)' : 'var(--sp-colors-surface2)',
102-
color: network === key ? '#fff' : 'var(--sp-colors-fg-inactive)',
112+
whiteSpace: 'nowrap',
113+
background: network === key ? T.activeBg : T.pillBg,
114+
color: network === key ? T.activeText : T.text,
103115
}}
104116
>
105117
{NETWORKS[key].label}
106118
</button>
107119
))}
108-
<span style={{ color: 'var(--sp-colors-fg-inactive)', fontSize: '10px' }}>
120+
<span
121+
style={{
122+
color: T.muted,
123+
fontSize: '10px',
124+
whiteSpace: 'nowrap',
125+
}}
126+
>
109127
· chain {NETWORKS[network].chainId}
110128
</span>
111129
</div>
112130
)
113131
}
114132

133+
// ── Props ────────────────────────────────────────────────────────────────────
134+
interface PlaygroundProps {
135+
file?: string
136+
files?: Record<string, string>
137+
template?: 'vanilla-ts' | 'node'
138+
showConsole?: boolean
139+
extraDeps?: Record<string, string>
140+
}
141+
142+
const DEFAULT_DEPS: Record<string, string> = {
143+
viem: '^2.0.0',
144+
'@cfxdevkit/core': 'latest',
145+
'@cfxdevkit/contracts': 'latest',
146+
}
147+
148+
// ── Main component ────────────────────────────────────────────────────────────
115149
export function Playground({
116150
files = {},
117151
template = 'vanilla-ts',
@@ -123,14 +157,7 @@ export function Playground({
123157

124158
const networkConfig = NETWORKS[network]
125159

126-
// Inject a network-config helper that examples can import
127-
const networkFile = `// Auto-generated — re-renders when you toggle network above
128-
export const NETWORK = {
129-
chainId: ${networkConfig.chainId},
130-
rpcUrl: '${networkConfig.rpcUrl}',
131-
blockExplorer: '${networkConfig.blockExplorer}',
132-
} as const
133-
`
160+
const networkFile = `// Auto-generated — changes when you toggle network\nexport const NETWORK = {\n chainId: ${networkConfig.chainId},\n rpcUrl: '${networkConfig.rpcUrl}',\n blockExplorer: '${networkConfig.blockExplorer}',\n} as const\n`
134161

135162
const mergedFiles = {
136163
'/network-config.ts': { code: networkFile, readOnly: true },
@@ -142,40 +169,49 @@ export const NETWORK = {
142169
),
143170
}
144171

172+
const activeFile = file.startsWith('/') ? file : `/${file}`
173+
145174
return (
146-
<div style={{ margin: '1.5rem 0', borderRadius: '8px', overflow: 'hidden' }}>
175+
<div
176+
style={{
177+
margin: '1.5rem 0',
178+
borderRadius: '8px',
179+
overflow: 'hidden',
180+
border: `1px solid ${T.border}`,
181+
}}
182+
>
147183
<SandpackProvider
148-
key={network} // remount on network change to reset execution
184+
key={network}
149185
template={template}
150-
theme={sandpackDark}
186+
theme="dark"
151187
files={mergedFiles}
152188
options={{
153-
activeFile: file.startsWith('/') ? file : `/${file}`,
189+
activeFile,
154190
visibleFiles: Object.keys(mergedFiles),
155191
recompileMode: 'delayed',
156-
recompileDelay: 500,
192+
recompileDelay: 600,
193+
autorun: true,
157194
}}
158195
customSetup={{
159-
dependencies: {
160-
...DEFAULT_DEPS,
161-
...extraDeps,
162-
},
196+
dependencies: { ...DEFAULT_DEPS, ...extraDeps },
163197
}}
164198
>
165-
{/* Inner toolbar — inside Provider so RunButton can access sandpack context */}
199+
{/* Toolbar — inside Provider to access sandpack context, outside Layout to control bg */}
166200
<div
167201
style={{
168202
display: 'flex',
169203
alignItems: 'center',
170204
justifyContent: 'space-between',
171-
padding: '6px 12px',
172-
borderBottom: '1px solid var(--sp-colors-surface2)',
173-
background: 'var(--sp-colors-surface1)',
205+
padding: '6px 10px',
206+
background: T.bg,
207+
borderBottom: `1px solid ${T.border}`,
208+
gap: '8px',
174209
}}
175210
>
176211
<NetworkToggle network={network} onChange={setNetwork} />
177212
<RunButton />
178213
</div>
214+
179215
<SandpackLayout>
180216
<SandpackCodeEditor
181217
showLineNumbers
@@ -184,11 +220,7 @@ export const NETWORK = {
184220
style={{ height: 380 }}
185221
/>
186222
{showConsole ? (
187-
<SandpackConsole
188-
showHeader
189-
showResetConsoleButton
190-
style={{ height: 380 }}
191-
/>
223+
<SandpackConsole showHeader style={{ height: 380 }} />
192224
) : (
193225
<SandpackPreview style={{ height: 380 }} showNavigator={false} />
194226
)}

docs-site/next-env.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/// <reference types="next" />
22
/// <reference types="next/image-types/global" />
3-
import "./.next/types/routes.d.ts";
3+
import "./.next/dev/types/routes.d.ts";
44

55
// NOTE: This file should not be edited
66
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.

0 commit comments

Comments
 (0)