Monaco editor dynamically resizable
Solution 1
TL;DR: add automaticLayout: true
to your editor's configuration.
NL;PR:
Monaco has a built-in auto resize to parent container functionality:
React >= 16.3.0
componentDidMount(){
let editor = monaco.editor.create(this.editorDiv.current, {
value: "var x = 0;",
language: 'javascript',
automaticLayout: true // <<== the important part
});
}
constructor(props){super(props); this.editorDiv = React.createRef();}
render(){return <div ref={this.editorDiv} className="editor" ></div>}
React<16.3.0
render(){
return <div ref={el=>{this.editorDiv = el}} className="editor" ></div>
}
// I use this configuration in the editor:
componentDidMount(){
let editor = monaco.editor.create(this.editorDiv, {
value: "var x = 0;",
language: 'javascript',
automaticLayout: true // <<== the important part
});
}
And the CSS for the editor (it avoids rendering the editor for the first time with like 10px height):
.editor{
height: 100%;
}
First tested: v0.10.1, Last tested: v0.30.1
Note: < v0.20.0: The mechanism does not listen to its container size changes, it polls them.
@nrayburn-tech (Monaco Editor's contributor): Version 0.20 uses MutationObserver for all browsers. Version 0.21 and later uses ResizeObserver on supported browsers, otherwise, it uses polling as a fallback.
Solution 2
if you have a reference to the editor you can just call
editor.layout()
on some resize event.
For example, on window resize:
window.onresize = function (){
editor.layout();
};
Solution 3
this is old question but get the problem to and solved it with react-resize-detector
based on ResizeObserver it feet perfectly to the need (check browser compatibility)
Exemple of component :
import React, { Component } from 'react';
import ReactResizeDetector from 'react-resize-detector';
import * as monaco from 'monaco-editor';
class Editor extends Component {
constructor(props) {
super(props)
this.state = {
width: 0,
height: 0,
}
this.editor_div = React.createRef()
this.handle_rezise = this.handle_rezise.bind(this);
}
componentDidMount() {
const editor_model = monaco.editor.createModel('', 'sql');
this.monaco_editor = monaco.editor.create(this.editor_div.current, this.props.editorOptions);
this.monaco_editor.setModel(editor_model);
}
componentWillUnmount() {
this.monaco_editor && this.monaco_editor.dispose();
}
handle_rezise(width, height) {
this.monaco_editor.layout({ height, width });
}
render() {
return(
<div
className="editor-container"
style={{ height: '100%' }}>
<ReactResizeDetector
handleWidth
handleHeight
onResize={ this.handle_rezise }
refreshMode="debounce"
refreshRate={100} />
<div
className="editor"
ref={ this.editor_div }
style={{ height: '100%' }} />
</div>
)
}
}
export default Editor;
Hope it's help
Solution 4
In my case I'm using that exact CSS but although automaticLayout: true works, I found out overkill (seems to pooling the DOM 100ms interval and I have several editors opened in the document. SO I ended up implementing it manually :
just in case , my needs are different: I want the user to resize it the container - in a standard way and cheap (both on code and performance) on libraries and performance. This is what I did:
css container : resize: vertical; overflow: auto
and this js :
function installResizeWatcher(el, fn, interval){
let offset = {width: el.offsetWidth, height: el.offsetHeight}
setInterval(()=>{
let newOffset = {width: el.offsetWidth, height: el.offsetHeight}
if(offset.height!=newOffset.height||offset.width!=newOffset.width){
offset = newOffset
fn()
}
}, interval)
}
const typeScriptCodeContainer = document.getElementById('typeScriptCodeContainer')
typeScriptCodeEditor = monaco.editor.create(typeScriptCodeContainer, Object.assign(editorOptions, {value: example.codeValue}))
installResizeWatcher(typeScriptCodeContainer, typeScriptCodeEditor.layout.bind(typeScriptCodeEditor), 2000)
yes, 2 seconds interval and make sure it registers only once. I see there is / was a resize interval on 100ms for the automatic relayout in monaco - IMHO that's too much.
See it in action: https://typescript-api-playground.glitch.me/?example=2
Related videos on Youtube
elenaHristova
Updated on June 06, 2022Comments
-
elenaHristova almost 2 years
I have been searching for a discussion about if it's possible to mimic the html tag textarea's resizing when using Monaco Editor's field all over the Internet but I couldn't find one answering my question.
I'm using the monaco-editor npm package in a React application. Do you have any idea if this is easy to implement?
Thank you in advance!
SOLUTION
With pure css I selected the target html element and just added these properties:div { resize: vertical; overflow: auto; }
-
Satnam Sandhu over 5 yearsi suggest you to answer your question in the answers section instead of just editing the answer, and accept it. It would be better.
-
-
atilkan over 5 yearsThis is not recommended if you need performance. github.com/Microsoft/monaco-editor/issues/28
-
David I. Samudio almost 5 yearsDid you read the note? polling vs. listening? the official documentation reference?
-
Trevor about 2 yearsStrange. When I set
automaticLayout
totrue
and set the editorheight
to100%
, the editor doesn't grow/resize. As you noted, if I don't set theheight
, if renders the editor as ~10px
the first time, but still doesn't resize. -
David I. Samudio about 2 yearsWhat version are you using? I remember there was an issue around version 0.2x. It works correctly when adding the option here: microsoft.github.io/monaco-editor/…