useScrollPositionui-interaction

useScrollPosition

NewSSR SAFE

Tracks scroll coordinates and direction in real time for the window or a specific scrollable element.

$ pnpm dlx shadcn@latest add @byphongphan/use-scroll-position
Requires @byphongphan in components.json
Loading preview...

Installation

$ pnpm dlx shadcn@latest add @byphongphan/use-scroll-position
Requires @byphongphan in components.json

Usage

Window Scroll (e.g. Auto-Hiding Navbar)

import { useScrollPosition } from "@/shared/hooks"
export function Navbar() { const { y, direction } = useScrollPosition()
const isHidden = direction === "down" && y > 80
return ( <header className={`fixed top-0 left-0 right-0 z-50 transition-transform duration-300 ${ isHidden ? "-translate-y-full" : "translate-y-0" }`} > <nav className="border-b bg-background/80 backdrop-blur-md px-6 py-4"> <span>Site Header (y: {Math.round(y)}px)</span> </nav> </header> )}

Custom Scrollable Container

import { useRef } from "react"import { useScrollPosition } from "@/shared/hooks"
export function ScrollableFeed() { const feedRef = useRef<HTMLDivElement>(null) const { y, direction } = useScrollPosition({ targetRef: feedRef })
return ( <div className="relative"> <div className="text-xs text-muted-foreground mb-2"> Feed Scroll Y: {Math.round(y)}px | Direction: {direction ?? "idle"} </div>
<div ref={feedRef} className="h-64 overflow-y-auto border rounded-lg p-4"> {/* Content list */} </div> </div> )}

Features

  • 60/120 FPS Performance: Throttled using native requestAnimationFrame to ensure zero main-thread blockage or frame drops during heavy scrolling.
  • Direction Detection: Automatically identifies "up" vs "down" movement to power floating action buttons, auto-hiding navigation bars, and reading progress bars.
  • Target Agnostic: Listens to the global window by default or any scrollable HTML element via targetRef.
  • Passive Listeners: Employs { passive: true } event listeners so mobile touch-scrolling remains butter-smooth.
  • SSR-Safe: Safely initializes on the server and synchronizes state on client mount with useIsomorphicLayoutEffect.

Parameters

ParameterTypeDefaultDescription
options.targetRefRefObject<HTMLElement | null>—Optional ref of a scrollable element to observe instead of window.
options.enabledbooleantruePass false to pause event listeners and reduce overhead.

Returns

PropertyTypeDescription
xnumberHorizontal scroll offset in pixels (scrollLeft).
ynumberVertical scroll offset in pixels (scrollTop).
direction"up" | "down" | nullActive scroll direction since previous frame ("up", "down" or null).

Command Palette

Quick search and commands navigation