The title says it all really. Is this currently possible? I was hoping to see an onLayoutChange event get fired on window resize.
Please mark the type of this issue:
As a follow up to this, it's now clear that my issue is the fact that whilst the size of each grid component changes, then layout does not (correctly so). So I need a callback if the sizes changes irrelevant of whether the layout changes. I tried simply listening to window resize events from inside the grid items, but this doesn't help because the new grid item sizes have not been calculated yet (I could also set a timer, but this seems like a hack as you never know for sure when the new griditem sizes have actually been calculated).
I found the way around this was to have an additional callback in ReactGridLayout that was called when the width prop was changed (from the WidthPprovider). It is flagged to call in componentWillUpdateProps and is actually called from componentDIdUpdate.
Is there a better way of doing this? If not, would you be OK with a PR?
I assume you have your RGL inside some component that provides it with an updated width. Simply callback when you change that on componentDidUpdate. RGL does not get its own width (unless you created it with WidthProvider), which is a short, sample component that can easily be copy/pasted and modified.
Thanks for the help. In the end, I created a custom WidthProvider and moved the resize event to the parent container. That was I could be happy that things were being calculated in the same update loop.
can you please post example
WidthProvider.jsx
import React from "react";
import PropTypes from "prop-types";
import type { ComponentType as ReactComponentType } from "react";
type Props = {
className?: string,
measureBeforeMount: boolean,
style?: Object
};
type State = {
width: number
};
/*
* A simple HOC that provides facility for listening to container resizes.
*/
type ProviderT = (
ComposedComponent: ReactComponentType<any>
) => ReactComponentType<any>;
const WidthProvider: ProviderT = ComposedComponent =>
class WidthProvider extends React.Component<Props, State> {
static defaultProps = {
measureBeforeMount: false,
width: 0
};
static propTypes = {
// If true, will not render children until mounted. Useful for getting the exact width before
// rendering, to prevent any unsightly resizing.
measureBeforeMount: PropTypes.bool
};
state: State = {
width: 1280
};
mounted: boolean = false;
componentDidMount() {
this.mounted = true;
//window.addEventListener("resize", this.onWindowResize);
// Call to properly set the breakpoint and resize the elements.
// Note that if you're doing a full-width element, this can get a little wonky if a scrollbar
// appears because of the grid. In that case, fire your own resize event, or set `overflow: scroll` on your body.
//this.onWindowResize();
}
componentWillUnmount() {
this.mounted = false;
}
componentWillReceiveProps(nextProps) {
if (nextProps.width != this.props.width) {
this.setState({ width: nextProps.width });
}
}
render() {
if (this.props.measureBeforeMount && !this.mounted) {
return (
<div className={this.props.className} style={this.props.style} />
);
}
return <ComposedComponent {...this.props} {...this.state} />;
}
};
export default WidthProvider;
Usage:
import WidthProvider from "../WidthProvider.jsx"
const ReactGridLayout = WidthProvider(RGL);
window.addEventListener("resize", this.onWindowResize);
onWindowResize = () => {
const node = ReactDOM.findDOMNode(this.gridElement);
if (node instanceof HTMLElement) {
this.setState({ width: node.offsetWidth });
}
}
<ReactGridLayout width={this.state.width} >
</ReactGridLayout>
@rooch84 Thanks for the code share. I understand this provider is to listen to the window resize. I am looking into how my child component will notify on its size changed. onResizeStop gives back a total layout not an individual item.
const ResponsiveReactGridLayout = WidthProvider(Responsive);
<ResponsiveReactGridLayout
breakpoints={{lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0}}
cols={this.dashboardStore.flowColGrid}
rowHeight={20}
autoSize={false}
draggableCancel="input,textarea"
// onLayoutChange={this.onLayoutChange}
// onBreakpointChange={this.onBreakpointChange}
containerPadding={[0, 0]}
margin={[5, 5]}
isDraggable={this.dashboardStore.isEditMode}
isResizable={this.dashboardStore.isEditMode}
onResizeStop={this.onReactGridResizeStop}
{...this.props}
>
{_.map((this.dashboardStore.currentDashboard.layout), el => this.createElement(el))}
</ResponsiveReactGridLayout>
onReactGridResizeStop(event: ItemCallback) {
//
}
// tslint:disable-next-line:no-any
createElement(el: any) {
return (
<div className="d_w_b" key={el.i} data-grid={el}>
<Widget wid={el.i} grid={el}/>
</div>
);
}
If time permits, please help.
@STRML @rooch84 . Thanks for the library
@abelkbil onResizeStop 2nd and 3rd parameters gives the old and new values of the changed item.
And you can use refs/props to pass it to other components.
Most helpful comment
WidthProvider.jsx
Usage: