-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
A hook that disables scrolling in the document body.
- Loading branch information
Showing
9 changed files
with
269 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@raddix/use-scroll-lock': major | ||
--- | ||
|
||
Added useScrollLock hook. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
--- | ||
title: useScrollLock | ||
description: Disables scrolling in the document body. | ||
--- | ||
|
||
## Features | ||
|
||
- Removes the scroll bar from the document, while preserving the width of the page. | ||
- Works on any desktop or mobile browser. | ||
|
||
## Installation | ||
|
||
Install the custom hook from your command line. | ||
|
||
<Snippet pkg text='@raddix/use-scroll-lock' /> | ||
|
||
## Usage | ||
|
||
Once the component using the `useScrollLock` hook is mounted, scrolling is disabled | ||
in the document body. When the component is unmounted, the hook returns a cleanup function | ||
that restores the original overflow style. | ||
|
||
```jsx | ||
import { useState } from 'react'; | ||
import { useScrollLock } from '@raddix/use-scroll-lock'; | ||
|
||
function Modal({ handleClose }) { | ||
useScrollLock(); | ||
|
||
return ( | ||
<dialog> | ||
<button onClick={handleClose}>Close</button> | ||
<h2>Modal</h2> | ||
</dialog> | ||
) | ||
} | ||
|
||
export default function App() { | ||
const [isOpen, setIsOpen] = useState(false); | ||
|
||
return ( | ||
<> | ||
{isOpen && <Modal handleClose={() => setIsOpen(false)} />} | ||
<button className="primary" onClick={() => setIsOpen(true)}> | ||
Open Modal | ||
</button> | ||
</> | ||
); | ||
} | ||
``` | ||
|
||
## API | ||
|
||
### Parameters | ||
|
||
The `useScrollLock` hook does not accept any parameters. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
--- | ||
title: useScrollLock | ||
description: Deshabilita el desplazamiento en el cuerpo del documento. | ||
--- | ||
|
||
## Características | ||
|
||
- Elimina la barra de desplazamiento del documento, conservando el ancho de la página. | ||
- Funciona en cualquier navegador de escritorio o móvil. | ||
|
||
## Instalación | ||
|
||
Instala el custom hook desde su linea de comando. | ||
|
||
<Snippet pkg text='@raddix/use-scroll-lock' /> | ||
|
||
## Uso | ||
|
||
Una vez que el componente que utiliza el hook `useScrollLock` se monta, se deshabilita el desplazamiento | ||
en el cuerpo del documento. Cuando se desmonta el componente el hook devuelve una función de limpieza | ||
que restaura el estilo de desbordamiento original. | ||
|
||
```jsx | ||
import { useState } from 'react'; | ||
import { useScrollLock } from '@raddix/use-scroll-lock'; | ||
|
||
function Modal({ handleClose }) { | ||
useScrollLock(); | ||
|
||
return ( | ||
<dialog> | ||
<button onClick={handleClose}>Close</button> | ||
<h2>Modal</h2> | ||
</dialog> | ||
) | ||
} | ||
|
||
export default function App() { | ||
const [isOpen, setIsOpen] = useState(false); | ||
|
||
return ( | ||
<> | ||
{isOpen && <Modal handleClose={() => setIsOpen(false)} />} | ||
<button className="primary" onClick={() => setIsOpen(true)}> | ||
Open Modal | ||
</button> | ||
</> | ||
); | ||
} | ||
``` | ||
|
||
## API | ||
|
||
### Parámetros | ||
|
||
El hook `useScrollLock` no acepta ningun parámetro. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# useScrollLock | ||
|
||
A hook that locks and unlocks scroll. | ||
|
||
Please refer to the [documentation](https://raddix.dev/hooks/use-scroll-lock) for more information. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
{ | ||
"name": "@raddix/use-scroll-lock", | ||
"description": "A hook that locks and unlocks scroll.", | ||
"version": "0.1.0", | ||
"license": "MIT", | ||
"main": "src/index.ts", | ||
"author": "Moises Machuca Valverde <rolan.machuca@gmail.com> (https://www.moisesmachuca.com)", | ||
"homepage": "https://raddix.dev", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/gdvu/raddix.git" | ||
}, | ||
"keywords": [ | ||
"react-hook", | ||
"react-scroll-lock-hook", | ||
"react-use-scroll-lock", | ||
"use-scroll-lock", | ||
"use-scroll-lock-hook", | ||
"hook-scroll-lock" | ||
], | ||
"sideEffects": false, | ||
"scripts": { | ||
"lint": "eslint \"{src,tests}/*.{ts,tsx,css}\"", | ||
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist", | ||
"build": "tsup src --dts", | ||
"prepack": "clean-package", | ||
"postpack": "clean-package restore" | ||
}, | ||
"files": [ | ||
"dist", | ||
"README.md" | ||
], | ||
"peerDependencies": { | ||
"react": ">=16.8.0", | ||
"react-dom": ">=16.8.0" | ||
}, | ||
"clean-package": "../../../clean-package.config.json", | ||
"tsup": { | ||
"clean": true, | ||
"target": "es2019", | ||
"format": [ | ||
"cjs", | ||
"esm" | ||
] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import { useLayoutEffect, useRef } from 'react'; | ||
|
||
interface OriginalStyle { | ||
overflow: string; | ||
paddingRight: string; | ||
} | ||
|
||
export const useScrollLock = (): void => { | ||
const originalStyle = useRef<OriginalStyle | null>(null); | ||
|
||
const preventTouch = (e: Event) => { | ||
e.preventDefault(); | ||
return false; | ||
}; | ||
|
||
useLayoutEffect(() => { | ||
const scrollbarWidth = window.innerWidth - document.body.scrollWidth; | ||
const paddingRight = window.getComputedStyle(document.body).paddingRight; | ||
const overflow = window.getComputedStyle(document.body).overflow; | ||
const right = scrollbarWidth + parseInt(paddingRight, 10); | ||
|
||
originalStyle.current = { overflow, paddingRight }; | ||
document.body.style.paddingRight = `${right}px`; | ||
document.body.style.overflow = 'hidden'; | ||
document.addEventListener('touchmove', preventTouch, { passive: false }); | ||
|
||
return () => { | ||
if (originalStyle.current) { | ||
document.body.style.overflow = originalStyle.current.overflow; | ||
document.body.style.paddingRight = originalStyle.current.paddingRight; | ||
} | ||
|
||
document.removeEventListener('touchmove', preventTouch); | ||
}; | ||
}, []); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
/* eslint-disable @typescript-eslint/unbound-method */ | ||
import { renderHook } from '@testing-library/react'; | ||
import { useScrollLock } from '../src'; | ||
|
||
describe('useScrollLock test:', () => { | ||
beforeEach(() => { | ||
document.body.style.overflow = 'auto'; | ||
document.body.style.paddingRight = '0px'; | ||
|
||
jest.spyOn(document, 'addEventListener'); | ||
jest.spyOn(document, 'removeEventListener'); | ||
}); | ||
|
||
afterEach(() => { | ||
jest.restoreAllMocks(); | ||
}); | ||
|
||
it('should block the scroll and add the touchmove event', () => { | ||
const { unmount } = renderHook(() => useScrollLock()); | ||
const touchMoveEvent = new Event('touchmove'); | ||
const scrollbarWidth = window.innerWidth - document.body.scrollWidth; | ||
touchMoveEvent.preventDefault = jest.fn(); | ||
document.dispatchEvent(touchMoveEvent); | ||
|
||
expect(touchMoveEvent.preventDefault).toHaveBeenCalled(); | ||
expect(document.body.style.overflow).toBe('hidden'); | ||
expect(document.body.style.paddingRight).toBe(`${scrollbarWidth}px`); | ||
|
||
expect(document.addEventListener).toHaveBeenCalledWith( | ||
'touchmove', | ||
expect.any(Function), | ||
{ passive: false } | ||
); | ||
|
||
unmount(); | ||
expect(document.body.style.overflow).toBe('auto'); | ||
expect(document.body.style.paddingRight).toBe('0px'); | ||
|
||
expect(document.removeEventListener).toHaveBeenCalledWith( | ||
'touchmove', | ||
expect.any(Function) | ||
); | ||
}); | ||
}); |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.