|
1 | | -import React, { Component } from "react"; |
2 | | -import ReactDOM from "react-dom"; |
3 | | -import PropTypes from "prop-types"; |
4 | | -import ResizeObserver from "resize-observer-polyfill"; |
5 | | -import WeakMap from "es6-weak-map"; |
| 1 | +# @zeecoder/react-resize-observer |
6 | 2 |
|
7 | | -const registry = new WeakMap(); |
| 3 | +A React component to use ResizeObserver instances. |
8 | 4 |
|
9 | | -const resizeObserver = new ResizeObserver(entries => { |
10 | | -entries.forEach(entry => { |
11 | | -const instance = registry.get(entry.target); |
12 | | -if (!instance) { |
13 | | -return; |
14 | | -} |
| 5 | +## Install |
15 | 6 |
|
16 | | - instance.handleResize(entry.contentRect); |
| 7 | +``` |
| 8 | +yarn add @zeecoder/react-resize-observer |
| 9 | +# or |
| 10 | +npm install --save @zeecoder/react-resize-observer |
| 11 | +``` |
17 | 12 |
|
18 | | -}); |
19 | | -}); |
| 13 | +## Usage |
20 | 14 |
|
21 | | -export default class ResizeObserverComponent extends Component { |
22 | | -constructor(props) { |
23 | | -super(props); |
| 15 | +```js |
| 16 | +const App = () => ( |
| 17 | + <ResizeObserver> |
| 18 | + {size => ( |
| 19 | + <div> |
| 20 | + My size is {size.width}x{size.height} |
| 21 | + </div> |
| 22 | + )} |
| 23 | + </ResizeObserver> |
| 24 | +); |
| 25 | +``` |
24 | 26 |
|
25 | | - this.state = { size: null }; |
| 27 | +## Notes |
26 | 28 |
|
27 | | - this.lastRegisteredElement = null; |
| 29 | +- The children prop must be a function, through which the size changes are |
| 30 | + communicated |
| 31 | +- If the optional `element` prop is given, the the component will observe the |
| 32 | + size changes of that given element, instead of looking for the root DOM node |
| 33 | + inside the component. (This avoids calling `ReactDOM.findDOMNode(this)`.) |
28 | 34 |
|
29 | | -} |
| 35 | +## License |
30 | 36 |
|
31 | | -componentDidMount() { |
32 | | -const element = ReactDOM.findDOMNode(this); |
33 | | - |
34 | | - if (element) { |
35 | | - registry.set(element, this); |
36 | | - resizeObserver.observe(element); |
37 | | - this.lastRegisteredElement = element; |
38 | | - } |
39 | | - |
40 | | -} |
41 | | - |
42 | | -handleResize(size) { |
43 | | -this.setState({ size }); |
44 | | -} |
45 | | - |
46 | | -componentWillUnmount() { |
47 | | -if (this.lastRegisteredElement) { |
48 | | -registry.delete(this.lastRegisteredElement); |
49 | | -resizeObserver.unobserve(this.lastRegisteredElement); |
50 | | -} |
51 | | -} |
52 | | - |
53 | | -componentDidUpdate() { |
54 | | -const element = ReactDOM.findDOMNode(this); |
55 | | -if (this.lastRegisteredElement === element) { |
56 | | -return; |
57 | | -} |
58 | | - |
59 | | - if (this.lastRegisteredElement !== null) { |
60 | | - registry.delete(this.lastRegisteredElement); |
61 | | - resizeObserver.unobserve(this.lastRegisteredElement); |
62 | | - this.lastRegisteredElement = null; |
63 | | - } |
64 | | - |
65 | | - if (element) { |
66 | | - registry.set(element, this); |
67 | | - resizeObserver.observe(element); |
68 | | - this.lastRegisteredElement = element; |
69 | | - } |
70 | | - |
71 | | -} |
72 | | - |
73 | | -render() { |
74 | | -if (this.props.children) { |
75 | | -return this.props.children(this.state.size); |
76 | | -} |
77 | | - |
78 | | - return this.props.render(this.state.size); |
79 | | - |
80 | | -} |
81 | | -} |
82 | | - |
83 | | -ResizeObserverComponent.defaultProps = { |
84 | | -render: size => ( |
85 | | -<div>My size is: {size ? `${size.width}x${size.height}` : "?"}</div> |
86 | | -) |
87 | | -}; |
88 | | - |
89 | | -ResizeObserverComponent.propTypes = { |
90 | | -render: PropTypes.func, |
91 | | -children: PropTypes.func |
92 | | -}; |
| 37 | +MIT |
0 commit comments