1
- import React , { Component } from "react" ;
2
-
3
- const MonacoEditor = React . lazy ( ( ) => import ( "react-monaco-editor" ) )
4
-
5
- import ReactResizeDetector from 'react-resize-detector'
1
+ import React , { useState , useEffect , useRef , lazy , Suspense } from "react" ;
2
+ import MonacoEditor from '@monaco-editor/react'
6
3
7
4
import PropTypes from 'prop-types'
8
5
@@ -12,102 +9,106 @@ import { setCode } from '../app/master/master-actions'
12
9
13
10
import languageToSyntax from '../assets/mapLanguageToSyntax.json' ;
14
11
15
- class Editor extends Component {
16
- constructor ( props ) {
17
- super ( props ) ;
18
- this . state = {
19
- height : 0 ,
20
- width : 0 ,
21
- isReady : false
22
- } ;
23
- this . editorContainerRef = React . createRef ( ) ;
24
- }
25
-
26
-
27
- editorDidMount = ( editor , monaco ) => {
12
+ const Editor = ( props ) => {
13
+ const {
14
+ language,
15
+ code,
16
+ setCode,
17
+ theme,
18
+ minimapStatus,
19
+ showUnused,
20
+ selectOnLineNumbers,
21
+ scrollbar,
22
+ quickSuggestion,
23
+ showFoldingControls,
24
+ } = props ;
25
+
26
+
27
+ const [ height , setHeight ] = useState ( 0 ) ;
28
+ const [ width , setWidth ] = useState ( 0 ) ;
29
+ const [ isReady , setIsReady ] = useState ( false ) ;
30
+ const editorContainerRef = useRef ( null ) ;
31
+ const resizeObserver = useRef ( null ) ;
32
+ const [ editorOptions , setEditorOptions ] = useState ( { } ) ;
33
+
34
+ const editorDidMount = ( editor , monaco ) => {
28
35
editor . onKeyDown ( event => {
29
36
const { browserEvent, ctrlKey } = event ;
30
37
const { key } = browserEvent ;
31
38
if ( key === 's' && ctrlKey ) {
32
39
event . preventDefault ( ) ;
33
- } else if ( key == 'Enter' && ctrlKey ) {
40
+ } else if ( key === 'Enter' && ctrlKey ) {
34
41
event . preventDefault ( ) ;
35
42
alert ( "Execute" ) ;
36
43
}
37
44
} ) ;
38
45
} ;
39
46
40
- componentDidMount ( ) {
41
- this . setState ( {
42
- ...this . state ,
43
- isReady : true
44
- } )
45
- }
46
-
47
- handleResize = ( width , height ) => {
48
- this . setState ( {
49
- ...this . state ,
50
- height : height ,
51
- width : width
52
- } )
53
- }
54
-
55
- render ( ) {
56
- const { width, height, isReady } = this . state ;
57
- const {
58
- language,
59
- code,
60
- setCode,
61
- theme,
62
- minimapStatus,
63
- showUnused,
64
- selectOnLineNumbers,
65
- scrollbar,
66
- quickSuggestion,
67
- showFoldingControls,
68
- } = this . props ;
69
-
70
- return (
71
- < div style = { {
72
- height : "100%" ,
73
- width : "100%"
74
- } } ref = { this . editorContainerRef } >
75
- < ReactResizeDetector
76
- handleWidth
77
- handleHeight
78
- onResize = { this . handleResize }
79
- refreshMode = "debounce"
80
- refreshRate = { 50 }
81
- targetRef = { this . editorContainerRef } />
82
- {
83
- isReady ? < MonacoEditor
84
- height = { height }
85
- width = { width }
86
- language = { languageToSyntax [ language ] }
87
- theme = { `vs-${ theme } ` }
88
- value = { code }
89
- options = { {
90
- minimap : {
91
- enabled : minimapStatus
92
- } ,
93
- showFoldingControls : showFoldingControls ,
94
- selectOnLineNumbers : selectOnLineNumbers ,
95
- scrollbar : scrollbar ,
96
- quickSuggestions : quickSuggestion ,
97
- showUnused : showUnused
98
- } }
99
- onChange = { ( newCode , event ) => {
100
- setCode ( newCode ) ;
101
- } }
102
- editorDidMount = { this . editorDidMount }
103
- editorWillMount = { this . editorWillMount }
104
- /> : null
105
- }
106
- </ div >
107
- ) ;
108
- }
109
- }
47
+ useEffect ( ( ) => {
48
+ resizeObserver . current = new ResizeObserver ( entries => {
49
+ for ( let entry of entries ) {
50
+ const { width, height } = entry . contentRect ;
51
+ handleResize ( width , height ) ;
52
+ }
53
+ } ) ;
54
+
55
+ if ( editorContainerRef . current ) {
56
+ resizeObserver . current . observe ( editorContainerRef . current ) ;
57
+ }
110
58
59
+ setIsReady ( true ) ;
60
+
61
+ return ( ) => {
62
+ if ( resizeObserver . current ) {
63
+ resizeObserver . current . disconnect ( ) ;
64
+ }
65
+ } ;
66
+ } , [ ] ) ;
67
+
68
+ useEffect ( ( ) => {
69
+ setEditorOptions ( {
70
+ minimap : {
71
+ enabled : minimapStatus
72
+ } ,
73
+ showFoldingControls : showFoldingControls ,
74
+ selectOnLineNumbers : selectOnLineNumbers ,
75
+ scrollbar : scrollbar ,
76
+ quickSuggestions : quickSuggestion ,
77
+ showUnused : showUnused
78
+ } ) ;
79
+ } , [ minimapStatus , showFoldingControls , selectOnLineNumbers , scrollbar , quickSuggestion , showUnused ] ) ;
80
+
81
+ const handleResize = ( newWidth , newHeight ) => {
82
+ setWidth ( newWidth ) ;
83
+ setHeight ( newHeight ) ;
84
+ } ;
85
+
86
+ return (
87
+ < div style = { {
88
+ height : "100%" ,
89
+ width : "100%"
90
+ } } ref = { editorContainerRef } >
91
+ {
92
+ isReady ? (
93
+ < Suspense fallback = { < div > Loading Editor...</ div > } >
94
+ < MonacoEditor
95
+ height = { height }
96
+ width = { width }
97
+ language = { languageToSyntax [ language ] }
98
+ theme = { `vs-${ theme } ` }
99
+ value = { code }
100
+ options = { editorOptions }
101
+ onChange = { ( newCode , event ) => {
102
+ setCode ( newCode ) ;
103
+ } }
104
+ editorDidMount = { editorDidMount }
105
+ />
106
+ </ Suspense >
107
+ ) : null
108
+ }
109
+ </ div >
110
+ ) ;
111
+ }
111
112
112
113
Editor . propTypes = {
113
114
editorOptions : PropTypes . object ,
0 commit comments