UNPKG

2.61 kBTypeScriptView Raw
1import { canUseDOM } from './util';
2
3/**
4 * This function creates a ResizeObserver used to handle resize events for the given containerRef. If ResizeObserver
5 * or the given containerRef are not available, a window resize event listener is used by default.
6 *
7 * Example 1:
8 *
9 * private containerRef = React.createRef<HTMLDivElement>();
10 * private observer: any = () => {};
11 *
12 * public componentDidMount() {
13 * this.observer = getResizeObserver(this.containerRef.current, this.handleResize);
14 * }
15 *
16 * public componentWillUnmount() {
17 * this.observer();
18 * }
19 *
20 * private handleResize = () => {
21 * if (this.containerRef.current && this.containerRef.current.clientWidth) {
22 * this.setState({ width: this.containerRef.current.clientWidth });
23 * }
24 * };
25 *
26 * public render() {
27 * return (
28 * <div ref={this.containerRef} >
29 * <Chart width={this.state.width} ... />
30 * </div>
31 * );
32 * }
33 *
34 * Example 2:
35 *
36 * private inputRef = React.createRef<HTMLInputElement>();
37 * private observer: any = () => {};
38 *
39 * public componentDidMount() {
40 * this.observer = getResizeObserver(this.inputRef.current, this.handleResize);
41 * }
42 *
43 * public componentWillUnmount() {
44 * this.observer();
45 * }
46 *
47 * private handleResize = () => {
48 * if (this.inputRef.current) {
49 * trimLeft(inputRef.current, String(this.props.value));
50 * }
51 * };
52 *
53 * public render() {
54 * return (
55 * <input ref={this.inputRef} ... />
56 * );
57 * }
58 *
59 * @param {Element} containerRefElement The container reference to observe
60 * @param {Function} handleResize The function to call for resize events
61 * @return {Function} The function used to unobserve resize events
62 */
63export const getResizeObserver = (containerRefElement: Element, handleResize: () => void) => {
64 let unobserve: any;
65
66 if (canUseDOM) {
67 const { ResizeObserver } = window as any;
68
69 if (containerRefElement && ResizeObserver) {
70 const resizeObserver = new ResizeObserver((entries: any) => {
71 // Wrap resize function in requestAnimationFrame to avoid "ResizeObserver loop limit exceeded" errors
72 window.requestAnimationFrame(() => {
73 if (Array.isArray(entries) && entries.length > 0) {
74 handleResize();
75 }
76 });
77 });
78 resizeObserver.observe(containerRefElement);
79 unobserve = () => resizeObserver.unobserve(containerRefElement);
80 } else {
81 window.addEventListener('resize', handleResize);
82 unobserve = () => window.removeEventListener('resize', handleResize);
83 }
84 }
85 return () => {
86 if (unobserve) {
87 unobserve();
88 }
89 };
90};