diff --git a/CHANGELOG.md b/CHANGELOG.md index e03758641..0f27062f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [3.127.1] - 2023-10-24 +### changed +- Behavior `scrollToElement` added to Gallery component for PLP. + ### Changed - Bump `vtex.store-resources` version. diff --git a/react/Gallery.tsx b/react/Gallery.tsx index e8ff8c3de..b0b7d1757 100644 --- a/react/Gallery.tsx +++ b/react/Gallery.tsx @@ -1,4 +1,4 @@ -import React, { Fragment } from 'react' +import React, { Fragment, useEffect } from 'react' import { ProductList as ProductListStructuredData } from 'vtex.structured-data' import GalleryLayout from './GalleryLayout' @@ -16,17 +16,58 @@ type GalleryLayoutPropsWithSlots = Omit & Slots const Gallery: React.FC< GalleryLegacyProps | GalleryLayoutPropsWithSlots > = props => { - if ('layouts' in props && props.layouts.length > 0) { - const { - layouts, - lazyItemsRemaining, - products, - showingFacets, - summary, - preferredSKU, - ...slots - } = props as GalleryLayoutPropsWithSlots + const { + layouts, + lazyItemsRemaining, + products, + showingFacets, + summary, + preferredSKU, + ...slots + } = props as GalleryLayoutPropsWithSlots + + useEffect(() => { + const lastClickedProductId = localStorage.getItem('lastClickedProductId') + const isMobile = window.innerWidth <= 768 + + const delayedExecution = setTimeout(() => { + const scrollToElement = (elementId: string, offset: number) => { + const elementToScrollTo = document.getElementById(elementId) + + if (elementToScrollTo) { + const rect = elementToScrollTo.getBoundingClientRect() + const isElementVisible = + rect.top >= 0 && + rect.bottom <= + (window.innerHeight || document.documentElement.clientHeight) + + if (!isElementVisible) { + elementToScrollTo.scrollIntoView({ + behavior: 'auto', + block: 'center', + inline: 'nearest', + }) + setTimeout(() => { + scrollToElement(elementId, offset) + }, 500) + } + } + } + + const recursiveScroll = () => { + if (lastClickedProductId) { + scrollToElement(lastClickedProductId, isMobile ? -200 : -200) + } + } + + recursiveScroll() + }, 1000) + + return () => clearTimeout(delayedExecution) + }, []) + + if ('layouts' in props && props.layouts.length > 0) { return ( diff --git a/react/components/GalleryLayoutItem.tsx b/react/components/GalleryLayoutItem.tsx index 24c2fb47d..5ee7dc45b 100644 --- a/react/components/GalleryLayoutItem.tsx +++ b/react/components/GalleryLayoutItem.tsx @@ -44,6 +44,7 @@ const GalleryLayoutItem: React.FC = ({ position, list: listName, }) + localStorage.setItem('lastClickedProductId', product.productId) }, [ product, push, diff --git a/react/components/GalleryLayoutRow.tsx b/react/components/GalleryLayoutRow.tsx index 9560e3500..d82c1d2b7 100644 --- a/react/components/GalleryLayoutRow.tsx +++ b/react/components/GalleryLayoutRow.tsx @@ -68,6 +68,7 @@ const GalleryLayoutRow: React.FC = ({ ]), 'pa4' )} + id={product.productId} >