@@ -3,19 +3,27 @@ import { ThemeContext } from 'styled-components'
3
3
import { toast } from 'react-hot-toast'
4
4
5
5
import * as s from './styles'
6
- import Switch from './switch'
7
6
import CodeEditor from './code-editor'
8
7
import { buildFnCodeValidator , buildFnCallValidator } from './validators'
9
- import { buildFnCodeDecomposer , buildFnCodeComposer , composeFnData , decomposeFnData } from './template-handler'
8
+ import {
9
+ buildFnCodeDecomposer ,
10
+ buildFnCodeComposer ,
11
+ composeFnData ,
12
+ decomposeFnData ,
13
+ } from './template-handler'
10
14
import templates from '../../config/templates'
11
15
import useFormInput from '../../hooks/use-form-input'
12
16
import useCarbonAds from '../../hooks/use-carbon-ads'
13
17
import useLocalStorage from '../../hooks/use-local-storage'
14
- import { Template , ThemeType , FunctionData , Language } from '../../types'
18
+ import {
19
+ Template ,
20
+ ThemeType ,
21
+ FunctionData ,
22
+ Language ,
23
<
8000
span class="diff-text-marker">+ GlobalVar ,
24
+ } from '../../types'
15
25
import './carbon-ads.css'
16
- import { DEFAULT_LANGUAGE , DEFAULT_TEMPLATE , LANGUAGES } from '../../config/consts'
17
-
18
- type GlobalVar = { name : string ; value : string }
26
+ import * as consts from '../../config/consts'
19
27
20
28
type Props = {
21
29
onSubmit : (
@@ -27,30 +35,32 @@ type Props = {
27
35
}
28
36
29
37
const FunctionForm = ( { onSubmit, onThemeChange } : Props ) => {
30
- const [ lang , setLang ] = useLocalStorage < Language > ( 'fn-lang' , DEFAULT_LANGUAGE )
38
+ const [ lang , setLang ] = useLocalStorage < Language > (
39
+ 'fn-lang' ,
40
+ consts . DEFAULT_LANGUAGE
41
+ )
31
42
const [ fnCall , setFnCall ] = useFormInput (
32
43
'fn-call' ,
33
44
'fn()' ,
34
45
buildFnCallValidator ( lang )
35
46
)
36
- const [ fnCode , setFnCode ] = useLocalStorage ( 'fn-code' , buildFnCodeComposer ( DEFAULT_LANGUAGE ) ( ) )
47
+ const [ fnCode , setFnCode ] = useLocalStorage ( 'fn-code' , consts . DEFAULT_FN_CODE )
37
48
const [ fnGlobalVars , setFnGlobalVars ] = useLocalStorage < GlobalVar [ ] > (
38
49
'fn-global-vars' ,
39
- [
40
- { name : '' , value : '' } ,
41
- { name : '' , value : '' } ,
42
- ]
50
+ consts . DEFAULT_GLOBAL_VARS
43
51
)
44
52
45
53
const [ memoize , setMemoize ] = useLocalStorage ( 'memoize' , false )
46
54
const [ animate , setAnimate ] = useLocalStorage ( 'animate' , true )
47
-
55
+
48
56
const theme = useContext ( ThemeContext )
49
57
50
- // if null, user changed the default template code
51
- const [ activeTemplate , setActiveTemplate ] = useState < Template | null > ( DEFAULT_TEMPLATE )
52
-
53
- const adsRef = useCarbonAds ( )
58
+ // if null, user changed the default code that comes in with template
59
+ const [ activeTemplate , setActiveTemplate ] = useState < Template | null > (
60
+ consts . DEFAULT_TEMPLATE
61
+ )
62
+
63
+ const divRefAds = useCarbonAds ( )
54
64
55
65
const handleSelectTemplateChange = (
56
66
e : React . ChangeEvent < HTMLSelectElement >
@@ -64,39 +74,37 @@ const FunctionForm = ({ onSubmit, onThemeChange }: Props) => {
64
74
setFnGlobalVars ( res . fnGlobalVars )
65
75
}
66
76
67
- // useEffect(() => {
68
- // console.log(activeTemplate)
69
- // }, [activeTemplate])
70
-
71
- // const handleSelectLanguageChange = (
72
- // e: React.ChangeEvent<HTMLSelectElement>
73
- // ) => {
74
- // const newLang = e.target.value as Language
75
- // setLang(newLang)
76
-
77
- // // DOING: testing (selecione um template node, mude o codigo manualmente e mude pra python)
78
- // if (activeTemplate === null) {
79
- // // keep user-defined body and params names (both contained in fnCode)
80
- // setFnCode((prevFnCode) => {
81
- // const decomposeFnCode = buildFnCodeDecomposer(lang)
82
- // const composeFnCode = buildFnCodeComposer(newLang)
83
- // return composeFnCode(decomposeFnCode(prevFnCode))
84
- // })
85
- // } else {
86
- // const { fnCode, fnCall, fnGlobalVars } = decomposeFnData(
87
- // templates[activeTemplate].fnData[newLang],
88
- // newLang
89
- // )
90
- // setFnCode(fnCode)
91
- // setFnCall(fnCall)
92
- // setFnGlobalVars(fnGlobalVars)
93
- // }
94
- // }
77
+ const handleSelectLanguageChange = (
78
+ e : React . ChangeEvent < HTMLSelectElement >
79
+ ) => {
80
+ const newLang = e . target . value as Language
81
+ setLang ( newLang )
82
+
83
+ if ( activeTemplate === null ) {
84
+ // keep only the previous params names (inside fnCode)
85
+ setFnCode ( ( prevFnCode ) => {
86
+ const decomposeFnCode = buildFnCodeDecomposer ( lang )
87
+ const composeFnCode = buildFnCodeComposer ( newLang )
88
+
89
+ const { paramsNames } = decomposeFnCode ( prevFnCode )
90
+ return composeFnCode ( { paramsNames } )
91
+ } )
92
+ } else {
93
+ const { fnCode, fnCall, fnGlobalVars } = decomposeFnData (
94
+ templates [ activeTemplate ] . fnData [ newLang ] ,
95
+ newLang
96
+ )
97
+ setFnCode ( fnCode )
98
+ setFnCall ( fnCall )
99
+ setFnGlobalVars ( fnGlobalVars )
100
+ }
101
+ }
95
102
96
103
const handleFormSubmit = ( e : React . FormEvent < HTMLFormElement > ) => {
97
104
e . preventDefault ( )
98
105
99
106
// client-side validation
107
+ // TODO: remover try/catch
100
108
try {
101
109
const fnData = composeFnData ( fnCode , fnCall . value , fnGlobalVars , lang ) // throw error
102
110
onSubmit ( lang , fnData , { memoize, animate } )
@@ -108,7 +116,7 @@ const FunctionForm = ({ onSubmit, onThemeChange }: Props) => {
108
116
return (
109
117
< s . FormContainer onSubmit = { handleFormSubmit } >
110
118
< s . FormContent >
111
- < div ref = { adsRef } />
119
+ < div ref = { divRefAds } />
112
120
113
121
< s . Title > Pre-defined templates</ s . Title >
114
122
< s . Select
@@ -135,7 +143,7 @@ const FunctionForm = ({ onSubmit, onThemeChange }: Props) => {
135
143
} )
136
144
} }
137
145
/>
138
- < span style = { { margin : '0 0.3em' } } > =</ span >
146
+ < span style = { { margin : '0 0.3em' } } > =</ span >
139
147
< CodeEditor
140
148
lang = { lang }
141
149
value = { value }
@@ -149,40 +157,60 @@ const FunctionForm = ({ onSubmit, onThemeChange }: Props) => {
149
157
</ s . VariableContainer >
150
158
) ) }
151
159
152
- { /* <s.Title>Language</s.Title>
153
- <s.Select value={lang} onChange={handleSelectLanguageChange}>
154
- {LANGUAGES.map((lang) => (
155
- <option key={lang} value={lang}>
156
- {lang}
157
- </option>
158
- ))}
159
- </s.Select> */ }
160
-
161
160
< s . Title > Recursive function</ s . Title >
162
- < CodeEditor
163
- lang = { lang }
164
- value = { fnCode }
165
- shouldValueChange = { buildFnCodeValidator ( lang ) }
166
- onValueChange = { ( newValue ) => {
167
- setFnCode ( ( prevValue ) => {
168
- if ( prevValue !== newValue ) setActiveTemplate ( null )
169
- return newValue
170
- } )
171
- } }
172
- />
161
+ < div style = { { position : 'relative' } } >
162
+ < s . Select
163
+ value = { lang }
164
+ onChange = { handleSelectLanguageChange }
165
+ style = { {
166
+ position : 'absolute' ,
167
+ top : '-27px' ,
168
+ right : '0' ,
169
+ width : '80px' ,
170
+ height : '22px' ,
171
+ fontSize : '14px'
172
+ } }
173
+ >
174
+ { consts . LANGUAGES . map ( ( lang ) => (
175
+ < option key = { lang } value = { lang } >
176
+ { lang }
177
+ </ option >
178
+ ) ) }
179
+ </ s . Select >
180
+ < CodeEditor
181
+ lang = { lang }
182
+ value = { fnCode }
183
+ shouldValueChange = { buildFnCodeValidator ( lang ) }
184
+ onValueChange = { ( newValue ) => {
185
+ setFnCode ( ( prevValue ) => {
186
+ if ( prevValue !== newValue ) setActiveTemplate ( null )
187
+ return newValue
188
+ } )
189
+ } }
190
+ onValueReset = { ( ) => {
191
+ const composeFnCode = buildFnCodeComposer ( lang )
192
+ setFnCode ( composeFnCode ( ) )
193
+ } }
194
+ />
195
+ </ div >
173
196
174
197
< s . Title > Options</ s . Title >
175
198
< s . Option >
176
199
< span > Enable step-by-step animation</ span >
177
- < Switch checked = { animate } onChange = { ( ) => setAnimate ( ( p ) => ! p ) } />
200
+ < s . Switch checked = { animate } onChange = { ( ) => setAnimate ( ( p ) => ! p ) } />
178
201
</ s . Option >
179
202
< s . Option >
180
203
< span > Enable memoization</ span >
181
- < Switch checked = { memoize } onChange = { ( ) => setMemoize ( ( p ) => ! p ) } />
204
+ < s . Switch checked = { memoize } onChange = { ( ) => setMemoize ( ( p ) => ! p ) } />
182
205
</ s . Option >
183
206
< s . Option >
184
207
< span > Enable dark mode</ span >
185
- < Switch checked = { theme . type === 'dark' } onChange = { ( ) => onThemeChange ( theme . type === 'light' ? 'dark' : 'light' ) } />
208
+ < s . Switch
209
+ checked = { theme . type === 'dark' }
210
+ onChange = { ( ) =>
211
+ onThemeChange ( theme . type === 'light' ? 'dark' : 'light' )
212
+ }
213
+ />
186
214
</ s . Option >
187
215
</ s . FormContent >
188
216
0 commit comments