Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | 772x 772x 772x 911x 911x 911x 911x 911x 911x 911x 911x 911x 892x 816x 76x 772x 500x 3x 497x 497x 414x 497x 497x 497x 463x 463x 463x 463x 772x 772x | import { useEffect, useState, useCallback, useMemo } from 'react'; import { useViewportRef } from './'; interface ViewportSize { width: number; height: number; offsetLeft: number; offsetTop: number; clientRect: DOMRect | null; isVisible: boolean; } /** * Hook that provides viewport size dimensions and monitors for changes * @param viewportId - The ID of the viewport to monitor * @returns ViewportSize object containing width, height, and visibility info */ function useViewportSize(viewportId: string): ViewportSize { const viewportElementRef = useViewportRef(viewportId); const [size, setSize] = useState<ViewportSize>({ width: 0, height: 0, offsetLeft: 0, offsetTop: 0, clientRect: null, isVisible: false, }); // Update viewport dimensions const updateViewportSize = useCallback(() => { Iif (!viewportElementRef?.current) { return; } const element = viewportElementRef.current; const clientRect = element.getBoundingClientRect(); const newWidth = clientRect.width; const newHeight = clientRect.height; const newOffsetLeft = element.offsetLeft; const newOffsetTop = element.offsetTop; const newIsVisible = newWidth > 0 && newHeight > 0; setSize(prevSize => { if ( prevSize.width === newWidth && prevSize.height === newHeight && prevSize.offsetLeft === newOffsetLeft && prevSize.offsetTop === newOffsetTop && prevSize.isVisible === newIsVisible ) { return prevSize; } return { width: newWidth, height: newHeight, offsetLeft: newOffsetLeft, offsetTop: newOffsetTop, clientRect, isVisible: newIsVisible, }; }); }, [viewportElementRef]); useEffect(() => { if (!viewportId || !viewportElementRef?.current) { return; } updateViewportSize(); const resizeObserver = new ResizeObserver(() => { updateViewportSize(); }); resizeObserver.observe(viewportElementRef.current); window.addEventListener('resize', updateViewportSize); return () => { window.removeEventListener('resize', updateViewportSize); if (viewportElementRef.current) { resizeObserver.unobserve(viewportElementRef.current); } resizeObserver.disconnect(); }; }, [viewportId, viewportElementRef, updateViewportSize]); const memoizedSize = useMemo(() => size, [size]); return memoizedSize; } export default useViewportSize; export { useViewportSize }; |