{"ast":null,"code":"import { useNavigation, useRoute } from '@react-navigation/core';\nimport * as React from 'react';\nfunction getScrollableNode(ref) {\n  if (ref.current == null) {\n    return null;\n  }\n  if ('scrollToTop' in ref.current || 'scrollTo' in ref.current || 'scrollToOffset' in ref.current || 'scrollResponderScrollTo' in ref.current) {\n    return ref.current;\n  } else if ('getScrollResponder' in ref.current) {\n    return ref.current.getScrollResponder();\n  } else if ('getNode' in ref.current) {\n    return ref.current.getNode();\n  } else {\n    return ref.current;\n  }\n}\nexport default function useScrollToTop(ref) {\n  var navigation = useNavigation();\n  var route = useRoute();\n  React.useEffect(function () {\n    var tabNavigations = [];\n    var currentNavigation = navigation;\n    while (currentNavigation) {\n      if (currentNavigation.getState().type === 'tab') {\n        tabNavigations.push(currentNavigation);\n      }\n      currentNavigation = currentNavigation.getParent();\n    }\n    if (tabNavigations.length === 0) {\n      return;\n    }\n    var unsubscribers = tabNavigations.map(function (tab) {\n      return tab.addListener('tabPress', function (e) {\n        var isFocused = navigation.isFocused();\n        var isFirst = tabNavigations.includes(navigation) || navigation.getState().routes[0].key === route.key;\n        requestAnimationFrame(function () {\n          var scrollable = getScrollableNode(ref);\n          if (isFocused && isFirst && scrollable && !e.defaultPrevented) {\n            if ('scrollToTop' in scrollable) {\n              scrollable.scrollToTop();\n            } else if ('scrollTo' in scrollable) {\n              scrollable.scrollTo({\n                y: 0,\n                animated: true\n              });\n            } else if ('scrollToOffset' in scrollable) {\n              scrollable.scrollToOffset({\n                offset: 0,\n                animated: true\n              });\n            } else if ('scrollResponderScrollTo' in scrollable) {\n              scrollable.scrollResponderScrollTo({\n                y: 0,\n                animated: true\n              });\n            }\n          }\n        });\n      });\n    });\n    return function () {\n      unsubscribers.forEach(function (unsubscribe) {\n        return unsubscribe();\n      });\n    };\n  }, [navigation, ref, route.key]);\n}","map":{"version":3,"sources":["useScrollToTop.tsx"],"names":["useNavigation","useRoute","React","getScrollableNode","ref","current","getScrollResponder","getNode","useScrollToTop","navigation","route","useEffect","tabNavigations","currentNavigation","getState","type","push","getParent","length","unsubscribers","map","tab","addListener","e","isFocused","isFirst","includes","routes","key","requestAnimationFrame","scrollable","defaultPrevented","scrollToTop","scrollTo","y","animated","scrollToOffset","offset","scrollResponderScrollTo","forEach","unsubscribe"],"mappings":"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","sourceRoot":"../../src","sourcesContent":["import { useNavigation, useRoute } from '@react-navigation/core';\nimport * as React from 'react';\nfunction getScrollableNode(ref) {\n  if (ref.current == null) {\n    return null;\n  }\n  if ('scrollToTop' in ref.current || 'scrollTo' in ref.current || 'scrollToOffset' in ref.current || 'scrollResponderScrollTo' in ref.current) {\n    // This is already a scrollable node.\n    return ref.current;\n  } else if ('getScrollResponder' in ref.current) {\n    // If the view is a wrapper like FlatList, SectionList etc.\n    // We need to use `getScrollResponder` to get access to the scroll responder\n    return ref.current.getScrollResponder();\n  } else if ('getNode' in ref.current) {\n    // When a `ScrollView` is wraped in `Animated.createAnimatedComponent`\n    // we need to use `getNode` to get the ref to the actual scrollview.\n    // Note that `getNode` is deprecated in newer versions of react-native\n    // this is why we check if we already have a scrollable node above.\n    return ref.current.getNode();\n  } else {\n    return ref.current;\n  }\n}\nexport default function useScrollToTop(ref) {\n  const navigation = useNavigation();\n  const route = useRoute();\n  React.useEffect(() => {\n    let tabNavigations = [];\n    let currentNavigation = navigation;\n\n    // If the screen is nested inside multiple tab navigators, we should scroll to top for any of them\n    // So we need to find all the parent tab navigators and add the listeners there\n    while (currentNavigation) {\n      if (currentNavigation.getState().type === 'tab') {\n        tabNavigations.push(currentNavigation);\n      }\n      currentNavigation = currentNavigation.getParent();\n    }\n    if (tabNavigations.length === 0) {\n      return;\n    }\n    const unsubscribers = tabNavigations.map(tab => {\n      return tab.addListener(\n      // We don't wanna import tab types here to avoid extra deps\n      // in addition, there are multiple tab implementations\n      // @ts-expect-error\n      'tabPress', e => {\n        // We should scroll to top only when the screen is focused\n        const isFocused = navigation.isFocused();\n\n        // In a nested stack navigator, tab press resets the stack to first screen\n        // So we should scroll to top only when we are on first screen\n        const isFirst = tabNavigations.includes(navigation) || navigation.getState().routes[0].key === route.key;\n\n        // Run the operation in the next frame so we're sure all listeners have been run\n        // This is necessary to know if preventDefault() has been called\n        requestAnimationFrame(() => {\n          const scrollable = getScrollableNode(ref);\n          if (isFocused && isFirst && scrollable && !e.defaultPrevented) {\n            if ('scrollToTop' in scrollable) {\n              scrollable.scrollToTop();\n            } else if ('scrollTo' in scrollable) {\n              scrollable.scrollTo({\n                y: 0,\n                animated: true\n              });\n            } else if ('scrollToOffset' in scrollable) {\n              scrollable.scrollToOffset({\n                offset: 0,\n                animated: true\n              });\n            } else if ('scrollResponderScrollTo' in scrollable) {\n              scrollable.scrollResponderScrollTo({\n                y: 0,\n                animated: true\n              });\n            }\n          }\n        });\n      });\n    });\n    return () => {\n      unsubscribers.forEach(unsubscribe => unsubscribe());\n    };\n  }, [navigation, ref, route.key]);\n}\n//# sourceMappingURL=useScrollToTop.js.map"]},"metadata":{},"sourceType":"module"}