diff --git a/src/view/com/pager/Pager.web.tsx b/src/view/com/pager/Pager.web.tsx index 7ec2926670..f0de811f3b 100644 --- a/src/view/com/pager/Pager.web.tsx +++ b/src/view/com/pager/Pager.web.tsx @@ -20,6 +20,7 @@ export const Pager = React.forwardRef(function PagerImpl( children, tabBarPosition = 'top', initialPage = 0, + headerOnlyHeight = 0, renderTabBar, onPageSelected, onPageSelecting, @@ -27,6 +28,7 @@ export const Pager = React.forwardRef(function PagerImpl( ref, ) { const [selectedPage, setSelectedPage] = React.useState(initialPage) + const scrollYs = React.useRef([]) React.useImperativeHandle(ref, () => ({ setPage: (index: number) => setSelectedPage(index), @@ -34,11 +36,25 @@ export const Pager = React.forwardRef(function PagerImpl( const onTabBarSelect = React.useCallback( (index: number) => { + const scrollY = window.scrollY + scrollYs.current[selectedPage] = scrollY setSelectedPage(index) onPageSelected?.(index) onPageSelecting?.(index) + if (scrollY >= headerOnlyHeight) { + window.scrollTo( + 0, + Math.max(headerOnlyHeight, scrollYs.current[index] ?? 0), + ) + } }, - [setSelectedPage, onPageSelected, onPageSelecting], + [ + selectedPage, + setSelectedPage, + onPageSelected, + onPageSelecting, + headerOnlyHeight, + ], ) return ( diff --git a/src/view/com/pager/PagerWithHeader.web.tsx b/src/view/com/pager/PagerWithHeader.web.tsx index cfdedb2a28..4b63aabe26 100644 --- a/src/view/com/pager/PagerWithHeader.web.tsx +++ b/src/view/com/pager/PagerWithHeader.web.tsx @@ -39,6 +39,17 @@ export const PagerWithHeader = React.forwardRef( ref, ) { const [currentPage, setCurrentPage] = React.useState(0) + const [headerOnlyHeight, setHeaderOnlyHeight] = React.useState(0) + + const onHeaderOnlyLayout = React.useCallback( + (evt: LayoutChangeEvent) => { + const height = evt.nativeEvent.layout.height + if (height > 0) { + setHeaderOnlyHeight(Math.round(height)) + } + }, + [setHeaderOnlyHeight], + ) const renderTabBar = React.useCallback( (props: RenderTabBarFnProps) => { @@ -48,12 +59,20 @@ export const PagerWithHeader = React.forwardRef( renderHeader={renderHeader} currentPage={currentPage} onCurrentPageSelected={onCurrentPageSelected} + onHeaderOnlyLayout={onHeaderOnlyLayout} onSelect={props.onSelect} testID={testID} /> ) }, - [items, renderHeader, currentPage, onCurrentPageSelected, testID], + [ + items, + renderHeader, + currentPage, + onCurrentPageSelected, + onHeaderOnlyLayout, + testID, + ], ) const onPageSelectedInner = React.useCallback( @@ -76,6 +95,7 @@ export const PagerWithHeader = React.forwardRef( onPageSelected={onPageSelectedInner} onPageSelecting={onPageSelecting} renderTabBar={renderTabBar} + headerOnlyHeight={headerOnlyHeight} tabBarPosition="top"> {toArray(children) .filter(Boolean) @@ -97,6 +117,7 @@ let PagerTabBar = ({ testID, renderHeader, onCurrentPageSelected, + onHeaderOnlyLayout, onSelect, }: { currentPage: number @@ -110,7 +131,9 @@ let PagerTabBar = ({ const {isMobile} = useWebMediaQueries() return ( <> - + {renderHeader?.()} (null) const startMode = useSharedValue(null) + useEffect(() => { + if (isWeb) { + return listenToForcedWindowScroll(() => { + startDragOffset.value = null + startMode.value = null + }) + } + }) + const onBeginDrag = useCallback( (e: NativeScrollEvent) => { 'worklet' @@ -95,3 +105,26 @@ export function MainScrollProvider({children}: {children: React.ReactNode}) { ) } + +const emitter = new EventEmitter() + +if (isWeb) { + const originalScroll = window.scroll + window.scroll = function () { + emitter.emit('forced-scroll') + return originalScroll.apply(this, arguments as any) + } + + const originalScrollTo = window.scrollTo + window.scrollTo = function () { + emitter.emit('forced-scroll') + return originalScrollTo.apply(this, arguments as any) + } +} + +function listenToForcedWindowScroll(listener: () => void) { + emitter.addListener('forced-scroll', listener) + return () => { + emitter.removeListener('forced-scroll', listener) + } +}