beautiful-react-hooks
Version:
A collection of beautiful (and hopefully useful) React hooks to speed-up your components and hooks development
54 lines (53 loc) • 2.33 kB
JavaScript
import debounce from 'lodash.debounce';
import { useEffect, useRef, useState } from 'react';
import isClient from './shared/isClient';
import isFunction from './shared/isFunction';
import isApiSupported from './shared/isAPISupported';
import warnOnce from './shared/warnOnce';
// eslint-disable-next-line max-len
const errorMessage = 'ResizeObserver is not supported, this could happen both because window. ResizeObserver is not supported by your current browser or you\'re using the useResizeObserver hook whilst server side rendering.';
/**
* Uses the ResizeObserver API to observe changes within the given HTML Element DOM Rect.
* @param elementRef
* @param debounceTimeout
* @returns {undefined}
*/
const useResizeObserver = (elementRef, debounceTimeout = 100) => {
const isSupported = isApiSupported('ResizeObserver');
const observerRef = useRef(null);
const [DOMRect, setDOMRect] = useState();
if (isClient && !isSupported) {
warnOnce(errorMessage);
return undefined;
}
// creates the observer reference on mount
useEffect(() => {
if (isSupported) {
const fn = debounce((entries) => {
const { bottom, height, left, right, top, width } = entries[0].contentRect;
setDOMRect({ bottom, height, left, right, top, width });
}, debounceTimeout);
observerRef.current = new ResizeObserver(fn);
return () => {
var _a;
fn.cancel();
if (observerRef.current && isFunction((_a = observerRef === null || observerRef === void 0 ? void 0 : observerRef.current) === null || _a === void 0 ? void 0 : _a.disconnect)) {
observerRef.current.disconnect();
}
};
}
return () => {
};
}, []);
// observes on the provided element ref
useEffect(() => {
var _a;
if (isSupported && elementRef.current) {
if (observerRef.current && isFunction((_a = observerRef === null || observerRef === void 0 ? void 0 : observerRef.current) === null || _a === void 0 ? void 0 : _a.observe)) {
observerRef.current.observe(elementRef.current);
}
}
}, [elementRef.current]);
return DOMRect;
};
export default useResizeObserver;