UNPKG

@1771technologies/lytenyte-pro

Version:

Blazingly fast headless React data grid with 100s of features.

72 lines (71 loc) 3.12 kB
import { useRoot } from "@1771technologies/lytenyte-core/internal"; import { useCallback, useRef } from "react"; export function useEdgeScroll() { const { viewport, dimensions, totalHeaderHeight, yPositions, source } = useRoot(); const rowTopCount = source.useTopCount(); const rowBottomCount = source.useBottomCount(); const bottomHeight = yPositions.at(-1) - yPositions.at(-1 - rowBottomCount); const topHeight = yPositions.at(rowTopCount); const intervalIdX = useRef(null); const intervalIdY = useRef(null); const cancelX = useCallback(() => { if (intervalIdX.current) { clearInterval(intervalIdX.current); intervalIdX.current = null; } }, []); const cancelY = useCallback(() => { if (intervalIdY.current) { clearInterval(intervalIdY.current); intervalIdY.current = null; } }, []); const edgeScrollY = useCallback((visualPositionY, startY) => { if (!viewport) return; const viewportClientHeight = dimensions.innerHeight; const topBound = totalHeaderHeight + topHeight; const botBound = viewportClientHeight - bottomHeight; const scrollTop = startY > topBound && visualPositionY <= totalHeaderHeight + 20; const scrollBottom = startY < botBound && visualPositionY >= viewportClientHeight - 20; const speed = 6; if (scrollTop && !intervalIdY.current) { intervalIdY.current = setInterval(() => { viewport.scrollBy({ top: -speed }); }, 6); } else if (scrollBottom && !intervalIdY.current) { intervalIdY.current = setInterval(() => { viewport.scrollBy({ top: speed }); }, 6); } if (!scrollBottom && !scrollTop && intervalIdY.current) { clearInterval(intervalIdY.current); intervalIdY.current = null; } }, [bottomHeight, dimensions.innerHeight, topHeight, totalHeaderHeight, viewport]); const edgeScrollX = useCallback((visualPositionX, isRtl) => { if (!viewport) return; const viewportClientWidth = dimensions.innerWidth; const viewportWidth = Math.min(viewportClientWidth * 0.1, 100); const buffer = viewportWidth; const leftBound = buffer; const rightBound = viewportClientWidth - buffer; const speed = 3; if (visualPositionX < leftBound && !intervalIdX.current) { intervalIdX.current = setInterval(() => { viewport.scrollBy({ left: isRtl ? speed : -speed }); }, 6); } else if (visualPositionX > rightBound && !intervalIdX.current) { intervalIdX.current = setInterval(() => { viewport.scrollBy({ left: isRtl ? -speed : speed }); }, 6); } if (intervalIdX.current && visualPositionX > leftBound && visualPositionX < rightBound) { cancelX(); } }, [cancelX, dimensions.innerWidth, viewport]); return { cancelX, edgeScrollX, cancelY, edgeScrollY }; }