@react-navigation/core 8.0.0-alpha.3 → 8.0.0-alpha.30

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 (283) hide show
  1. package/lib/module/BaseNavigationContainer.js +34 -17
  2. package/lib/module/BaseNavigationContainer.js.map +1 -1
  3. package/lib/module/ConsumedParamsContext.js +5 -0
  4. package/lib/module/ConsumedParamsContext.js.map +1 -0
  5. package/lib/module/DataLoading.js +127 -0
  6. package/lib/module/DataLoading.js.map +1 -0
  7. package/lib/module/NavigationBuilderContext.js +1 -0
  8. package/lib/module/NavigationBuilderContext.js.map +1 -1
  9. package/lib/module/NavigationIndependentTree.js +17 -8
  10. package/lib/module/NavigationIndependentTree.js.map +1 -1
  11. package/lib/module/NavigationProvider.js +22 -11
  12. package/lib/module/NavigationProvider.js.map +1 -1
  13. package/lib/module/NavigationStateContext.js.map +1 -1
  14. package/lib/module/PreventRemoveContext.js.map +1 -1
  15. package/lib/module/PreventRemoveProvider.js +37 -27
  16. package/lib/module/PreventRemoveProvider.js.map +1 -1
  17. package/lib/module/SceneView.js +7 -40
  18. package/lib/module/SceneView.js.map +1 -1
  19. package/lib/module/StaticNavigation.js +179 -50
  20. package/lib/module/StaticNavigation.js.map +1 -1
  21. package/lib/module/StaticTreeContext.js +5 -0
  22. package/lib/module/StaticTreeContext.js.map +1 -0
  23. package/lib/module/checkSerializable.js +18 -13
  24. package/lib/module/checkSerializable.js.map +1 -1
  25. package/lib/module/createNavigationContainerRef.js +6 -8
  26. package/lib/module/createNavigationContainerRef.js.map +1 -1
  27. package/lib/module/createNavigatorFactory.js +27 -5
  28. package/lib/module/createNavigatorFactory.js.map +1 -1
  29. package/lib/module/findFocusedRoute.js +7 -4
  30. package/lib/module/findFocusedRoute.js.map +1 -1
  31. package/lib/module/getActionFromState.js +45 -20
  32. package/lib/module/getActionFromState.js.map +1 -1
  33. package/lib/module/getPathFromState.js +171 -90
  34. package/lib/module/getPathFromState.js.map +1 -1
  35. package/lib/module/getPatternParts.js +20 -4
  36. package/lib/module/getPatternParts.js.map +1 -1
  37. package/lib/module/getStateFromPath.js +485 -214
  38. package/lib/module/getStateFromPath.js.map +1 -1
  39. package/lib/module/getStateFromRouteParams.js +24 -0
  40. package/lib/module/getStateFromRouteParams.js.map +1 -0
  41. package/lib/module/index.js +5 -4
  42. package/lib/module/index.js.map +1 -1
  43. package/lib/module/theming/useTheme.js +1 -1
  44. package/lib/module/theming/useTheme.js.map +1 -1
  45. package/lib/module/types.js +35 -0
  46. package/lib/module/types.js.map +1 -1
  47. package/lib/module/useDescriptors.js +19 -11
  48. package/lib/module/useDescriptors.js.map +1 -1
  49. package/lib/module/useEventEmitter.js +48 -33
  50. package/lib/module/useEventEmitter.js.map +1 -1
  51. package/lib/module/useFocusEvents.js +12 -4
  52. package/lib/module/useFocusEvents.js.map +1 -1
  53. package/lib/module/useFocusedListenersChildrenAdapter.js +2 -2
  54. package/lib/module/useFocusedListenersChildrenAdapter.js.map +1 -1
  55. package/lib/module/useIsFocused.js +7 -12
  56. package/lib/module/useIsFocused.js.map +1 -1
  57. package/lib/module/useKeyedChildListeners.js +4 -2
  58. package/lib/module/useKeyedChildListeners.js.map +1 -1
  59. package/lib/module/useLazyValue.js.map +1 -1
  60. package/lib/module/useNavigation.js +2 -15
  61. package/lib/module/useNavigation.js.map +1 -1
  62. package/lib/module/useNavigationBuilder.js +201 -131
  63. package/lib/module/useNavigationBuilder.js.map +1 -1
  64. package/lib/module/useNavigationCache.js +22 -17
  65. package/lib/module/useNavigationCache.js.map +1 -1
  66. package/lib/module/useNavigationHelpers.js +28 -10
  67. package/lib/module/useNavigationHelpers.js.map +1 -1
  68. package/lib/module/useNavigationIndependentTree.js +1 -1
  69. package/lib/module/useNavigationIndependentTree.js.map +1 -1
  70. package/lib/module/useNavigationState.js +70 -35
  71. package/lib/module/useNavigationState.js.map +1 -1
  72. package/lib/module/useOnAction.js +37 -7
  73. package/lib/module/useOnAction.js.map +1 -1
  74. package/lib/module/useOnGetState.js +6 -3
  75. package/lib/module/useOnGetState.js.map +1 -1
  76. package/lib/module/useOnPreventRemove.js +39 -30
  77. package/lib/module/useOnPreventRemove.js.map +1 -1
  78. package/lib/module/useOnRouteFocus.js +1 -1
  79. package/lib/module/useOnRouteFocus.js.map +1 -1
  80. package/lib/module/useOptionsGetters.js +10 -5
  81. package/lib/module/useOptionsGetters.js.map +1 -1
  82. package/lib/module/usePreventRemove.js +10 -3
  83. package/lib/module/usePreventRemove.js.map +1 -1
  84. package/lib/module/usePreventRemoveContext.js +1 -1
  85. package/lib/module/usePreventRemoveContext.js.map +1 -1
  86. package/lib/module/useRegisterNavigator.js +2 -2
  87. package/lib/module/useRegisterNavigator.js.map +1 -1
  88. package/lib/module/useRoute.js +2 -0
  89. package/lib/module/useRoute.js.map +1 -1
  90. package/lib/module/useRouteCache.js +17 -11
  91. package/lib/module/useRouteCache.js.map +1 -1
  92. package/lib/module/useScheduleUpdate.js +9 -9
  93. package/lib/module/useScheduleUpdate.js.map +1 -1
  94. package/lib/module/useStateForPath.js +1 -1
  95. package/lib/module/useStateForPath.js.map +1 -1
  96. package/lib/module/useSyncState.js +7 -3
  97. package/lib/module/useSyncState.js.map +1 -1
  98. package/lib/module/validatePathConfig.js +50 -36
  99. package/lib/module/validatePathConfig.js.map +1 -1
  100. package/lib/typescript/src/BaseNavigationContainer.d.ts +6 -3
  101. package/lib/typescript/src/BaseNavigationContainer.d.ts.map +1 -1
  102. package/lib/typescript/src/ConsumedParamsContext.d.ts +3 -0
  103. package/lib/typescript/src/ConsumedParamsContext.d.ts.map +1 -0
  104. package/lib/typescript/src/DataLoading.d.ts +21 -0
  105. package/lib/typescript/src/DataLoading.d.ts.map +1 -0
  106. package/lib/typescript/src/EnsureSingleNavigator.d.ts +1 -1
  107. package/lib/typescript/src/EnsureSingleNavigator.d.ts.map +1 -1
  108. package/lib/typescript/src/Group.d.ts +1 -1
  109. package/lib/typescript/src/Group.d.ts.map +1 -1
  110. package/lib/typescript/src/NavigationBuilderContext.d.ts +9 -8
  111. package/lib/typescript/src/NavigationBuilderContext.d.ts.map +1 -1
  112. package/lib/typescript/src/NavigationContainerRefContext.d.ts +1 -1
  113. package/lib/typescript/src/NavigationContainerRefContext.d.ts.map +1 -1
  114. package/lib/typescript/src/NavigationFocusedRouteStateContext.d.ts +4 -4
  115. package/lib/typescript/src/NavigationFocusedRouteStateContext.d.ts.map +1 -1
  116. package/lib/typescript/src/NavigationHelpersContext.d.ts +1 -1
  117. package/lib/typescript/src/NavigationHelpersContext.d.ts.map +1 -1
  118. package/lib/typescript/src/NavigationIndependentTree.d.ts +1 -1
  119. package/lib/typescript/src/NavigationIndependentTree.d.ts.map +1 -1
  120. package/lib/typescript/src/NavigationProvider.d.ts +12 -13
  121. package/lib/typescript/src/NavigationProvider.d.ts.map +1 -1
  122. package/lib/typescript/src/NavigationStateContext.d.ts +3 -3
  123. package/lib/typescript/src/NavigationStateContext.d.ts.map +1 -1
  124. package/lib/typescript/src/PreventRemoveContext.d.ts +1 -0
  125. package/lib/typescript/src/PreventRemoveContext.d.ts.map +1 -1
  126. package/lib/typescript/src/PreventRemoveProvider.d.ts +1 -1
  127. package/lib/typescript/src/PreventRemoveProvider.d.ts.map +1 -1
  128. package/lib/typescript/src/SceneView.d.ts +3 -2
  129. package/lib/typescript/src/SceneView.d.ts.map +1 -1
  130. package/lib/typescript/src/Screen.d.ts +1 -1
  131. package/lib/typescript/src/Screen.d.ts.map +1 -1
  132. package/lib/typescript/src/StaticContainer.d.ts +1 -1
  133. package/lib/typescript/src/StaticContainer.d.ts.map +1 -1
  134. package/lib/typescript/src/StaticNavigation.d.ts +189 -109
  135. package/lib/typescript/src/StaticNavigation.d.ts.map +1 -1
  136. package/lib/typescript/src/StaticTreeContext.d.ts +4 -0
  137. package/lib/typescript/src/StaticTreeContext.d.ts.map +1 -0
  138. package/lib/typescript/src/checkSerializable.d.ts +8 -4
  139. package/lib/typescript/src/checkSerializable.d.ts.map +1 -1
  140. package/lib/typescript/src/createNavigationContainerRef.d.ts +1 -1
  141. package/lib/typescript/src/createNavigationContainerRef.d.ts.map +1 -1
  142. package/lib/typescript/src/createNavigatorFactory.d.ts +23 -5
  143. package/lib/typescript/src/createNavigatorFactory.d.ts.map +1 -1
  144. package/lib/typescript/src/findFocusedRoute.d.ts +3 -3
  145. package/lib/typescript/src/findFocusedRoute.d.ts.map +1 -1
  146. package/lib/typescript/src/getActionFromState.d.ts +4 -4
  147. package/lib/typescript/src/getActionFromState.d.ts.map +1 -1
  148. package/lib/typescript/src/getPathFromState.d.ts +3 -3
  149. package/lib/typescript/src/getPathFromState.d.ts.map +1 -1
  150. package/lib/typescript/src/getPatternParts.d.ts +1 -0
  151. package/lib/typescript/src/getPatternParts.d.ts.map +1 -1
  152. package/lib/typescript/src/getStateFromPath.d.ts +5 -5
  153. package/lib/typescript/src/getStateFromPath.d.ts.map +1 -1
  154. package/lib/typescript/src/getStateFromRouteParams.d.ts +3 -0
  155. package/lib/typescript/src/getStateFromRouteParams.d.ts.map +1 -0
  156. package/lib/typescript/src/index.d.ts +36 -33
  157. package/lib/typescript/src/index.d.ts.map +1 -1
  158. package/lib/typescript/src/theming/ThemeContext.d.ts +1 -1
  159. package/lib/typescript/src/theming/ThemeContext.d.ts.map +1 -1
  160. package/lib/typescript/src/theming/ThemeProvider.d.ts +2 -2
  161. package/lib/typescript/src/theming/ThemeProvider.d.ts.map +1 -1
  162. package/lib/typescript/src/theming/useTheme.d.ts +1 -1
  163. package/lib/typescript/src/theming/useTheme.d.ts.map +1 -1
  164. package/lib/typescript/src/types.d.ts +260 -159
  165. package/lib/typescript/src/types.d.ts.map +1 -1
  166. package/lib/typescript/src/useChildListeners.d.ts +3 -3
  167. package/lib/typescript/src/useChildListeners.d.ts.map +1 -1
  168. package/lib/typescript/src/useComponent.d.ts +1 -1
  169. package/lib/typescript/src/useComponent.d.ts.map +1 -1
  170. package/lib/typescript/src/useDescriptors.d.ts +8 -8
  171. package/lib/typescript/src/useDescriptors.d.ts.map +1 -1
  172. package/lib/typescript/src/useEventEmitter.d.ts +2 -2
  173. package/lib/typescript/src/useEventEmitter.d.ts.map +1 -1
  174. package/lib/typescript/src/useFocusEvents.d.ts +2 -2
  175. package/lib/typescript/src/useFocusEvents.d.ts.map +1 -1
  176. package/lib/typescript/src/useFocusedListenersChildrenAdapter.d.ts +2 -2
  177. package/lib/typescript/src/useFocusedListenersChildrenAdapter.d.ts.map +1 -1
  178. package/lib/typescript/src/useIsFocused.d.ts +3 -0
  179. package/lib/typescript/src/useIsFocused.d.ts.map +1 -1
  180. package/lib/typescript/src/useKeyedChildListeners.d.ts +3 -3
  181. package/lib/typescript/src/useKeyedChildListeners.d.ts.map +1 -1
  182. package/lib/typescript/src/useLazyValue.d.ts.map +1 -1
  183. package/lib/typescript/src/useNavigation.d.ts +4 -2
  184. package/lib/typescript/src/useNavigation.d.ts.map +1 -1
  185. package/lib/typescript/src/useNavigationBuilder.d.ts +23 -30
  186. package/lib/typescript/src/useNavigationBuilder.d.ts.map +1 -1
  187. package/lib/typescript/src/useNavigationCache.d.ts +3 -3
  188. package/lib/typescript/src/useNavigationCache.d.ts.map +1 -1
  189. package/lib/typescript/src/useNavigationContainerRef.d.ts +1 -1
  190. package/lib/typescript/src/useNavigationContainerRef.d.ts.map +1 -1
  191. package/lib/typescript/src/useNavigationHelpers.d.ts +19 -27
  192. package/lib/typescript/src/useNavigationHelpers.d.ts.map +1 -1
  193. package/lib/typescript/src/useNavigationState.d.ts +13 -3
  194. package/lib/typescript/src/useNavigationState.d.ts.map +1 -1
  195. package/lib/typescript/src/useOnAction.d.ts +9 -9
  196. package/lib/typescript/src/useOnAction.d.ts.map +1 -1
  197. package/lib/typescript/src/useOnGetState.d.ts +1 -1
  198. package/lib/typescript/src/useOnGetState.d.ts.map +1 -1
  199. package/lib/typescript/src/useOnPreventRemove.d.ts +5 -9
  200. package/lib/typescript/src/useOnPreventRemove.d.ts.map +1 -1
  201. package/lib/typescript/src/useOnRouteFocus.d.ts +6 -6
  202. package/lib/typescript/src/useOnRouteFocus.d.ts.map +1 -1
  203. package/lib/typescript/src/useOptionsGetters.d.ts +1 -1
  204. package/lib/typescript/src/useOptionsGetters.d.ts.map +1 -1
  205. package/lib/typescript/src/usePreventRemove.d.ts.map +1 -1
  206. package/lib/typescript/src/usePreventRemoveContext.d.ts +2 -1
  207. package/lib/typescript/src/usePreventRemoveContext.d.ts.map +1 -1
  208. package/lib/typescript/src/useRoute.d.ts +7 -3
  209. package/lib/typescript/src/useRoute.d.ts.map +1 -1
  210. package/lib/typescript/src/useRouteCache.d.ts +5 -5
  211. package/lib/typescript/src/useRouteCache.d.ts.map +1 -1
  212. package/lib/typescript/src/useScheduleUpdate.d.ts +5 -4
  213. package/lib/typescript/src/useScheduleUpdate.d.ts.map +1 -1
  214. package/lib/typescript/src/useStateForPath.d.ts +1 -1
  215. package/lib/typescript/src/useStateForPath.d.ts.map +1 -1
  216. package/lib/typescript/src/useSyncState.d.ts.map +1 -1
  217. package/lib/typescript/src/utilities.d.ts +74 -37
  218. package/lib/typescript/src/utilities.d.ts.map +1 -1
  219. package/lib/typescript/src/validatePathConfig.d.ts.map +1 -1
  220. package/package.json +23 -22
  221. package/src/BaseNavigationContainer.tsx +351 -333
  222. package/src/ConsumedParamsContext.tsx +5 -0
  223. package/src/DataLoading.tsx +203 -0
  224. package/src/NavigationBuilderContext.tsx +14 -9
  225. package/src/NavigationFocusedRouteStateContext.tsx +4 -4
  226. package/src/NavigationIndependentTree.tsx +18 -12
  227. package/src/NavigationProvider.tsx +26 -15
  228. package/src/NavigationStateContext.tsx +5 -6
  229. package/src/PreventRemoveContext.tsx +1 -0
  230. package/src/PreventRemoveProvider.tsx +51 -46
  231. package/src/SceneView.tsx +7 -39
  232. package/src/StaticNavigation.tsx +659 -307
  233. package/src/StaticTreeContext.tsx +7 -0
  234. package/src/checkSerializable.tsx +35 -19
  235. package/src/createNavigationContainerRef.tsx +12 -9
  236. package/src/createNavigatorFactory.tsx +92 -8
  237. package/src/findFocusedRoute.tsx +13 -8
  238. package/src/getActionFromState.tsx +86 -51
  239. package/src/getPathFromState.tsx +254 -128
  240. package/src/getPatternParts.tsx +25 -4
  241. package/src/getStateFromPath.tsx +811 -309
  242. package/src/getStateFromRouteParams.tsx +60 -0
  243. package/src/index.tsx +55 -5
  244. package/src/theming/useTheme.tsx +1 -1
  245. package/src/types.tsx +798 -373
  246. package/src/useDescriptors.tsx +28 -14
  247. package/src/useEventEmitter.tsx +52 -38
  248. package/src/useFocusEvents.tsx +15 -7
  249. package/src/useFocusedListenersChildrenAdapter.tsx +2 -2
  250. package/src/useIsFocused.tsx +14 -21
  251. package/src/useKeyedChildListeners.tsx +4 -2
  252. package/src/useLazyValue.tsx +2 -2
  253. package/src/useNavigation.tsx +7 -24
  254. package/src/useNavigationBuilder.tsx +311 -186
  255. package/src/useNavigationCache.tsx +32 -25
  256. package/src/useNavigationHelpers.tsx +27 -10
  257. package/src/useNavigationIndependentTree.tsx +1 -1
  258. package/src/useNavigationState.tsx +93 -59
  259. package/src/useOnAction.tsx +61 -13
  260. package/src/useOnGetState.tsx +5 -3
  261. package/src/useOnPreventRemove.tsx +75 -42
  262. package/src/useOnRouteFocus.tsx +10 -12
  263. package/src/useOptionsGetters.tsx +11 -5
  264. package/src/usePreventRemove.tsx +12 -3
  265. package/src/usePreventRemoveContext.tsx +1 -1
  266. package/src/useRegisterNavigator.tsx +2 -2
  267. package/src/useRoute.tsx +20 -6
  268. package/src/useRouteCache.tsx +22 -16
  269. package/src/useScheduleUpdate.tsx +9 -10
  270. package/src/useStateForPath.tsx +1 -1
  271. package/src/useSyncState.tsx +8 -3
  272. package/src/utilities.tsx +144 -31
  273. package/src/validatePathConfig.tsx +86 -57
  274. package/lib/module/CurrentRenderContext.js +0 -10
  275. package/lib/module/CurrentRenderContext.js.map +0 -1
  276. package/lib/module/useCurrentRender.js +0 -19
  277. package/lib/module/useCurrentRender.js.map +0 -1
  278. package/lib/typescript/src/CurrentRenderContext.d.ts +0 -9
  279. package/lib/typescript/src/CurrentRenderContext.d.ts.map +0 -1
  280. package/lib/typescript/src/useCurrentRender.d.ts +0 -14
  281. package/lib/typescript/src/useCurrentRender.d.ts.map +0 -1
  282. package/src/CurrentRenderContext.tsx +0 -9
  283. package/src/useCurrentRender.tsx +0 -31
@@ -113,10 +113,10 @@ export function useDescriptors<
113
113
  router,
114
114
  emitter,
115
115
  }: Options<State, ScreenOptions, EventMap>) {
116
- const theme = React.useContext(ThemeContext);
117
- const [options, setOptions] = React.useState<Record<string, ScreenOptions>>(
118
- {}
119
- );
116
+ const theme = React.use(ThemeContext);
117
+ const [options, setOptions] = React.useState<
118
+ Record<string, Partial<ScreenOptions> | undefined>
119
+ >({});
120
120
  const {
121
121
  onDispatchAction,
122
122
  onEmitEvent,
@@ -124,7 +124,8 @@ export function useDescriptors<
124
124
  scheduleUpdate,
125
125
  flushUpdates,
126
126
  stackRef,
127
- } = React.useContext(NavigationBuilderContext);
127
+ getIsStateEmitted,
128
+ } = React.use(NavigationBuilderContext);
128
129
 
129
130
  const context = React.useMemo(
130
131
  () => ({
@@ -136,6 +137,7 @@ export function useDescriptors<
136
137
  onDispatchAction,
137
138
  onEmitEvent,
138
139
  onOptionsChange,
140
+ getIsStateEmitted,
139
141
  scheduleUpdate,
140
142
  flushUpdates,
141
143
  stackRef,
@@ -149,6 +151,7 @@ export function useDescriptors<
149
151
  onDispatchAction,
150
152
  onEmitEvent,
151
153
  onOptionsChange,
154
+ getIsStateEmitted,
152
155
  scheduleUpdate,
153
156
  flushUpdates,
154
157
  stackRef,
@@ -180,20 +183,20 @@ export function useDescriptors<
180
183
  ScreenOptions,
181
184
  EventMap
182
185
  >,
183
- overrides: Record<string, ScreenOptions>
186
+ overrides: Partial<ScreenOptions> | undefined
184
187
  ) => {
185
188
  const config = screens[route.name];
186
- const screen = config.props;
189
+ const screen = config?.props;
187
190
 
188
191
  const optionsList = [
189
192
  // The default `screenOptions` passed to the navigator
190
193
  screenOptions,
191
194
  // The `screenOptions` props passed to `Group` elements
192
- ...((config.options
195
+ ...((config?.options
193
196
  ? config.options.filter(Boolean)
194
197
  : []) as ScreenOptionsOrCallback<ScreenOptions>[]),
195
198
  // The `options` prop passed to `Screen` elements,
196
- screen.options,
199
+ screen?.options,
197
200
  // The options set via `navigation.setOptions`
198
201
  overrides,
199
202
  ];
@@ -222,12 +225,15 @@ export function useDescriptors<
222
225
  routeState: NavigationState | PartialState<NavigationState> | undefined
223
226
  ) => {
224
227
  const config = screens[route.name];
225
- const screen = config.props;
228
+ const screen = config?.props;
229
+
230
+ if (screen == null) {
231
+ throw new Error(`Couldn't find a screen named '${route.name}'.`);
232
+ }
226
233
 
227
234
  const clearOptions = () =>
228
235
  setOptions((o) => {
229
236
  if (route.key in o) {
230
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
231
237
  const { [route.key]: _, ...rest } = o;
232
238
  return rest;
233
239
  }
@@ -239,7 +245,7 @@ export function useDescriptors<
239
245
  // The `layout` prop passed to `Screen` elements,
240
246
  screen.layout ??
241
247
  // The `screenLayout` props passed to `Group` elements
242
- config.layout ??
248
+ config?.layout ??
243
249
  // The default `screenLayout` passed to the navigator
244
250
  screenLayout;
245
251
 
@@ -294,7 +300,15 @@ export function useDescriptors<
294
300
  >
295
301
  >((acc, route, i) => {
296
302
  const navigation = navigations[route.key];
297
- const customOptions = getOptions(route, navigation, options[route.key]);
303
+ const overrides = options[route.key];
304
+
305
+ if (navigation == null) {
306
+ throw new Error(
307
+ `Couldn't find a navigation object for route '${route.key}'.`
308
+ );
309
+ }
310
+
311
+ const customOptions = getOptions(route, navigation, overrides);
298
312
  const element = render(route, navigation, customOptions, routes[i]?.state);
299
313
 
300
314
  acc[route.key] = {
@@ -303,7 +317,7 @@ export function useDescriptors<
303
317
  render() {
304
318
  return element;
305
319
  },
306
- options: customOptions as ScreenOptions,
320
+ options: customOptions,
307
321
  };
308
322
 
309
323
  return acc;
@@ -13,12 +13,15 @@ type Listeners = Set<(e: any) => void>;
13
13
  * Hook to manage the event system used by the navigator to notify screens of various events.
14
14
  */
15
15
  export function useEventEmitter<T extends Record<string, any>>(
16
- listen?: (e: any) => void
16
+ listen?: (e: any) => void,
17
+ onPostEmit?: (e: any) => void
17
18
  ): NavigationEventEmitter<T> {
18
19
  const listenRef = React.useRef(listen);
20
+ const onPostEmitRef = React.useRef(onPostEmit);
19
21
 
20
- React.useEffect(() => {
22
+ React.useInsertionEffect(() => {
21
23
  listenRef.current = listen;
24
+ onPostEmitRef.current = onPostEmit;
22
25
  });
23
26
 
24
27
  const listeners = React.useRef<Record<string, Record<string, Listeners>>>(
@@ -59,62 +62,73 @@ export function useEventEmitter<T extends Record<string, any>>(
59
62
  target?: string;
60
63
  canPreventDefault?: boolean;
61
64
  }) => {
62
- const items = listeners.current[type] || {};
65
+ const items = listeners.current[type];
63
66
 
64
67
  // Copy the current list of callbacks in case they are mutated during execution
65
- const callbacks = new Set(
66
- Object.values(target ? { [target]: items[target] } : items).flatMap(
67
- (t) => (t ? Array.from(t) : [])
68
- )
69
- );
68
+ let callbacks: Set<(e: any) => void> | undefined;
69
+
70
+ if (items) {
71
+ if (target !== undefined) {
72
+ const targetSet = items[target];
73
+
74
+ if (targetSet && targetSet.size) {
75
+ callbacks = new Set(targetSet);
76
+ }
77
+ } else {
78
+ for (const key in items) {
79
+ const set = items[key];
80
+
81
+ if (set && set.size) {
82
+ callbacks ??= new Set();
83
+
84
+ for (const cb of set) {
85
+ callbacks.add(cb);
86
+ }
87
+ }
88
+ }
89
+ }
90
+ }
70
91
 
71
- const event: EventArg<any, any, any> = {
72
- get type() {
73
- return type;
74
- },
92
+ const descriptors: PropertyDescriptorMap = {
93
+ type: { enumerable: true, value: type },
75
94
  };
76
95
 
77
96
  if (target !== undefined) {
78
- Object.defineProperty(event, 'target', {
79
- enumerable: true,
80
- get() {
81
- return target;
82
- },
83
- });
97
+ descriptors.target = { enumerable: true, value: target };
84
98
  }
85
99
 
86
100
  if (data !== undefined) {
87
- Object.defineProperty(event, 'data', {
88
- enumerable: true,
89
- get() {
90
- return data;
91
- },
92
- });
101
+ descriptors.data = { enumerable: true, value: data };
93
102
  }
94
103
 
104
+ let defaultPrevented = false;
105
+
95
106
  if (canPreventDefault) {
96
- let defaultPrevented = false;
97
-
98
- Object.defineProperties(event, {
99
- defaultPrevented: {
100
- enumerable: true,
101
- get() {
102
- return defaultPrevented;
103
- },
107
+ descriptors.defaultPrevented = {
108
+ enumerable: true,
109
+ get() {
110
+ return defaultPrevented;
104
111
  },
105
- preventDefault: {
106
- enumerable: true,
107
- value() {
108
- defaultPrevented = true;
109
- },
112
+ };
113
+ descriptors.preventDefault = {
114
+ enumerable: true,
115
+ value() {
116
+ defaultPrevented = true;
110
117
  },
111
- });
118
+ };
112
119
  }
113
120
 
121
+ const event: EventArg<any, any, any> = Object.defineProperties(
122
+ {} as EventArg<any, any, any>,
123
+ descriptors
124
+ );
125
+
114
126
  listenRef.current?.(event);
115
127
 
116
128
  callbacks?.forEach((cb) => cb(event));
117
129
 
130
+ onPostEmitRef.current?.(event);
131
+
118
132
  return event as any;
119
133
  },
120
134
  []
@@ -17,10 +17,16 @@ export function useFocusEvents<State extends NavigationState>({
17
17
  state,
18
18
  emitter,
19
19
  }: Options<State>) {
20
- const navigation = React.useContext(NavigationContext);
20
+ const navigation = React.use(NavigationContext);
21
21
  const lastFocusedKeyRef = React.useRef<string | undefined>(undefined);
22
22
 
23
- const currentFocusedKey = state.routes[state.index].key;
23
+ const currentFocusedRoute = state.routes[state.index];
24
+
25
+ if (currentFocusedRoute == null) {
26
+ throw new Error(`Couldn't find a route at index ${state.index}.`);
27
+ }
28
+
29
+ const currentFocusedKey = currentFocusedRoute.key;
24
30
 
25
31
  // When the parent screen changes its focus state, we also need to change child's focus
26
32
  // Coz the child screen can't be focused if the parent screen is out of focus
@@ -45,7 +51,12 @@ export function useFocusEvents<State extends NavigationState>({
45
51
  React.useEffect(() => {
46
52
  const lastFocusedKey = lastFocusedKeyRef.current;
47
53
 
48
- lastFocusedKeyRef.current = currentFocusedKey;
54
+ const isFocused = navigation ? navigation.isFocused() : true;
55
+
56
+ if (isFocused) {
57
+ // Remember the current route as focused if the navigator is focused
58
+ lastFocusedKeyRef.current = currentFocusedKey;
59
+ }
49
60
 
50
61
  // We wouldn't have `lastFocusedKey` on initial mount
51
62
  // Fire focus event for the current route on mount if there's no parent navigator
@@ -55,10 +66,7 @@ export function useFocusEvents<State extends NavigationState>({
55
66
 
56
67
  // We should only emit events when the focused key changed and navigator is focused
57
68
  // When navigator is not focused, screens inside shouldn't receive focused status either
58
- if (
59
- lastFocusedKey === currentFocusedKey ||
60
- !(navigation ? navigation.isFocused() : true)
61
- ) {
69
+ if (lastFocusedKey === currentFocusedKey || !isFocused) {
62
70
  return;
63
71
  }
64
72
 
@@ -20,7 +20,7 @@ export function useFocusedListenersChildrenAdapter({
20
20
  navigation,
21
21
  focusedListeners,
22
22
  }: Options) {
23
- const { addListener } = React.useContext(NavigationBuilderContext);
23
+ const { addListener } = React.use(NavigationBuilderContext);
24
24
 
25
25
  const listener = React.useCallback(
26
26
  (callback: FocusedNavigationCallback<any>) => {
@@ -41,7 +41,7 @@ export function useFocusedListenersChildrenAdapter({
41
41
  [focusedListeners, navigation]
42
42
  );
43
43
 
44
- React.useEffect(
44
+ React.useInsertionEffect(
45
45
  () => addListener?.('focus', listener),
46
46
  [addListener, listener]
47
47
  );
@@ -1,32 +1,25 @@
1
1
  import * as React from 'react';
2
2
 
3
- import { useNavigation } from './useNavigation';
3
+ export const FocusedRouteKeyContext = React.createContext<string | undefined>(
4
+ undefined
5
+ );
6
+
7
+ export const IsFocusedContext = React.createContext<boolean | undefined>(
8
+ undefined
9
+ );
4
10
 
5
11
  /**
6
12
  * Hook to get the current focus state of the screen. Returns a `true` if screen is focused, otherwise `false`.
7
13
  * This can be used if a component needs to render something based on the focus state.
8
14
  */
9
15
  export function useIsFocused(): boolean {
10
- const navigation = useNavigation();
11
-
12
- const subscribe = React.useCallback(
13
- (callback: () => void) => {
14
- const unsubscribeFocus = navigation.addListener('focus', callback);
15
- const unsubscribeBlur = navigation.addListener('blur', callback);
16
-
17
- return () => {
18
- unsubscribeFocus();
19
- unsubscribeBlur();
20
- };
21
- },
22
- [navigation]
23
- );
16
+ const isFocused = React.use(IsFocusedContext);
24
17
 
25
- const value = React.useSyncExternalStore(
26
- subscribe,
27
- navigation.isFocused,
28
- navigation.isFocused
29
- );
18
+ if (isFocused === undefined) {
19
+ throw new Error(
20
+ "Couldn't determine focus state. Is your component inside a screen in a navigator?"
21
+ );
22
+ }
30
23
 
31
- return value;
24
+ return isFocused;
32
25
  }
@@ -28,8 +28,10 @@ export function useKeyedChildListeners() {
28
28
  keyedListeners[type][key] = listener;
29
29
 
30
30
  return () => {
31
- // @ts-expect-error: according to ref stated above you can use `key` to index type
32
- keyedListeners[type][key] = undefined;
31
+ if (keyedListeners[type][key] === listener) {
32
+ // @ts-expect-error: according to ref stated above you can use `key` to index type
33
+ keyedListeners[type][key] = undefined;
34
+ }
33
35
  };
34
36
  },
35
37
  [keyedListeners]
@@ -1,11 +1,11 @@
1
1
  import * as React from 'react';
2
2
 
3
- export function useLazyValue<T>(create: () => T) {
3
+ export function useLazyValue<T>(create: () => T): T {
4
4
  const lazyRef = React.useRef<T>(undefined);
5
5
 
6
6
  if (lazyRef.current === undefined) {
7
7
  lazyRef.current = create();
8
8
  }
9
9
 
10
- return lazyRef.current as T;
10
+ return lazyRef.current;
11
11
  }
@@ -1,10 +1,7 @@
1
1
  import * as React from 'react';
2
2
 
3
3
  import { NavigationContainerRefContext } from './NavigationContainerRefContext';
4
- import {
5
- NavigationContext,
6
- NavigationRouteNameContext,
7
- } from './NavigationProvider';
4
+ import { NavigationContext } from './NavigationProvider';
8
5
  import type {
9
6
  GenericNavigation,
10
7
  NavigationListForNavigator,
@@ -13,6 +10,8 @@ import type {
13
10
  RootParamList,
14
11
  } from './types';
15
12
 
13
+ type RootNavigation = GenericNavigation<RootParamList>;
14
+
16
15
  /**
17
16
  * Hook to access the navigation prop of the parent screen anywhere.
18
17
  *
@@ -21,14 +20,14 @@ import type {
21
20
  *
22
21
  * @returns Navigation prop of the parent screen.
23
22
  */
24
- export function useNavigation(): GenericNavigation<RootParamList>;
23
+ export function useNavigation(): RootNavigation;
25
24
  export function useNavigation<
26
25
  const Navigator = RootNavigator,
27
26
  >(): NavigationListForNavigator<Navigator>[keyof NavigationListForNavigator<Navigator>];
28
27
  export function useNavigation<
29
28
  const Navigator = RootNavigator,
30
- const RouteName extends
31
- keyof NavigationListForNested<Navigator> = keyof NavigationListForNested<Navigator>,
29
+ const RouteName extends keyof NavigationListForNested<Navigator> =
30
+ keyof NavigationListForNested<Navigator>,
32
31
  >(name: RouteName): NavigationListForNested<Navigator>[RouteName];
33
32
  export function useNavigation(name?: string): unknown {
34
33
  const root = React.use(NavigationContainerRefContext);
@@ -44,23 +43,7 @@ export function useNavigation(name?: string): unknown {
44
43
  return navigation ?? root;
45
44
  }
46
45
 
47
- const routeName = React.use(NavigationRouteNameContext);
48
-
49
- // Generally, this condition isn't needed as `getParent(name)` works for current screen
50
- // However, it'll throw if the hook is used in a preloaded screen
51
- if (routeName === name) {
52
- if (navigation === undefined) {
53
- throw new Error(
54
- `Couldn't find a navigation object for '${name}'. This is not expected.`
55
- );
56
- }
57
-
58
- return navigation;
59
- }
60
-
61
- // We get parent first so that `getParent(name)` is not called in preloaded screens
62
- // It's ok since `getParent` also works for current screen, so parent is not skipped
63
- const parent = navigation?.getParent()?.getParent(name);
46
+ const parent = navigation?.getParent(name);
64
47
 
65
48
  if (parent === undefined) {
66
49
  throw new Error(