import { EventArg , useNavigation , useRoute } from '@react-navigation/core' ; import * as React from 'react' ; type ScrollOptions = { x ? : number ; y ? : number ; animated ? : boolean ; } ; type ScrollableView = { scrollToTop ( ) : void ; } | { scrollTo ( options ) : void ; } | { scrollToOffset ( options ) : void ; } | { scrollResponderScrollTo ( options ) : void ; } ; type ScrollableWrapper = { getScrollResponder ( ) : React . ReactNode ; } | { getNode ( ) : ScrollableView ; } | ScrollableView ; function getScrollableNode ( ref ) { if ( ref . current == null ) { return null ; } if ( 'scrollToTop' in ref . current || 'scrollTo' in ref . current || 'scrollToOffset' in ref . current || 'scrollResponderScrollTo' in ref . current ) { return ref . current ; } else if ( 'getScrollResponder' in ref . current ) { return ref . current . getScrollResponder ( ) ; } else if ( 'getNode' in ref . current ) { return ref . current . getNode ( ) ; } else { return ref . current ; } } export default function useScrollToTop ( ref ) { const navigation = useNavigation ( ) ; const route = useRoute ( ) ; React . useEffect ( ( ) => { let current = navigation ; while ( current && current . getState ( ) . type !== 'tab' ) { current = current . getParent ( ) ; } if ( ! current ) { return ; } const unsubscribe = current . addListener ( 'tabPress' , ( e ) => { const isFocused = navigation . isFocused ( ) ; const isFirst = navigation === current || navigation . getState ( ) . routes [ 0 ] . key === route . key ; requestAnimationFrame ( ( ) => { const scrollable = getScrollableNode ( ref ) as ScrollableWrapper ; if ( isFocused && isFirst && scrollable && ! e . defaultPrevented ) { if ( 'scrollToTop' in scrollable ) { scrollable . scrollToTop ( ) ; } else if ( 'scrollTo' in scrollable ) { scrollable . scrollTo ( { x : 0 , y : 0 , animated : true } ) ; } else if ( 'scrollToOffset' in scrollable ) { scrollable . scrollToOffset ( { offset : 0 , animated : true } ) ; } else if ( 'scrollResponderScrollTo' in scrollable ) { scrollable . scrollResponderScrollTo ( { y : 0 , animated : true } ) ; } } } ) ; } ) ; return unsubscribe ; } , [ navigation , ref , route . key ] ) ; }