manifold/web/hooks/use-measure-size.ts
TrueMilli 0f2a311b74
Refactoring (#401)
* refactoring

(cherry picked from commit 4de86d5b08)

* removed unused imports and variables

* added type for binary resolution

* Prettier

* const for binary resolutions

* using the type "resolution"

* Prettier

* Update functions/src/create-contract.ts

* launch config for debugging with vs code
* "Launch Chrome" does not work since login via google is not possible in debugger-chrome
* Breakpoints are unbound when attached to chrome
2022-06-02 17:30:34 -07:00

64 lines
1.8 KiB
TypeScript

import { debounce } from 'lodash'
import { RefObject, useMemo, useLayoutEffect, useRef, useState } from 'react'
type elem_size =
| { width: number; height: number }
| { width: undefined; height: undefined }
const getSize = (elem: HTMLElement | null) =>
elem
? { width: elem.offsetWidth, height: elem.offsetHeight }
: { width: undefined, height: undefined }
export function useListenElemSize<T extends HTMLElement>(
elemRef: RefObject<T | null>,
callback: (size: elem_size) => void,
debounceMs: number | undefined = undefined
) {
const handleResize = useMemo(() => {
const updateSize = () => {
if (elemRef.current) callback(getSize(elemRef.current))
}
return debounceMs
? debounce(updateSize, debounceMs, { leading: false, trailing: true })
: updateSize
}, [callback, elemRef, debounceMs])
const elem = elemRef.current
useLayoutEffect(() => {
if (!elemRef.current) return
const resizeObserver = new ResizeObserver(handleResize)
resizeObserver.observe(elemRef.current)
return () => resizeObserver.disconnect()
}, [elemRef, elem, handleResize])
}
export function useMeasureSize(debounceMs: number | undefined = undefined) {
const elemRef = useRef<HTMLElement | null>(null)
const [size, setSize] = useState(() => getSize(null))
const sizeRef = useRef<elem_size>(size)
const setSizeIfDifferent = (newSize: typeof size) => {
if (newSize?.height !== size?.height || newSize?.width !== size?.width) {
sizeRef.current = newSize
setSize(newSize)
}
}
useListenElemSize(elemRef, setSizeIfDifferent, debounceMs)
const setElem = (elem: HTMLElement | null) => {
elemRef.current = elem
if (elem) {
setSizeIfDifferent(getSize(elem))
}
}
return { setElem, elemRef, sizeRef, ...size }
}