LibreChat/client/src/hooks/useScrollToRef.ts
Danny Avila c2a79aee1b
feat: Optimize Scroll Handling with Intersection Observer (#3564)
*  refactor(ScrollToBottom): use Intersection Observer for efficient scroll handling

* chore: imports, remove debug console
2024-08-06 16:18:15 -04:00

53 lines
1.4 KiB
TypeScript

import { RefObject, useCallback } from 'react';
import throttle from 'lodash/throttle';
type TUseScrollToRef = {
targetRef: RefObject<HTMLDivElement>;
callback: () => void;
smoothCallback: () => void;
};
type ThrottledFunction = (() => void) & {
cancel: () => void;
flush: () => void;
};
type ScrollToRefReturn = {
scrollToRef?: ThrottledFunction;
handleSmoothToRef: React.MouseEventHandler<HTMLButtonElement>;
};
export default function useScrollToRef({
targetRef,
callback,
smoothCallback,
}: TUseScrollToRef): ScrollToRefReturn {
const logAndScroll = (behavior: 'instant' | 'smooth', callbackFn: () => void) => {
// Debugging:
// console.log(`Scrolling with behavior: ${behavior}, Time: ${new Date().toISOString()}`);
targetRef.current?.scrollIntoView({ behavior });
callbackFn();
};
// eslint-disable-next-line react-hooks/exhaustive-deps
const scrollToRef = useCallback(
throttle(() => logAndScroll('instant', callback), 145, { leading: true }),
[targetRef],
);
// eslint-disable-next-line react-hooks/exhaustive-deps
const scrollToRefSmooth = useCallback(
throttle(() => logAndScroll('smooth', smoothCallback), 750, { leading: true }),
[targetRef],
);
const handleSmoothToRef: React.MouseEventHandler<HTMLButtonElement> = (e) => {
e.preventDefault();
scrollToRefSmooth();
};
return {
scrollToRef,
handleSmoothToRef,
};
}