@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,134 @@
1
+ import type {
2
+ NavigationState,
3
+ ParamListBase,
4
+ PartialState,
5
+ Route,
6
+ } from '@react-navigation/routers';
7
+ import * as React from 'react';
8
+
9
+ import EnsureSingleNavigator from './EnsureSingleNavigator';
10
+ import NavigationStateContext from './NavigationStateContext';
11
+ import StaticContainer from './StaticContainer';
12
+ import type { NavigationProp, RouteConfigComponent } from './types';
13
+ import useOptionsGetters from './useOptionsGetters';
14
+
15
+ type Props<State extends NavigationState, ScreenOptions extends {}> = {
16
+ screen: RouteConfigComponent<ParamListBase, string> & { name: string };
17
+ navigation: NavigationProp<ParamListBase, string, State, ScreenOptions>;
18
+ route: Route<string>;
19
+ routeState: NavigationState | PartialState<NavigationState> | undefined;
20
+ getState: () => State;
21
+ setState: (state: State) => void;
22
+ options: object;
23
+ clearOptions: () => void;
24
+ };
25
+
26
+ /**
27
+ * Component which takes care of rendering the screen for a route.
28
+ * It provides all required contexts and applies optimizations when applicable.
29
+ */
30
+ export default function SceneView<
31
+ State extends NavigationState,
32
+ ScreenOptions extends {}
33
+ >({
34
+ screen,
35
+ route,
36
+ navigation,
37
+ routeState,
38
+ getState,
39
+ setState,
40
+ options,
41
+ clearOptions,
42
+ }: Props<State, ScreenOptions>) {
43
+ const navigatorKeyRef = React.useRef<string | undefined>();
44
+ const getKey = React.useCallback(() => navigatorKeyRef.current, []);
45
+
46
+ const { addOptionsGetter } = useOptionsGetters({
47
+ key: route.key,
48
+ options,
49
+ navigation,
50
+ });
51
+
52
+ const setKey = React.useCallback((key: string) => {
53
+ navigatorKeyRef.current = key;
54
+ }, []);
55
+
56
+ const getCurrentState = React.useCallback(() => {
57
+ const state = getState();
58
+ const currentRoute = state.routes.find((r) => r.key === route.key);
59
+
60
+ return currentRoute ? currentRoute.state : undefined;
61
+ }, [getState, route.key]);
62
+
63
+ const setCurrentState = React.useCallback(
64
+ (child: NavigationState | PartialState<NavigationState> | undefined) => {
65
+ const state = getState();
66
+
67
+ setState({
68
+ ...state,
69
+ routes: state.routes.map((r) =>
70
+ r.key === route.key ? { ...r, state: child } : r
71
+ ),
72
+ });
73
+ },
74
+ [getState, route.key, setState]
75
+ );
76
+
77
+ const isInitialRef = React.useRef(true);
78
+
79
+ React.useEffect(() => {
80
+ isInitialRef.current = false;
81
+ });
82
+
83
+ // Clear options set by this screen when it is unmounted
84
+ React.useEffect(() => {
85
+ return clearOptions;
86
+ // eslint-disable-next-line react-hooks/exhaustive-deps
87
+ }, []);
88
+
89
+ const getIsInitial = React.useCallback(() => isInitialRef.current, []);
90
+
91
+ const context = React.useMemo(
92
+ () => ({
93
+ state: routeState,
94
+ getState: getCurrentState,
95
+ setState: setCurrentState,
96
+ getKey,
97
+ setKey,
98
+ getIsInitial,
99
+ addOptionsGetter,
100
+ }),
101
+ [
102
+ routeState,
103
+ getCurrentState,
104
+ setCurrentState,
105
+ getKey,
106
+ setKey,
107
+ getIsInitial,
108
+ addOptionsGetter,
109
+ ]
110
+ );
111
+
112
+ const ScreenComponent = screen.getComponent
113
+ ? screen.getComponent()
114
+ : screen.component;
115
+
116
+ return (
117
+ <NavigationStateContext.Provider value={context}>
118
+ <EnsureSingleNavigator>
119
+ <StaticContainer
120
+ name={screen.name}
121
+ render={ScreenComponent || screen.children}
122
+ navigation={navigation}
123
+ route={route}
124
+ >
125
+ {ScreenComponent !== undefined ? (
126
+ <ScreenComponent navigation={navigation} route={route} />
127
+ ) : screen.children !== undefined ? (
128
+ screen.children({ navigation, route })
129
+ ) : null}
130
+ </StaticContainer>
131
+ </EnsureSingleNavigator>
132
+ </NavigationStateContext.Provider>
133
+ );
134
+ }
package/src/Screen.tsx ADDED
@@ -0,0 +1,17 @@
1
+ import type { NavigationState, ParamListBase } from '@react-navigation/routers';
2
+
3
+ import type { EventMapBase, RouteConfig } from './types';
4
+
5
+ /**
6
+ * Empty component used for specifying route configuration.
7
+ */
8
+ export default function Screen<
9
+ ParamList extends ParamListBase,
10
+ RouteName extends keyof ParamList,
11
+ State extends NavigationState,
12
+ ScreenOptions extends {},
13
+ EventMap extends EventMapBase
14
+ >(_: RouteConfig<ParamList, RouteName, State, ScreenOptions, EventMap>) {
15
+ /* istanbul ignore next */
16
+ return null;
17
+ }
@@ -0,0 +1,29 @@
1
+ import * as React from 'react';
2
+
3
+ /**
4
+ * Component which prevents updates for children if no props changed
5
+ */
6
+ function StaticContainer(props: any) {
7
+ return props.children;
8
+ }
9
+
10
+ export default React.memo(StaticContainer, (prevProps: any, nextProps: any) => {
11
+ const prevPropKeys = Object.keys(prevProps);
12
+ const nextPropKeys = Object.keys(nextProps);
13
+
14
+ if (prevPropKeys.length !== nextPropKeys.length) {
15
+ return false;
16
+ }
17
+
18
+ for (const key of prevPropKeys) {
19
+ if (key === 'children') {
20
+ continue;
21
+ }
22
+
23
+ if (prevProps[key] !== nextProps[key]) {
24
+ return false;
25
+ }
26
+ }
27
+
28
+ return true;
29
+ });
@@ -0,0 +1,9 @@
1
+ import type { NavigationAction } from '@react-navigation/routers';
2
+ import * as React from 'react';
3
+
4
+ const UnhandledActionContext =
5
+ React.createContext<((action: NavigationAction) => void) | undefined>(
6
+ undefined
7
+ );
8
+
9
+ export default UnhandledActionContext;
@@ -0,0 +1,33 @@
1
+ import type { NavigationState, PartialState } from '@react-navigation/routers';
2
+
3
+ export default function checkDuplicateRouteNames(state: NavigationState) {
4
+ const duplicates: string[][] = [];
5
+
6
+ const getRouteNames = (
7
+ location: string,
8
+ state: NavigationState | PartialState<NavigationState>
9
+ ) => {
10
+ state.routes.forEach((route: typeof state.routes[0]) => {
11
+ const currentLocation = location
12
+ ? `${location} > ${route.name}`
13
+ : route.name;
14
+
15
+ route.state?.routeNames?.forEach((routeName) => {
16
+ if (routeName === route.name) {
17
+ duplicates.push([
18
+ currentLocation,
19
+ `${currentLocation} > ${route.name}`,
20
+ ]);
21
+ }
22
+ });
23
+
24
+ if (route.state) {
25
+ getRouteNames(currentLocation, route.state);
26
+ }
27
+ });
28
+ };
29
+
30
+ getRouteNames('', state);
31
+
32
+ return duplicates;
33
+ }
@@ -0,0 +1,74 @@
1
+ const checkSerializableWithoutCircularReference = (
2
+ o: { [key: string]: any },
3
+ seen: Set<any>,
4
+ location: (string | number)[]
5
+ ):
6
+ | { serializable: true }
7
+ | {
8
+ serializable: false;
9
+ location: (string | number)[];
10
+ reason: string;
11
+ } => {
12
+ if (
13
+ o === undefined ||
14
+ o === null ||
15
+ typeof o === 'boolean' ||
16
+ typeof o === 'number' ||
17
+ typeof o === 'string'
18
+ ) {
19
+ return { serializable: true };
20
+ }
21
+
22
+ if (
23
+ Object.prototype.toString.call(o) !== '[object Object]' &&
24
+ !Array.isArray(o)
25
+ ) {
26
+ return {
27
+ serializable: false,
28
+ location,
29
+ reason: typeof o === 'function' ? 'Function' : String(o),
30
+ };
31
+ }
32
+
33
+ if (seen.has(o)) {
34
+ return {
35
+ serializable: false,
36
+ reason: 'Circular reference',
37
+ location,
38
+ };
39
+ }
40
+
41
+ seen.add(o);
42
+
43
+ if (Array.isArray(o)) {
44
+ for (let i = 0; i < o.length; i++) {
45
+ const childResult = checkSerializableWithoutCircularReference(
46
+ o[i],
47
+ new Set<any>(seen),
48
+ [...location, i]
49
+ );
50
+
51
+ if (!childResult.serializable) {
52
+ return childResult;
53
+ }
54
+ }
55
+ } else {
56
+ for (const key in o) {
57
+ const childResult = checkSerializableWithoutCircularReference(
58
+ o[key],
59
+ new Set<any>(seen),
60
+ [...location, key]
61
+ );
62
+
63
+ if (!childResult.serializable) {
64
+ return childResult;
65
+ }
66
+ }
67
+ }
68
+
69
+ return { serializable: true };
70
+ };
71
+
72
+ export default function checkSerializable(o: { [key: string]: any }) {
73
+ return checkSerializableWithoutCircularReference(o, new Set<any>(), []);
74
+ }
@@ -0,0 +1,97 @@
1
+ import { CommonActions } from '@react-navigation/routers';
2
+
3
+ import type {
4
+ NavigationContainerEventMap,
5
+ NavigationContainerRef,
6
+ NavigationContainerRefWithCurrent,
7
+ } from './types';
8
+
9
+ export const NOT_INITIALIZED_ERROR =
10
+ "The 'navigation' object hasn't been initialized yet. This might happen if you don't have a navigator mounted, or if the navigator hasn't finished mounting. See https://reactnavigation.org/docs/navigating-without-navigation-prop#handling-initialization for more details.";
11
+
12
+ export default function createNavigationContainerRef<
13
+ ParamList extends {} = ReactNavigation.RootParamList
14
+ >(): NavigationContainerRefWithCurrent<ParamList> {
15
+ const methods = [
16
+ ...Object.keys(CommonActions),
17
+ 'addListener',
18
+ 'removeListener',
19
+ 'resetRoot',
20
+ 'dispatch',
21
+ 'isFocused',
22
+ 'canGoBack',
23
+ 'getRootState',
24
+ 'getState',
25
+ 'getParent',
26
+ 'getCurrentRoute',
27
+ 'getCurrentOptions',
28
+ ] as const;
29
+
30
+ const listeners: Record<string, ((...args: any[]) => void)[]> = {};
31
+
32
+ const removeListener = (
33
+ event: string,
34
+ callback: (...args: any[]) => void
35
+ ) => {
36
+ listeners[event] = listeners[event]?.filter((cb) => cb !== callback);
37
+ };
38
+
39
+ let current: NavigationContainerRef<ParamList> | null = null;
40
+
41
+ const ref: NavigationContainerRefWithCurrent<ParamList> = {
42
+ get current() {
43
+ return current;
44
+ },
45
+ set current(value: NavigationContainerRef<ParamList> | null) {
46
+ current = value;
47
+
48
+ if (value != null) {
49
+ Object.entries(listeners).forEach(([event, callbacks]) => {
50
+ callbacks.forEach((callback) => {
51
+ value.addListener(
52
+ event as keyof NavigationContainerEventMap,
53
+ callback
54
+ );
55
+ });
56
+ });
57
+ }
58
+ },
59
+ isReady: () => {
60
+ if (current == null) {
61
+ return false;
62
+ }
63
+
64
+ return current.isReady();
65
+ },
66
+ ...methods.reduce<any>((acc, name) => {
67
+ acc[name] = (...args: any[]) => {
68
+ if (current == null) {
69
+ switch (name) {
70
+ case 'addListener': {
71
+ const [event, callback] = args;
72
+
73
+ listeners[event] = listeners[event] || [];
74
+ listeners[event].push(callback);
75
+
76
+ return () => removeListener(event, callback);
77
+ }
78
+ case 'removeListener': {
79
+ const [event, callback] = args;
80
+
81
+ removeListener(event, callback);
82
+ break;
83
+ }
84
+ default:
85
+ console.error(NOT_INITIALIZED_ERROR);
86
+ }
87
+ } else {
88
+ // @ts-expect-error: this is ok
89
+ return current[name](...args);
90
+ }
91
+ };
92
+ return acc;
93
+ }, {}),
94
+ };
95
+
96
+ return ref;
97
+ }
@@ -0,0 +1,40 @@
1
+ import type { NavigationState, ParamListBase } from '@react-navigation/routers';
2
+ import type * as React from 'react';
3
+
4
+ import Group from './Group';
5
+ import Screen from './Screen';
6
+ import type { EventMapBase, TypedNavigator } from './types';
7
+
8
+ /**
9
+ * Higher order component to create a `Navigator` and `Screen` pair.
10
+ * Custom navigators should wrap the navigator component in `createNavigator` before exporting.
11
+ *
12
+ * @param Navigator The navigtor component to wrap.
13
+ * @returns Factory method to create a `Navigator` and `Screen` pair.
14
+ */
15
+ export default function createNavigatorFactory<
16
+ State extends NavigationState,
17
+ ScreenOptions extends {},
18
+ EventMap extends EventMapBase,
19
+ NavigatorComponent extends React.ComponentType<any>
20
+ >(Navigator: NavigatorComponent) {
21
+ return function <ParamList extends ParamListBase>(): TypedNavigator<
22
+ ParamList,
23
+ State,
24
+ ScreenOptions,
25
+ EventMap,
26
+ typeof Navigator
27
+ > {
28
+ if (arguments[0] !== undefined) {
29
+ throw new Error(
30
+ "Creating a navigator doesn't take an argument. Maybe you are trying to use React Navigation 4 API? See https://reactnavigation.org/docs/hello-react-navigation for the latest API and guides."
31
+ );
32
+ }
33
+
34
+ return {
35
+ Navigator,
36
+ Group,
37
+ Screen,
38
+ };
39
+ };
40
+ }
@@ -0,0 +1,13 @@
1
+ import type { InitialState } from '@react-navigation/routers';
2
+
3
+ export default function findFocusedRoute(state: InitialState) {
4
+ let current: InitialState | undefined = state;
5
+
6
+ while (current?.routes[current.index ?? 0].state != null) {
7
+ current = current.routes[current.index ?? 0].state;
8
+ }
9
+
10
+ const route = current?.routes[current?.index ?? 0];
11
+
12
+ return route;
13
+ }
@@ -0,0 +1,13 @@
1
+ // Object.fromEntries is not available in older iOS versions
2
+ export default function fromEntries<K extends string, V>(
3
+ entries: (readonly [K, V])[]
4
+ ) {
5
+ return entries.reduce((acc, [k, v]) => {
6
+ if (acc.hasOwnProperty(k)) {
7
+ throw new Error(`A value for key '${k}' already exists in the object.`);
8
+ }
9
+
10
+ acc[k] = v;
11
+ return acc;
12
+ }, {} as Record<K, V>);
13
+ }
@@ -0,0 +1,154 @@
1
+ import type {
2
+ CommonActions,
3
+ NavigationState,
4
+ ParamListBase,
5
+ PartialRoute,
6
+ PartialState,
7
+ Route,
8
+ } from '@react-navigation/routers';
9
+
10
+ import type { NavigatorScreenParams, PathConfig, PathConfigMap } from './types';
11
+
12
+ type ConfigItem = {
13
+ initialRouteName?: string;
14
+ screens?: Record<string, ConfigItem>;
15
+ };
16
+
17
+ type Options = {
18
+ initialRouteName?: string;
19
+ screens: PathConfigMap<object>;
20
+ };
21
+
22
+ type NavigateAction<State extends NavigationState> = {
23
+ type: 'NAVIGATE';
24
+ payload: {
25
+ name: string;
26
+ params?: NavigatorScreenParams<State>;
27
+ path?: string;
28
+ };
29
+ };
30
+
31
+ export default function getActionFromState(
32
+ state: PartialState<NavigationState>,
33
+ options?: Options
34
+ ): NavigateAction<NavigationState> | CommonActions.Action | undefined {
35
+ // Create a normalized configs object which will be easier to use
36
+ const normalizedConfig = options
37
+ ? createNormalizedConfigItem(options as PathConfig<object> | string)
38
+ : {};
39
+
40
+ const routes =
41
+ state.index != null ? state.routes.slice(0, state.index + 1) : state.routes;
42
+
43
+ if (routes.length === 0) {
44
+ return undefined;
45
+ }
46
+
47
+ if (
48
+ !(
49
+ (routes.length === 1 && routes[0].key === undefined) ||
50
+ (routes.length === 2 &&
51
+ routes[0].key === undefined &&
52
+ routes[0].name === normalizedConfig?.initialRouteName &&
53
+ routes[1].key === undefined)
54
+ )
55
+ ) {
56
+ return {
57
+ type: 'RESET',
58
+ payload: state,
59
+ };
60
+ }
61
+
62
+ const route = state.routes[state.index ?? state.routes.length - 1];
63
+
64
+ let current: PartialState<NavigationState> | undefined = route?.state;
65
+ let config: ConfigItem | undefined = normalizedConfig?.screens?.[route?.name];
66
+ let params = { ...route.params } as NavigatorScreenParams<
67
+ ParamListBase,
68
+ NavigationState
69
+ >;
70
+
71
+ let payload = route
72
+ ? { name: route.name, path: route.path, params }
73
+ : undefined;
74
+
75
+ while (current) {
76
+ if (current.routes.length === 0) {
77
+ return undefined;
78
+ }
79
+
80
+ const routes =
81
+ current.index != null
82
+ ? current.routes.slice(0, current.index + 1)
83
+ : current.routes;
84
+
85
+ const route: Route<string> | PartialRoute<Route<string>> =
86
+ routes[routes.length - 1];
87
+
88
+ // Explicitly set to override existing value when merging params
89
+ Object.assign(params, {
90
+ initial: undefined,
91
+ screen: undefined,
92
+ params: undefined,
93
+ state: undefined,
94
+ });
95
+
96
+ if (routes.length === 1 && routes[0].key === undefined) {
97
+ params.initial = true;
98
+ params.screen = route.name;
99
+ } else if (
100
+ routes.length === 2 &&
101
+ routes[0].key === undefined &&
102
+ routes[0].name === config?.initialRouteName &&
103
+ routes[1].key === undefined
104
+ ) {
105
+ params.initial = false;
106
+ params.screen = route.name;
107
+ } else {
108
+ params.state = current;
109
+ break;
110
+ }
111
+
112
+ if (route.state) {
113
+ params.params = { ...route.params };
114
+ params = params.params as NavigatorScreenParams<
115
+ ParamListBase,
116
+ NavigationState
117
+ >;
118
+ } else {
119
+ params.path = route.path;
120
+ params.params = route.params;
121
+ }
122
+
123
+ current = route.state;
124
+ config = config?.screens?.[route.name];
125
+ }
126
+
127
+ if (!payload) {
128
+ return;
129
+ }
130
+
131
+ // Try to construct payload for a `NAVIGATE` action from the state
132
+ // This lets us preserve the navigation state and not lose it
133
+ return {
134
+ type: 'NAVIGATE',
135
+ payload,
136
+ };
137
+ }
138
+
139
+ const createNormalizedConfigItem = (config: PathConfig<object> | string) =>
140
+ typeof config === 'object' && config != null
141
+ ? {
142
+ initialRouteName: config.initialRouteName,
143
+ screens:
144
+ config.screens != null
145
+ ? createNormalizedConfigs(config.screens)
146
+ : undefined,
147
+ }
148
+ : {};
149
+
150
+ const createNormalizedConfigs = (options: PathConfigMap<object>) =>
151
+ Object.entries(options).reduce<Record<string, ConfigItem>>((acc, [k, v]) => {
152
+ acc[k] = createNormalizedConfigItem(v);
153
+ return acc;
154
+ }, {});
@@ -0,0 +1,28 @@
1
+ import type { Route } from '@react-navigation/routers';
2
+
3
+ import { CHILD_STATE } from './useRouteCache';
4
+
5
+ export default function getFocusedRouteNameFromRoute(
6
+ route: Partial<Route<string>>
7
+ ): string | undefined {
8
+ // @ts-expect-error: this isn't in type definitions coz we want this private
9
+ const state = route[CHILD_STATE] ?? route.state;
10
+ const params = route.params as { screen?: unknown } | undefined;
11
+
12
+ const routeName = state
13
+ ? // Get the currently active route name in the nested navigator
14
+ state.routes[
15
+ // If we have a partial state without index, for tab/drawer, first screen will be focused one, and last for stack
16
+ // The type property will only exist for rehydrated state and not for state from deep link
17
+ state.index ??
18
+ (typeof state.type === 'string' && state.type !== 'stack'
19
+ ? 0
20
+ : state.routes.length - 1)
21
+ ].name
22
+ : // If state doesn't exist, we need to default to `screen` param if available
23
+ typeof params?.screen === 'string'
24
+ ? params.screen
25
+ : undefined;
26
+
27
+ return routeName;
28
+ }