useScrollDirection
hookas/use-scroll-directionFreeHook
A hook to track the scroll direction
Install it
npx shadcn@latest add https://hookas.letstri.dev/r/use-scroll-direction.jsonSource
1'use client'23import * as React from 'react'45export type ScrollDirection = 'up' | 'down' | 'left' | 'right' | null67export function useScrollDirection(ref?: React.RefObject<HTMLElement | null>, delay = 500) {8 const [scrollDirection, setScrollDirection] = React.useState<ScrollDirection>(null)9 const lastScrollRef = React.useRef({ y: 0, x: 0 })10 const timeoutRef = React.useRef<ReturnType<typeof setTimeout> | null>(null)1112 React.useEffect(() => {13 const element = ref ? ref.current : window1415 if (!element)16 return1718 function handleScroll() {19 const currentScrollY = element === window ? window.scrollY : (element as HTMLElement).scrollTop20 const currentScrollX = element === window ? window.scrollX : (element as HTMLElement).scrollLeft2122 let newDirection: ScrollDirection = null2324 if (currentScrollY > lastScrollRef.current.y) {25 newDirection = 'down'26 }27 else if (currentScrollY < lastScrollRef.current.y) {28 newDirection = 'up'29 }30 else if (currentScrollX > lastScrollRef.current.x) {31 newDirection = 'right'32 }33 else if (currentScrollX < lastScrollRef.current.x) {34 newDirection = 'left'35 }3637 if (newDirection !== scrollDirection) {38 setScrollDirection(newDirection)39 }4041 lastScrollRef.current = {42 y: currentScrollY,43 x: currentScrollX,44 }4546 if (timeoutRef.current) {47 clearTimeout(timeoutRef.current)48 }4950 timeoutRef.current = setTimeout(() => {51 setScrollDirection(null)52 }, delay)53 }5455 element.addEventListener('scroll', handleScroll)5657 return () => {58 if (timeoutRef.current) {59 clearTimeout(timeoutRef.current)60 }61 element.removeEventListener('scroll', handleScroll)62 }63 }, [scrollDirection, ref, delay])6465 return scrollDirection66}
Files it writes
More from hookas
All 30 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| useAsyncEffectuse-async-effect | hookas | Hooks | Free | no deps | |
| useClickOutsideuse-click-outside | hookas | Hooks | Free | no deps | |
| useDebounceCallbackuse-debounced-callback | hookas | Hooks | Free | no deps | |
| useDebounceMemouse-debounced-memo | hookas | Hooks | Free | no deps | |
| useDebounceStateuse-debounced-state | hookas | Hooks | Free | no deps | |
| useElementSizeuse-element-size | hookas | Hooks | Free | no deps | |
| useFullscreenuse-fullscreen | hookas | Hooks | Free | no deps | |
| useIntervaluse-interval | hookas | Hooks | Free | no deps |
