@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,98 @@
1
+ import type { ParamListBase } from '@react-navigation/routers';
2
+ import * as React from 'react';
3
+
4
+ import NavigationBuilderContext from './NavigationBuilderContext';
5
+ import NavigationStateContext from './NavigationStateContext';
6
+ import type { NavigationProp } from './types';
7
+
8
+ type Options = {
9
+ key?: string;
10
+ navigation?: NavigationProp<ParamListBase>;
11
+ options?: object | undefined;
12
+ };
13
+
14
+ export default function useOptionsGetters({
15
+ key,
16
+ options,
17
+ navigation,
18
+ }: Options) {
19
+ const optionsRef = React.useRef<object | undefined>(options);
20
+ const optionsGettersFromChildRef = React.useRef<
21
+ Record<string, () => object | undefined | null>
22
+ >({});
23
+
24
+ const { onOptionsChange } = React.useContext(NavigationBuilderContext);
25
+ const { addOptionsGetter: parentAddOptionsGetter } = React.useContext(
26
+ NavigationStateContext
27
+ );
28
+
29
+ const optionsChangeListener = React.useCallback(() => {
30
+ const isFocused = navigation?.isFocused() ?? true;
31
+ const hasChildren = Object.keys(optionsGettersFromChildRef.current).length;
32
+
33
+ if (isFocused && !hasChildren) {
34
+ onOptionsChange(optionsRef.current ?? {});
35
+ }
36
+ }, [navigation, onOptionsChange]);
37
+
38
+ React.useEffect(() => {
39
+ optionsRef.current = options;
40
+ optionsChangeListener();
41
+
42
+ return navigation?.addListener('focus', optionsChangeListener);
43
+ }, [navigation, options, optionsChangeListener]);
44
+
45
+ const getOptionsFromListener = React.useCallback(() => {
46
+ for (let key in optionsGettersFromChildRef.current) {
47
+ if (optionsGettersFromChildRef.current.hasOwnProperty(key)) {
48
+ const result = optionsGettersFromChildRef.current[key]?.();
49
+
50
+ // null means unfocused route
51
+ if (result !== null) {
52
+ return result;
53
+ }
54
+ }
55
+ }
56
+
57
+ return null;
58
+ }, []);
59
+
60
+ const getCurrentOptions = React.useCallback(() => {
61
+ const isFocused = navigation?.isFocused() ?? true;
62
+
63
+ if (!isFocused) {
64
+ return null;
65
+ }
66
+
67
+ const optionsFromListener = getOptionsFromListener();
68
+
69
+ if (optionsFromListener !== null) {
70
+ return optionsFromListener;
71
+ }
72
+
73
+ return optionsRef.current;
74
+ }, [navigation, getOptionsFromListener]);
75
+
76
+ React.useEffect(() => {
77
+ return parentAddOptionsGetter?.(key!, getCurrentOptions);
78
+ }, [getCurrentOptions, parentAddOptionsGetter, key]);
79
+
80
+ const addOptionsGetter = React.useCallback(
81
+ (key: string, getter: () => object | undefined | null) => {
82
+ optionsGettersFromChildRef.current[key] = getter;
83
+ optionsChangeListener();
84
+
85
+ return () => {
86
+ // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
87
+ delete optionsGettersFromChildRef.current[key];
88
+ optionsChangeListener();
89
+ };
90
+ },
91
+ [optionsChangeListener]
92
+ );
93
+
94
+ return {
95
+ addOptionsGetter,
96
+ getCurrentOptions,
97
+ };
98
+ }
@@ -0,0 +1,29 @@
1
+ import { nanoid } from 'nanoid/non-secure';
2
+ import * as React from 'react';
3
+
4
+ import { SingleNavigatorContext } from './EnsureSingleNavigator';
5
+
6
+ /**
7
+ * Register a navigator in the parent context (either a navigation container or a screen).
8
+ * This is used to prevent multiple navigators under a single container or screen.
9
+ */
10
+ export default function useRegisterNavigator() {
11
+ const [key] = React.useState(() => nanoid());
12
+ const container = React.useContext(SingleNavigatorContext);
13
+
14
+ if (container === undefined) {
15
+ throw new Error(
16
+ "Couldn't register the navigator. Have you wrapped your app with 'NavigationContainer'?\n\nThis can also happen if there are multiple copies of '@react-navigation' packages installed."
17
+ );
18
+ }
19
+
20
+ React.useEffect(() => {
21
+ const { register, unregister } = container;
22
+
23
+ register(key);
24
+
25
+ return () => unregister(key);
26
+ }, [container, key]);
27
+
28
+ return key;
29
+ }
@@ -0,0 +1,22 @@
1
+ import type { ParamListBase } from '@react-navigation/routers';
2
+ import * as React from 'react';
3
+
4
+ import NavigationRouteContext from './NavigationRouteContext';
5
+ import type { RouteProp } from './types';
6
+
7
+ /**
8
+ * Hook to access the route prop of the parent screen anywhere.
9
+ *
10
+ * @returns Route prop of the parent screen.
11
+ */
12
+ export default function useRoute<T extends RouteProp<ParamListBase>>(): T {
13
+ const route = React.useContext(NavigationRouteContext);
14
+
15
+ if (route === undefined) {
16
+ throw new Error(
17
+ "Couldn't find a route object. Is your component inside a screen in a navigator?"
18
+ );
19
+ }
20
+
21
+ return route as T;
22
+ }
@@ -0,0 +1,55 @@
1
+ import type {
2
+ NavigationState,
3
+ ParamListBase,
4
+ Route,
5
+ } from '@react-navigation/routers';
6
+ import * as React from 'react';
7
+
8
+ import type { RouteProp } from './types';
9
+
10
+ type RouteCache = Map<Route<string>, RouteProp<ParamListBase>>;
11
+
12
+ /**
13
+ * Utilites such as `getFocusedRouteNameFromRoute` need to access state.
14
+ * So we need a way to suppress the warning for those use cases.
15
+ * This is fine since they are internal utilities and this is not public API.
16
+ */
17
+ export const CHILD_STATE = Symbol('CHILD_STATE');
18
+
19
+ /**
20
+ * Hook to cache route props for each screen in the navigator.
21
+ * This lets add warnings and modifications to the route object but keep references between renders.
22
+ */
23
+ export default function useRouteCache<State extends NavigationState>(
24
+ routes: State['routes']
25
+ ) {
26
+ // Cache object which holds route objects for each screen
27
+ const cache = React.useMemo(() => ({ current: new Map() as RouteCache }), []);
28
+
29
+ if (process.env.NODE_ENV === 'production') {
30
+ // We don't want the overhead of creating extra maps every render in prod
31
+ return routes;
32
+ }
33
+
34
+ cache.current = routes.reduce((acc, route) => {
35
+ const previous = cache.current.get(route);
36
+
37
+ if (previous) {
38
+ // If a cached route object already exists, reuse it
39
+ acc.set(route, previous);
40
+ } else {
41
+ const { state, ...proxy } = route;
42
+
43
+ Object.defineProperty(proxy, CHILD_STATE, {
44
+ enumerable: false,
45
+ value: state,
46
+ });
47
+
48
+ acc.set(route, proxy);
49
+ }
50
+
51
+ return acc;
52
+ }, new Map() as RouteCache);
53
+
54
+ return Array.from(cache.current.values());
55
+ }
@@ -0,0 +1,32 @@
1
+ import * as React from 'react';
2
+
3
+ const MISSING_CONTEXT_ERROR = "Couldn't find a schedule context.";
4
+
5
+ export const ScheduleUpdateContext = React.createContext<{
6
+ scheduleUpdate: (callback: () => void) => void;
7
+ flushUpdates: () => void;
8
+ }>({
9
+ scheduleUpdate() {
10
+ throw new Error(MISSING_CONTEXT_ERROR);
11
+ },
12
+ flushUpdates() {
13
+ throw new Error(MISSING_CONTEXT_ERROR);
14
+ },
15
+ });
16
+
17
+ /**
18
+ * When screen config changes, we want to update the navigator in the same update phase.
19
+ * However, navigation state is in the root component and React won't let us update it from a child.
20
+ * This is a workaround for that, the scheduled update is stored in the ref without actually calling setState.
21
+ * It lets all subsequent updates access the latest state so it stays correct.
22
+ * Then we call setState during after the component updates.
23
+ */
24
+ export default function useScheduleUpdate(callback: () => void) {
25
+ const { scheduleUpdate, flushUpdates } = React.useContext(
26
+ ScheduleUpdateContext
27
+ );
28
+
29
+ scheduleUpdate(callback);
30
+
31
+ React.useEffect(flushUpdates);
32
+ }
@@ -0,0 +1,74 @@
1
+ import * as React from 'react';
2
+
3
+ const UNINTIALIZED_STATE = {};
4
+
5
+ /**
6
+ * This is definitely not compatible with concurrent mode, but we don't have a solution for sync state yet.
7
+ */
8
+ export default function useSyncState<T>(initialState?: (() => T) | T) {
9
+ const stateRef = React.useRef<T>(UNINTIALIZED_STATE as any);
10
+ const isSchedulingRef = React.useRef(false);
11
+ const isMountedRef = React.useRef(true);
12
+
13
+ React.useEffect(() => {
14
+ isMountedRef.current = true;
15
+
16
+ return () => {
17
+ isMountedRef.current = false;
18
+ };
19
+ }, []);
20
+
21
+ if (stateRef.current === UNINTIALIZED_STATE) {
22
+ stateRef.current =
23
+ // @ts-expect-error: initialState is a function, but TypeScript doesn't think so
24
+ typeof initialState === 'function' ? initialState() : initialState;
25
+ }
26
+
27
+ const [trackingState, setTrackingState] = React.useState(stateRef.current);
28
+
29
+ const getState = React.useCallback(() => stateRef.current, []);
30
+
31
+ const setState = React.useCallback((state: T) => {
32
+ if (state === stateRef.current || !isMountedRef.current) {
33
+ return;
34
+ }
35
+
36
+ stateRef.current = state;
37
+
38
+ if (!isSchedulingRef.current) {
39
+ setTrackingState(state);
40
+ }
41
+ }, []);
42
+
43
+ const scheduleUpdate = React.useCallback((callback: () => void) => {
44
+ isSchedulingRef.current = true;
45
+
46
+ try {
47
+ callback();
48
+ } finally {
49
+ isSchedulingRef.current = false;
50
+ }
51
+ }, []);
52
+
53
+ const flushUpdates = React.useCallback(() => {
54
+ if (!isMountedRef.current) {
55
+ return;
56
+ }
57
+
58
+ // Make sure that the tracking state is up-to-date.
59
+ // We call it unconditionally, but React should skip the update if state is unchanged.
60
+ setTrackingState(stateRef.current);
61
+ }, []);
62
+
63
+ // If we're rendering and the tracking state is out of date, update it immediately
64
+ // This will make sure that our updates are applied as early as possible.
65
+ if (trackingState !== stateRef.current) {
66
+ setTrackingState(stateRef.current);
67
+ }
68
+
69
+ const state = stateRef.current;
70
+
71
+ React.useDebugValue(state);
72
+
73
+ return [state, getState, setState, scheduleUpdate, flushUpdates] as const;
74
+ }
@@ -0,0 +1,32 @@
1
+ const formatToList = (items: string[]) =>
2
+ items.map((key) => `- ${key}`).join('\n');
3
+
4
+ export default function validatePathConfig(config: any, root = true) {
5
+ const validKeys = ['initialRouteName', 'screens'];
6
+
7
+ if (!root) {
8
+ validKeys.push('path', 'exact', 'stringify', 'parse');
9
+ }
10
+
11
+ const invalidKeys = Object.keys(config).filter(
12
+ (key) => !validKeys.includes(key)
13
+ );
14
+
15
+ if (invalidKeys.length) {
16
+ throw new Error(
17
+ `Found invalid properties in the configuration:\n${formatToList(
18
+ invalidKeys
19
+ )}\n\nDid you forget to specify them under a 'screens' property?\n\nYou can only specify the following properties:\n${formatToList(
20
+ validKeys
21
+ )}\n\nSee https://reactnavigation.org/docs/configuring-links for more details on how to specify a linking configuration.`
22
+ );
23
+ }
24
+
25
+ if (config.screens) {
26
+ Object.entries(config.screens).forEach(([_, value]) => {
27
+ if (typeof value !== 'string') {
28
+ validatePathConfig(value, false);
29
+ }
30
+ });
31
+ }
32
+ }