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>
)
}