import { RefCallback , RefObject , useCallback , useRef } from "react" ; import { isFunction , isNil } from "./assertions" ; interface MapValue { elementRef : RefObject < HTMLElement > ; handler : ( entry : ResizeObserverEntry , elementRef : RefObject < HTMLElement > ) => void ; } const handlersMap = new WeakMap < Element , MapValue > ( ) ; let observer ; function getResizeObserver ( ) { return ( observer = observer || new ResizeObserver ( ( entries ) => { entries . forEach ( entry => { const mapValue = handlersMap . get ( entry . target ) ; if ( ! isNil ( mapValue ) ) { const { elementRef , handler } = mapValue ; if ( isFunction ( handler ) ) { handler ( entry , elementRef ) ; } } } ) ; } ) ) ; } interface UseResizeObserverOptions extends ResizeObserverOptions { isDisabled ? : boolean ; } export const useResizeObserver = ( onResize , { box , isDisabled } = { } ) : RefCallback < HTMLElement > => { const elementRef = useRef < HTMLElement > ( null ) ; const dispose = useCallback ( ( ) => { const element = elementRef . current ; if ( ! isNil ( element ) ) { elementRef . current = null ; if ( ! handlersMap . has ( element ) ) { getResizeObserver ( ) . unobserve ( element ) ; } handlersMap . delete ( element ) ; } } , [ elementRef ] ) ; const resizeRef = ( ( element ) => { dispose ( ) ; if ( ! isDisabled ) { if ( ! isNil ( element ) ) { elementRef . current = element ; getResizeObserver ( ) . observe ( element , { box } ) ; handlersMap . set ( element , { elementRef : elementRef , handler : onResize } ) ; } } } ) ; return resizeRef ; } ;