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'
63
74import PropTypes from 'prop-types'
85
@@ -12,102 +9,106 @@ import { setCode } from '../app/master/master-actions'
129
1310import languageToSyntax from '../assets/mapLanguageToSyntax.json' ;
1411
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 ) => {
2835 editor . onKeyDown ( event => {
2936 const { browserEvent, ctrlKey } = event ;
3037 const { key } = browserEvent ;
3138 if ( key === 's' && ctrlKey ) {
3239 event . preventDefault ( ) ;
33- } else if ( key == 'Enter' && ctrlKey ) {
40+ } else if ( key === 'Enter' && ctrlKey ) {
3441 event . preventDefault ( ) ;
3542 alert ( "Execute" ) ;
3643 }
3744 } ) ;
3845 } ;
3946
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+ }
11058
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+ }
111112
112113Editor . propTypes = {
113114 editorOptions : PropTypes . object ,
0 commit comments