UNPKG

react-photo-album

Version:

Responsive photo gallery component for React

54 lines (53 loc) 2.25 kB
"use client"; import { useRef, useReducer, useCallback } from "react"; function useArray(array) { const ref = useRef(array); if (!array || !ref.current || array.length !== ref.current.length || ref.current.some((el, i) => el !== array[i])) { ref.current = array; } return ref.current; } function containerWidthReducer(state, [newContainerWidth, newScrollbarWidth]) { const [containerWidth, scrollbarWidth] = state; if (containerWidth !== void 0 && scrollbarWidth !== void 0 && newContainerWidth !== void 0 && newScrollbarWidth !== void 0 && newContainerWidth > containerWidth && newContainerWidth - containerWidth <= 20 && newScrollbarWidth < scrollbarWidth) { return [containerWidth, newScrollbarWidth]; } return containerWidth !== newContainerWidth || scrollbarWidth !== newScrollbarWidth ? [newContainerWidth, newScrollbarWidth] : state; } function resolveContainerWidth(el, breakpoints) { let width = el?.clientWidth; if (width !== void 0 && breakpoints && breakpoints.length > 0) { const sorted = [...breakpoints.filter((x) => x > 0)].sort((a, b) => b - a); sorted.push(Math.floor(sorted[sorted.length - 1] / 2)); width = sorted.find((breakpoint, index) => breakpoint <= width || index === sorted.length - 1); } return width; } function useContainerWidth(ref, breakpointsArray, defaultContainerWidth) { const [[containerWidth], dispatch] = useReducer(containerWidthReducer, [defaultContainerWidth]); const breakpoints = useArray(breakpointsArray); const observerRef = useRef(void 0); const containerRef = useCallback( (node) => { observerRef.current?.disconnect(); observerRef.current = void 0; const updateWidth = () => dispatch([resolveContainerWidth(node, breakpoints), window.innerWidth - document.documentElement.clientWidth]); updateWidth(); if (node && typeof ResizeObserver !== "undefined") { observerRef.current = new ResizeObserver(updateWidth); observerRef.current.observe(node); } if (typeof ref === "function") { ref(node); } else if (ref) { ref.current = node; } }, [ref, breakpoints] ); return { containerRef, containerWidth }; } export { useArray, useContainerWidth };