/
useMeasure.ts
40 lines (35 loc) · 848 Bytes
/
useMeasure.ts
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
import { useCallback, useState } from 'react';
import ResizeObserver from 'resize-observer-polyfill';
export type ContentRect = Pick<DOMRectReadOnly, 'x' | 'y' | 'top' | 'left' | 'right' | 'bottom' | 'height' | 'width'>;
const useMeasure = <T>(): [(instance: T) => void, ContentRect] => {
const [rect, set] = useState<ContentRect>({
x: 0,
y: 0,
width: 0,
height: 0,
top: 0,
left: 0,
bottom: 0,
right: 0,
});
const [observer] = useState(
() =>
new ResizeObserver(entries => {
const entry = entries[0];
if (entry) {
set(entry.contentRect);
}
})
);
const ref = useCallback(
node => {
observer.disconnect();
if (node) {
observer.observe(node);
}
},
[observer]
);
return [ref, rect];
};
export default useMeasure;