UNPKG

react-resize-detector

Version:
80 lines (77 loc) 3.65 kB
import { useRef, useState, useCallback, useEffect } from 'react'; import { useCallbackRef, useRefProxy, getDimensions, patchResizeCallback } from './utils.js'; // eslint-disable-next-line @typescript-eslint/no-explicit-any function useResizeDetector({ skipOnMount = false, refreshMode, refreshRate = 1000, refreshOptions, handleWidth = true, handleHeight = true, targetRef, observerOptions, onResize, } = {}) { // If `skipOnMount` is enabled, skip the first resize event const skipResize = useRef(skipOnMount); // Wrap the `onResize` callback with a ref to avoid re-renders const onResizeRef = useCallbackRef(onResize); const [size, setSize] = useState({ width: undefined, height: undefined, }); // Create a proxy ref to handle conditional rendering and dynamic ref changes of the target element const { refProxy, refElement } = useRefProxy(targetRef); const { box } = observerOptions || {}; const resizeCallback = useCallback((entries) => { if (!handleWidth && !handleHeight) return; if (skipResize.current) { skipResize.current = false; return; } // Only update the size if one of the observed dimensions has changed const shouldSetSize = (prevSize, nextSize) => (handleWidth && prevSize.width !== nextSize.width) || (handleHeight && prevSize.height !== nextSize.height); entries.forEach((entry) => { const dimensions = getDimensions(entry, box); setSize((prevSize) => { if (!shouldSetSize(prevSize, dimensions)) return prevSize; onResizeRef === null || onResizeRef === void 0 ? void 0 : onResizeRef({ width: dimensions.width, height: dimensions.height, entry, }); return dimensions; }); }); }, [handleWidth, handleHeight, skipResize, box]); // Throttle/Debounce the resize event if refreshMode is configured const resizeHandler = useCallback(patchResizeCallback(resizeCallback, refreshMode, refreshRate, refreshOptions), [ resizeCallback, refreshMode, refreshRate, refreshOptions, ]); // Attach ResizeObserver to the element useEffect(() => { let resizeObserver; if (refElement) { try { resizeObserver = new window.ResizeObserver(resizeHandler); resizeObserver.observe(refElement, observerOptions); } catch (error) { console.warn('ResizeObserver not supported or failed to initialize:', error); } } // If refElement is not available, reset the size else if (size.width || size.height) { onResizeRef === null || onResizeRef === void 0 ? void 0 : onResizeRef({ width: null, height: null, entry: null, }); setSize({ width: undefined, height: undefined }); } // Disconnect the ResizeObserver when the component is unmounted return () => { var _a, _b, _c; (_a = resizeObserver === null || resizeObserver === void 0 ? void 0 : resizeObserver.disconnect) === null || _a === void 0 ? void 0 : _a.call(resizeObserver); (_c = (_b = resizeHandler).cancel) === null || _c === void 0 ? void 0 : _c.call(_b); }; }, [resizeHandler, refElement]); return Object.assign({ ref: refProxy }, size); } export { useResizeDetector as default }; //# sourceMappingURL=useResizeDetector.js.map