mirror of
https://github.com/documenso/documenso.git
synced 2026-07-11 05:25:08 +10:00
72 lines
1.5 KiB
TypeScript
72 lines
1.5 KiB
TypeScript
import { useEffect, useMemo, useState } from 'react';
|
|
|
|
import { getBoundingClientRect } from '@documenso/lib/client-only/get-bounding-client-rect';
|
|
|
|
export const useElementBounds = (elementOrSelector: HTMLElement | string, withScroll = false) => {
|
|
const [forceRecalc, setForceRecalc] = useState(0);
|
|
|
|
const bounds = useMemo(() => {
|
|
const $el =
|
|
typeof elementOrSelector === 'string'
|
|
? document.querySelector<HTMLElement>(elementOrSelector)
|
|
: elementOrSelector;
|
|
|
|
if (!$el) {
|
|
return {
|
|
top: 0,
|
|
left: 0,
|
|
height: 0,
|
|
width: 0,
|
|
};
|
|
}
|
|
|
|
if (withScroll) {
|
|
return getBoundingClientRect($el);
|
|
}
|
|
|
|
const { top, left, width, height } = $el.getBoundingClientRect();
|
|
|
|
return {
|
|
top,
|
|
left,
|
|
width,
|
|
height,
|
|
};
|
|
}, [elementOrSelector, withScroll, forceRecalc]);
|
|
|
|
useEffect(() => {
|
|
const onResize = () => {
|
|
setForceRecalc((prev) => prev + 1);
|
|
};
|
|
|
|
window.addEventListener('resize', onResize);
|
|
|
|
return () => {
|
|
window.removeEventListener('resize', onResize);
|
|
};
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
const $el =
|
|
typeof elementOrSelector === 'string'
|
|
? document.querySelector<HTMLElement>(elementOrSelector)
|
|
: elementOrSelector;
|
|
|
|
if (!$el) {
|
|
return;
|
|
}
|
|
|
|
const observer = new ResizeObserver(() => {
|
|
setForceRecalc((prev) => prev + 1);
|
|
});
|
|
|
|
observer.observe($el);
|
|
|
|
return () => {
|
|
observer.disconnect();
|
|
};
|
|
}, [elementOrSelector]);
|
|
|
|
return bounds;
|
|
};
|