type ResizeCallback = () => void const callbacks = new Map() let observer: ResizeObserver | null = null /** * Returns the singleton ResizeObserver, lazily constructing it on first use. * Returns `null` when `ResizeObserver` is not available in the global scope * (SSR, very old browsers, or tests that intentionally remove it). */ function getObserver(): ResizeObserver | null { if (typeof ResizeObserver === 'undefined') return null observer ??= new ResizeObserver((entries) => { for (const entry of entries) { const callback = callbacks.get(entry.target) callback?.() } }) return observer } const NOOP_CLEANUP = (): void => undefined export function observeResize( element: Element, callback: ResizeCallback, ): () => void { const ro = getObserver() // Gracefully degrade when no ResizeObserver is available — consumers // still see one initial measure() pass via their own effect; we just // skip the subsequent resize-driven re-measures. if (!ro) return NOOP_CLEANUP callbacks.set(element, callback) ro.observe(element) return () => { callbacks.delete(element) if (observer) { observer.unobserve(element) // Disconnect the singleton once the last subscriber leaves so the // observer doesn't outlive its consumers in SSR teardown / micro- // frontend unmount scenarios. A subsequent observeResize() will // lazily re-create it via getObserver(). if (callbacks.size === 0) { observer.disconnect() observer = null } } } } /** @internal — for tests only. */ export function __resetSharedResizeObserver(): void { if (observer) observer.disconnect() callbacks.clear() observer = null }