Files
standardnotes-app-web/packages/web/src/javascripts/Hooks/useElementRect.ts
2022-07-21 02:20:14 +05:30

54 lines
1.3 KiB
TypeScript

import { useEffect, useState } from 'react'
const DebounceTimeInMs = 100
type Options = {
updateOnWindowResize: boolean
}
/**
* Returns the bounding rect of an element, auto-updated when the element resizes.
* Can optionally be auto-update on window resize.
*/
export const useAutoElementRect = (
element: HTMLElement | null | undefined,
{ updateOnWindowResize }: Options = { updateOnWindowResize: false },
) => {
const [rect, setRect] = useState<DOMRect>()
useEffect(() => {
let windowResizeDebounceTimeout: number
let windowResizeHandler: () => void
if (element) {
const resizeObserver = new ResizeObserver(() => {
setRect(element.getBoundingClientRect())
})
resizeObserver.observe(element)
if (updateOnWindowResize) {
windowResizeHandler = () => {
window.clearTimeout(windowResizeDebounceTimeout)
window.setTimeout(() => {
setRect(element.getBoundingClientRect())
}, DebounceTimeInMs)
}
window.addEventListener('resize', windowResizeHandler)
}
return () => {
resizeObserver.unobserve(element)
if (windowResizeHandler) {
window.removeEventListener('resize', windowResizeHandler)
}
}
} else {
setRect(undefined)
return
}
}, [element, updateOnWindowResize])
return rect
}