useScrollLock
Lock and unlock scrolling on a target element or document.body. Useful for modals, drawers, and overlays that need to prevent background scrolling.
Lock and unlock page scrolling. Try scrolling the page after locking.
import { const useScrollLock: (element?: MaybeEventTarget<HTMLElement>, initialState?: MaybeObservable<boolean>, options?: DeepMaybeObservable<ConfigurableWindow>) => UseScrollLockReturn
useScrollLock } from "@usels/web";
function function Component(): JSX.Element
Component() { const { const isLocked$: any
Current scroll lock state
isLocked$, const lock: () => void
Lock scrolling
lock, const unlock: () => void
Unlock scrolling
unlock, const toggle: () => void
Toggle lock state
toggle } = function useScrollLock(element?: MaybeEventTarget<HTMLElement>, initialState?: MaybeObservable<boolean>, options?: DeepMaybeObservable<ConfigurableWindow>): UseScrollLockReturn
Framework-agnostic reactive scroll-lock controller. Applies
overflow: hidden and scrollbar-width padding to the target element (or
document.body when no target is provided), and toggles the touchmove
preventDefault listener for iOS Safari support.
useScrollLock();
return ( <JSX.IntrinsicElements.div: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div> <JSX.IntrinsicElements.p: DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p>Scroll is {const isLocked$: any
Current scroll lock state
isLocked$.any
get() ? "locked" : "unlocked"}</JSX.IntrinsicElements.p: DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p> <JSX.IntrinsicElements.button: DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
button DOMAttributes<HTMLButtonElement>.onClick?: MouseEventHandler<HTMLButtonElement> | undefined
onClick={const toggle: () => void
Toggle lock state
toggle}>Toggle scroll lock</JSX.IntrinsicElements.button: DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
button> </JSX.IntrinsicElements.div: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div> );}import { createScrollLock } from "@usels/web";
function Component() { "use scope" const { isLocked$, toggle } = createScrollLock();
return ( <div> <p>Scroll is {isLocked$.get() ? "locked" : "unlocked"}</p> <button onClick={toggle}>Toggle scroll lock</button> </div> );}With target element
Section titled “With target element”By default, scroll lock is applied to document.body. Pass any element via the first argument to scope locking to that element.
// @noErrorsimport { useRef$ } from "@usels/core";import { useScrollLock } from "@usels/web";
function Component() { const el$ = useRef$<HTMLDivElement>(); const { isLocked$, toggle } = useScrollLock(el$);
return ( <div ref={el$} style={{ overflow: "auto", height: 300 }}> <button onClick={toggle}>{isLocked$.get() ? "Unlock" : "Lock"} scroll</button> {/* long content */} </div> );}Initial locked state
Section titled “Initial locked state”Pass true as the second argument to start with scrolling locked on mount.
// @noErrorsimport { useScrollLock } from "@usels/web";// ---cut---const { isLocked$, unlock } = useScrollLock(undefined, true);// scrolling is locked immediately on mountReactive control
Section titled “Reactive control”Pass an Observable as initialState to seed the lock state reactively.
// @noErrorsimport { observable } from "@usels/core";import { useScrollLock } from "@usels/web";// ---cut---const locked$ = observable(false);const { isLocked$ } = useScrollLock(undefined, locked$);Parameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
element | MaybeEventTarget<HTMLElement> (optional) | - |
initialState | MaybeObservable<boolean> | undefined (optional) | - |
options | ConfigurableWindow (optional) | - |
Returns
Section titled “Returns”UseScrollLockReturn
| Name | Type | Description |
|---|---|---|
isLocked$ | ObservableBoolean<boolean> | Current scroll lock state |
lock | () => void | Lock scrolling |
unlock | () => void | Unlock scrolling |
toggle | () => void | Toggle lock state |