1
1
import type { RefObject } from 'react'
2
- import { useRef } from 'react'
2
+ import { useRef , useState } from 'react'
3
3
import useLayoutEffect from '../utils/useIsomorphicLayoutEffect'
4
4
5
5
// https://gist.github.com/strothj/708afcf4f01dd04de8f49c92e88093c3
@@ -14,6 +14,7 @@ export function useResizeObserver<T extends HTMLElement>(
14
14
target ?: RefObject < T > ,
15
15
depsArray : unknown [ ] = [ ] ,
16
16
) {
17
+ const [ targetClientRect , setTargetClientRect ] = useState < DOMRect | null > ( null )
17
18
const savedCallback = useRef ( callback )
18
19
19
20
useLayoutEffect ( ( ) => {
@@ -26,15 +27,37 @@ export function useResizeObserver<T extends HTMLElement>(
26
27
return
27
28
}
28
29
29
- const observer = new ResizeObserver ( entries => {
30
- savedCallback . current ( entries )
31
- } )
32
-
33
- observer . observe ( targetEl )
34
-
35
- return ( ) => {
36
- observer . disconnect ( )
30
+ if ( typeof ResizeObserver === 'function' ) {
31
+ const observer = new ResizeObserver ( entries => {
32
+ savedCallback . current ( entries )
33
+ } )
34
+
35
+ observer . observe ( targetEl )
36
+
37
+ return ( ) => {
38
+ observer . disconnect ( )
39
+ }
40
+ } else {
41
+ const saveTargetDimensions = ( ) => {
42
+ const currTargetRect = targetEl . getBoundingClientRect ( )
43
+
44
+ if ( currTargetRect . width !== targetClientRect ?. width || currTargetRect . height !== targetClientRect . height ) {
45
+ savedCallback . current ( [
46
+ {
47
+ contentRect : currTargetRect ,
48
+ } ,
49
+ ] )
50
+ }
51
+ setTargetClientRect ( currTargetRect )
52
+ }
53
+ // eslint-disable-next-line github/prefer-observers
54
+ window . addEventListener ( 'resize' , saveTargetDimensions )
55
+
56
+ return ( ) => {
57
+ window . removeEventListener ( 'resize' , saveTargetDimensions )
58
+ }
37
59
}
60
+
38
61
// eslint-disable-next-line react-hooks/exhaustive-deps
39
62
} , [ target , ...depsArray ] )
40
63
}
0 commit comments