15
15
*/
16
16
17
17
import React , { useEffect , useMemo , useReducer , useRef , useState } from 'react'
18
- import MonacoEditor , { MonacoDiffEditor } from 'react-monaco-editor'
18
+ import MonacoEditor , { ChangeHandler , DiffEditorDidMount , EditorDidMount , MonacoDiffEditor } from 'react-monaco-editor'
19
19
import ReactGA from 'react-ga4'
20
20
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api'
21
21
import { configureMonacoYaml } from 'monaco-yaml'
@@ -94,10 +94,10 @@ const CodeEditor: React.FC<CodeEditorInterface> & CodeEditorComposition = React.
94
94
const memoisedReducer = React . useCallback ( CodeEditorReducer , [ ] )
95
95
const [ state , dispatch ] = useReducer (
96
96
memoisedReducer ,
97
- initialState ( { mode, theme, value, diffView, noParsing, tabSize } ) ,
97
+ initialState ( { mode, theme, value, defaultValue , diffView, noParsing, tabSize } ) ,
98
98
)
99
99
const [ , json , yamlCode , error ] = useJsonYaml ( state . code , tabSize , state . mode , ! state . noParsing )
100
- const [ , originalJson , originlaYaml ] = useJsonYaml ( defaultValue , tabSize , state . mode , ! state . noParsing )
100
+ const [ , originalJson , originalYaml ] = useJsonYaml ( state . defaultCode , tabSize , state . mode , ! state . noParsing )
101
101
const [ contentHeight , setContentHeight ] = useState (
102
102
adjustEditorHeightToContent ? INITIAL_HEIGHT_WHEN_DYNAMIC_HEIGHT : height ,
103
103
)
@@ -160,7 +160,7 @@ const CodeEditor: React.FC<CodeEditorInterface> & CodeEditorComposition = React.
160
160
}
161
161
} , [ disableSearch ] )
162
162
163
- const editorDidMount = ( editor , monaco ) => {
163
+ const editorDidMount : EditorDidMount = ( editor ) => {
164
164
if (
165
165
mode === MODES . YAML &&
166
166
editor &&
@@ -181,15 +181,21 @@ const CodeEditor: React.FC<CodeEditorInterface> & CodeEditorComposition = React.
181
181
}
182
182
183
183
if ( adjustEditorHeightToContent && editor ) {
184
- if ( ! ( 'getModifiedEditor' in editor ) ) {
185
- editor . onDidContentSizeChange ( ( ) => {
186
- setContentHeight ( editor . getContentHeight ( ) )
187
- } )
184
+ editor . onDidContentSizeChange ( ( ) => {
188
185
setContentHeight ( editor . getContentHeight ( ) )
189
- return
190
- }
191
- const modifiedEditor = editor . getModifiedEditor ( )
192
- const originalEditor = editor . getOriginalEditor ( )
186
+ } )
187
+ setContentHeight ( editor . getContentHeight ( ) )
188
+ }
189
+
190
+ editorRef . current = editor
191
+ monacoRef . current = monaco
192
+ }
193
+
194
+ const diffEditorDidMount : DiffEditorDidMount = ( editor , monaco ) => {
195
+ const originalEditor = editor . getOriginalEditor ( )
196
+ const modifiedEditor = editor . getModifiedEditor ( )
197
+
198
+ if ( adjustEditorHeightToContent ) {
193
199
originalEditor . onDidContentSizeChange ( ( ) => {
194
200
setContentHeight (
195
201
Math . max (
@@ -198,6 +204,7 @@ const CodeEditor: React.FC<CodeEditorInterface> & CodeEditorComposition = React.
198
204
) ,
199
205
)
200
206
} )
207
+
201
208
modifiedEditor . onDidContentSizeChange ( ( ) => {
202
209
setContentHeight (
203
210
Math . max (
@@ -206,9 +213,14 @@ const CodeEditor: React.FC<CodeEditorInterface> & CodeEditorComposition = React.
206
213
) ,
207
214
)
208
215
} )
209
- setContentHeight ( Math . max ( modifiedEditor . getContentHeight ( ) , modifiedEditor . getContentHeight ( ) ) )
216
+
217
+ setContentHeight ( Math . max ( originalEditor . getContentHeight ( ) , modifiedEditor . getContentHeight ( ) ) )
210
218
}
211
219
220
+ originalEditor . onDidChangeModelContent ( ( ) => {
221
+ codeEditorOnChange ( modifiedEditor . getValue ( ) , originalEditor . getValue ( ) )
222
+ } )
223
+
212
224
editorRef . current = editor
213
225
monacoRef . current = monaco
214
226
}
@@ -254,14 +266,15 @@ const CodeEditor: React.FC<CodeEditorInterface> & CodeEditorComposition = React.
254
266
editorRef . current . layout ( )
255
267
} , [ width , windowHeight ] )
256
268
257
- const setCode = ( value : string ) => {
269
+ const setCode = ( value : string , originalValue : string ) => {
258
270
dispatch ( { type : 'setCode' , value } )
259
- onChangeRef . current ?.( value )
271
+ dispatch ( { type : 'setDefaultCode' , value : originalValue } )
272
+ onChangeRef . current ?.( value , originalValue )
260
273
}
261
274
262
275
useEffectAfterMount ( ( ) => {
263
276
if ( noParsing ) {
264
- setCode ( value )
277
+ setCode ( value , defaultValue )
265
278
266
279
return
267
280
}
@@ -270,8 +283,8 @@ const CodeEditor: React.FC<CodeEditorInterface> & CodeEditorComposition = React.
270
283
return
271
284
}
272
285
273
- setCode ( parseValueToCode ( value , state . mode , tabSize ) )
274
- } , [ value , noParsing ] )
286
+ setCode ( parseValueToCode ( value , state . mode , tabSize ) , parseValueToCode ( defaultValue , state . mode , tabSize ) )
287
+ } , [ value , defaultValue , noParsing ] )
275
288
276
289
useEffect ( ( ) => {
277
290
dispatch ( { type : 'setDiff' , value : diffView } )
@@ -283,13 +296,17 @@ const CodeEditor: React.FC<CodeEditorInterface> & CodeEditorComposition = React.
283
296
}
284
297
} , [ focus ] )
285
298
286
- function handleOnChange ( newValue , e ) {
287
- setCode ( newValue )
299
+ const codeEditorOnChange = ( newValue : string , newOriginalValue : string ) => {
300
+ setCode ( newValue , newOriginalValue )
301
+ }
302
+
303
+ const handleOnChange : ChangeHandler = ( newValue ) => {
304
+ codeEditorOnChange ( newValue , editorRef . current ?. getOriginalEditor ?.( ) . getValue ?.( ) ?? '' )
288
305
}
289
306
290
307
function handleLanguageChange ( mode : 'json' | 'yaml' ) {
291
308
dispatch ( { type : 'changeLanguage' , value : mode } )
292
- setCode ( mode === 'json' ? json : yamlCode )
309
+ setCode ( mode === 'json' ? json : yamlCode , mode === 'json' ? originalJson : originalYaml )
293
310
}
294
311
295
312
const options : monaco . editor . IEditorConstructionOptions = {
@@ -325,6 +342,7 @@ const CodeEditor: React.FC<CodeEditorInterface> & CodeEditorComposition = React.
325
342
326
343
const diffViewOptions : monaco . editor . IDiffEditorConstructionOptions = {
327
344
...options ,
345
+ originalEditable : ! readOnly ,
328
346
useInlineViewWhenSpaceIsLimited : false ,
329
347
}
330
348
@@ -340,15 +358,13 @@ const CodeEditor: React.FC<CodeEditorInterface> & CodeEditorComposition = React.
340
358
{ shebang && < div className = "code-editor__shebang" > { shebang } </ div > }
341
359
{ state . diffMode ? (
342
360
< MonacoDiffEditor
343
- original = {
344
- noParsing ? defaultValue : state . mode === 'json' ? originalJson : originlaYaml
345
- }
361
+ original = { state . defaultCode }
346
362
value = { state . code }
347
363
language = { state . mode }
348
364
onChange = { handleOnChange }
349
365
options = { diffViewOptions }
350
366
theme = { state . theme . toLowerCase ( ) . split ( ' ' ) . join ( '-' ) }
351
- editorDidMount = { editorDidMount }
367
+ editorDidMount = { diffEditorDidMount }
352
368
height = { editorHeight }
353
369
width = "100%"
354
370
/>
0 commit comments