@react-navigation/core 7.17.2 → 7.17.3

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 (40) hide show
  1. package/lib/module/StaticNavigation.js +0 -19
  2. package/lib/module/StaticNavigation.js.map +1 -1
  3. package/lib/module/checkSerializable.js +11 -4
  4. package/lib/module/checkSerializable.js.map +1 -1
  5. package/lib/module/getActionFromState.js +15 -2
  6. package/lib/module/getActionFromState.js.map +1 -1
  7. package/lib/module/getStateFromPath.js +11 -16
  8. package/lib/module/getStateFromPath.js.map +1 -1
  9. package/lib/module/index.js.map +1 -1
  10. package/lib/module/types.js +55 -0
  11. package/lib/module/types.js.map +1 -1
  12. package/lib/module/useEventEmitter.js +28 -29
  13. package/lib/module/useEventEmitter.js.map +1 -1
  14. package/lib/module/useNavigationBuilder.js +38 -40
  15. package/lib/module/useNavigationBuilder.js.map +1 -1
  16. package/lib/module/useRouteCache.js +2 -1
  17. package/lib/module/useRouteCache.js.map +1 -1
  18. package/lib/typescript/src/StaticNavigation.d.ts +2 -63
  19. package/lib/typescript/src/StaticNavigation.d.ts.map +1 -1
  20. package/lib/typescript/src/checkSerializable.d.ts +5 -3
  21. package/lib/typescript/src/checkSerializable.d.ts.map +1 -1
  22. package/lib/typescript/src/getActionFromState.d.ts.map +1 -1
  23. package/lib/typescript/src/getStateFromPath.d.ts.map +1 -1
  24. package/lib/typescript/src/index.d.ts +1 -1
  25. package/lib/typescript/src/index.d.ts.map +1 -1
  26. package/lib/typescript/src/types.d.ts +102 -2
  27. package/lib/typescript/src/types.d.ts.map +1 -1
  28. package/lib/typescript/src/useEventEmitter.d.ts.map +1 -1
  29. package/lib/typescript/src/useNavigationBuilder.d.ts.map +1 -1
  30. package/lib/typescript/src/useRouteCache.d.ts.map +1 -1
  31. package/package.json +3 -3
  32. package/src/StaticNavigation.tsx +1 -91
  33. package/src/checkSerializable.tsx +22 -12
  34. package/src/getActionFromState.tsx +20 -4
  35. package/src/getStateFromPath.tsx +23 -20
  36. package/src/index.tsx +0 -1
  37. package/src/types.tsx +138 -4
  38. package/src/useEventEmitter.tsx +33 -38
  39. package/src/useNavigationBuilder.tsx +59 -65
  40. package/src/useRouteCache.tsx +2 -1
@@ -376,44 +376,7 @@ export function useNavigationBuilder<
376
376
  return original;
377
377
  });
378
378
 
379
- const screens = routeConfigs.reduce<
380
- Record<string, ScreenConfigWithParent<State, ScreenOptions, EventMap>>
381
- >((acc, config) => {
382
- if (config.props.name in acc) {
383
- throw new Error(
384
- `A navigator cannot contain multiple 'Screen' components with the same name (found duplicate screen named '${config.props.name}')`
385
- );
386
- }
387
-
388
- acc[config.props.name] = config;
389
- return acc;
390
- }, {});
391
-
392
379
  const routeNames = routeConfigs.map((config) => config.props.name);
393
- const routeKeyList = routeNames.reduce<Record<string, React.Key | undefined>>(
394
- (acc, curr) => {
395
- acc[curr] = screens[curr].keys.map((key) => key ?? '').join(':');
396
- return acc;
397
- },
398
- {}
399
- );
400
- const routeParamList = routeNames.reduce<Record<string, object | undefined>>(
401
- (acc, curr) => {
402
- const { initialParams } = screens[curr].props;
403
- acc[curr] = initialParams;
404
- return acc;
405
- },
406
- {}
407
- );
408
- const routeGetIdList = routeNames.reduce<
409
- RouterConfigOptions['routeGetIdList']
410
- >(
411
- (acc, curr) =>
412
- Object.assign(acc, {
413
- [curr]: screens[curr].props.getId,
414
- }),
415
- {}
416
- );
417
380
 
418
381
  if (!routeNames.length) {
419
382
  throw new Error(
@@ -421,6 +384,31 @@ export function useNavigationBuilder<
421
384
  );
422
385
  }
423
386
 
387
+ const screens: Record<
388
+ string,
389
+ ScreenConfigWithParent<State, ScreenOptions, EventMap>
390
+ > = {};
391
+
392
+ const routeKeyList: Record<string, React.Key | undefined> = {};
393
+ const routeParamList: Record<string, object | undefined> = {};
394
+ const routeGetIdList: RouterConfigOptions['routeGetIdList'] = {};
395
+
396
+ for (const config of routeConfigs) {
397
+ const name = config.props.name;
398
+
399
+ if (name in screens) {
400
+ throw new Error(
401
+ `A navigator cannot contain multiple 'Screen' components with the same name (found duplicate screen named '${name}')`
402
+ );
403
+ }
404
+
405
+ screens[name] = config;
406
+ routeKeyList[name] = config.keys.map((key) => key ?? '').join(':');
407
+ routeParamList[name] = config.props.initialParams;
408
+
409
+ Object.assign(routeGetIdList, { [name]: config.props.getId });
410
+ }
411
+
424
412
  const isStateValid = React.useCallback(
425
413
  (state: NavigationState | PartialState<NavigationState>) =>
426
414
  state.type === undefined || state.type === router.type,
@@ -835,35 +823,41 @@ export function useNavigationBuilder<
835
823
  return;
836
824
  }
837
825
 
838
- const navigation = descriptors[route.key].navigation;
839
-
840
- const listeners = ([] as (((e: any) => void) | undefined)[])
841
- .concat(
842
- // Get an array of listeners for all screens + common listeners on navigator
843
- ...[
844
- screenListeners,
845
- ...routeNames.map((name) => {
846
- const { listeners } = screens[name].props;
847
- return listeners;
848
- }),
849
- ].map((listeners) => {
850
- const map =
851
- typeof listeners === 'function'
852
- ? listeners({ route: route as any, navigation })
853
- : listeners;
854
-
855
- return map
856
- ? Object.keys(map)
857
- .filter((type) => type === e.type)
858
- .map((type) => map?.[type])
859
- : undefined;
860
- })
861
- )
862
- // We don't want same listener to be called multiple times for same event
863
- // So we remove any duplicate functions from the array
864
- .filter((cb, i, self) => cb && self.lastIndexOf(cb) === i);
826
+ const hasPerScreenListeners = routeNames.some(
827
+ (name) => screens[name].props.listeners != null
828
+ );
865
829
 
866
- listeners.forEach((listener) => listener?.(e));
830
+ if (screenListeners != null || hasPerScreenListeners) {
831
+ const navigation = descriptors[route.key].navigation;
832
+
833
+ const listeners = ([] as (((e: any) => void) | undefined)[])
834
+ .concat(
835
+ // Get an array of listeners for all screens + common listeners on navigator
836
+ ...[
837
+ screenListeners,
838
+ ...routeNames.map((name) => {
839
+ const { listeners } = screens[name].props;
840
+ return listeners;
841
+ }),
842
+ ].map((listeners) => {
843
+ const map =
844
+ typeof listeners === 'function'
845
+ ? listeners({ route: route as any, navigation })
846
+ : listeners;
847
+
848
+ return map
849
+ ? Object.keys(map)
850
+ .filter((type) => type === e.type)
851
+ .map((type) => map?.[type])
852
+ : undefined;
853
+ })
854
+ )
855
+ // We don't want same listener to be called multiple times for same event
856
+ // So we remove any duplicate functions from the array
857
+ .filter((cb, i, self) => cb && self.lastIndexOf(cb) === i);
858
+
859
+ listeners.forEach((listener) => listener?.(e));
860
+ }
867
861
  });
868
862
 
869
863
  useFocusEvents({ state, emitter });
@@ -36,9 +36,10 @@ export function useRouteCache<State extends NavigationState>(
36
36
  proxy = routeWithoutState;
37
37
  }
38
38
 
39
- if (process.env.NODE_ENV !== 'production') {
39
+ if (process.env.NODE_ENV !== 'production' && proxy !== previous) {
40
40
  // FIXME: since the state is updated with mutation, the route object cannot be frozen
41
41
  // As a workaround, loop through the object and make the properties readonly
42
+ // Only needed once per proxy - skip if we're reusing a previously-frozen one
42
43
  for (const key in proxy) {
43
44
  // @ts-expect-error: this is fine since we are looping through the object
44
45
  const value = proxy[key];