diff --git a/packages/compose/src/hooks/use-resize-observer/index.ts b/packages/compose/src/hooks/use-resize-observer/index.ts index 30360983e9fc9..2a76b2aa6ab59 100644 --- a/packages/compose/src/hooks/use-resize-observer/index.ts +++ b/packages/compose/src/hooks/use-resize-observer/index.ts @@ -13,6 +13,41 @@ import _useLegacyResizeObserver from './_legacy'; */ import type { ReactElement } from 'react'; +// This is the current implementation of `useResizeObserver`. +// +// The legacy implementation is still supported for backwards compatibility. +// This is achieved by overloading the exported function with both signatures, +// and detecting which API is being used at runtime. +function _useResizeObserver< T extends HTMLElement >( + callback: ResizeObserverCallback, + resizeObserverOptions: ResizeObserverOptions = {} +): ( element?: T | null ) => void { + const callbackEvent = useEvent( callback ); + + const observedElementRef = useRef< T | null >(); + const resizeObserverRef = useRef< ResizeObserver >(); + return useEvent( ( element?: T | null ) => { + if ( element === observedElementRef.current ) { + return; + } + observedElementRef.current = element; + + // Set up `ResizeObserver`. + resizeObserverRef.current ??= new ResizeObserver( callbackEvent ); + const { current: resizeObserver } = resizeObserverRef; + + // Unobserve previous element. + if ( observedElementRef.current ) { + resizeObserver.unobserve( observedElementRef.current ); + } + + // Observe new element. + if ( element ) { + resizeObserver.observe( element, resizeObserverOptions ); + } + } ); +} + /** * Sets up a [`ResizeObserver`](https://developer.mozilla.org/en-US/docs/Web/API/Resize_Observer_API) * for an HTML or SVG element. @@ -82,33 +117,3 @@ export default function useResizeObserver< T extends HTMLElement >( ? _useResizeObserver( callback, options ) : _useLegacyResizeObserver(); } - -function _useResizeObserver< T extends HTMLElement >( - callback: ResizeObserverCallback, - resizeObserverOptions: ResizeObserverOptions = {} -): ( element?: T | null ) => void { - const callbackEvent = useEvent( callback ); - - const observedElementRef = useRef< T | null >(); - const resizeObserverRef = useRef< ResizeObserver >(); - return useEvent( ( element?: T | null ) => { - if ( element === observedElementRef.current ) { - return; - } - observedElementRef.current = element; - - // Set up `ResizeObserver`. - resizeObserverRef.current ??= new ResizeObserver( callbackEvent ); - const { current: resizeObserver } = resizeObserverRef; - - // Unobserve previous element. - if ( observedElementRef.current ) { - resizeObserver.unobserve( observedElementRef.current ); - } - - // Observe new element. - if ( element ) { - resizeObserver.observe( element, resizeObserverOptions ); - } - } ); -}