| | 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) => { |
| | |
| | |
| | targetRef.current?.scrollIntoView({ behavior }); |
| | callbackFn(); |
| | }; |
| |
|
| | |
| | const scrollToRef = useCallback( |
| | throttle(() => logAndScroll('instant', callback), 145, { leading: true }), |
| | [targetRef], |
| | ); |
| |
|
| | |
| | const scrollToRefSmooth = useCallback( |
| | throttle(() => logAndScroll('smooth', smoothCallback), 750, { leading: true }), |
| | [targetRef], |
| | ); |
| |
|
| | const handleSmoothToRef: React.MouseEventHandler<HTMLButtonElement> = (e) => { |
| | e.preventDefault(); |
| | scrollToRefSmooth(); |
| | }; |
| |
|
| | return { |
| | scrollToRef, |
| | handleSmoothToRef, |
| | }; |
| | } |
| |
|