0Day Forums
Monaco editor dynamically resizable - Printable Version

+- 0Day Forums (https://0day.red)
+-- Forum: Coding (https://0day.red/Forum-Coding)
+--- Forum: NodeJs (https://0day.red/Forum-NodeJs)
+--- Thread: Monaco editor dynamically resizable (/Thread-Monaco-editor-dynamically-resizable)



Monaco editor dynamically resizable - buersuqcklaeo - 07-21-2023

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**<br>
With pure css I selected the target html element and just added these properties:

div {
resize: vertical;
overflow: auto;
}



RE: Monaco editor dynamically resizable - juliusjullundur380 - 07-21-2023

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:

[To see links please register here]




RE: Monaco editor dynamically resizable - kendrickzonwqp - 07-21-2023

this is old question but get the problem to and solved it with [react-resize-detector][1]

based on [ResizeObserver][2] it feet perfectly to the need (check [browser compatibility][3])

Exemple of component :

<!-- language: lang-js -->

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

[1]:

[To see links please register here]

[2]:

[To see links please register here]

[3]:

[To see links please register here]




RE: Monaco editor dynamically resizable - zaradzza - 07-21-2023

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();
};
```



RE: Monaco editor dynamically resizable - gustoes737600 - 07-21-2023

For posterity, the solution I arrived on was to set `automaticLayout: false` so that I could perform all the layout in a resize event listener.

```typescript
const placeholder = document.getElementById('placeholder')

const editor = monaco.editor.create(placeholder, {
value: '// hello world',
language: 'javascript',
automaticLayout: false // or remove, it defaults to false
})

// we need the parent of the editor
const parent = placeholder.parentElement

window.addEventListener('resize', () => {
// make editor as small as possible
editor.layout({ width: 0, height: 0 })

// wait for next frame to ensure last layout finished
window.requestAnimationFrame(() => {
// get the parent dimensions and re-layout the editor
const rect = parent.getBoundingClientRect()
editor.layout({ width: rect.width, height: rect.height })
})
})
```

By first reducing the editor layout to 0 we can safely query the dimensions of the parent element without the child (editor) contributing to its size. We can then match the editor to the new parent dimensions. Since this takes place over a single frame, there should be no flickering or lag.


RE: Monaco editor dynamically resizable - decumanushzponw - 07-21-2023

**TL;DR:** add `automaticLayout: true` to your editor's configuration.



**NL;PR:**


Monaco has a built-in auto resize to parent container functionality:

```js
createEditorWithAutoResize(){
this.editor = monaco.editor.create(
this.editorDiv.current, {
value: "var x = 0;",
language: 'javascript',
automaticLayout: true // <<== the important part
}
);
}
componentDidMount(){this.createEditorWithAutoResize();}
constructor(props){super(props); this.editorDiv = React.createRef();}
render(){return <div ref={this.editorDiv} className="editor" ></div>}
```

And the CSS for the editor (it avoids rendering the editor for the first time with like 10px height):
```css
.editor{
height: 100%;
}
```

**First tested:** v0.10.1, **Last tested:** v0.32.1

**Note:**
< v0.20.0: The mechanism does not listen to its container size changes, it [polls them](

[To see links please register here]

).

[@nrayburn-tech](

[To see links please register here]

) (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.


RE: Monaco editor dynamically resizable - dewless435812 - 07-21-2023

For anyone coming here having this issue in a basic web app (html, css, javascript) I've found a solution for the resizing issue I'm experiencing.

I have the monaco editor in a resizable flex container. It will only grow the width, not shrink it, and vertical resizing doesn't seem to work out of the box.

If you use the monaco config "automaticLayout: true" and the following CSS it seems to resize as expected:

.monaco-editor { position: absolute !important; }

I tried the max-width 99% trick but it causes a laggy delayed effect when increasing the width near edge of page.