2023-12-16 00:24:50 +01:00
|
|
|
import { MutableRefObject, useEffect, useMemo, useState } from "react";
|
|
|
|
|
2024-03-05 21:19:56 +01:00
|
|
|
type RefType = MutableRefObject<Element | null> | Window;
|
|
|
|
|
|
|
|
export function useResizeObserver(...refs: RefType[]) {
|
|
|
|
const [dimensions, setDimensions] = useState<
|
|
|
|
{ width: number; height: number; x: number; y: number }[]
|
|
|
|
>(
|
2023-12-16 00:24:50 +01:00
|
|
|
new Array(refs.length).fill({
|
|
|
|
width: 0,
|
|
|
|
height: 0,
|
|
|
|
x: -Infinity,
|
|
|
|
y: -Infinity,
|
2024-02-28 23:23:56 +01:00
|
|
|
}),
|
2023-12-16 00:24:50 +01:00
|
|
|
);
|
|
|
|
const resizeObserver = useMemo(
|
|
|
|
() =>
|
|
|
|
new ResizeObserver((entries) => {
|
|
|
|
window.requestAnimationFrame(() => {
|
|
|
|
setDimensions(entries.map((entry) => entry.contentRect));
|
|
|
|
});
|
|
|
|
}),
|
2024-02-28 23:23:56 +01:00
|
|
|
[],
|
2023-12-16 00:24:50 +01:00
|
|
|
);
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
refs.forEach((ref) => {
|
2024-03-05 21:19:56 +01:00
|
|
|
if (ref instanceof Window) {
|
|
|
|
resizeObserver.observe(document.body);
|
|
|
|
} else if (ref.current) {
|
2023-12-16 00:24:50 +01:00
|
|
|
resizeObserver.observe(ref.current);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
return () => {
|
|
|
|
refs.forEach((ref) => {
|
2024-03-05 21:19:56 +01:00
|
|
|
if (ref instanceof Window) {
|
|
|
|
resizeObserver.unobserve(document.body);
|
|
|
|
} else if (ref.current) {
|
2023-12-16 00:24:50 +01:00
|
|
|
resizeObserver.unobserve(ref.current);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
};
|
|
|
|
}, [refs, resizeObserver]);
|
|
|
|
|
2024-05-09 23:06:29 +02:00
|
|
|
if (dimensions.length == refs.length) {
|
|
|
|
return dimensions;
|
|
|
|
} else {
|
|
|
|
const items = [...dimensions];
|
|
|
|
for (let i = dimensions.length; i < refs.length; i++) {
|
|
|
|
items.push({
|
|
|
|
width: 0,
|
|
|
|
height: 0,
|
|
|
|
x: -Infinity,
|
|
|
|
y: -Infinity,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
return items;
|
|
|
|
}
|
2023-12-16 00:24:50 +01:00
|
|
|
}
|