question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Respond to window resize

See original GitHub issue

When the window size changes, I want to keep the same proportional size of my panes.

For example:

  • I make a resizable pane at the bottom.
  • The user has a window 600px high
  • The user drags the bottom panel to take up 200px of the height, and the top pane is sized by the browser to 400px.
  • The user maximized their browser and the window height is now 1200px

In this case the bottom pane was taking 1/3 of the height and the top pane 2/3 of the height, but after resize the bottom pane is only 1/6 of the height. I want to be able to keep the proportions so the bottom pane would grow to 400px high on window resize.

I can make it work with code outside the component, but it would feel pretty natural to either pass in a prop that says to use proportional sizing when the window size changes, or to pass in a callback to use when the window size changes. Edit: it is actually pretty tricky to get it to change size on window resize. I have a default height of 30%, which I use to set defaultSize prop to defaultHeight * window.innerHeight and that works initially, and resizes to 30% whenever I change the window height, but as soon as I drag the panel to a different size, it ignores defaultHeight so it is stuck at the pixel size it has been dragged to. If I set size prop I can no longer drag it to resize.

Issue Analytics

  • State:open
  • Created 7 years ago
  • Reactions:3
  • Comments:9 (2 by maintainers)

github_iconTop GitHub Comments

4reactions
BernardoFBBragacommented, Jul 6, 2018

I managed to get it working in a different approach, without touching the source


        componentDidMount () {
            window.addEventListener('resize', this.updateSize)
        }

        componentWillUnmount () {
            window.removeEventListener('resize', this.updateSize)
        }

        componentDidUpdate () {
            if (this.state.windowResize) this.setState({windowResize: false})
        }

        updateSize = () => this.setState({windowResize: true})

        onChange = () => {
            const draggedSize = _.get(this.splitpane.current, 'state.draggedSize')

            if (draggedSize && this.splitpane.current.splitPane.clientHeight) {
                const percentage = draggedSize / this.splitpane.current.splitPane.clientHeight

                this.setState({panelSize: `${percentage * 100}%`})
            }
        }

and on the render function there’s something like

<SplitPane
    ref={this.splitpane}
    split="horizontal"
    minSize={50}
    maxSize={-50}
    defaultSize={this.state.panelSize}
    size={this.state.windowResize ? this.state.panelSize : undefined}
    onChange={this.onChange}
>

Rationale is this: when the window updates, I set the boolean so on the render function the splitpane is updated with the size prop. In the next render, the componentDidUpdate function sets the boolean to false, meaning the drag is back online

3reactions
davidmasoncommented, Apr 8, 2016

I think the container size would be best.

I have managed to get something working with this, but I had to reach in and mess with some of the internals from the parent component - super fragile but it works. I did these things:

  • onDragFinished: look up this.refs.mySplitPane.state.draggedSize and save as a percentage of my height (e.g. percentageSize = draggedSize / window.innerHeight might give 0.33)
  • listen to window resize events to tweak the size to the percentage size (var pixelHeight = window.innerHeight * percentageSize)
  • update the size with this.refs.mySplitPane.setState({ draggedSize: pixelHeight }) since I could not find any other way to override the size after a drag resize
  • this.forceUpdate() to force a rerender

so what I did would be a lot easier if I had a callback that triggered whenever the container size changed, and gave me the current element size, previous container size and next container size and let me return the size I want it to use. The default implementation would just return the current element size:

function onContainerSizeChange (elementPixelSize, previousContainerSize, currentContainerSize) {
  // default could just be this:
  // return elementPixelSize

  // my case would just be this:
  return elementPixelSize * (currentContainerSize / previousContainerSize)
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

Re-render a React Component on Window Resize | Pluralsight
This code will simply listen for the window resize event and console log something like "resized to: 1024 x 768". Re-render on Resize....
Read more >
Rerender view on browser resize with React - Stack Overflow
Resize events can technically be called at every pixel as you resize a window from large to small. When a user does this...
Read more >
Window: resize event - Web APIs | MDN
The resize event fires when the document view (window) has been resized. This event is not cancelable and does not bubble.
Read more >
Handle window resizing with a React context - Medium
Optimal layouts automatically adapt to different screen sizes and window size changes automatically, they behave like a “responsive” component.
Read more >
Resize event listener using React hooks - DEV Community ‍ ‍
I used useState hook to keep window width value in the state object and useEffect to add a listener for the resize event....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found