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();
}
@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
@MartinHaeusler this is out now in 4.4.0 Thanks
Thanks for this very fast response! I just upgraded my package.json to use 4.4.0 and it works very well, thank you!
@MartinHaeusler could you probably share a link to solution you created?
@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.
@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?
@dmigo that sounds great! If we think that could solve the issues let's do it
@dmigo Nice catch! That might have been the issue for me as well.
I'm up to it!
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?
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:
resize: vertical property (ie. allow the user to drag the bottom-right corner to resize). 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;
}
here is a pure css solution, using 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
Thanks @milahu your solution worked perfectly for my use case.
Thanks @milahu vary much.Your solution so helpful. In addition, It will be better to use the event "window.onresize".
Most helpful comment
I succeed by using react-resize-detector
CSS of
resizableclass