1
+ import React , { useState } from "react" ;
2
+ import AceEditor from "react-ace" ;
3
+
4
+ import "ace-builds/src-noconflict/mode-python" ;
5
+ import "ace-builds/src-noconflict/theme-terminal" ;
6
+ import "ace-builds/src-noconflict/ext-language_tools" ;
7
+ import "ace-builds/src-noconflict/ext-searchbox" ;
8
+ import "ace-builds/src-noconflict/ext-inline_autocomplete" ;
9
+ import "ace-builds/src-noconflict/keybinding-vim" ;
10
+
11
+ const languages = [
12
+ "javascript" ,
13
+ "java" ,
14
+ "python" ,
15
+ "mysql" ,
16
+ "golang" ,
17
+ "typescript" ,
18
+ ] ;
19
+
20
+ const themes = [
21
+ "monokai" ,
22
+ "github" ,
23
+ "tomorrow" ,
24
+ "kuroir" ,
25
+ "twilight" ,
26
+ "xcode" ,
27
+ "textmate" ,
28
+ "solarized_dark" ,
29
+ "solarized_light" ,
30
+ "terminal"
31
+ ] ;
32
+
33
+ languages . forEach ( lang => {
34
+ require ( `ace-builds/src-noconflict/mode-${ lang } ` ) ;
35
+ require ( `ace-builds/src-noconflict/snippets/${ lang } ` ) ;
36
+ } ) ;
37
+
38
+ themes . forEach ( theme => require ( `ace-builds/src-noconflict/theme-${ theme } ` ) ) ;
39
+
40
+ import "ace-builds/src-min-noconflict/ext-searchbox" ;
41
+ import "ace-builds/src-min-noconflict/ext-language_tools" ;
42
+
43
+
44
+ import { Question } from "@/api/structs" ;
45
+
46
+ interface Props {
47
+ question : Question ;
48
+ }
49
+
50
+
51
+ export default function CollabEditor ( { question} : Props ) {
52
+ const [ theme , setTheme ] = useState ( "twilight" )
53
+ const [ fontSize , setFontSize ] = useState ( 16 )
54
+ const [ language , setLanguage ] = useState ( "python" )
55
+
56
+
57
+ const handleOnChange = ( newValue : string ) => {
58
+ console . log ( "Content changed:" , newValue ) ;
59
+ } ;
60
+
61
+ const handleOnLoad = ( editor : any ) => {
62
+ editor . container . style . resize = "both"
63
+ }
64
+
65
+ // TODO: to be taken from question props instead
66
+ // const value = question[language] ?? "// Comment"
67
+ const value = `def foo:
68
+ pass`
69
+
70
+
71
+ return < >
72
+ < div className = "flex space-x-4 items-center p-4" >
73
+ < div className = "flex flex-col" >
74
+ < label className = "font-semibold mb-1" > Font Size</ label >
75
+ < input
76
+ type = "number"
77
+ className = "border border-gray-600 bg-gray-800 text-white p-2 rounded w-20"
78
+ value = { fontSize }
79
+ onChange = { ( e ) => setFontSize ( Number ( e . target . value ) ) }
80
+ />
81
+ </ div >
82
+
83
+ < div className = "flex flex-col" >
84
+ < label className = "font-semibold mb-1" > Theme</ label >
85
+ < select
86
+ className = "border border-gray-600 bg-gray-800 text-white p-2 rounded"
87
+ value = { theme }
88
+ onChange = { ( e ) => setTheme ( e . target . value ) }
89
+ >
90
+ { themes . map ( ( theme ) => (
91
+ < option key = { theme } value = { theme } >
92
+ { theme }
93
+ </ option >
94
+ ) ) }
95
+ </ select >
96
+ </ div >
97
+
98
+ < div className = "flex flex-col" >
99
+ < label className = "font-semibold mb-1" > Language</ label >
100
+ < select
101
+ className = "border border-gray-600 bg-gray-800 text-white p-2 rounded"
102
+ value = { language }
103
+ onChange = { ( e ) => setLanguage ( e . target . value ) }
104
+ >
105
+ { languages . map ( ( lang ) => (
106
+ < option key = { lang } value = { lang } >
107
+ { lang }
108
+ </ option >
109
+ ) ) }
110
+ </ select >
111
+ </ div >
112
+ </ div >
113
+
114
+
115
+ < AceEditor
116
+ mode = { language }
117
+ className = { "editor" }
118
+ width = { "90%" }
119
+ height = { "90%" }
120
+ theme = { theme }
121
+ name = "Editor"
122
+ fontSize = { fontSize }
123
+ onLoad = { handleOnLoad }
124
+ onChange = { handleOnChange }
125
+ lineHeight = { 19 }
126
+ showPrintMargin = { true }
127
+ showGutter = { true }
128
+ highlightActiveLine = { true }
129
+ value = { value }
130
+ setOptions = { {
131
+ enableBasicAutocompletion : true ,
132
+ enableLiveAutocompletion : true ,
133
+ enableSnippets : false ,
134
+ showLineNumbers : true ,
135
+ tabSize : 4 ,
136
+ } } />
137
+ </ >
138
+
139
+ }
0 commit comments