@react-navigation/core 6.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (327) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +38 -0
  3. package/lib/commonjs/BaseNavigationContainer.js +393 -0
  4. package/lib/commonjs/BaseNavigationContainer.js.map +1 -0
  5. package/lib/commonjs/CurrentRenderContext.js +21 -0
  6. package/lib/commonjs/CurrentRenderContext.js.map +1 -0
  7. package/lib/commonjs/EnsureSingleNavigator.js +53 -0
  8. package/lib/commonjs/EnsureSingleNavigator.js.map +1 -0
  9. package/lib/commonjs/Group.js +15 -0
  10. package/lib/commonjs/Group.js.map +1 -0
  11. package/lib/commonjs/NavigationBuilderContext.js +23 -0
  12. package/lib/commonjs/NavigationBuilderContext.js.map +1 -0
  13. package/lib/commonjs/NavigationContainerRefContext.js +20 -0
  14. package/lib/commonjs/NavigationContainerRefContext.js.map +1 -0
  15. package/lib/commonjs/NavigationContext.js +20 -0
  16. package/lib/commonjs/NavigationContext.js.map +1 -0
  17. package/lib/commonjs/NavigationHelpersContext.js +21 -0
  18. package/lib/commonjs/NavigationHelpersContext.js.map +1 -0
  19. package/lib/commonjs/NavigationRouteContext.js +20 -0
  20. package/lib/commonjs/NavigationRouteContext.js.map +1 -0
  21. package/lib/commonjs/NavigationStateContext.js +42 -0
  22. package/lib/commonjs/NavigationStateContext.js.map +1 -0
  23. package/lib/commonjs/SceneView.js +97 -0
  24. package/lib/commonjs/SceneView.js.map +1 -0
  25. package/lib/commonjs/Screen.js +15 -0
  26. package/lib/commonjs/Screen.js.map +1 -0
  27. package/lib/commonjs/StaticContainer.js +43 -0
  28. package/lib/commonjs/StaticContainer.js.map +1 -0
  29. package/lib/commonjs/UnhandledActionContext.js +17 -0
  30. package/lib/commonjs/UnhandledActionContext.js.map +1 -0
  31. package/lib/commonjs/checkDuplicateRouteNames.js +31 -0
  32. package/lib/commonjs/checkDuplicateRouteNames.js.map +1 -0
  33. package/lib/commonjs/checkSerializable.js +59 -0
  34. package/lib/commonjs/checkSerializable.js.map +1 -0
  35. package/lib/commonjs/createNavigationContainerRef.js +82 -0
  36. package/lib/commonjs/createNavigationContainerRef.js.map +1 -0
  37. package/lib/commonjs/createNavigatorFactory.js +34 -0
  38. package/lib/commonjs/createNavigatorFactory.js.map +1 -0
  39. package/lib/commonjs/findFocusedRoute.js +22 -0
  40. package/lib/commonjs/findFocusedRoute.js.map +1 -0
  41. package/lib/commonjs/fromEntries.js +19 -0
  42. package/lib/commonjs/fromEntries.js.map +1 -0
  43. package/lib/commonjs/getActionFromState.js +99 -0
  44. package/lib/commonjs/getActionFromState.js.map +1 -0
  45. package/lib/commonjs/getFocusedRouteNameFromRoute.js +23 -0
  46. package/lib/commonjs/getFocusedRouteNameFromRoute.js.map +1 -0
  47. package/lib/commonjs/getPathFromState.js +238 -0
  48. package/lib/commonjs/getPathFromState.js.map +1 -0
  49. package/lib/commonjs/getStateFromPath.js +450 -0
  50. package/lib/commonjs/getStateFromPath.js.map +1 -0
  51. package/lib/commonjs/index.js +227 -0
  52. package/lib/commonjs/index.js.map +1 -0
  53. package/lib/commonjs/isArrayEqual.js +15 -0
  54. package/lib/commonjs/isArrayEqual.js.map +1 -0
  55. package/lib/commonjs/types.js +18 -0
  56. package/lib/commonjs/types.js.map +1 -0
  57. package/lib/commonjs/useChildListeners.js +38 -0
  58. package/lib/commonjs/useChildListeners.js.map +1 -0
  59. package/lib/commonjs/useComponent.js +36 -0
  60. package/lib/commonjs/useComponent.js.map +1 -0
  61. package/lib/commonjs/useCurrentRender.js +33 -0
  62. package/lib/commonjs/useCurrentRender.js.map +1 -0
  63. package/lib/commonjs/useDescriptors.js +141 -0
  64. package/lib/commonjs/useDescriptors.js.map +1 -0
  65. package/lib/commonjs/useEventEmitter.js +118 -0
  66. package/lib/commonjs/useEventEmitter.js.map +1 -0
  67. package/lib/commonjs/useFocusEffect.js +97 -0
  68. package/lib/commonjs/useFocusEffect.js.map +1 -0
  69. package/lib/commonjs/useFocusEvents.js +77 -0
  70. package/lib/commonjs/useFocusEvents.js.map +1 -0
  71. package/lib/commonjs/useFocusedListenersChildrenAdapter.js +57 -0
  72. package/lib/commonjs/useFocusedListenersChildrenAdapter.js.map +1 -0
  73. package/lib/commonjs/useIsFocused.js +47 -0
  74. package/lib/commonjs/useIsFocused.js.map +1 -0
  75. package/lib/commonjs/useKeyedChildListeners.js +35 -0
  76. package/lib/commonjs/useKeyedChildListeners.js.map +1 -0
  77. package/lib/commonjs/useNavigation.js +36 -0
  78. package/lib/commonjs/useNavigation.js.map +1 -0
  79. package/lib/commonjs/useNavigationBuilder.js +480 -0
  80. package/lib/commonjs/useNavigationBuilder.js.map +1 -0
  81. package/lib/commonjs/useNavigationCache.js +122 -0
  82. package/lib/commonjs/useNavigationCache.js.map +1 -0
  83. package/lib/commonjs/useNavigationContainerRef.js +27 -0
  84. package/lib/commonjs/useNavigationContainerRef.js.map +1 -0
  85. package/lib/commonjs/useNavigationHelpers.js +77 -0
  86. package/lib/commonjs/useNavigationHelpers.js.map +1 -0
  87. package/lib/commonjs/useNavigationState.js +41 -0
  88. package/lib/commonjs/useNavigationState.js.map +1 -0
  89. package/lib/commonjs/useOnAction.js +118 -0
  90. package/lib/commonjs/useOnAction.js.map +1 -0
  91. package/lib/commonjs/useOnGetState.js +60 -0
  92. package/lib/commonjs/useOnGetState.js.map +1 -0
  93. package/lib/commonjs/useOnPreventRemove.js +89 -0
  94. package/lib/commonjs/useOnPreventRemove.js.map +1 -0
  95. package/lib/commonjs/useOnRouteFocus.js +45 -0
  96. package/lib/commonjs/useOnRouteFocus.js.map +1 -0
  97. package/lib/commonjs/useOptionsGetters.js +99 -0
  98. package/lib/commonjs/useOptionsGetters.js.map +1 -0
  99. package/lib/commonjs/useRegisterNavigator.js +40 -0
  100. package/lib/commonjs/useRegisterNavigator.js.map +1 -0
  101. package/lib/commonjs/useRoute.js +32 -0
  102. package/lib/commonjs/useRoute.js.map +1 -0
  103. package/lib/commonjs/useRouteCache.js +61 -0
  104. package/lib/commonjs/useRouteCache.js.map +1 -0
  105. package/lib/commonjs/useScheduleUpdate.js +44 -0
  106. package/lib/commonjs/useScheduleUpdate.js.map +1 -0
  107. package/lib/commonjs/useSyncState.js +76 -0
  108. package/lib/commonjs/useSyncState.js.map +1 -0
  109. package/lib/commonjs/validatePathConfig.js +31 -0
  110. package/lib/commonjs/validatePathConfig.js.map +1 -0
  111. package/lib/module/BaseNavigationContainer.js +360 -0
  112. package/lib/module/BaseNavigationContainer.js.map +1 -0
  113. package/lib/module/CurrentRenderContext.js +9 -0
  114. package/lib/module/CurrentRenderContext.js.map +1 -0
  115. package/lib/module/EnsureSingleNavigator.js +38 -0
  116. package/lib/module/EnsureSingleNavigator.js.map +1 -0
  117. package/lib/module/Group.js +8 -0
  118. package/lib/module/Group.js.map +1 -0
  119. package/lib/module/NavigationBuilderContext.js +11 -0
  120. package/lib/module/NavigationBuilderContext.js.map +1 -0
  121. package/lib/module/NavigationContainerRefContext.js +8 -0
  122. package/lib/module/NavigationContainerRefContext.js.map +1 -0
  123. package/lib/module/NavigationContext.js +8 -0
  124. package/lib/module/NavigationContext.js.map +1 -0
  125. package/lib/module/NavigationHelpersContext.js +9 -0
  126. package/lib/module/NavigationHelpersContext.js.map +1 -0
  127. package/lib/module/NavigationRouteContext.js +8 -0
  128. package/lib/module/NavigationRouteContext.js.map +1 -0
  129. package/lib/module/NavigationStateContext.js +27 -0
  130. package/lib/module/NavigationStateContext.js.map +1 -0
  131. package/lib/module/SceneView.js +80 -0
  132. package/lib/module/SceneView.js.map +1 -0
  133. package/lib/module/Screen.js +8 -0
  134. package/lib/module/Screen.js.map +1 -0
  135. package/lib/module/StaticContainer.js +30 -0
  136. package/lib/module/StaticContainer.js.map +1 -0
  137. package/lib/module/UnhandledActionContext.js +4 -0
  138. package/lib/module/UnhandledActionContext.js.map +1 -0
  139. package/lib/module/checkDuplicateRouteNames.js +24 -0
  140. package/lib/module/checkDuplicateRouteNames.js.map +1 -0
  141. package/lib/module/checkSerializable.js +52 -0
  142. package/lib/module/checkSerializable.js.map +1 -0
  143. package/lib/module/createNavigationContainerRef.js +71 -0
  144. package/lib/module/createNavigationContainerRef.js.map +1 -0
  145. package/lib/module/createNavigatorFactory.js +24 -0
  146. package/lib/module/createNavigatorFactory.js.map +1 -0
  147. package/lib/module/findFocusedRoute.js +15 -0
  148. package/lib/module/findFocusedRoute.js.map +1 -0
  149. package/lib/module/fromEntries.js +12 -0
  150. package/lib/module/fromEntries.js.map +1 -0
  151. package/lib/module/getActionFromState.js +92 -0
  152. package/lib/module/getActionFromState.js.map +1 -0
  153. package/lib/module/getFocusedRouteNameFromRoute.js +15 -0
  154. package/lib/module/getFocusedRouteNameFromRoute.js.map +1 -0
  155. package/lib/module/getPathFromState.js +223 -0
  156. package/lib/module/getPathFromState.js.map +1 -0
  157. package/lib/module/getStateFromPath.js +434 -0
  158. package/lib/module/getStateFromPath.js.map +1 -0
  159. package/lib/module/index.js +24 -0
  160. package/lib/module/index.js.map +1 -0
  161. package/lib/module/isArrayEqual.js +8 -0
  162. package/lib/module/isArrayEqual.js.map +1 -0
  163. package/lib/module/types.js +9 -0
  164. package/lib/module/types.js.map +1 -0
  165. package/lib/module/useChildListeners.js +27 -0
  166. package/lib/module/useChildListeners.js.map +1 -0
  167. package/lib/module/useComponent.js +24 -0
  168. package/lib/module/useComponent.js.map +1 -0
  169. package/lib/module/useCurrentRender.js +19 -0
  170. package/lib/module/useCurrentRender.js.map +1 -0
  171. package/lib/module/useDescriptors.js +122 -0
  172. package/lib/module/useDescriptors.js.map +1 -0
  173. package/lib/module/useEventEmitter.js +107 -0
  174. package/lib/module/useEventEmitter.js.map +1 -0
  175. package/lib/module/useFocusEffect.js +83 -0
  176. package/lib/module/useFocusEffect.js.map +1 -0
  177. package/lib/module/useFocusEvents.js +63 -0
  178. package/lib/module/useFocusEvents.js.map +1 -0
  179. package/lib/module/useFocusedListenersChildrenAdapter.js +43 -0
  180. package/lib/module/useFocusedListenersChildrenAdapter.js.map +1 -0
  181. package/lib/module/useIsFocused.js +34 -0
  182. package/lib/module/useIsFocused.js.map +1 -0
  183. package/lib/module/useKeyedChildListeners.js +24 -0
  184. package/lib/module/useKeyedChildListeners.js.map +1 -0
  185. package/lib/module/useNavigation.js +21 -0
  186. package/lib/module/useNavigation.js.map +1 -0
  187. package/lib/module/useNavigationBuilder.js +443 -0
  188. package/lib/module/useNavigationBuilder.js.map +1 -0
  189. package/lib/module/useNavigationCache.js +107 -0
  190. package/lib/module/useNavigationCache.js.map +1 -0
  191. package/lib/module/useNavigationContainerRef.js +12 -0
  192. package/lib/module/useNavigationContainerRef.js.map +1 -0
  193. package/lib/module/useNavigationHelpers.js +59 -0
  194. package/lib/module/useNavigationHelpers.js.map +1 -0
  195. package/lib/module/useNavigationState.js +27 -0
  196. package/lib/module/useNavigationState.js.map +1 -0
  197. package/lib/module/useOnAction.js +103 -0
  198. package/lib/module/useOnAction.js.map +1 -0
  199. package/lib/module/useOnGetState.js +43 -0
  200. package/lib/module/useOnGetState.js.map +1 -0
  201. package/lib/module/useOnPreventRemove.js +68 -0
  202. package/lib/module/useOnPreventRemove.js.map +1 -0
  203. package/lib/module/useOnRouteFocus.js +31 -0
  204. package/lib/module/useOnRouteFocus.js.map +1 -0
  205. package/lib/module/useOptionsGetters.js +83 -0
  206. package/lib/module/useOptionsGetters.js.map +1 -0
  207. package/lib/module/useRegisterNavigator.js +27 -0
  208. package/lib/module/useRegisterNavigator.js.map +1 -0
  209. package/lib/module/useRoute.js +18 -0
  210. package/lib/module/useRoute.js.map +1 -0
  211. package/lib/module/useRouteCache.js +47 -0
  212. package/lib/module/useRouteCache.js.map +1 -0
  213. package/lib/module/useScheduleUpdate.js +29 -0
  214. package/lib/module/useScheduleUpdate.js.map +1 -0
  215. package/lib/module/useSyncState.js +64 -0
  216. package/lib/module/useSyncState.js.map +1 -0
  217. package/lib/module/validatePathConfig.js +24 -0
  218. package/lib/module/validatePathConfig.js.map +1 -0
  219. package/lib/typescript/src/BaseNavigationContainer.d.ts +14 -0
  220. package/lib/typescript/src/CurrentRenderContext.d.ts +9 -0
  221. package/lib/typescript/src/EnsureSingleNavigator.d.ts +13 -0
  222. package/lib/typescript/src/Group.d.ts +6 -0
  223. package/lib/typescript/src/NavigationBuilderContext.d.ts +34 -0
  224. package/lib/typescript/src/NavigationContainerRefContext.d.ts +8 -0
  225. package/lib/typescript/src/NavigationContext.d.ts +24 -0
  226. package/lib/typescript/src/NavigationHelpersContext.d.ts +9 -0
  227. package/lib/typescript/src/NavigationRouteContext.d.ts +7 -0
  228. package/lib/typescript/src/NavigationStateContext.d.ts +45 -0
  229. package/lib/typescript/src/SceneView.d.ts +21 -0
  230. package/lib/typescript/src/Screen.d.ts +6 -0
  231. package/lib/typescript/src/StaticContainer.d.ts +7 -0
  232. package/lib/typescript/src/UnhandledActionContext.d.ts +4 -0
  233. package/lib/typescript/src/checkDuplicateRouteNames.d.ts +2 -0
  234. package/lib/typescript/src/checkSerializable.d.ts +9 -0
  235. package/lib/typescript/src/createNavigationContainerRef.d.ts +3 -0
  236. package/lib/typescript/src/createNavigatorFactory.d.ts +11 -0
  237. package/lib/typescript/src/findFocusedRoute.d.ts +22 -0
  238. package/lib/typescript/src/fromEntries.d.ts +1 -0
  239. package/lib/typescript/src/getActionFromState.d.ts +16 -0
  240. package/lib/typescript/src/getFocusedRouteNameFromRoute.d.ts +2 -0
  241. package/lib/typescript/src/getPathFromState.d.ts +38 -0
  242. package/lib/typescript/src/getStateFromPath.d.ts +32 -0
  243. package/lib/typescript/src/index.d.ts +23 -0
  244. package/lib/typescript/src/isArrayEqual.d.ts +5 -0
  245. package/lib/typescript/src/types.d.ts +485 -0
  246. package/lib/typescript/src/useChildListeners.d.ts +11 -0
  247. package/lib/typescript/src/useComponent.d.ts +2 -0
  248. package/lib/typescript/src/useCurrentRender.d.ts +13 -0
  249. package/lib/typescript/src/useDescriptors.d.ts +89 -0
  250. package/lib/typescript/src/useEventEmitter.d.ts +8 -0
  251. package/lib/typescript/src/useFocusEffect.d.ts +10 -0
  252. package/lib/typescript/src/useFocusEvents.d.ts +12 -0
  253. package/lib/typescript/src/useFocusedListenersChildrenAdapter.d.ts +12 -0
  254. package/lib/typescript/src/useIsFocused.d.ts +5 -0
  255. package/lib/typescript/src/useKeyedChildListeners.d.ts +11 -0
  256. package/lib/typescript/src/useNavigation.d.ts +7 -0
  257. package/lib/typescript/src/useNavigationBuilder.d.ts +223 -0
  258. package/lib/typescript/src/useNavigationCache.d.ts +19 -0
  259. package/lib/typescript/src/useNavigationContainerRef.d.ts +2 -0
  260. package/lib/typescript/src/useNavigationHelpers.d.ts +174 -0
  261. package/lib/typescript/src/useNavigationState.d.ts +9 -0
  262. package/lib/typescript/src/useOnAction.d.ts +25 -0
  263. package/lib/typescript/src/useOnGetState.d.ts +8 -0
  264. package/lib/typescript/src/useOnPreventRemove.d.ts +16 -0
  265. package/lib/typescript/src/useOnRouteFocus.d.ts +14 -0
  266. package/lib/typescript/src/useOptionsGetters.d.ts +12 -0
  267. package/lib/typescript/src/useRegisterNavigator.d.ts +5 -0
  268. package/lib/typescript/src/useRoute.d.ts +8 -0
  269. package/lib/typescript/src/useRouteCache.d.ts +13 -0
  270. package/lib/typescript/src/useScheduleUpdate.d.ts +13 -0
  271. package/lib/typescript/src/useSyncState.d.ts +4 -0
  272. package/lib/typescript/src/validatePathConfig.d.ts +1 -0
  273. package/package.json +73 -0
  274. package/src/BaseNavigationContainer.tsx +453 -0
  275. package/src/CurrentRenderContext.tsx +10 -0
  276. package/src/EnsureSingleNavigator.tsx +53 -0
  277. package/src/Group.tsx +14 -0
  278. package/src/NavigationBuilderContext.tsx +70 -0
  279. package/src/NavigationContainerRefContext.tsx +14 -0
  280. package/src/NavigationContext.tsx +12 -0
  281. package/src/NavigationHelpersContext.tsx +13 -0
  282. package/src/NavigationRouteContext.tsx +10 -0
  283. package/src/NavigationStateContext.tsx +39 -0
  284. package/src/SceneView.tsx +134 -0
  285. package/src/Screen.tsx +17 -0
  286. package/src/StaticContainer.tsx +29 -0
  287. package/src/UnhandledActionContext.tsx +9 -0
  288. package/src/checkDuplicateRouteNames.tsx +33 -0
  289. package/src/checkSerializable.tsx +74 -0
  290. package/src/createNavigationContainerRef.tsx +97 -0
  291. package/src/createNavigatorFactory.tsx +40 -0
  292. package/src/findFocusedRoute.tsx +13 -0
  293. package/src/fromEntries.tsx +13 -0
  294. package/src/getActionFromState.tsx +154 -0
  295. package/src/getFocusedRouteNameFromRoute.tsx +28 -0
  296. package/src/getPathFromState.tsx +297 -0
  297. package/src/getStateFromPath.tsx +575 -0
  298. package/src/index.tsx +23 -0
  299. package/src/isArrayEqual.tsx +7 -0
  300. package/src/types.tsx +645 -0
  301. package/src/useChildListeners.tsx +37 -0
  302. package/src/useComponent.tsx +30 -0
  303. package/src/useCurrentRender.tsx +35 -0
  304. package/src/useDescriptors.tsx +229 -0
  305. package/src/useEventEmitter.tsx +130 -0
  306. package/src/useFocusEffect.tsx +112 -0
  307. package/src/useFocusEvents.tsx +73 -0
  308. package/src/useFocusedListenersChildrenAdapter.tsx +47 -0
  309. package/src/useIsFocused.tsx +43 -0
  310. package/src/useKeyedChildListeners.tsx +40 -0
  311. package/src/useNavigation.tsx +26 -0
  312. package/src/useNavigationBuilder.tsx +640 -0
  313. package/src/useNavigationCache.tsx +159 -0
  314. package/src/useNavigationContainerRef.tsx +17 -0
  315. package/src/useNavigationHelpers.tsx +98 -0
  316. package/src/useNavigationState.tsx +41 -0
  317. package/src/useOnAction.tsx +166 -0
  318. package/src/useOnGetState.tsx +47 -0
  319. package/src/useOnPreventRemove.tsx +99 -0
  320. package/src/useOnRouteFocus.tsx +47 -0
  321. package/src/useOptionsGetters.tsx +98 -0
  322. package/src/useRegisterNavigator.tsx +29 -0
  323. package/src/useRoute.tsx +22 -0
  324. package/src/useRouteCache.tsx +55 -0
  325. package/src/useScheduleUpdate.tsx +32 -0
  326. package/src/useSyncState.tsx +74 -0
  327. package/src/validatePathConfig.tsx +32 -0
@@ -0,0 +1,35 @@
1
+ import type { NavigationState, ParamListBase } from '@react-navigation/routers';
2
+ import * as React from 'react';
3
+
4
+ import CurrentRenderContext from './CurrentRenderContext';
5
+ import type {
6
+ Descriptor,
7
+ NavigationHelpers,
8
+ NavigationProp,
9
+ RouteProp,
10
+ } from './types';
11
+
12
+ type Options = {
13
+ state: NavigationState;
14
+ navigation: NavigationHelpers<ParamListBase>;
15
+ descriptors: Record<
16
+ string,
17
+ Descriptor<object, NavigationProp<ParamListBase>, RouteProp<ParamListBase>>
18
+ >;
19
+ };
20
+
21
+ /**
22
+ * Write the current options, so that server renderer can get current values
23
+ * Mutating values like this is not safe in async mode, but it doesn't apply to SSR
24
+ */
25
+ export default function useCurrentRender({
26
+ state,
27
+ navigation,
28
+ descriptors,
29
+ }: Options) {
30
+ const current = React.useContext(CurrentRenderContext);
31
+
32
+ if (current && navigation.isFocused()) {
33
+ current.options = descriptors[state.routes[state.index].key].options;
34
+ }
35
+ }
@@ -0,0 +1,229 @@
1
+ import type {
2
+ NavigationAction,
3
+ NavigationState,
4
+ ParamListBase,
5
+ Router,
6
+ } from '@react-navigation/routers';
7
+ import * as React from 'react';
8
+
9
+ import NavigationBuilderContext, {
10
+ AddKeyedListener,
11
+ AddListener,
12
+ } from './NavigationBuilderContext';
13
+ import NavigationContext from './NavigationContext';
14
+ import NavigationRouteContext from './NavigationRouteContext';
15
+ import SceneView from './SceneView';
16
+ import type {
17
+ Descriptor,
18
+ EventMapBase,
19
+ NavigationHelpers,
20
+ NavigationProp,
21
+ RouteConfig,
22
+ RouteProp,
23
+ } from './types';
24
+ import type { NavigationEventEmitter } from './useEventEmitter';
25
+ import useNavigationCache from './useNavigationCache';
26
+ import useRouteCache from './useRouteCache';
27
+
28
+ export type ScreenConfigWithParent<
29
+ State extends NavigationState,
30
+ ScreenOptions extends {},
31
+ EventMap extends EventMapBase
32
+ > = [
33
+ (ScreenOptionsOrCallback<ScreenOptions> | undefined)[] | undefined,
34
+ RouteConfig<ParamListBase, string, State, ScreenOptions, EventMap>
35
+ ];
36
+
37
+ type ScreenOptionsOrCallback<ScreenOptions extends {}> =
38
+ | ScreenOptions
39
+ | ((props: {
40
+ route: RouteProp<ParamListBase, string>;
41
+ navigation: any;
42
+ }) => ScreenOptions);
43
+
44
+ type Options<
45
+ State extends NavigationState,
46
+ ScreenOptions extends {},
47
+ EventMap extends EventMapBase
48
+ > = {
49
+ state: State;
50
+ screens: Record<
51
+ string,
52
+ ScreenConfigWithParent<State, ScreenOptions, EventMap>
53
+ >;
54
+ navigation: NavigationHelpers<ParamListBase>;
55
+ screenOptions?: ScreenOptionsOrCallback<ScreenOptions>;
56
+ defaultScreenOptions?:
57
+ | ScreenOptions
58
+ | ((props: {
59
+ route: RouteProp<ParamListBase>;
60
+ navigation: any;
61
+ options: ScreenOptions;
62
+ }) => ScreenOptions);
63
+ onAction: (action: NavigationAction) => boolean;
64
+ getState: () => State;
65
+ setState: (state: State) => void;
66
+ addListener: AddListener;
67
+ addKeyedListener: AddKeyedListener;
68
+ onRouteFocus: (key: string) => void;
69
+ router: Router<State, NavigationAction>;
70
+ emitter: NavigationEventEmitter<EventMap>;
71
+ };
72
+
73
+ /**
74
+ * Hook to create descriptor objects for the child routes.
75
+ *
76
+ * A descriptor object provides 3 things:
77
+ * - Helper method to render a screen
78
+ * - Options specified by the screen for the navigator
79
+ * - Navigation object intended for the route
80
+ */
81
+ export default function useDescriptors<
82
+ State extends NavigationState,
83
+ ActionHelpers extends Record<string, () => void>,
84
+ ScreenOptions extends {},
85
+ EventMap extends EventMapBase
86
+ >({
87
+ state,
88
+ screens,
89
+ navigation,
90
+ screenOptions,
91
+ defaultScreenOptions,
92
+ onAction,
93
+ getState,
94
+ setState,
95
+ addListener,
96
+ addKeyedListener,
97
+ onRouteFocus,
98
+ router,
99
+ emitter,
100
+ }: Options<State, ScreenOptions, EventMap>) {
101
+ const [options, setOptions] = React.useState<Record<string, object>>({});
102
+ const { onDispatchAction, onOptionsChange, stackRef } = React.useContext(
103
+ NavigationBuilderContext
104
+ );
105
+
106
+ const context = React.useMemo(
107
+ () => ({
108
+ navigation,
109
+ onAction,
110
+ addListener,
111
+ addKeyedListener,
112
+ onRouteFocus,
113
+ onDispatchAction,
114
+ onOptionsChange,
115
+ stackRef,
116
+ }),
117
+ [
118
+ navigation,
119
+ onAction,
120
+ addListener,
121
+ addKeyedListener,
122
+ onRouteFocus,
123
+ onDispatchAction,
124
+ onOptionsChange,
125
+ stackRef,
126
+ ]
127
+ );
128
+
129
+ const navigations = useNavigationCache<State, ScreenOptions, EventMap>({
130
+ state,
131
+ getState,
132
+ navigation,
133
+ setOptions,
134
+ router,
135
+ emitter,
136
+ });
137
+
138
+ const routes = useRouteCache(state.routes);
139
+
140
+ return routes.reduce<
141
+ Record<
142
+ string,
143
+ Descriptor<
144
+ ScreenOptions,
145
+ NavigationProp<ParamListBase, string, State, ScreenOptions, EventMap> &
146
+ ActionHelpers,
147
+ RouteProp<ParamListBase>
148
+ >
149
+ >
150
+ >((acc, route, i) => {
151
+ const config = screens[route.name];
152
+ const screen = config[1];
153
+ const navigation = navigations[route.key];
154
+
155
+ const optionsList = [
156
+ // The default `screenOptions` passed to the navigator
157
+ screenOptions,
158
+ // The `screenOptions` props passed to `Group` elements
159
+ ...((config[0]
160
+ ? config[0].filter(Boolean)
161
+ : []) as ScreenOptionsOrCallback<ScreenOptions>[]),
162
+ // The `options` prop passed to `Screen` elements,
163
+ screen.options,
164
+ // The options set via `navigation.setOptions`
165
+ options[route.key],
166
+ ];
167
+
168
+ const customOptions = optionsList.reduce<ScreenOptions>(
169
+ (acc, curr) =>
170
+ Object.assign(
171
+ acc,
172
+ typeof curr !== 'function' ? curr : curr({ route, navigation })
173
+ ),
174
+ {} as ScreenOptions
175
+ );
176
+
177
+ const mergedOptions = {
178
+ ...(typeof defaultScreenOptions === 'function'
179
+ ? // @ts-expect-error: ts gives incorrect error here
180
+ defaultScreenOptions({
181
+ route,
182
+ navigation,
183
+ options: customOptions,
184
+ })
185
+ : defaultScreenOptions),
186
+ ...customOptions,
187
+ };
188
+
189
+ const clearOptions = () =>
190
+ setOptions((o) => {
191
+ if (route.key in o) {
192
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
193
+ const { [route.key]: _, ...rest } = o;
194
+ return rest;
195
+ }
196
+
197
+ return o;
198
+ });
199
+
200
+ acc[route.key] = {
201
+ route,
202
+ // @ts-expect-error: it's missing action helpers, fix later
203
+ navigation,
204
+ render() {
205
+ return (
206
+ <NavigationBuilderContext.Provider key={route.key} value={context}>
207
+ <NavigationContext.Provider value={navigation}>
208
+ <NavigationRouteContext.Provider value={route}>
209
+ <SceneView
210
+ navigation={navigation}
211
+ route={route}
212
+ screen={screen}
213
+ routeState={state.routes[i].state}
214
+ getState={getState}
215
+ setState={setState}
216
+ options={mergedOptions}
217
+ clearOptions={clearOptions}
218
+ />
219
+ </NavigationRouteContext.Provider>
220
+ </NavigationContext.Provider>
221
+ </NavigationBuilderContext.Provider>
222
+ );
223
+ },
224
+ options: mergedOptions as ScreenOptions,
225
+ };
226
+
227
+ return acc;
228
+ }, {});
229
+ }
@@ -0,0 +1,130 @@
1
+ import * as React from 'react';
2
+
3
+ import type { EventArg, EventConsumer, EventEmitter } from './types';
4
+
5
+ export type NavigationEventEmitter<T extends Record<string, any>> =
6
+ EventEmitter<T> & {
7
+ create: (target: string) => EventConsumer<T>;
8
+ };
9
+
10
+ type Listeners = ((e: any) => void)[];
11
+
12
+ /**
13
+ * Hook to manage the event system used by the navigator to notify screens of various events.
14
+ */
15
+ export default function useEventEmitter<T extends Record<string, any>>(
16
+ listen?: (e: any) => void
17
+ ): NavigationEventEmitter<T> {
18
+ const listenRef = React.useRef(listen);
19
+
20
+ React.useEffect(() => {
21
+ listenRef.current = listen;
22
+ });
23
+
24
+ const listeners = React.useRef<Record<string, Record<string, Listeners>>>({});
25
+
26
+ const create = React.useCallback((target: string) => {
27
+ const removeListener = (type: string, callback: (data: any) => void) => {
28
+ const callbacks = listeners.current[type]
29
+ ? listeners.current[type][target]
30
+ : undefined;
31
+
32
+ if (!callbacks) {
33
+ return;
34
+ }
35
+
36
+ const index = callbacks.indexOf(callback);
37
+
38
+ callbacks.splice(index, 1);
39
+ };
40
+
41
+ const addListener = (type: string, callback: (data: any) => void) => {
42
+ listeners.current[type] = listeners.current[type] || {};
43
+ listeners.current[type][target] = listeners.current[type][target] || [];
44
+ listeners.current[type][target].push(callback);
45
+
46
+ return () => removeListener(type, callback);
47
+ };
48
+
49
+ return {
50
+ addListener,
51
+ removeListener,
52
+ };
53
+ }, []);
54
+
55
+ const emit = React.useCallback(
56
+ ({
57
+ type,
58
+ data,
59
+ target,
60
+ canPreventDefault,
61
+ }: {
62
+ type: string;
63
+ data?: any;
64
+ target?: string;
65
+ canPreventDefault?: boolean;
66
+ }) => {
67
+ const items = listeners.current[type] || {};
68
+
69
+ // Copy the current list of callbacks in case they are mutated during execution
70
+ const callbacks =
71
+ target !== undefined
72
+ ? items[target]?.slice()
73
+ : ([] as Listeners)
74
+ .concat(...Object.keys(items).map((t) => items[t]))
75
+ .filter((cb, i, self) => self.lastIndexOf(cb) === i);
76
+
77
+ const event: EventArg<any, any, any> = {
78
+ get type() {
79
+ return type;
80
+ },
81
+ };
82
+
83
+ if (target !== undefined) {
84
+ Object.defineProperty(event, 'target', {
85
+ enumerable: true,
86
+ get() {
87
+ return target;
88
+ },
89
+ });
90
+ }
91
+
92
+ if (data !== undefined) {
93
+ Object.defineProperty(event, 'data', {
94
+ enumerable: true,
95
+ get() {
96
+ return data;
97
+ },
98
+ });
99
+ }
100
+
101
+ if (canPreventDefault) {
102
+ let defaultPrevented = false;
103
+
104
+ Object.defineProperties(event, {
105
+ defaultPrevented: {
106
+ enumerable: true,
107
+ get() {
108
+ return defaultPrevented;
109
+ },
110
+ },
111
+ preventDefault: {
112
+ enumerable: true,
113
+ value() {
114
+ defaultPrevented = true;
115
+ },
116
+ },
117
+ });
118
+ }
119
+
120
+ listenRef.current?.(event);
121
+
122
+ callbacks?.forEach((cb) => cb(event));
123
+
124
+ return event as any;
125
+ },
126
+ []
127
+ );
128
+
129
+ return React.useMemo(() => ({ create, emit }), [create, emit]);
130
+ }
@@ -0,0 +1,112 @@
1
+ import * as React from 'react';
2
+
3
+ import useNavigation from './useNavigation';
4
+
5
+ type EffectCallback = () => undefined | void | (() => void);
6
+
7
+ /**
8
+ * Hook to run an effect in a focused screen, similar to `React.useEffect`.
9
+ * This can be used to perform side-effects such as fetching data or subscribing to events.
10
+ * The passed callback should be wrapped in `React.useCallback` to avoid running the effect too often.
11
+ *
12
+ * @param callback Memoized callback containing the effect, should optionally return a cleanup function.
13
+ */
14
+ export default function useFocusEffect(effect: EffectCallback) {
15
+ const navigation = useNavigation();
16
+
17
+ if (arguments[1] !== undefined) {
18
+ const message =
19
+ "You passed a second argument to 'useFocusEffect', but it only accepts one argument. " +
20
+ "If you want to pass a dependency array, you can use 'React.useCallback':\n\n" +
21
+ 'useFocusEffect(\n' +
22
+ ' React.useCallback(() => {\n' +
23
+ ' // Your code here\n' +
24
+ ' }, [depA, depB])\n' +
25
+ ');\n\n' +
26
+ 'See usage guide: https://reactnavigation.org/docs/use-focus-effect';
27
+
28
+ console.error(message);
29
+ }
30
+
31
+ React.useEffect(() => {
32
+ let isFocused = false;
33
+ let cleanup: undefined | void | (() => void);
34
+
35
+ const callback = () => {
36
+ const destroy = effect();
37
+
38
+ if (destroy === undefined || typeof destroy === 'function') {
39
+ return destroy;
40
+ }
41
+
42
+ if (process.env.NODE_ENV !== 'production') {
43
+ let message =
44
+ 'An effect function must not return anything besides a function, which is used for clean-up.';
45
+
46
+ if (destroy === null) {
47
+ message +=
48
+ " You returned 'null'. If your effect does not require clean-up, return 'undefined' (or nothing).";
49
+ } else if (typeof (destroy as any).then === 'function') {
50
+ message +=
51
+ "\n\nIt looks like you wrote 'useFocusEffect(async () => ...)' or returned a Promise. " +
52
+ 'Instead, write the async function inside your effect ' +
53
+ 'and call it immediately:\n\n' +
54
+ 'useFocusEffect(\n' +
55
+ ' React.useCallback() => {\n' +
56
+ ' async function fetchData() {\n' +
57
+ ' // You can await here\n' +
58
+ ' const response = await MyAPI.getData(someId);\n' +
59
+ ' // ...\n' +
60
+ ' }\n\n' +
61
+ ' fetchData();\n' +
62
+ ' }, [someId])\n' +
63
+ ');\n\n' +
64
+ 'See usage guide: https://reactnavigation.org/docs/use-focus-effect';
65
+ } else {
66
+ message += ` You returned '${JSON.stringify(destroy)}'.`;
67
+ }
68
+
69
+ console.error(message);
70
+ }
71
+ };
72
+
73
+ // We need to run the effect on intial render/dep changes if the screen is focused
74
+ if (navigation.isFocused()) {
75
+ cleanup = callback();
76
+ isFocused = true;
77
+ }
78
+
79
+ const unsubscribeFocus = navigation.addListener('focus', () => {
80
+ // If callback was already called for focus, avoid calling it again
81
+ // The focus event may also fire on intial render, so we guard against runing the effect twice
82
+ if (isFocused) {
83
+ return;
84
+ }
85
+
86
+ if (cleanup !== undefined) {
87
+ cleanup();
88
+ }
89
+
90
+ cleanup = callback();
91
+ isFocused = true;
92
+ });
93
+
94
+ const unsubscribeBlur = navigation.addListener('blur', () => {
95
+ if (cleanup !== undefined) {
96
+ cleanup();
97
+ }
98
+
99
+ cleanup = undefined;
100
+ isFocused = false;
101
+ });
102
+
103
+ return () => {
104
+ if (cleanup !== undefined) {
105
+ cleanup();
106
+ }
107
+
108
+ unsubscribeFocus();
109
+ unsubscribeBlur();
110
+ };
111
+ }, [effect, navigation]);
112
+ }
@@ -0,0 +1,73 @@
1
+ import type { NavigationState } from '@react-navigation/routers';
2
+ import * as React from 'react';
3
+
4
+ import NavigationContext from './NavigationContext';
5
+ import type { EventMapCore } from './types';
6
+ import type { NavigationEventEmitter } from './useEventEmitter';
7
+
8
+ type Options<State extends NavigationState> = {
9
+ state: State;
10
+ emitter: NavigationEventEmitter<EventMapCore<State>>;
11
+ };
12
+
13
+ /**
14
+ * Hook to take care of emitting `focus` and `blur` events.
15
+ */
16
+ export default function useFocusEvents<State extends NavigationState>({
17
+ state,
18
+ emitter,
19
+ }: Options<State>) {
20
+ const navigation = React.useContext(NavigationContext);
21
+ const lastFocusedKeyRef = React.useRef<string | undefined>();
22
+
23
+ const currentFocusedKey = state.routes[state.index].key;
24
+
25
+ // When the parent screen changes its focus state, we also need to change child's focus
26
+ // Coz the child screen can't be focused if the parent screen is out of focus
27
+ React.useEffect(
28
+ () =>
29
+ navigation?.addListener('focus', () => {
30
+ lastFocusedKeyRef.current = currentFocusedKey;
31
+ emitter.emit({ type: 'focus', target: currentFocusedKey });
32
+ }),
33
+ [currentFocusedKey, emitter, navigation]
34
+ );
35
+
36
+ React.useEffect(
37
+ () =>
38
+ navigation?.addListener('blur', () => {
39
+ lastFocusedKeyRef.current = undefined;
40
+ emitter.emit({ type: 'blur', target: currentFocusedKey });
41
+ }),
42
+ [currentFocusedKey, emitter, navigation]
43
+ );
44
+
45
+ React.useEffect(() => {
46
+ const lastFocusedKey = lastFocusedKeyRef.current;
47
+
48
+ lastFocusedKeyRef.current = currentFocusedKey;
49
+
50
+ // We wouldn't have `lastFocusedKey` on initial mount
51
+ // Fire focus event for the current route on mount if there's no parent navigator
52
+ if (lastFocusedKey === undefined && !navigation) {
53
+ emitter.emit({ type: 'focus', target: currentFocusedKey });
54
+ }
55
+
56
+ // We should only emit events when the focused key changed and navigator is focused
57
+ // When navigator is not focused, screens inside shouldn't receive focused status either
58
+ if (
59
+ lastFocusedKey === currentFocusedKey ||
60
+ !(navigation ? navigation.isFocused() : true)
61
+ ) {
62
+ return;
63
+ }
64
+
65
+ if (lastFocusedKey === undefined) {
66
+ // Only fire events after initial mount
67
+ return;
68
+ }
69
+
70
+ emitter.emit({ type: 'blur', target: lastFocusedKey });
71
+ emitter.emit({ type: 'focus', target: currentFocusedKey });
72
+ }, [currentFocusedKey, emitter, navigation]);
73
+ }
@@ -0,0 +1,47 @@
1
+ import type { ParamListBase } from '@react-navigation/routers';
2
+ import * as React from 'react';
3
+
4
+ import NavigationBuilderContext, {
5
+ FocusedNavigationCallback,
6
+ FocusedNavigationListener,
7
+ } from './NavigationBuilderContext';
8
+ import type { NavigationHelpers } from './types';
9
+
10
+ type Options = {
11
+ navigation: NavigationHelpers<ParamListBase>;
12
+ focusedListeners: FocusedNavigationListener[];
13
+ };
14
+
15
+ /**
16
+ * Hook for passing focus callback to children
17
+ */
18
+ export default function useFocusedListenersChildrenAdapter({
19
+ navigation,
20
+ focusedListeners,
21
+ }: Options) {
22
+ const { addListener } = React.useContext(NavigationBuilderContext);
23
+
24
+ const listener = React.useCallback(
25
+ (callback: FocusedNavigationCallback<any>) => {
26
+ if (navigation.isFocused()) {
27
+ for (const listener of focusedListeners) {
28
+ const { handled, result } = listener(callback);
29
+
30
+ if (handled) {
31
+ return { handled, result };
32
+ }
33
+ }
34
+
35
+ return { handled: true, result: callback(navigation) };
36
+ } else {
37
+ return { handled: false, result: null };
38
+ }
39
+ },
40
+ [focusedListeners, navigation]
41
+ );
42
+
43
+ React.useEffect(
44
+ () => addListener?.('focus', listener),
45
+ [addListener, listener]
46
+ );
47
+ }
@@ -0,0 +1,43 @@
1
+ import * as React from 'react';
2
+ import { useState } from 'react';
3
+
4
+ import useNavigation from './useNavigation';
5
+
6
+ /**
7
+ * Hook to get the current focus state of the screen. Returns a `true` if screen is focused, otherwise `false`.
8
+ * This can be used if a component needs to render something based on the focus state.
9
+ */
10
+ export default function useIsFocused(): boolean {
11
+ const navigation = useNavigation();
12
+ const [isFocused, setIsFocused] = useState(navigation.isFocused);
13
+
14
+ const valueToReturn = navigation.isFocused();
15
+
16
+ if (isFocused !== valueToReturn) {
17
+ // If the value has changed since the last render, we need to update it.
18
+ // This could happen if we missed an update from the event listeners during re-render.
19
+ // React will process this update immediately, so the old subscription value won't be committed.
20
+ // It is still nice to avoid returning a mismatched value though, so let's override the return value.
21
+ // This is the same logic as in https://github.com/facebook/react/tree/master/packages/use-subscription
22
+ setIsFocused(valueToReturn);
23
+ }
24
+
25
+ React.useEffect(() => {
26
+ const unsubscribeFocus = navigation.addListener('focus', () =>
27
+ setIsFocused(true)
28
+ );
29
+
30
+ const unsubscribeBlur = navigation.addListener('blur', () =>
31
+ setIsFocused(false)
32
+ );
33
+
34
+ return () => {
35
+ unsubscribeFocus();
36
+ unsubscribeBlur();
37
+ };
38
+ }, [navigation]);
39
+
40
+ React.useDebugValue(valueToReturn);
41
+
42
+ return valueToReturn;
43
+ }