Skip to content

Commit 3a052ad

Browse files
committed
Fixed bug with nested modals and body scrolling
1 parent 6947089 commit 3a052ad

File tree

3 files changed

+32
-17
lines changed

3 files changed

+32
-17
lines changed

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "vue3-side-panel",
3-
"version": "1.1.0",
3+
"version": "1.1.1",
44
"description": "Easy to use and flexible modal sidebar component for Vue3",
55
"main": "dist/vue3-side-panel.js",
66
"module": "dist/vue3-side-panel.esm.js",

src/components/SidePanel.vue

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
<script lang="ts">
2-
import { defineComponent, onBeforeMount, onUnmounted, PropType, watch, ref, computed, onMounted, nextTick } from 'vue';
3-
import { clearAllBodyScrollLocks, disableBodyScroll, enableBodyScroll } from 'body-scroll-lock';
2+
import {
3+
defineComponent,
4+
onBeforeMount,
5+
onBeforeUnmount,
6+
PropType,
7+
watch,
8+
ref,
9+
computed,
10+
onMounted,
11+
nextTick,
12+
} from 'vue';
13+
import { disableBodyScroll, enableBodyScroll } from 'body-scroll-lock';
414
import SidePanelCloseButton from './SidePanelCloseButton.vue';
515
616
export default defineComponent({
@@ -106,6 +116,7 @@ export default defineComponent({
106116
const panelHeight = ref(0);
107117
const windowHeight = ref(0);
108118
const zIndex = ref<number>();
119+
const isBodyAlreadyLocked = ref(false);
109120
110121
const calculateRightSize = async () => {
111122
if (window?.innerHeight > 0) windowHeight.value = window.innerHeight;
@@ -147,9 +158,9 @@ export default defineComponent({
147158
document.body.appendChild(teleportContainer);
148159
});
149160
150-
onUnmounted(() => {
151-
if (props.lockScroll) {
152-
clearAllBodyScrollLocks();
161+
onBeforeUnmount(() => {
162+
if (props.lockScroll && panel.value && props.modelValue) {
163+
enableBodyScroll(panel.value);
153164
lockUnlockHtml(false);
154165
}
155166
if (teleportContainer) document.body.removeChild(teleportContainer);
@@ -165,9 +176,14 @@ export default defineComponent({
165176
166177
watch(
167178
() => [props.modelValue, panel.value],
168-
(p) => {
169-
const [isShown, panelEl] = p as [boolean, HTMLElement | null];
179+
(newP, oldP) => {
180+
const wasShown = oldP ? (oldP[0] as boolean) : false;
181+
const [isShown, panelEl] = newP as [boolean, HTMLElement | null];
182+
const isOpening = isShown;
183+
const isClosing = wasShown && !isShown;
170184
if (!panelEl) return;
185+
if (isOpening) isBodyAlreadyLocked.value = !!document.body.style.overflow;
186+
171187
if (isShown) {
172188
if (props.lockScroll) {
173189
disableBodyScroll(panelEl, { reserveScrollBarGap: true });
@@ -178,14 +194,13 @@ export default defineComponent({
178194
return;
179195
}
180196
181-
if (props.lockScroll) {
182-
setTimeout(() => {
183-
if (!panelEl) return;
184-
enableBodyScroll(panelEl);
185-
lockUnlockHtml(false);
186-
}, props.panelDuration);
187-
}
197+
if (!props.lockScroll || !isClosing || isBodyAlreadyLocked.value) return;
188198
199+
setTimeout(() => {
200+
if (!panelEl) return;
201+
enableBodyScroll(panelEl);
202+
lockUnlockHtml(false);
203+
}, props.panelDuration);
189204
window.removeEventListener('resize', calculateRightSize);
190205
},
191206
{ immediate: true },

0 commit comments

Comments
 (0)