useScrollPosition

Tracks the current scroll position (X and Y coordinates) of the window.

Code

1import { useState } from "react"
2import { useEventListener } from "./use-event-listener"
3import { useIsomorphicLayoutEffect } from "./use-isomorphic-layout-effect"
4
5interface ScrollPosition {
6  x: number
7  y: number
8}
9
10export function useScrollPosition(): ScrollPosition {
11  const [scrollPosition, setScrollPosition] = useState<ScrollPosition>({ x: 0, y: 0 })
12
13  const handleScroll = () => {
14    setScrollPosition({ x: window.scrollX, y: window.scrollY })
15  }
16
17  useEventListener("scroll", handleScroll)
18
19  useIsomorphicLayoutEffect(() => {
20    handleScroll()
21  }, [])
22
23  return scrollPosition
24}

Usage Example

import { useScrollPosition } from "@/hooks/use-scroll-position" import { Card, CardContent } from "@/components/ui/card" export function ScrollPositionExample() { const { x, y } = useScrollPosition() return ( <div className="space-y-4"> <Card className="p-4 sticky top-20 z-20 bg-npui-card border-npui-border"> <CardContent className="p-0"> <p className="text-lg">Scroll X: {x}px</p> <p className="text-lg">Scroll Y: {y}px</p> </CardContent> </Card> <div className="h-[1000px] bg-npui-secondary/20 flex items-center justify-center"> <p className="text-npui-muted-foreground">Scroll down to see the Y position change.</p> </div> <div className="h-[1000px] bg-npui-secondary/40 flex items-center justify-center"> <p className="text-npui-muted-foreground">Keep scrolling!</p> </div> </div> ) }