UNPKG

@thibault.sh/hooks

Version:

A comprehensive collection of React hooks for browser storage, UI interactions, and more

1 lines 4.69 kB
{"version":3,"sources":["../src/hooks/useContainerScroll.ts"],"names":["useContainerScroll","containerRef","delay","scroll","setScroll","useState","useEffect","scrollTimeout","element","handleScroll","scrollTop","scrollLeft","scrollWidth","scrollHeight","clientWidth","clientHeight","prev","__spreadProps","__spreadValues"],"mappings":"8EAgDO,SAASA,CAAmBC,CAAAA,CAAAA,CAA6CC,CAAgB,CAAA,GAAA,CAAsB,CACpH,GAAM,CAACC,CAAQC,CAAAA,CAAS,CAAIC,CAAAA,QAAAA,CAA0B,CACpD,SAAA,CAAW,CACX,CAAA,UAAA,CAAY,CACZ,CAAA,WAAA,CAAa,CACb,CAAA,YAAA,CAAc,CACd,CAAA,WAAA,CAAa,CACb,CAAA,YAAA,CAAc,EACd,WAAa,CAAA,CAAA,CACf,CAAC,CAAA,CAED,OAAAC,SAAAA,CAAU,IAAM,CACd,GAAI,CAACL,CAAa,CAAA,OAAA,CAAS,OAE3B,IAAIM,CACEC,CAAAA,CAAAA,CAAUP,EAAa,OAEvBQ,CAAAA,CAAAA,CAAe,IAAM,CACzB,GAAM,CAAE,SAAAC,CAAAA,CAAAA,CAAW,UAAAC,CAAAA,CAAAA,CAAY,WAAAC,CAAAA,CAAAA,CAAa,YAAAC,CAAAA,GAAAA,CAAc,WAAAC,CAAAA,CAAAA,CAAa,aAAAC,GAAa,CAAA,CAAIP,CAExFJ,CAAAA,CAAAA,CAAWY,CAAU,GAAA,CACnB,SAAAN,CAAAA,CAAAA,CACA,UAAAC,CAAAA,CAAAA,CACA,WAAAC,CAAAA,CAAAA,CACA,YAAAC,CAAAA,GAAAA,CACA,WAAAC,CAAAA,CAAAA,CACA,aAAAC,GACA,CAAA,WAAA,CAAa,CACf,CAAA,CAAA,CAAE,CAEF,CAAA,YAAA,CAAaR,CAAa,CAAA,CAC1BA,CAAgB,CAAA,UAAA,CAAW,IAAM,CAC/BH,CAAWY,CAAAA,CAAAA,EAAUC,CAAAC,CAAAA,CAAAA,CAAA,GAAKF,CAAL,CAAA,CAAA,CAAW,WAAa,CAAA,CAAA,CAAM,CAAE,CAAA,EACvD,CAAGd,CAAAA,CAAK,EACV,CAAA,CAEA,OAAAM,CAAAA,CAAQ,gBAAiB,CAAA,QAAA,CAAUC,CAAY,CAAA,CAC/CA,GAEO,CAAA,IAAM,CACXD,CAAAA,CAAQ,mBAAoB,CAAA,QAAA,CAAUC,CAAY,CAAA,CAClD,YAAaF,CAAAA,CAAa,EAC5B,CACF,CAAG,CAAA,CAACN,CAAY,CAAC,EAEVE,CACT","file":"useContainerScroll.mjs","sourcesContent":["import { useState, useEffect, RefObject } from \"react\";\n\ninterface ContainerScroll {\n scrollTop: number;\n scrollLeft: number;\n scrollWidth: number;\n scrollHeight: number;\n clientWidth: number;\n clientHeight: number;\n isScrolling: boolean;\n}\n\n/**\n * Hook that tracks scroll position, dimensions, and scrolling state of a container element.\n *\n * Provides real-time scroll information including position, dimensions, and a debounced\n * scrolling indicator that's useful for optimizing scroll-based animations or effects.\n *\n * @param containerRef - React ref object pointing to the scrollable container element\n * @param delay - Delay in milliseconds before setting `isScrolling` to false (default: 150)\n *\n * @returns An object containing:\n * - `scrollTop`: Vertical scroll position in pixels\n * - `scrollLeft`: Horizontal scroll position in pixels\n * - `scrollWidth`: Total scrollable width of the content\n * - `scrollHeight`: Total scrollable height of the content\n * - `clientWidth`: Visible width of the container\n * - `clientHeight`: Visible height of the container\n * - `isScrolling`: Boolean indicating if the user is currently scrolling (debounced)\n *\n * @example\n * ```tsx\n * const containerRef = useRef<HTMLDivElement>(null);\n * const scroll = useContainerScroll(containerRef, 200);\n *\n * return (\n * <div ref={containerRef} className=\"scrollable-container\">\n * <div>Scroll position: {scroll.scrollTop}px</div>\n * <div>Container size: {scroll.clientWidth}x{scroll.clientHeight}</div>\n * <div>Content size: {scroll.scrollWidth}x{scroll.scrollHeight}</div>\n * {scroll.isScrolling && <div>Currently scrolling...</div>}\n *\n * <div style={{ height: '2000px' }}>Long content...</div>\n * </div>\n * );\n * ```\n * @see https://thibault.sh/hooks/use-container-scroll\n */\nexport function useContainerScroll(containerRef: RefObject<HTMLElement | null>, delay: number = 150): ContainerScroll {\n const [scroll, setScroll] = useState<ContainerScroll>({\n scrollTop: 0,\n scrollLeft: 0,\n scrollWidth: 0,\n scrollHeight: 0,\n clientWidth: 0,\n clientHeight: 0,\n isScrolling: false,\n });\n\n useEffect(() => {\n if (!containerRef.current) return;\n\n let scrollTimeout: ReturnType<typeof setTimeout>;\n const element = containerRef.current;\n\n const handleScroll = () => {\n const { scrollTop, scrollLeft, scrollWidth, scrollHeight, clientWidth, clientHeight } = element;\n\n setScroll((prev) => ({\n scrollTop,\n scrollLeft,\n scrollWidth,\n scrollHeight,\n clientWidth,\n clientHeight,\n isScrolling: true,\n }));\n\n clearTimeout(scrollTimeout);\n scrollTimeout = setTimeout(() => {\n setScroll((prev) => ({ ...prev, isScrolling: false }));\n }, delay);\n };\n\n element.addEventListener(\"scroll\", handleScroll);\n handleScroll();\n\n return () => {\n element.removeEventListener(\"scroll\", handleScroll);\n clearTimeout(scrollTimeout);\n };\n }, [containerRef]);\n\n return scroll;\n}\n"]}