@mantine/hooks
Version:
A collection of 50+ hooks for state and UI management
62 lines (61 loc) • 1.64 kB
JavaScript
"use client";
import { useCallback, useRef, useState } from "react";
//#region packages/@mantine/hooks/src/use-resize-observer/use-resize-observer.ts
const defaultState = {
x: 0,
y: 0,
width: 0,
height: 0,
top: 0,
left: 0,
bottom: 0,
right: 0
};
function useResizeObserver(options) {
const frameID = useRef(0);
const [rect, setRect] = useState(defaultState);
const observerRef = useRef(null);
return [useCallback((node) => {
if (observerRef.current) {
observerRef.current.disconnect();
observerRef.current = null;
}
if (frameID.current) cancelAnimationFrame(frameID.current);
if (!node) return;
observerRef.current = new ResizeObserver((entries) => {
const entry = entries[0];
if (entry) {
cancelAnimationFrame(frameID.current);
frameID.current = requestAnimationFrame(() => {
const boxSize = entry.borderBoxSize?.[0] || entry.contentBoxSize?.[0];
if (boxSize) {
const width = boxSize.inlineSize;
const height = boxSize.blockSize;
setRect({
width,
height,
x: entry.contentRect.x,
y: entry.contentRect.y,
top: entry.contentRect.top,
left: entry.contentRect.left,
bottom: entry.contentRect.bottom,
right: entry.contentRect.right
});
} else setRect(entry.contentRect);
});
}
});
observerRef.current.observe(node, options);
}, [options]), rect];
}
function useElementSize(options) {
const [ref, { width, height }] = useResizeObserver(options);
return {
ref,
width,
height
};
}
//#endregion
export { useElementSize, useResizeObserver };
//# sourceMappingURL=use-resize-observer.mjs.map