use-scroll-lock
shadcn-hooks/use-scroll-lockFreeHook
A hook to lock the scroll of the body
Install it
npx shadcn@latest add https://shadcn-hooks.com/r/use-scroll-lock.jsonSource
1import { useCallback, useRef, useState } from 'react'2import { useIsomorphicLayoutEffect } from '@/registry/hooks/use-isomorphic-layout-effect'3import { isBrowser } from '@/registry/lib/is-browser'45interface UseScrollLockOptions {6 autoLock?: boolean7 lockTarget?: HTMLElement | string8 widthReflow?: boolean9}1011interface UseScrollLockReturn {12 isLocked: boolean13 lock: () => void14 unlock: () => void15}1617interface OriginalStyle {18 overflow: CSSStyleDeclaration['overflow']19 paddingRight: CSSStyleDeclaration['paddingRight']20}2122export function useScrollLock(23 options: UseScrollLockOptions = {},24): UseScrollLockReturn {25 const { autoLock = true, lockTarget, widthReflow = true } = options26 const [isLocked, setIsLocked] = useState(false)27 const target = useRef<HTMLElement | null>(null)28 const originalStyle = useRef<OriginalStyle | null>(null)2930 const lock = useCallback(() => {31 if (target.current) {32 const { overflow, paddingRight } = target.current.style3334 // Save the original styles35 originalStyle.current = { overflow, paddingRight }3637 // Prevent width reflow38 if (widthReflow) {39 // Use window inner width if body is the target as global scrollbar isn't part of the document40 const offsetWidth =41 target.current === document.body42 ? window.innerWidth43 : target.current.offsetWidth44 // Get current computed padding right in pixels45 const currentPaddingRight =46 Number.parseInt(47 window.getComputedStyle(target.current).paddingRight,48 10,49 ) || 05051 const scrollbarWidth = offsetWidth - target.current.scrollWidth52 target.current.style.paddingRight = `${scrollbarWidth + currentPaddingRight}px`53 }5455 // Lock the scroll56 target.current.style.overflow = 'hidden'5758 setIsLocked(true)59 }60 }, [widthReflow])6162 const unlock = useCallback(() => {63 if (target.current && originalStyle.current) {64 target.current.style.overflow = originalStyle.current.overflow6566 // Only reset padding right if we changed it67 if (widthReflow) {68 target.current.style.paddingRight = originalStyle.current.paddingRight69 }70 }7172 setIsLocked(false)73 }, [widthReflow])7475 useIsomorphicLayoutEffect(() => {76 if (!isBrowser) return7778 if (lockTarget) {79 target.current =80 typeof lockTarget === 'string'81 ? document.querySelector(lockTarget)82 : lockTarget83 }8485// … truncated
What it pulls in
Other registry items
Files it writes
More from shadcn-hooks
All 58 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| use-active-elementuse-active-element | shadcn-hooks | Hooks | Free | no deps | |
| use-batteryuse-battery | shadcn-hooks | Hooks | Free | no deps | |
| use-booleanuse-boolean | shadcn-hooks | Hooks | Free | no deps | |
| use-click-any-whereuse-click-any-where | shadcn-hooks | Hooks | Free | no deps | |
| use-click-awayuse-click-away | shadcn-hooks | Hooks | Free | no deps | |
| use-clipboarduse-clipboard | shadcn-hooks | Hooks | Free | no deps | |
| use-controllable-valueuse-controllable-value | shadcn-hooks | Hooks | Free | 1 dep | |
| use-counteruse-counter | shadcn-hooks | Hooks | Free | no deps |
