wkkkis-hooks

use-scroll-lock (use-scroll-lock)

Lock and unlock scrolling on an element or the page.

v0.1.0

Usage

import { use-scroll-lock } from "@/hooks"
1"use client"; 2 3import React, { useRef } from "react"; 4 5import { Button } from "@/components/ui/button"; 6import { 7 Card, 8 CardContent, 9 CardDescription, 10 CardFooter, 11 CardHeader, 12 CardTitle, 13} from "@/components/ui/card"; 14 15import { useScrollLock } from "@/components/hooks/use-scroll-lock"; 16 17export function UseScrollLockDemo() { 18 const containerRef = useRef<HTMLDivElement>(null); 19 20 const { 21 isLocked: isContainerLocked, 22 lock: lockContainer, 23 unlock: unlockContainer, 24 toggle: toggleContainer, 25 } = useScrollLock<HTMLDivElement>(containerRef); 26 27 const { 28 isLocked: isPageLocked, 29 lock: lockPage, 30 unlock: unlockPage, 31 toggle: togglePage, 32 } = useScrollLock(); 33 34 return ( 35 <Card className="relative max-w-md w-full space-y-4"> 36 <CardHeader> 37 <CardTitle>useScrollLock</CardTitle> 38 <CardDescription> 39 This component demonstrates locking and unlocking scroll on an element 40 or the page. 41 </CardDescription> 42 </CardHeader> 43 <CardContent className="space-y-6"> 44 <div className="space-y-2"> 45 <p> 46 Container scroll locked:{" "} 47 <strong>{isContainerLocked ? "Yes" : "No"}</strong> 48 </p> 49 <div 50 ref={containerRef} 51 className="h-40 overflow-y-auto border p-2 space-y-2" 52 > 53 {Array.from({ length: 20 }).map((_, i) => ( 54 <p key={i}>Content line {i + 1}</p> 55 ))} 56 </div> 57 <div className="flex flex-wrap gap-2"> 58 <Button onClick={lockContainer}>Lock Container</Button> 59 <Button variant="outline" onClick={unlockContainer}> 60 Unlock Container 61 </Button> 62 <Button variant="secondary" onClick={toggleContainer}> 63 Toggle Container 64 </Button> 65 </div> 66 </div> 67 <div className="space-y-2"> 68 <p> 69 Page scroll locked: <strong>{isPageLocked ? "Yes" : "No"}</strong> 70 </p> 71 <div className="flex gap-2"> 72 <Button onClick={lockPage}>Lock Page</Button> 73 <Button variant="outline" onClick={unlockPage}> 74 Unlock Page 75 </Button> 76 <Button variant="secondary" onClick={togglePage}> 77 Toggle Page 78 </Button> 79 </div> 80 </div> 81 </CardContent> 82 <CardFooter> 83 <p className="text-sm text-muted-foreground"> 84 Try scrolling this container or the page and use the buttons above. 85 </p> 86 </CardFooter> 87 </Card> 88 ); 89} 90

Install

npx wkkkis-hooks add use-scroll-lock

Options

NameTypeDefaultDescription
refRefObject<HTMLElement> <MutableRefObject<HTMLElement | null>undefinedThe ref of the element to lock scroll on. If not provided, locks the document body.

Target Behavior

  • The hook accepts a ref to an element or defaults to the document body.

Cleanup

  • Restores the original overflow style on unmount.

Performance & Safety

  • Methods are memoized with useCallback .
  • Uses useRef to store the original overflow value.

Files in this hook

SourceDestination
files/use-scroll-lock.tssrc/hooks/use-scroll-lock.ts