Skip to content

Commit

Permalink
Fix issue where ref to hidden product pillow would cause sticky heade…
Browse files Browse the repository at this point in the history
…r to be visible (#4883)

<!--
PR title: GRW-123 / Feature / Awesome new thing
-->

## Describe your changes
Since we hide the product pillow when `isCondensedProductHero` is true, the behaviour became inconsistent when using a ref to check if you had scrolled past the pillow since the height would be 0 of that empty div. 

We can rather simplify it by just checking scroll position in StickyHeader instead.

### Issue:
StickyHeader is visible when user hasn't scrolled
![Screenshot_20241022-091927](https://github.com/user-attachments/assets/d122e0a0-78f9-46e4-8807-f8471da37ed0)

<!--
What changes are made?
If there are many changes, a list might be a good format.
If it makes sense, add screenshots and/or screen recordings here.
-->

## Justify why they are needed

## Checklist before requesting a review

- [ ] I have performed a self-review of my code
  • Loading branch information
gustaveen authored Oct 23, 2024
2 parents 8b96c5f + 2121fd0 commit 6e9c4ed
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@
import clsx from 'clsx'
import type { Variants } from 'framer-motion'
import { AnimatePresence, motion } from 'framer-motion'
import { type ReactNode, useRef } from 'react'
import { type ReactNode } from 'react'
import { Badge, framerTransitions, Heading, sprinkles, Text } from 'ui'
import { Pillow } from '@/components/Pillow/Pillow'
import { useProductData } from '@/components/ProductData/ProductDataProvider'
import { useIsPriceIntentStateReady } from '@/components/ProductPage/PurchaseForm/priceIntentAtoms'
import { useSelectedOffer } from '@/components/ProductPage/PurchaseForm/useSelectedOffer'
import { useHasScrolledPast } from '@/components/ProductPage/ScrollPast/useHasScrolledPast'
import { useFormatter } from '@/utils/useFormatter'
import {
pillow,
Expand All @@ -31,12 +30,10 @@ const ANIMATION: Variants = {
const TRANSITION = { duration: 0.3, ...framerTransitions.easeInOutCubic }

export function ProductHeroV2() {
const ref = useRef(null)
const formatter = useFormatter()
const productData = useProductData()
const [selectedOffer] = useSelectedOffer()
const isReady = useIsPriceIntentStateReady()
const hasScrolledPast = useHasScrolledPast({ targetRef: ref, offset: -100 })
const subType = selectedOffer?.variant.displayNameSubtype

const productHeading = (
Expand Down Expand Up @@ -71,7 +68,7 @@ export function ProductHeroV2() {
return (
<>
{isReady && (
<StickyProductHeader hasScrolledPast={hasScrolledPast}>
<StickyProductHeader>
{
<>
<Pillow size="small" {...productData.pillowImage} priority={true} />
Expand All @@ -81,11 +78,7 @@ export function ProductHeroV2() {
</StickyProductHeader>
)}

{isReady && (
<div ref={ref}>
<ProductHeroPillow subType={subType}>{productHeading}</ProductHeroPillow>
</div>
)}
{isReady && <ProductHeroPillow subType={subType}>{productHeading}</ProductHeroPillow>}
</>
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,29 @@
import clsx from 'clsx'
import { useAtomValue } from 'jotai'
import { useMotionValueEvent, useScroll } from 'framer-motion'
import { useState } from 'react'
import { yStack, xStack } from 'ui'
import { priceCalculatorStepAtom } from '../../priceCalculatorAtoms'
import { ProgressBar } from '../ProgressBar/ProgressBar'
import { useCondensedProductHero } from '../useCondensedProductHero'
import { stickyProductHeader, stickyProductHeaderContent } from './StickyProductHeader.css'

type Props = {
children: React.ReactNode
hasScrolledPast: boolean
}

export function StickyProductHeader({ children, hasScrolledPast }: Props) {
const step = useAtomValue(priceCalculatorStepAtom)
const HERO_TRESHOLD = 250

export function StickyProductHeader({ children }: Props) {
const { scrollY } = useScroll()
const [scrolledPast, setScrolledPast] = useState(false)
const isCondensedProductHero = useCondensedProductHero()
const showStickyHeader = isCondensedProductHero || hasScrolledPast
const showStickyHeader = isCondensedProductHero || scrolledPast

useMotionValueEvent(scrollY, 'change', (latest) => {
setScrolledPast(latest > HERO_TRESHOLD)
})

// Scroll to top when going to next step to avoid sticky header overlap
if (isCondensedProductHero || step === 'calculatingPrice') {
if (isCondensedProductHero) {
window.scrollTo({ top: 0, behavior: 'instant' })
}

Expand Down

0 comments on commit 6e9c4ed

Please sign in to comment.