{"version":3,"names":["getScrollableNode","ref","current","getScrollResponder","getNode","useScrollToTop","navigation","useNavigation","route","useRoute","React","useEffect","getState","type","getParent","unsubscribe","addListener","e","isFocused","isFirst","routes","key","requestAnimationFrame","scrollable","defaultPrevented","scrollToTop","scrollTo","x","y","animated","scrollToOffset","offset","scrollResponderScrollTo"],"sources":["useScrollToTop.tsx"],"sourcesContent":["import { EventArg, useNavigation, useRoute } from '@react-navigation/core';\nimport * as React from 'react';\n\ntype ScrollOptions = { x?: number; y?: number; animated?: boolean };\n\ntype ScrollableView =\n  | { scrollToTop(): void }\n  | { scrollTo(options: ScrollOptions): void }\n  | { scrollToOffset(options: { offset?: number; animated?: boolean }): void }\n  | { scrollResponderScrollTo(options: ScrollOptions): void };\n\ntype ScrollableWrapper =\n  | { getScrollResponder(): React.ReactNode }\n  | { getNode(): ScrollableView }\n  | ScrollableView;\n\nfunction getScrollableNode(ref: React.RefObject<ScrollableWrapper>) {\n  if (ref.current == null) {\n    return null;\n  }\n\n  if (\n    'scrollToTop' in ref.current ||\n    'scrollTo' in ref.current ||\n    'scrollToOffset' in ref.current ||\n    'scrollResponderScrollTo' in ref.current\n  ) {\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}\n\nexport default function useScrollToTop(\n  ref: React.RefObject<ScrollableWrapper>\n) {\n  const navigation = useNavigation();\n  const route = useRoute();\n\n  React.useEffect(() => {\n    let current = navigation;\n\n    // The screen might be inside another navigator such as stack nested in tabs\n    // We need to find the closest tab navigator and add the listener there\n    while (current && current.getState().type !== 'tab') {\n      current = current.getParent();\n    }\n\n    if (!current) {\n      return;\n    }\n\n    const unsubscribe = current.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',\n      (e: EventArg<'tabPress', true>) => {\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 =\n          navigation === current ||\n          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) as ScrollableWrapper;\n\n          if (isFocused && isFirst && scrollable && !e.defaultPrevented) {\n            if ('scrollToTop' in scrollable) {\n              scrollable.scrollToTop();\n            } else if ('scrollTo' in scrollable) {\n              scrollable.scrollTo({ x: 0, y: 0, animated: true });\n            } else if ('scrollToOffset' in scrollable) {\n              scrollable.scrollToOffset({ offset: 0, animated: true });\n            } else if ('scrollResponderScrollTo' in scrollable) {\n              scrollable.scrollResponderScrollTo({ y: 0, animated: true });\n            }\n          }\n        });\n      }\n    );\n\n    return unsubscribe;\n  }, [navigation, ref, route.key]);\n}\n"],"mappings":";;;;;;;AAAA;;AACA;;;;;;AAeA,SAASA,iBAAT,CAA2BC,GAA3B,EAAoE;EAClE,IAAIA,GAAG,CAACC,OAAJ,IAAe,IAAnB,EAAyB;IACvB,OAAO,IAAP;EACD;;EAED,IACE,iBAAiBD,GAAG,CAACC,OAArB,IACA,cAAcD,GAAG,CAACC,OADlB,IAEA,oBAAoBD,GAAG,CAACC,OAFxB,IAGA,6BAA6BD,GAAG,CAACC,OAJnC,EAKE;IACA;IACA,OAAOD,GAAG,CAACC,OAAX;EACD,CARD,MAQO,IAAI,wBAAwBD,GAAG,CAACC,OAAhC,EAAyC;IAC9C;IACA;IACA,OAAOD,GAAG,CAACC,OAAJ,CAAYC,kBAAZ,EAAP;EACD,CAJM,MAIA,IAAI,aAAaF,GAAG,CAACC,OAArB,EAA8B;IACnC;IACA;IACA;IACA;IACA,OAAOD,GAAG,CAACC,OAAJ,CAAYE,OAAZ,EAAP;EACD,CANM,MAMA;IACL,OAAOH,GAAG,CAACC,OAAX;EACD;AACF;;AAEc,SAASG,cAAT,CACbJ,GADa,EAEb;EACA,MAAMK,UAAU,GAAG,IAAAC,mBAAA,GAAnB;EACA,MAAMC,KAAK,GAAG,IAAAC,cAAA,GAAd;EAEAC,KAAK,CAACC,SAAN,CAAgB,MAAM;IACpB,IAAIT,OAAO,GAAGI,UAAd,CADoB,CAGpB;IACA;;IACA,OAAOJ,OAAO,IAAIA,OAAO,CAACU,QAAR,GAAmBC,IAAnB,KAA4B,KAA9C,EAAqD;MACnDX,OAAO,GAAGA,OAAO,CAACY,SAAR,EAAV;IACD;;IAED,IAAI,CAACZ,OAAL,EAAc;MACZ;IACD;;IAED,MAAMa,WAAW,GAAGb,OAAO,CAACc,WAAR,EAClB;IACA;IACA;IACA,UAJkB,EAKjBC,CAAD,IAAmC;MACjC;MACA,MAAMC,SAAS,GAAGZ,UAAU,CAACY,SAAX,EAAlB,CAFiC,CAIjC;MACA;;MACA,MAAMC,OAAO,GACXb,UAAU,KAAKJ,OAAf,IACAI,UAAU,CAACM,QAAX,GAAsBQ,MAAtB,CAA6B,CAA7B,EAAgCC,GAAhC,KAAwCb,KAAK,CAACa,GAFhD,CANiC,CAUjC;MACA;;MACAC,qBAAqB,CAAC,MAAM;QAC1B,MAAMC,UAAU,GAAGvB,iBAAiB,CAACC,GAAD,CAApC;;QAEA,IAAIiB,SAAS,IAAIC,OAAb,IAAwBI,UAAxB,IAAsC,CAACN,CAAC,CAACO,gBAA7C,EAA+D;UAC7D,IAAI,iBAAiBD,UAArB,EAAiC;YAC/BA,UAAU,CAACE,WAAX;UACD,CAFD,MAEO,IAAI,cAAcF,UAAlB,EAA8B;YACnCA,UAAU,CAACG,QAAX,CAAoB;cAAEC,CAAC,EAAE,CAAL;cAAQC,CAAC,EAAE,CAAX;cAAcC,QAAQ,EAAE;YAAxB,CAApB;UACD,CAFM,MAEA,IAAI,oBAAoBN,UAAxB,EAAoC;YACzCA,UAAU,CAACO,cAAX,CAA0B;cAAEC,MAAM,EAAE,CAAV;cAAaF,QAAQ,EAAE;YAAvB,CAA1B;UACD,CAFM,MAEA,IAAI,6BAA6BN,UAAjC,EAA6C;YAClDA,UAAU,CAACS,uBAAX,CAAmC;cAAEJ,CAAC,EAAE,CAAL;cAAQC,QAAQ,EAAE;YAAlB,CAAnC;UACD;QACF;MACF,CAdoB,CAArB;IAeD,CAhCiB,CAApB;IAmCA,OAAOd,WAAP;EACD,CAjDD,EAiDG,CAACT,UAAD,EAAaL,GAAb,EAAkBO,KAAK,CAACa,GAAxB,CAjDH;AAkDD"}