1 |
|
2 | import {RefObject} from '@react-types/shared';
|
3 | import {useEffect} from 'react';
|
4 |
|
5 | function hasResizeObserver() {
|
6 | return typeof window.ResizeObserver !== 'undefined';
|
7 | }
|
8 |
|
9 | type useResizeObserverOptionsType<T> = {
|
10 | ref: RefObject<T | undefined | null> | undefined,
|
11 | box?: ResizeObserverBoxOptions,
|
12 | onResize: () => void
|
13 | }
|
14 |
|
15 | export function useResizeObserver<T extends Element>(options: useResizeObserverOptionsType<T>) {
|
16 | const {ref, box, onResize} = options;
|
17 |
|
18 | useEffect(() => {
|
19 | let element = ref?.current;
|
20 | if (!element) {
|
21 | return;
|
22 | }
|
23 |
|
24 | if (!hasResizeObserver()) {
|
25 | window.addEventListener('resize', onResize, false);
|
26 | return () => {
|
27 | window.removeEventListener('resize', onResize, false);
|
28 | };
|
29 | } else {
|
30 |
|
31 | const resizeObserverInstance = new window.ResizeObserver((entries) => {
|
32 | if (!entries.length) {
|
33 | return;
|
34 | }
|
35 |
|
36 | onResize();
|
37 | });
|
38 | resizeObserverInstance.observe(element, {box});
|
39 |
|
40 | return () => {
|
41 | if (element) {
|
42 | resizeObserverInstance.unobserve(element);
|
43 | }
|
44 | };
|
45 | }
|
46 |
|
47 | }, [onResize, ref, box]);
|
48 | }
|