From fa27ce833cf046f47c1f214aa6d53efb1bbe866c Mon Sep 17 00:00:00 2001 From: Omar Alshaker Date: Tue, 10 Dec 2024 00:46:55 +0100 Subject: [PATCH] Handle closing --- .../src/components/help-center-content.tsx | 27 ++++++------- .../src/hooks/use-scroll-position.ts | 38 +++++++++---------- 2 files changed, 31 insertions(+), 34 deletions(-) diff --git a/packages/help-center/src/components/help-center-content.tsx b/packages/help-center/src/components/help-center-content.tsx index ba7adf86a7722..dbc74a86278d3 100644 --- a/packages/help-center/src/components/help-center-content.tsx +++ b/packages/help-center/src/components/help-center-content.tsx @@ -71,22 +71,18 @@ const HelpCenterContent: React.FC< { isRelative?: boolean; currentRoute?: string } ); }, [ location, sectionName, isUserEligibleForPaidSupport ] ); - const { currentSupportInteraction, navigateToRoute, isMinimized, isShown } = useSelect( - ( select ) => { - const store = select( HELP_CENTER_STORE ) as HelpCenterSelect; - return { - currentSupportInteraction: store.getCurrentSupportInteraction(), - navigateToRoute: store.getNavigateToRoute(), - isMinimized: store.getIsMinimized(), - isShown: store.isHelpCenterShown(), - }; - }, - [] - ); + const { currentSupportInteraction, navigateToRoute, isMinimized } = useSelect( ( select ) => { + const store = select( HELP_CENTER_STORE ) as HelpCenterSelect; + return { + currentSupportInteraction: store.getCurrentSupportInteraction(), + navigateToRoute: store.getNavigateToRoute(), + isMinimized: store.getIsMinimized(), + }; + }, [] ); const scrollPosition = useArticleScrollPosition( containerRef, - location.pathname.includes( '/post' ) && Boolean( isShown ) + location.pathname + location.search ); useEffect( () => { @@ -118,9 +114,10 @@ const HelpCenterContent: React.FC< { isRelative?: boolean; currentRoute?: string useEffect( () => { if ( containerRef.current && ! location.hash && ! location.pathname.includes( '/odie' ) ) { - if ( location.pathname.includes( '/post' ) && scrollPosition > 0 ) { + const pos = scrollPosition[ location.pathname + location.search ]; + if ( pos ) { containerRef.current.style.scrollBehavior = 'unset'; - containerRef.current.scrollTo( 0, scrollPosition ); + containerRef.current.scrollTo( 0, pos ); containerRef.current.style.scrollBehavior = 'smooth'; } else { containerRef.current.scrollTo( 0, 0 ); diff --git a/packages/help-center/src/hooks/use-scroll-position.ts b/packages/help-center/src/hooks/use-scroll-position.ts index 0741496b3c173..7d280e7dab405 100644 --- a/packages/help-center/src/hooks/use-scroll-position.ts +++ b/packages/help-center/src/hooks/use-scroll-position.ts @@ -3,35 +3,35 @@ import { useEffect, useState } from '@wordpress/element'; /** * Persist the value in memory so when the element is unmounted it doesn't get lost. */ -let cachedScrollPosition = 0; +let cachedScrollPositions: Record< string, number > = {}; /** * Persists the scroll position of an element in memory and returns it. * @param ref the HTML element to track the scroll position of. - * @param enabled to only enable for article pages. + * @param url the pathname of the current route. * @returns the current or last recorded scroll position. */ -export function useArticleScrollPosition( ref: React.RefObject< HTMLElement >, enabled: boolean ) { - const [ scrollPosition, setScrollPosition ] = useState( cachedScrollPosition ); +export function useArticleScrollPosition( ref: React.RefObject< HTMLElement >, url: string ) { + const [ scrollPositions, setScrollPositions ] = useState( cachedScrollPositions ); useEffect( () => { - const element = ref?.current; - - const handleScroll = () => { - if ( element ) { - setScrollPosition( ( cachedScrollPosition = ref.current.scrollTop ) ); + const handleScroll = ( event: { target: EventTarget | null } ) => { + if ( event.target === ref.current ) { + if ( url.startsWith( '/post' ) && event.target && 'scrollTop' in event.target ) { + const positions = { ...cachedScrollPositions }; + positions[ url ] = Number( event.target?.scrollTop ); + setScrollPositions( ( cachedScrollPositions = positions ) ); + } } }; - if ( enabled ) { - element?.addEventListener( 'scroll', handleScroll ); - } else { - // Reset the cached scroll position when the HC is closed or the article page is unmounted. - cachedScrollPosition = 0; + window.addEventListener( 'scroll', handleScroll, true ); + + if ( ! url.startsWith( '/post' ) ) { + setScrollPositions( ( cachedScrollPositions = {} ) ); } - return () => { - element?.removeEventListener( 'scroll', handleScroll ); - }; - }, [ ref, enabled ] ); - return scrollPosition; + return () => window.removeEventListener( 'scroll', handleScroll ); + }, [ ref, url ] ); + + return scrollPositions; }