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
|
import AceEditor from "react-ace"
import "ace-builds/src-noconflict/mode-java"
import "ace-builds/src-noconflict/theme-github"
import { useState } from "react"
import styles from "./Editor.module.css"
import { SubmitResult, submitSource, useExamples } from "./api"
import Select from "react-select"
const defaultSourceText = `define times2
dup +
;
2 times2 .
-- prints 4
`
const Editor = () => {
const examples = useExamples()
const [sourceText, setSourceText] = useState(defaultSourceText)
const [result, setResult] = useState<SubmitResult>({ type: "not_yet_requested" })
const onChange = setSourceText
const executeCode = async (text: string) => {
const result = await submitSource(text)
setResult(result)
}
const renderExamples = () => {
switch (examples.type) {
case "not_yet_requested":
case "loading":
return <div>Loading examples...</div>
case "failed":
return <div className={styles.error}>
An unexpected error occurred while loading examples. See console for details.
</div>
case "success": {
const options = examples.data.examples.map(example => ({
value: example.content, label: example.title,
}))
const customStyles = {
option: (styles: any) => ({
...styles,
cursor: "pointer",
}),
control: (styles: any) => ({
...styles,
cursor: "pointer",
}),
}
return (
<Select
placeholder="Pick an example code snippet..."
options={options}
onChange={(val) => { setSourceText(val?.value as string) }}
styles={customStyles}
/>
)
}
}
}
const renderResults = () => {
switch (result.type) {
case "not_yet_requested":
case "loading":
return null
case "failed":
return (
<div className={styles.error}>
Failed to run code on the server. See console for details.
</div>
)
case "success": {
const text = `Output:\n${result.data}`
return (
<AceEditor
mode=""
theme="github"
onChange={() => undefined}
value={text}
name="results"
editorProps={{ $blockScrolling: true }}
width="100%"
minLines={10}
maxLines={10}
fontSize={16}
readOnly
/>
)
}
}
}
return (
<>
<div className={styles.examples}>
{renderExamples()}
</div>
<AceEditor
mode=""
theme="github"
onChange={onChange}
value={sourceText}
name="editor"
editorProps={{ $blockScrolling: true }}
width="100%"
fontSize={16}
/>
<button className={styles.runButton} onClick={() => executeCode(sourceText)}>
▶️ Run code on server
</button>
<div className={styles.results}>
{renderResults()}
</div>
</>
)
}
export default Editor
|