/** * Copy from https://github.com/mantinedev/mantine/blob/master/packages/@mantine/hooks/src/use-resize-observer/use-resize-observer.ts */ import { useRef, useState, useMemo, useEffect } from 'react'; type ObserverRect = Omit; const defaultState: ObserverRect = { x: 0, y: 0, width: 0, height: 0, top: 0, left: 0, bottom: 0, right: 0, }; export function useResizeObserver( options?: ResizeObserverOptions ) { const frameID = useRef(0); const ref = useRef(null); const [rect, setRect] = useState(defaultState); const observer = useMemo( () => typeof window !== 'undefined' ? new ResizeObserver((entries: any) => { const entry = entries[0]; if (entry) { cancelAnimationFrame(frameID.current); frameID.current = requestAnimationFrame(() => { if (ref.current) { setRect(entry.contentRect); } }); } }) : null, [] ); useEffect(() => { if (ref.current) { observer?.observe(ref.current, options); } return () => { observer?.disconnect(); if (frameID.current) { cancelAnimationFrame(frameID.current); } }; }, [ref.current]); return [ref, rect] as const; } export function useElementSize( options?: ResizeObserverOptions ) { const [ref, { width, height }] = useResizeObserver(options); return { ref, width, height }; }