Skip to content

Commit 126ca7b

Browse files
authored
Merge pull request #28 from yuki0410-dev/master
change scroll lock module
2 parents 83faeb3 + 67f3de0 commit 126ca7b

File tree

3 files changed

+78
-36
lines changed

3 files changed

+78
-36
lines changed

package-lock.json

+39-21
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,10 @@
1717
"module": "dist/index.modern.js",
1818
"types": "dist/index.d.ts",
1919
"dependencies": {
20-
"disable-scroll": "^0.6.0"
20+
"body-scroll-lock": "^3.1.5"
2121
},
2222
"devDependencies": {
23+
"@types/body-scroll-lock": "^3.1.0",
2324
"@types/react": "^17.0.16",
2425
"@types/react-dom": "^17.0.9",
2526
"eslint": "^8.22.0",

src/index.tsx

+37-14
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import disableScroll from 'disable-scroll';
2-
import React, { useCallback, useState } from 'react';
1+
import React, { useCallback, useEffect, useRef, useState } from 'react';
32
import { createPortal } from 'react-dom';
3+
import { disableBodyScroll, enableBodyScroll } from 'body-scroll-lock';
44
import { useKeyDown } from './useKeyDown';
55

66
export interface ModalProps {
@@ -9,6 +9,7 @@ export interface ModalProps {
99
close: () => void;
1010
onOverlayClick: React.MouseEventHandler<HTMLDivElement>;
1111
elementId: 'root' | string;
12+
preventScroll?: boolean;
1213
}
1314

1415
export interface ModalOptions {
@@ -59,15 +60,42 @@ const Modal: React.FC<ModalProps> = ({
5960
close,
6061
onOverlayClick,
6162
elementId = 'root',
63+
preventScroll = false,
6264
}) => {
65+
const containerRef = useRef<HTMLDivElement>(null);
6366
const [ref] = useKeyDown<HTMLDivElement>(isOpen, close);
6467

68+
useEffect(() => {
69+
if (containerRef.current === null) {
70+
return;
71+
}
72+
if (isOpen) {
73+
if (preventScroll) {
74+
disableBodyScroll(containerRef.current, {
75+
reserveScrollBarGap: true,
76+
});
77+
}
78+
} else {
79+
if (preventScroll) {
80+
enableBodyScroll(containerRef.current)
81+
}
82+
}
83+
return () => {
84+
if (containerRef.current === null) {
85+
return;
86+
}
87+
if (preventScroll) {
88+
enableBodyScroll(containerRef.current)
89+
}
90+
}
91+
},[containerRef, isOpen, preventScroll]);
92+
6593
if (isOpen === false) {
6694
return null;
6795
}
6896

6997
return createPortal(
70-
<div style={wrapperStyle}>
98+
<div ref={containerRef} style={wrapperStyle}>
7199
<div style={overlayStyle} onClick={onOverlayClick} />
72100
<div ref={ref} role="dialog" aria-modal={isOpen} style={containerStyle} tabIndex={0}>
73101
{children}
@@ -78,23 +106,17 @@ const Modal: React.FC<ModalProps> = ({
78106
};
79107

80108
export const useModal: UseModal = (elementId = 'root', options = {}) => {
81-
const { preventScroll = false, closeOnOverlayClick = true } = options;
109+
const { preventScroll, closeOnOverlayClick = true } = options;
82110
const [isOpen, setOpen] = useState<boolean>(false);
83111

84112
const open = useCallback(() => {
85113
setOpen(true);
86-
if (preventScroll) {
87-
disableScroll.on();
88-
}
89-
}, [setOpen, preventScroll]);
90-
114+
}, [setOpen]);
115+
91116
const close = useCallback(() => {
92117
setOpen(false);
93-
if (preventScroll) {
94-
disableScroll.off();
95-
}
96-
}, [setOpen, preventScroll]);
97-
118+
}, [setOpen]);
119+
98120
const onOverlayClick = useCallback(
99121
(event: React.MouseEvent<HTMLDivElement>) => {
100122
event.stopPropagation();
@@ -113,6 +135,7 @@ export const useModal: UseModal = (elementId = 'root', options = {}) => {
113135
close={close}
114136
onOverlayClick={onOverlayClick}
115137
elementId={elementId}
138+
preventScroll={preventScroll}
116139
>
117140
{children}
118141
</Modal>

0 commit comments

Comments
 (0)