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}
90Install
npx wkkkis-hooks add use-scroll-lockOptions
| Name | Type | Default | Description | 
|---|---|---|---|
| ref | RefObject<HTMLElement> <MutableRefObject<HTMLElement | null> | undefined | The 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
| Source | Destination | 
|---|---|
| files/use-scroll-lock.ts | src/hooks/use-scroll-lock.ts |