Skip to content

Commit

Permalink
feat: add optional reserveScrollBarGap (#484)
Browse files Browse the repository at this point in the history
  • Loading branch information
huksley committed Dec 14, 2021
1 parent 61c3493 commit 69249f8
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 6 deletions.
20 changes: 20 additions & 0 deletions react-responsive-modal/__tests__/index.test.tsx
Expand Up @@ -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(
<Modal open={true} onClose={() => null} reserveScrollBarGap={true}>
<div>modal content</div>
</Modal>
);
expect(document.body.style.paddingRight).toBe(`${scrollBarWidth}px`);
});
});

describe('closeIcon', () => {
Expand Down
4 changes: 2 additions & 2 deletions react-responsive-modal/package.json
Expand Up @@ -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": {
Expand Down
7 changes: 6 additions & 1 deletion react-responsive-modal/src/index.tsx
Expand Up @@ -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
*/
Expand Down Expand Up @@ -179,6 +183,7 @@ export const Modal = React.forwardRef(
onOverlayClick,
onAnimationEnd,
children,
reserveScrollBarGap,
}: ModalProps,
ref: React.ForwardedRef<HTMLDivElement>
) => {
Expand All @@ -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 (
Expand Down
7 changes: 4 additions & 3 deletions react-responsive-modal/src/useScrollLock.ts
Expand Up @@ -5,20 +5,21 @@ export const useScrollLock = (
refModal: React.RefObject<Element>,
open: boolean,
showPortal: boolean,
blockScroll: boolean
blockScroll: boolean,
reserveScrollBarGap?: boolean
) => {
const oldRef = useRef<Element | null>(null);

useEffect(() => {
if (open && refModal.current && blockScroll) {
oldRef.current = refModal.current;
disableBodyScroll(refModal.current);
disableBodyScroll(refModal.current, { reserveScrollBarGap });
}
return () => {
if (oldRef.current) {
enableBodyScroll(oldRef.current);
oldRef.current = null;
}
};
}, [open, showPortal, refModal]);
}, [open, showPortal, refModal, blockScroll, reserveScrollBarGap]);
};

0 comments on commit 69249f8

Please sign in to comment.