| 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, |
| }; |
| } |
|
|