Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

react-ace in resizable container #207

Closed
MartinHaeusler opened this issue May 27, 2017 · 18 comments · Fixed by #208
Closed

react-ace in resizable container #207

MartinHaeusler opened this issue May 27, 2017 · 18 comments · Fixed by #208

Comments

@MartinHaeusler
Copy link

MartinHaeusler commented May 27, 2017

I am trying to use react-ace inside a div that can be resized by the user at runtime (to be precise, the size of the div is controlled by a flexbox). By default, the ACE editor requires fixed with and height values in pixels.

By using react-measure and some div nesting, I was able to get the ACE Editor to resize its bounds correctly, at least visually. However, the controls inside the editor (e.g. the width of the line wrapping, the scroll bar, ...) behave weirdly, because they did not get properly notified about the change in editor dimensions.

The "vanilla" ACE editor has a resize() method to fix just that problem (see this fiddle).

My request is: please either forward resize() in react-ace, or call resize() internally on componentWillReceiveProps in case that width and/or height has changed.

EDIT: I had a quick look at the source code. You actually do this:

if(nextProps.height !== this.props.height){
  this.editor.resize();
}

... but what about changes in width? Shouldn't it be this:

if(nextProps.height !== this.props.height || nextProps.width !== this.props.width){
  this.editor.resize();
}
@securingsincity
Copy link
Owner

@MartinHaeusler thanks for the issue. I'm working on this right now. should be out in 4.4.0 and will be in 5.0.0 when that comes out

@securingsincity
Copy link
Owner

@MartinHaeusler this is out now in 4.4.0 Thanks

@MartinHaeusler
Copy link
Author

Thanks for this very fast response! I just upgraded my package.json to use 4.4.0 and it works very well, thank you!

@dmigo
Copy link

dmigo commented Aug 1, 2017

@MartinHaeusler could you probably share a link to solution you created?

@MartinHaeusler
Copy link
Author

@dmigo: I tried using react-measure for the job. However, it only worked in some cases, not all of them. There were always some odd corner cases left where the editor wouldn't behave as intended. In the end, I switched from Ace to CodeMirror for that reason. I had some issues there as well with making things resizable and had to do some quite ugly hacks, but that works now. Sorry, I discarded the prototype for the resizable react-ace editor shortly after. But it never really worked properly as intended anyways.

@dmigo
Copy link

dmigo commented Aug 2, 2017

@securingsincity
Trying to implement something similar to what @MartinHaeusler did, I found out an interesting behaviour of react-ace. It seemed that resize() wasn't happening properly.
After some investigation it turned out that this.editor.resize() is being called on componentWillReceiveProps which occurs before render.
It would make more sense to call this.editor.resize() during componentDidUpdate, after render happened and ace-editor received new values for height and width.
If we agree on that, then I would be happy to fix this one for you (along with #212). What would you say?

@securingsincity
Copy link
Owner

@dmigo that sounds great! If we think that could solve the issues let's do it

@MartinHaeusler
Copy link
Author

@dmigo Nice catch! That might have been the issue for me as well.

@dmigo
Copy link

dmigo commented Aug 2, 2017

I'm up to it!

@dmigo dmigo mentioned this issue Aug 3, 2017
@rclabs
Copy link

rclabs commented Aug 17, 2017

I upgraded to 5.1.2 and calling AceEditor with the props:

mode: 'json',
theme: 'chrome',
readOnly: true

Is there anything I need to add to get it to resize to the container?

@brandontle
Copy link

brandontle commented Oct 17, 2018

Is there anything I need to add to get it to resize to the container?

Anyone figure out how to automatically resize the container based on user-control? I'm trying to:

  1. allow the user to actively resize the container via the CSS resize: vertical property (ie. allow the user to drag the bottom-right corner to resize).
  2. automatically resize the container based on the number of lines the user has inputted. With the default height of 500px, if the user inputs >27 lines, the editor remains the same height, while making the container scrollable to add extra space. I'd like to have the container grow (or shrink down to a min-height) based on the lines inputted.

@xgaia
Copy link

xgaia commented Oct 23, 2019

Anyone figure out how to automatically resize the container based on user-control?

I succeed by using react-resize-detector

import AceEditor from 'react-ace'
import ReactResizeDetector from 'react-resize-detector'

export default class myComponent extends Component {

  constructor (props) {
    super(props)
    this.state = {
      editorHeight: 400,
      editorWidth: "auto"
    }
    this.onResize = this.onResize.bind(this)
  }


  onResize (w, h) {
    this.setState({
      editorHeight: h,
      editorWidth: w
    })
  }

  render () {
    <div className="resizable">
     <ReactResizeDetector handleWidth handleHeight onResize={this.onResize} />
     <AceEditor
       height={this.state.editorHeight}
       width={this.state.editorWidth}
     />
    </div>
  }
}

CSS of resizable class

.resizable {
    overflow: auto;
    resize: both;
    height: 400px;
    width: auto;
}

@milahu
Copy link

milahu commented Aug 16, 2020

here is a pure css solution, using CSS resize: both on the editor div

<AceEditor
  onLoad={editorInstance => {
    editorInstance.container.style.resize = "both";
    // mouseup = css resize end
    document.addEventListener("mouseup", e => (
      editorInstance.resize()
    ));
  }}
/>

downside: on resize-larger the editor content is hidden

here is a demo fiddle with vanilla js

@bassiebangura
Copy link

Thanks @milahu your solution worked perfectly for my use case.

@panfangqi
Copy link

Thanks @milahu vary much.Your solution so helpful. In addition, It will be better to use the event "window.onresize".

@dimkajasons
Copy link

dimkajasons commented Aug 18, 2021

Thanks, @milahu your solution works fine. Unfortunately, this approach is not working in safari :( Do someone faced with the same problem? Looks like it's safari specific problem with resizing. You can check it out with the above example

@milahu
Copy link

milahu commented Aug 18, 2021

this approach is not working in safari

yepp. try a polyfill

@karanattriCaw
Copy link

karanattriCaw commented Oct 20, 2021

add a className to AceEditor component and use this in your CSS or other styling file

.ace-editor {
max-height: 300px;
min-height: 150px;
resize: both;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.