forked from react-grid-layout/react-grid-layout
-
Notifications
You must be signed in to change notification settings - Fork 0
/
WidthProvider.jsx
57 lines (46 loc) · 1.59 KB
/
WidthProvider.jsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
// @noflow
// Intentional; Flow can't handle the bind on L20
import React from "react";
import ReactDOM from 'react-dom';
type State = {
mounted: boolean,
width: number
};
/*
* A simple HOC that provides facility for listening to container resizes.
*/
export default (ComposedComponent: ReactClass): ReactClass => class extends React.Component {
static defaultProps = {
measureBeforeMount: false
};
static propTypes = {
// If true, will not render children until mounted. Useful for getting the exact width before
// rendering, to prevent any unsightly resizing.
measureBeforeMount: React.PropTypes.bool
};
state: State = {
mounted: false,
width: 1280
};
componentDidMount() {
this.setState({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() {
window.removeEventListener('resize', this.onWindowResize);
}
onWindowResize = (_event: Event, cb: ?Function) => {
const node = ReactDOM.findDOMNode(this);
this.setState({width: node.offsetWidth}, cb);
}
render() {
if (this.props.measureBeforeMount && !this.state.mounted) {
return <div className={this.props.className} style={this.props.style} />;
}
return <ComposedComponent {...this.props} {...this.state} />;
}
};