diff --git a/react-responsive-modal/__tests__/index.test.tsx b/react-responsive-modal/__tests__/index.test.tsx
index ffd8a4f3..6b794b2d 100644
--- a/react-responsive-modal/__tests__/index.test.tsx
+++ b/react-responsive-modal/__tests__/index.test.tsx
@@ -260,6 +260,26 @@ describe('modal', () => {
);
expect(document.body.style.overflow).toBe('');
});
+ it('should reserve scroll bar gap', () => {
+ const scrollBarWidth = 42;
+ const innerWidth = 500;
+ Object.defineProperty(window, 'innerWidth', {
+ writable: true,
+ configurable: true,
+ value: innerWidth,
+ });
+ Object.defineProperty(document.documentElement, 'clientWidth', {
+ writable: true,
+ configurable: true,
+ value: innerWidth - scrollBarWidth,
+ });
+ render(
+ null} reserveScrollBarGap={true}>
+ modal content
+
+ );
+ expect(document.body.style.paddingRight).toBe(`${scrollBarWidth}px`);
+ });
});
describe('closeIcon', () => {
diff --git a/react-responsive-modal/package.json b/react-responsive-modal/package.json
index 95addf30..de56e8f6 100644
--- a/react-responsive-modal/package.json
+++ b/react-responsive-modal/package.json
@@ -47,11 +47,11 @@
"size-limit": [
{
"path": "dist/react-responsive-modal.cjs.production.min.js",
- "limit": "4.0 KB"
+ "limit": "4.1 KB"
},
{
"path": "dist/react-responsive-modal.esm.js",
- "limit": "4.0 KB"
+ "limit": "4.1 KB"
}
],
"dependencies": {
diff --git a/react-responsive-modal/src/index.tsx b/react-responsive-modal/src/index.tsx
index b06ddc41..cadd74ac 100644
--- a/react-responsive-modal/src/index.tsx
+++ b/react-responsive-modal/src/index.tsx
@@ -128,6 +128,10 @@ export interface ModalProps {
* ARIA description for modal
*/
ariaDescribedby?: string;
+ /**
+ * Avoid unpleasant flickering effect when body overflow is hidden. For more information see https://www.npmjs.com/package/body-scroll-lock
+ */
+ reserveScrollBarGap?: boolean;
/**
* id attribute for modal
*/
@@ -179,6 +183,7 @@ export const Modal = React.forwardRef(
onOverlayClick,
onAnimationEnd,
children,
+ reserveScrollBarGap,
}: ModalProps,
ref: React.ForwardedRef
) => {
@@ -200,7 +205,7 @@ export const Modal = React.forwardRef(
useModalManager(refModal, open);
// Hook used to manage the scroll
- useScrollLock(refModal, open, showPortal, blockScroll);
+ useScrollLock(refModal, open, showPortal, blockScroll, reserveScrollBarGap);
const handleOpen = () => {
if (
diff --git a/react-responsive-modal/src/useScrollLock.ts b/react-responsive-modal/src/useScrollLock.ts
index 810905c1..37e52f85 100644
--- a/react-responsive-modal/src/useScrollLock.ts
+++ b/react-responsive-modal/src/useScrollLock.ts
@@ -5,14 +5,15 @@ export const useScrollLock = (
refModal: React.RefObject,
open: boolean,
showPortal: boolean,
- blockScroll: boolean
+ blockScroll: boolean,
+ reserveScrollBarGap?: boolean
) => {
const oldRef = useRef(null);
useEffect(() => {
if (open && refModal.current && blockScroll) {
oldRef.current = refModal.current;
- disableBodyScroll(refModal.current);
+ disableBodyScroll(refModal.current, { reserveScrollBarGap });
}
return () => {
if (oldRef.current) {
@@ -20,5 +21,5 @@ export const useScrollLock = (
oldRef.current = null;
}
};
- }, [open, showPortal, refModal]);
+ }, [open, showPortal, refModal, blockScroll, reserveScrollBarGap]);
};