fix: keep search scroll position when opening the product image preview

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
s.esmaeili
2026-10-11 19:14:14 +03:30
co-authored by Cursor
parent c04505fbd8
commit 759625d2a1
2 changed files with 24 additions and 10 deletions
@@ -426,18 +426,25 @@ watch(slides, (list) => {
// for the former, so opening the preview needs no drag-jitter bookkeeping here // for the former, so opening the preview needs no drag-jitter bookkeeping here
// the way the old inline handlers did. // the way the old inline handlers did.
const previewOpen = ref(false) const previewOpen = ref(false)
let lockedBody = false
function openPreview() { function openPreview() {
if (!hasImages.value) return if (!hasImages.value) return
previewOpen.value = true previewOpen.value = true
// The preview is teleported to <body> and would otherwise let the page (or // The preview is teleported to <body> and would otherwise let the page
// the Drawer) scroll behind it. // scroll behind it. Skipped when ProductMorph already holds <html>: with
document.body.style.overflow = 'hidden' // both locked, <body> 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() { function closePreview() {
previewOpen.value = false previewOpen.value = false
document.body.style.overflow = '' if (lockedBody) document.body.style.overflow = ''
lockedBody = false
} }
const wageLabel = computed(() => { const wageLabel = computed(() => {
@@ -517,7 +524,7 @@ onBeforeMount(async () => {
// closed, or the routed page is navigated away from — the body scroll lock it // 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. // set would otherwise outlive it and leave the rest of the app unscrollable.
onBeforeUnmount(() => { onBeforeUnmount(() => {
if (previewOpen.value) document.body.style.overflow = '' if (lockedBody) document.body.style.overflow = ''
}) })
</script> </script>
@@ -416,18 +416,25 @@ watch(selectedVariant, (v) => {
// full-screen viewer teleported to <body>, with its own GallerySlider kept in // full-screen viewer teleported to <body>, with its own GallerySlider kept in
// lockstep via the shared `imageIndex` v-model. // lockstep via the shared `imageIndex` v-model.
const previewOpen = ref(false) const previewOpen = ref(false)
let lockedBody = false
function openPreview() { function openPreview() {
if (!hasImages.value) return if (!hasImages.value) return
previewOpen.value = true previewOpen.value = true
// Teleported to <body>, so without this the page (or the Drawer) would // Teleported to <body>, so without this the page would still scroll behind
// still scroll behind the preview. // the preview. Skipped when ProductMorph already holds <html>: with both
document.body.style.overflow = 'hidden' // locked, <body> 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() { function closePreview() {
previewOpen.value = false previewOpen.value = false
document.body.style.overflow = '' if (lockedBody) document.body.style.overflow = ''
lockedBody = false
} }
const wageLabel = computed(() => { const wageLabel = computed(() => {
@@ -496,7 +503,7 @@ onBeforeMount(async () => {
// closed, or the routed page is navigated away from — the body scroll lock it // 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. // set would otherwise outlive it and leave the rest of the app unscrollable.
onBeforeUnmount(() => { onBeforeUnmount(() => {
if (previewOpen.value) document.body.style.overflow = '' if (lockedBody) document.body.style.overflow = ''
}) })
</script> </script>