Git Product home page Git Product logo

Comments (17)

alexdima avatar alexdima commented on May 14, 2024 41

@tylerlong Yes, there is a creation option called automaticLayout:

     /**
     * Enable that the editor will install an interval to check if its container dom node size has changed.
     * Enabling this might have a severe performance impact.
     * Defaults to false.
     */
    automaticLayout?:boolean;

Although convenient, I would personally not use this option as it is implemented by installing an interval that measures the container's size every 100ms. The reason is because the editor has no way of knowing what specifically in your app might cause its container to resize. In your case (when the container size is modified only by the window size), I would add a window.onresize listener and call editor.layout() inside that listener. That will cause the editor to rescan its container size. Even better, if you can somehow compute the size of the container, you can pass the size in to the editor.layout() method.

from monaco-editor.

zdne avatar zdne commented on May 14, 2024 13

This worked for me:

  updateDimensions() {
    this.editor.layout();
  }

  componentDidMount() {
    window.addEventListener("resize", this.updateDimensions.bind(this));
  }

  componentWillUnmount() {
    window.removeEventListener("resize", this.updateDimensions.bind(this));
  }

from monaco-editor.

jmrog avatar jmrog commented on May 14, 2024 5

Just in case anyone happens across this issue and sees the snippet posted by @zdne, I wanted to point out that it has a bug. bind creates and returns a new function on each call, so the result of this...

  componentDidMount() {
    window.addEventListener("resize", this.updateDimensions.bind(this));
  }

  componentWillUnmount() {
    window.removeEventListener("resize", this.updateDimensions.bind(this));
  }

...is that a new function is created and added as a resize listener in componentDidMount, and then another new (different) function is created and "removed" (scare-quotes because it was never actually added in the first place) as a resize listener in componentWillMount. What this means is that the listener that was added in componentDidMount is never actually removed, which could result in errors and/or memory leaks. A workaround is to store a reference to the bound function the first time it is created, and then add and remove that same one (using the reference) in the respective methods.

from monaco-editor.

MRchenkuan avatar MRchenkuan commented on May 14, 2024 4

listening resize event on window is better than a interval every 100ms , if it is not too frequently

from monaco-editor.

jmledantec avatar jmledantec commented on May 14, 2024 4

Hi,

get the same problem here and solved it with this :
react-resize-detector
@atilkan it's based on resizeobserver

Take care to the browser compatibility (I don't care in my project and don't have test it on any other brother than Chrome)

My editor 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;

New to react this code could be better, but hope this help someone.

from monaco-editor.

alexdima avatar alexdima commented on May 14, 2024 2

From https://api.jquery.com/resize/ I understand that it is a wrapper for the resize event.
From https://www.w3.org/TR/DOM-Level-3-Events/#event-type-resize I understand that the resize event is emitted when the window resizes (not when the element resizes).

I have validated my understanding using the following test page: https://jsfiddle.net/du0d9v9g/1/

$('#element').resize(function(){
  console.log('element resized');
  alert('element resized!');
});
setTimeout(function() {
  // resizing the element
    document.getElementById('element').style.width = '200px';
}, 2000);

That is why automaticLayout scans for the size of the container. The size of the container might be changed by the embedder of the editor due to a number of reasons, only one of them being window.onresize. That is what I mean in my above comment:

The reason is because the editor has no way of knowing what specifically in your app might cause its container to resize. In your case (when the container size is modified only by the window size), I would add a window.onresize listener and call editor.layout() inside that listener. That will cause the editor to rescan its container size. Even better, if you can somehow compute the size of the container, you can pass the size in to the editor.layout() method.

I am open to change the implementation of automaticLayout if we find a JS event that tells us when an element has changed its size.

from monaco-editor.

 avatar commented on May 14, 2024 1

@ alexandrudima There is a js event for element resize now. Check the links. First one would do the job.
https://developers.google.com/web/updates/2016/10/resizeobserver
https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver

from monaco-editor.

tylerlong avatar tylerlong commented on May 14, 2024

Although convenient, I would personally not use this option as it is implemented by installing an interval that measures the container's size every 100ms. The reason is because the editor has no way of knowing what specifically in your app might cause its container to resize.

Can we do something like:

$('#container').resize(function(){
  editor.layout();
});

Ref: https://api.jquery.com/resize/

I think the code above should be inside this project instead of let users write it themselves.

Maybe it's a better idea to reimplement the automaticLayout?:boolean; option?

from monaco-editor.

nikikante avatar nikikante commented on May 14, 2024

Made some example using transitionend event, works in all major browsers:
https://github.com/nikikante/ResizableElement
demo: https://rawgit.com/nikikante/ResizableElement/master/index.html

Additional testing: Works only on fixed width. Not working with width 100%;

from monaco-editor.

tylerlong avatar tylerlong commented on May 14, 2024

I see there is a commit that referenced this issue on Aug 19. So is this fixed or not?

from monaco-editor.

fdewannemaeker avatar fdewannemaeker commented on May 14, 2024

The automaticlayout option is the only one mentioned here that really worked for me. I'm using the Monaco editor inside a golden-layout module, and everything i tried (including ResizableElement mentioned above) failed. So thank you very much for this option.

from monaco-editor.

scniro avatar scniro commented on May 14, 2024

@zdne GOAT

from monaco-editor.

alexdima avatar alexdima commented on May 14, 2024

I'm not sure what else there is to do on our side, so I'm opting to close this issue.

The host of the editor can call editor.layout() when the container size has changed.

If the host of the editor does not want to call editor.layout(), then there is the option automaticLayout (implemented via setInterval that constantly probes for the container's size).

from monaco-editor.

cancerberoSgx avatar cancerberoSgx commented on May 14, 2024

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 peformance) 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

from monaco-editor.

ddb1494 avatar ddb1494 commented on May 14, 2024

from monaco-editor.

sheerun avatar sheerun commented on May 14, 2024

automaticLayout doesn't work when using css grid and reducing window size as ace-editor "fixes" it's height so grid layout engine assumes it cannot reduce it's size

from monaco-editor.

epicfaace avatar epicfaace commented on May 14, 2024

@ alexandrudima There is a js event for element resize now. Check the links. First one would do the job.
https://developers.google.com/web/updates/2016/10/resizeobserver
https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver

@alexandrudima so you would be open to a PR that implements automaticLayout using ResizeObserver?

from monaco-editor.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.