opendash
Version:
open.DASH data visualization framework
76 lines (61 loc) • 1.65 kB
text/typescript
import { useState, useCallback, useLayoutEffect } from "react";
import throttle from "lodash.throttle";
interface ComponentSize {
width: number;
height: number;
}
function getSize(ref): ComponentSize {
if (!ref || !ref.current) {
return {
width: 0,
height: 0,
};
}
return {
width: ref.current.offsetWidth,
height: ref.current.offsetHeight,
};
}
export function useElementSize<T = any>(
ref: React.RefObject<T>,
throttleDuration: number = 0
): ComponentSize {
const [state, setState] = useState(getSize(ref));
function _handleResize() {
const nextState = getSize(ref);
const shouldUpdate =
nextState.width !== state.width || nextState.height !== state.height;
if (shouldUpdate) {
setState(nextState);
}
}
const handleResize = useCallback(
throttleDuration
? throttle(_handleResize, throttleDuration)
: _handleResize,
[ref, throttleDuration]
);
useLayoutEffect(() => {
if (!ref || !ref.current) {
return;
}
handleResize();
// @ts-ignore // TS doesn't know about ResizeObserver yet
if (typeof ResizeObserver === "function") {
// @ts-ignore // TS doesn't know about ResizeObserver yet
const resizeObserver = new ResizeObserver(() => {
handleResize();
});
resizeObserver.observe(ref.current);
return () => {
resizeObserver.disconnect(ref.current);
};
} else {
window.addEventListener("resize", handleResize);
return () => {
window.removeEventListener("resize", handleResize);
};
}
}, [ref.current]);
return state;
}