@servicetitan/assist-ui
Version:
ServiceTitan Atlas UI Components
58 lines (46 loc) • 1.61 kB
text/typescript
import { useCallback, useEffect, useRef } from 'react';
interface UseScrollCallbackOptions {
onScrollDown?: () => void;
onScrollTop?: () => void;
threshold?: number;
element?: HTMLElement | null;
}
export const useScrollCallback = ({
onScrollDown,
onScrollTop,
threshold = 50,
element,
}: UseScrollCallbackOptions = {}) => {
const lastScrollTop = useRef(0);
const hasTriggeredScrollDown = useRef(false);
const handleScroll = useCallback(() => {
const scrollTop = element
? element.scrollTop
: window.scrollY || document.documentElement.scrollTop;
// Check if scrolled down past threshold
if (scrollTop >= threshold && !hasTriggeredScrollDown.current) {
hasTriggeredScrollDown.current = true;
onScrollDown?.();
}
// Check if scrolled back to top
if (scrollTop === 0 && hasTriggeredScrollDown.current) {
hasTriggeredScrollDown.current = false;
onScrollTop?.();
}
lastScrollTop.current = scrollTop;
}, [onScrollDown, onScrollTop, threshold, element]);
useEffect(() => {
if (!element) {
return;
}
const targetElement = element;
targetElement.addEventListener('scroll', handleScroll, { passive: true });
return () => {
targetElement.removeEventListener('scroll', handleScroll);
};
}, [handleScroll, element]);
return {
lastScrollTop: lastScrollTop.current,
hasTriggeredScrollDown: hasTriggeredScrollDown.current,
};
};