Files
frigate/web/src/hooks/resize-observer.ts
T

69 lines
1.8 KiB
TypeScript
Raw Normal View History

2023-12-15 16:24:50 -07:00
import { MutableRefObject, useEffect, useMemo, useState } from "react";
2024-03-05 14:19:56 -06: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-15 16:24:50 -07:00
new Array(refs.length).fill({
width: 0,
height: 0,
x: -Infinity,
y: -Infinity,
2024-02-28 15:23:56 -07:00
}),
2023-12-15 16:24:50 -07:00
);
const resizeObserver = useMemo(
() =>
new ResizeObserver((entries) => {
window.requestAnimationFrame(() => {
2025-02-10 10:42:35 -06:00
setDimensions((prevDimensions) => {
const newDimensions = entries.map((entry) => entry.contentRect);
if (
JSON.stringify(prevDimensions) !== JSON.stringify(newDimensions)
) {
return newDimensions;
}
return prevDimensions;
});
2023-12-15 16:24:50 -07:00
});
}),
2024-02-28 15:23:56 -07:00
[],
2023-12-15 16:24:50 -07:00
);
2026-03-05 08:42:38 -06:00
// Resolve refs to actual DOM elements for use as stable effect dependencies.
// Rest params create a new array each call, but the underlying elements are
// stable DOM nodes, so spreading them into the dep array avoids re-running
// the effect on every render.
const elements = refs.map((ref) =>
ref instanceof Window ? document.body : ref.current,
);
2023-12-15 16:24:50 -07:00
useEffect(() => {
2026-03-05 08:42:38 -06:00
elements.forEach((el) => {
if (el) resizeObserver.observe(el);
2023-12-15 16:24:50 -07:00
});
return () => {
2026-03-05 08:42:38 -06:00
resizeObserver.disconnect();
2023-12-15 16:24:50 -07:00
};
2026-03-05 08:42:38 -06:00
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [...elements, resizeObserver]);
2023-12-15 16:24:50 -07: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-15 16:24:50 -07:00
}