Files

68 lines
2.4 KiB
TypeScript
Raw Permalink Normal View History

import useResizeObserver from "@react-hook/resize-observer";
import { useCallback, useRef, useState } from "react";
import { debounce } from "throttle-debounce";
2024-08-23 15:18:49 +08:00
/**
* Get the current dimensions for the specified element, and whether it is currently changing size. Update when the element resizes.
* @param ref The reference to the element to observe.
* @param delay The debounce delay to use for updating the dimensions.
* @returns The dimensions of the element, and direction in which the dimensions are changing.
*/
2024-08-23 15:18:49 +08:00
const useDimensions = (ref: React.RefObject<HTMLElement>, delay = 0) => {
const [dimensions, setDimensions] = useState<{
height: number | null;
width: number | null;
widthDirection?: string;
heightDirection?: string;
}>({
height: null,
width: null,
});
const previousDimensions = useRef<{ height: number | null; width: number | null }>({
height: null,
width: null,
});
const updateDimensions = useCallback((entry: ResizeObserverEntry) => {
const parentHeight = entry.contentRect.height;
const parentWidth = entry.contentRect.width;
2024-08-23 15:18:49 +08:00
let widthDirection = "";
let heightDirection = "";
2024-08-23 15:18:49 +08:00
if (previousDimensions.current.width !== null && previousDimensions.current.height !== null) {
if (parentWidth > previousDimensions.current.width) {
widthDirection = "expanding";
} else if (parentWidth < previousDimensions.current.width) {
widthDirection = "shrinking";
} else {
widthDirection = "unchanged";
2024-08-23 15:18:49 +08:00
}
if (parentHeight > previousDimensions.current.height) {
heightDirection = "expanding";
} else if (parentHeight < previousDimensions.current.height) {
heightDirection = "shrinking";
} else {
heightDirection = "unchanged";
}
2024-08-23 15:18:49 +08:00
}
previousDimensions.current = { height: parentHeight, width: parentWidth };
setDimensions({ height: parentHeight, width: parentWidth, widthDirection, heightDirection });
}, []);
const fUpdateDimensions = useCallback(delay > 0 ? debounce(delay, updateDimensions) : updateDimensions, [
2024-08-23 15:18:49 +08:00
updateDimensions,
delay,
]);
useResizeObserver(ref, fUpdateDimensions);
2024-08-23 15:18:49 +08:00
return dimensions;
};
export { useDimensions };