Fix pager scroll restoration

This commit is contained in:
Dan Abramov
2023-12-22 02:52:23 +00:00
parent 79eadf5141
commit 72d01685b0
3 changed files with 30 additions and 16 deletions
+1 -4
View File
@@ -521,10 +521,7 @@ function RoutesContainer({children}: React.PropsWithChildren<{}>) {
// TODO: Clean up?
navigationRef.current?.addListener('__unsafe_action__', e => {
if (webFocusedScreen) {
webScrollPositions.set(
webFocusedScreen,
Math.round(window.scrollY),
)
webScrollPositions.set(webFocusedScreen, window.scrollY)
}
})
}
+25 -12
View File
@@ -1,4 +1,5 @@
import React from 'react'
import {flushSync} from 'react-dom'
import {View} from 'react-native'
import {s} from 'lib/styles'
@@ -28,6 +29,7 @@ export const Pager = React.forwardRef(function PagerImpl(
) {
const [selectedPage, setSelectedPage] = React.useState(initialPage)
const scrollYs = React.useRef([])
const anchorRef = React.useRef(null)
React.useImperativeHandle(ref, () => ({
setPage: (index: number) => setSelectedPage(index),
@@ -35,18 +37,28 @@ export const Pager = React.forwardRef(function PagerImpl(
const onTabBarSelect = React.useCallback(
(index: number) => {
const scrollY = Math.round(window.scrollY)
scrollYs.current[selectedPage] = scrollY
setSelectedPage(index)
onPageSelected?.(index)
onPageSelecting?.(index)
// if (scrollY >= headerOnlyHeight) {
window.scrollTo(
0,
scrollYs.current[index] ?? 0,
// Math.max(headerOnlyHeight, scrollYs.current[index] ?? 0),
)
// }
const scrollY = window.scrollY
let anchorTop = anchorRef.current
? anchorRef.current.getBoundingClientRect().top
: -scrollY
const isSticking = anchorTop <= 5
if (isSticking) {
scrollYs.current[selectedPage] = window.scrollY
} else {
scrollYs.current[selectedPage] = null
}
flushSync(() => {
setSelectedPage(index)
onPageSelected?.(index)
onPageSelecting?.(index)
})
if (isSticking) {
if (scrollYs.current[index]) {
window.scrollTo(0, scrollYs.current[index])
} else {
window.scrollTo(0, scrollY + anchorTop)
}
}
},
[selectedPage, setSelectedPage, onPageSelected, onPageSelecting],
)
@@ -56,6 +68,7 @@ export const Pager = React.forwardRef(function PagerImpl(
{tabBarPosition === 'top' &&
renderTabBar({
selectedPage,
tabBarAnchor: <View ref={anchorRef} />,
onSelect: onTabBarSelect,
})}
{React.Children.map(children, (child, i) => (
@@ -6,6 +6,7 @@ import {TabBar} from './TabBar'
import {usePalette} from '#/lib/hooks/usePalette'
import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
import {ListMethods} from '../util/List'
import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
export interface PagerWithHeaderChildParams {
headerHeight: number
@@ -49,6 +50,7 @@ export const PagerWithHeader = React.forwardRef<PagerRef, PagerWithHeaderProps>(
currentPage={currentPage}
onCurrentPageSelected={onCurrentPageSelected}
onSelect={props.onSelect}
tabBarAnchor={props.tabBarAnchor}
testID={testID}
/>
)
@@ -98,6 +100,7 @@ let PagerTabBar = ({
renderHeader,
onCurrentPageSelected,
onSelect,
tabBarAnchor,
}: {
currentPage: number
items: string[]
@@ -113,6 +116,7 @@ let PagerTabBar = ({
<View style={[!isMobile && styles.headerContainerDesktop, pal.border]}>
{renderHeader?.()}
</View>
{tabBarAnchor}
<View
style={[
styles.tabBarContainer,