-
Notifications
You must be signed in to change notification settings - Fork 28
/
Copy pathindex.js
64 lines (55 loc) · 1.78 KB
/
index.js
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
58
59
60
61
62
63
64
import React, { Children, Component } from 'react'
import PropTypes from 'prop-types'
import ReactDOM from 'react-dom'
import elementResizeDetectorMaker from 'element-resize-detector'
import invariant from 'invariant'
export default class ContainerDimensions extends Component {
static propTypes = {
children: PropTypes.oneOfType([PropTypes.element, PropTypes.func]).isRequired
}
static getDomNodeDimensions(node) {
const { top, right, bottom, left, width, height } = node.getBoundingClientRect()
return { top, right, bottom, left, width, height }
}
constructor() {
super()
this.state = {
initiated: false
}
this.onResize = this.onResize.bind(this)
}
componentDidMount() {
this.parentNode = ReactDOM.findDOMNode(this).parentNode
this.elementResizeDetector = elementResizeDetectorMaker({
strategy: 'scroll',
callOnAdd: false
})
this.elementResizeDetector.listenTo(this.parentNode, this.onResize)
this.componentIsMounted = true
this.onResize()
}
componentWillUnmount() {
this.componentIsMounted = false
this.elementResizeDetector.uninstall(this.parentNode)
}
onResize() {
const clientRect = ContainerDimensions.getDomNodeDimensions(this.parentNode)
if (this.componentIsMounted) {
this.setState({
initiated: true,
...clientRect
})
}
}
render() {
invariant(this.props.children, 'Expected children to be one of function or React.Element')
if (!this.state.initiated) {
return <div />
}
if (typeof this.props.children === 'function') {
const renderedChildren = this.props.children(this.state)
return renderedChildren && Children.only(renderedChildren)
}
return Children.only(React.cloneElement(this.props.children, this.state))
}
}