From 759625d2a1bef077818d84f10be498863537bdf5 Mon Sep 17 00:00:00 2001 From: "s.esmaeili" Date: Sun, 11 Oct 2026 19:13:37 +0330 Subject: [PATCH] fix: keep search scroll position when opening the product image preview Co-authored-by: Cursor --- .../src/components/product/SingleProduct.vue | 17 ++++++++++++----- .../src/components/product/SingleProduct.vue | 17 ++++++++++++----- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/apps/user-app-v2/src/components/product/SingleProduct.vue b/apps/user-app-v2/src/components/product/SingleProduct.vue index e887a67..b31513a 100644 --- a/apps/user-app-v2/src/components/product/SingleProduct.vue +++ b/apps/user-app-v2/src/components/product/SingleProduct.vue @@ -426,18 +426,25 @@ watch(slides, (list) => { // for the former, so opening the preview needs no drag-jitter bookkeeping here // the way the old inline handlers did. const previewOpen = ref(false) +let lockedBody = false function openPreview() { if (!hasImages.value) return previewOpen.value = true - // The preview is teleported to and would otherwise let the page (or - // the Drawer) scroll behind it. - document.body.style.overflow = 'hidden' + // The preview is teleported to and would otherwise let the page + // scroll behind it. Skipped when ProductMorph already holds : with + // both locked, becomes its own viewport-tall scroller and the page + // underneath loses its scroll position. + if (document.documentElement.style.overflow !== 'hidden') { + document.body.style.overflow = 'hidden' + lockedBody = true + } } function closePreview() { previewOpen.value = false - document.body.style.overflow = '' + if (lockedBody) document.body.style.overflow = '' + lockedBody = false } const wageLabel = computed(() => { @@ -517,7 +524,7 @@ onBeforeMount(async () => { // closed, or the routed page is navigated away from — the body scroll lock it // set would otherwise outlive it and leave the rest of the app unscrollable. onBeforeUnmount(() => { - if (previewOpen.value) document.body.style.overflow = '' + if (lockedBody) document.body.style.overflow = '' }) diff --git a/apps/user-app/src/components/product/SingleProduct.vue b/apps/user-app/src/components/product/SingleProduct.vue index ccd19be..ac3b7a0 100644 --- a/apps/user-app/src/components/product/SingleProduct.vue +++ b/apps/user-app/src/components/product/SingleProduct.vue @@ -416,18 +416,25 @@ watch(selectedVariant, (v) => { // full-screen viewer teleported to , with its own GallerySlider kept in // lockstep via the shared `imageIndex` v-model. const previewOpen = ref(false) +let lockedBody = false function openPreview() { if (!hasImages.value) return previewOpen.value = true - // Teleported to , so without this the page (or the Drawer) would - // still scroll behind the preview. - document.body.style.overflow = 'hidden' + // Teleported to , so without this the page would still scroll behind + // the preview. Skipped when ProductMorph already holds : with both + // locked, becomes its own viewport-tall scroller and the page + // underneath loses its scroll position. + if (document.documentElement.style.overflow !== 'hidden') { + document.body.style.overflow = 'hidden' + lockedBody = true + } } function closePreview() { previewOpen.value = false - document.body.style.overflow = '' + if (lockedBody) document.body.style.overflow = '' + lockedBody = false } const wageLabel = computed(() => { @@ -496,7 +503,7 @@ onBeforeMount(async () => { // closed, or the routed page is navigated away from — the body scroll lock it // set would otherwise outlive it and leave the rest of the app unscrollable. onBeforeUnmount(() => { - if (previewOpen.value) document.body.style.overflow = '' + if (lockedBody) document.body.style.overflow = '' })