UNPKG

@nafr/echo-ui

Version:

A UI library born for WAA

47 lines (46 loc) 1.98 kB
import { useEffect, useRef } from 'react'; /** * Hook that returns the dimensions of the element that is passed as a ref. * * @param {RefObject<T>} ref - The ref of the element to observe. * @param {number} defaultWidth - The default width to return if the ref is not yet defined. * @param {number} defaultHeight - The default height to return if the ref is not yet defined. * @param {() => void} callback - The callback function to run when the dimensions change. * @param {boolean} toggleThrottle - Whether to throttle the callback function. * @param {any} data - The data to watch for changes. * @returns {{ width: number, height: number }} - The dimensions of the element. * * @example * const ref = useRef<HTMLDivElement>(null) * const { width, height } = useResizeObserver(ref, 0, 0, () => console.log('Dimensions changed!')) */ export const useResizeObserver = (ref, defaultWidth, defaultHeight, callback, toggleThrottle = true, data = null) => { const dimensions = useRef({ width: defaultWidth, height: defaultHeight }); useEffect(() => { const throttledCallback = throttle(callback, 100); const observer = new ResizeObserver(([entry]) => { const { width, height } = entry.contentRect; if (width !== dimensions.current.width || height !== dimensions.current.height) { dimensions.current = { width, height }; toggleThrottle ? throttledCallback() : callback(); } }); if (ref.current) observer.observe(ref.current); return () => observer.disconnect(); }, [ref, toggleThrottle, defaultWidth, defaultHeight, data]); return dimensions; }; const throttle = (func, limit) => { let inThrottle; return function () { if (!inThrottle) { func(); inThrottle = true; setTimeout(() => { inThrottle = false; func(); }, limit); } }; };