Skip to main content
Glama
useScrollDetection.ts2.84 kB
'use client'; import { useCallback, useEffect, useState } from 'react'; import { useGetElementOrWindow } from './useGetElementOrWindow'; import { useScrollBlockage } from './useScrollBlockage'; type useScrollDetectionProps = { isEnabled?: boolean; delta?: number; // how much user has to scroll to trigger the event deltaFromTop?: number; // how much user has to scroll from top to detect if the user has been scrolled onScrollDown?: (e: WheelEvent) => void; onScrollUp?: (e: WheelEvent) => void; element?: HTMLElement; // The element to detect the scroll on. If not defined, the window.document.body will be used }; export const useScrollDetection = (props?: useScrollDetectionProps) => { const { isEnabled = true, delta = 5, deltaFromTop = 0, onScrollDown, onScrollUp, element, } = props ?? {}; const [isScrolled, setIsScrolled] = useState<boolean>(false); const [isScrollable, setIsScrollable] = useState<boolean>(false); const { isScrollBlocked } = useScrollBlockage(); const containerElement = useGetElementOrWindow(element); const onMobileMove = useCallback( (event: globalThis.TouchEvent) => { const startY = event.touches?.[0]?.clientY ?? 0; const onMove = (event: globalThis.TouchEvent) => { if (isEnabled) { const currentY = event.touches?.[0]?.clientY ?? 0; const deltaY = startY - currentY; setIsScrolled(deltaY > 0); containerElement?.removeEventListener('touchmove', onMove); } }; containerElement?.addEventListener('touchmove', onMove); }, [isEnabled, containerElement] ); const onScroll = useCallback( (e: WheelEvent) => { const isScrolledDown = e.deltaY > 0; if (isEnabled && !isScrollBlocked && isScrollable) { const isDeTected = Math.abs(e.deltaY) > Math.abs(delta); if (isDeTected) { if (isScrolledDown) { onScrollDown?.(e); } else { onScrollUp?.(e); } } setIsScrolled(window.scrollY > deltaFromTop); } }, [isEnabled, isScrollBlocked, isScrollable] ); useEffect(() => { if (isEnabled) { containerElement?.addEventListener('wheel', onScroll, { passive: true }); containerElement?.addEventListener('touchstart', onMobileMove, { passive: true, }); } else { setIsScrolled(false); } return () => { containerElement?.removeEventListener('wheel', onScroll); containerElement?.removeEventListener('touchstart', onMobileMove); }; }, [isEnabled, onScroll, onMobileMove, containerElement]); useEffect(() => { const isScrollable = window.innerHeight < window.document.body.scrollHeight; setIsScrollable(isScrollable); }, []); return { isScrolled, isScrollable }; };

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/aymericzip/intlayer'

If you have feedback or need assistance with the MCP directory API, please join our Discord server