@react-navigation/core 7.21.11 → 7.21.12

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.
@@ -1 +1 @@
1
- {"version":3,"names":["React","NavigationBuilderContext","createContext","onDispatchAction","undefined","onEmitEvent","onOptionsChange","getIsStateEmitted","scheduleUpdate","Error","flushUpdates"],"sourceRoot":"../../src","sources":["NavigationBuilderContext.tsx"],"mappings":";;AAKA,OAAO,KAAKA,KAAK,MAAM,OAAO;AA6C9B;AACA;AACA;AACA,OAAO,MAAMC,wBAAwB,gBAAGD,KAAK,CAACE,aAAa,CAiBxD;EACDC,gBAAgB,EAAEA,CAAA,KAAMC,SAAS;EACjCC,WAAW,EAAEA,CAAA,KAAMD,SAAS;EAC5BE,eAAe,EAAEA,CAAA,KAAMF,SAAS;EAChCG,iBAAiB,EAAEA,CAAA,KAAM,KAAK;EAC9BC,cAAc,EAAEA,CAAA,KAAM;IACpB,MAAM,IAAIC,KAAK,CAAC,iDAAiD,CAAC;EACpE,CAAC;EACDC,YAAY,EAAEA,CAAA,KAAM;IAClB,MAAM,IAAID,KAAK,CAAC,+CAA+C,CAAC;EAClE;AACF,CAAC,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["React","NavigationBuilderContext","createContext","onDispatchAction","undefined","onEmitEvent","onOptionsChange","getIsStateEmitted","scheduleUpdate","Error","flushUpdates"],"sourceRoot":"../../src","sources":["NavigationBuilderContext.tsx"],"mappings":";;AAMA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAgD9B;AACA;AACA;AACA,OAAO,MAAMC,wBAAwB,gBAAGD,KAAK,CAACE,aAAa,CAiBxD;EACDC,gBAAgB,EAAEA,CAAA,KAAMC,SAAS;EACjCC,WAAW,EAAEA,CAAA,KAAMD,SAAS;EAC5BE,eAAe,EAAEA,CAAA,KAAMF,SAAS;EAChCG,iBAAiB,EAAEA,CAAA,KAAM,KAAK;EAC9BC,cAAc,EAAEA,CAAA,KAAM;IACpB,MAAM,IAAIC,KAAK,CAAC,iDAAiD,CAAC;EACpE,CAAC;EACDC,YAAY,EAAEA,CAAA,KAAM;IAClB,MAAM,IAAID,KAAK,CAAC,+CAA+C,CAAC;EAClE;AACF,CAAC,CAAC","ignoreList":[]}
@@ -5,37 +5,48 @@ import { NavigationBuilderContext } from "./NavigationBuilderContext.js";
5
5
  import { NavigationRouteContext } from "./NavigationProvider.js";
6
6
  const VISITED_ROUTE_KEYS = Symbol('VISITED_ROUTE_KEYS');
7
7
  export const shouldPreventRemove = (emitter, beforeRemoveListeners, currentRoutes, nextRoutes, action) => {
8
- const nextRouteKeys = nextRoutes.map(route => route.key);
9
-
10
- // Call these in reverse order so last screens handle the event first
11
- const removedRoutes = currentRoutes.filter(route => !nextRouteKeys.includes(route.key)).reverse();
8
+ const nextRoutesByKey = new Map(nextRoutes.map(route => [route.key, route]).filter(([, route]) => route.key != null));
12
9
  const visitedRouteKeys = VISITED_ROUTE_KEYS in action && action[VISITED_ROUTE_KEYS] instanceof Set ? action[VISITED_ROUTE_KEYS] : new Set();
13
10
  const beforeRemoveAction = {
14
11
  ...action,
15
12
  [VISITED_ROUTE_KEYS]: visitedRouteKeys
16
13
  };
17
- for (const route of removedRoutes) {
14
+
15
+ // Call these in reverse order so last screens handle the event first
16
+ const reversedCurrentRoutes = [...currentRoutes].reverse();
17
+ for (const route of reversedCurrentRoutes) {
18
18
  if (visitedRouteKeys.has(route.key)) {
19
19
  // Skip if we've already emitted this action for this screen
20
20
  continue;
21
21
  }
22
-
23
- // First, we need to check if any child screens want to prevent it
24
- const isPrevented = beforeRemoveListeners[route.key]?.(beforeRemoveAction);
25
- if (isPrevented) {
26
- return true;
27
- }
28
- visitedRouteKeys.add(route.key);
29
- const event = emitter.emit({
30
- type: 'beforeRemove',
31
- target: route.key,
32
- data: {
33
- action: beforeRemoveAction
34
- },
35
- canPreventDefault: true
36
- });
37
- if (event.defaultPrevented) {
38
- return true;
22
+ if (!nextRoutesByKey.has(route.key)) {
23
+ // The route is not in next state, so it's being removed
24
+ // First, we need to check if any child screens want to prevent it
25
+ const isPrevented = beforeRemoveListeners[route.key]?.(beforeRemoveAction, undefined);
26
+ if (isPrevented) {
27
+ return true;
28
+ }
29
+ visitedRouteKeys.add(route.key);
30
+ const event = emitter.emit({
31
+ type: 'beforeRemove',
32
+ target: route.key,
33
+ data: {
34
+ action: beforeRemoveAction
35
+ },
36
+ canPreventDefault: true
37
+ });
38
+ if (event.defaultPrevented) {
39
+ return true;
40
+ }
41
+ } else {
42
+ // The route is kept but its nested state changed, so propagate the check into the nested navigator
43
+ const nextRoute = nextRoutesByKey.get(route.key);
44
+ if (route.state != null && route.state !== nextRoute?.state) {
45
+ const isPrevented = beforeRemoveListeners[route.key]?.(beforeRemoveAction, nextRoute?.state);
46
+ if (isPrevented) {
47
+ return true;
48
+ }
49
+ }
39
50
  }
40
51
  }
41
52
  return false;
@@ -52,9 +63,9 @@ export function useOnPreventRemove({
52
63
  const routeKey = route?.key;
53
64
  React.useEffect(() => {
54
65
  if (routeKey) {
55
- return addKeyedListener?.('beforeRemove', routeKey, action => {
66
+ return addKeyedListener?.('beforeRemove', routeKey, (action, nextState) => {
56
67
  const state = getState();
57
- return shouldPreventRemove(emitter, beforeRemoveListeners, state.routes, [], action);
68
+ return shouldPreventRemove(emitter, beforeRemoveListeners, state.routes, nextState?.routes ?? [], action);
58
69
  });
59
70
  }
60
71
  }, [addKeyedListener, beforeRemoveListeners, emitter, getState, routeKey]);
@@ -1 +1 @@
1
- {"version":3,"names":["React","NavigationBuilderContext","NavigationRouteContext","VISITED_ROUTE_KEYS","Symbol","shouldPreventRemove","emitter","beforeRemoveListeners","currentRoutes","nextRoutes","action","nextRouteKeys","map","route","key","removedRoutes","filter","includes","reverse","visitedRouteKeys","Set","beforeRemoveAction","has","isPrevented","add","event","emit","type","target","data","canPreventDefault","defaultPrevented","useOnPreventRemove","getState","addKeyedListener","useContext","routeKey","useEffect","state","routes"],"sourceRoot":"../../src","sources":["useOnPreventRemove.tsx"],"mappings":";;AAIA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAE9B,SAEEC,wBAAwB,QACnB,+BAA4B;AACnC,SAASC,sBAAsB,QAAQ,yBAAsB;AAU7D,MAAMC,kBAAkB,GAAGC,MAAM,CAAC,oBAAoB,CAAC;AAEvD,OAAO,MAAMC,mBAAmB,GAAGA,CACjCC,OAAkD,EAClDC,qBAA4E,EAC5EC,aAAgC,EAChCC,UAA0C,EAC1CC,MAAwB,KACrB;EACH,MAAMC,aAAa,GAAGF,UAAU,CAACG,GAAG,CAAEC,KAAK,IAAKA,KAAK,CAACC,GAAG,CAAC;;EAE1D;EACA,MAAMC,aAAa,GAAGP,aAAa,CAChCQ,MAAM,CAAEH,KAAK,IAAK,CAACF,aAAa,CAACM,QAAQ,CAACJ,KAAK,CAACC,GAAG,CAAC,CAAC,CACrDI,OAAO,CAAC,CAAC;EAEZ,MAAMC,gBAAgB,GACpBhB,kBAAkB,IAAIO,MAAM,IAAIA,MAAM,CAACP,kBAAkB,CAAC,YAAYiB,GAAG,GACrEV,MAAM,CAACP,kBAAkB,CAAC,GAC1B,IAAIiB,GAAG,CAAS,CAAC;EAEvB,MAAMC,kBAAkB,GAAG;IACzB,GAAGX,MAAM;IACT,CAACP,kBAAkB,GAAGgB;EACxB,CAAC;EAED,KAAK,MAAMN,KAAK,IAAIE,aAAa,EAAE;IACjC,IAAII,gBAAgB,CAACG,GAAG,CAACT,KAAK,CAACC,GAAG,CAAC,EAAE;MACnC;MACA;IACF;;IAEA;IACA,MAAMS,WAAW,GAAGhB,qBAAqB,CAACM,KAAK,CAACC,GAAG,CAAC,GAAGO,kBAAkB,CAAC;IAE1E,IAAIE,WAAW,EAAE;MACf,OAAO,IAAI;IACb;IAEAJ,gBAAgB,CAACK,GAAG,CAACX,KAAK,CAACC,GAAG,CAAC;IAE/B,MAAMW,KAAK,GAAGnB,OAAO,CAACoB,IAAI,CAAC;MACzBC,IAAI,EAAE,cAAc;MACpBC,MAAM,EAAEf,KAAK,CAACC,GAAG;MACjBe,IAAI,EAAE;QAAEnB,MAAM,EAAEW;MAAmB,CAAC;MACpCS,iBAAiB,EAAE;IACrB,CAAC,CAAC;IAEF,IAAIL,KAAK,CAACM,gBAAgB,EAAE;MAC1B,OAAO,IAAI;IACb;EACF;EAEA,OAAO,KAAK;AACd,CAAC;AAED,OAAO,SAASC,kBAAkBA,CAAC;EACjCC,QAAQ;EACR3B,OAAO;EACPC;AACO,CAAC,EAAE;EACV,MAAM;IAAE2B;EAAiB,CAAC,GAAGlC,KAAK,CAACmC,UAAU,CAAClC,wBAAwB,CAAC;EACvE,MAAMY,KAAK,GAAGb,KAAK,CAACmC,UAAU,CAACjC,sBAAsB,CAAC;EACtD,MAAMkC,QAAQ,GAAGvB,KAAK,EAAEC,GAAG;EAE3Bd,KAAK,CAACqC,SAAS,CAAC,MAAM;IACpB,IAAID,QAAQ,EAAE;MACZ,OAAOF,gBAAgB,GAAG,cAAc,EAAEE,QAAQ,EAAG1B,MAAM,IAAK;QAC9D,MAAM4B,KAAK,GAAGL,QAAQ,CAAC,CAAC;QAExB,OAAO5B,mBAAmB,CACxBC,OAAO,EACPC,qBAAqB,EACrB+B,KAAK,CAACC,MAAM,EACZ,EAAE,EACF7B,MACF,CAAC;MACH,CAAC,CAAC;IACJ;EACF,CAAC,EAAE,CAACwB,gBAAgB,EAAE3B,qBAAqB,EAAED,OAAO,EAAE2B,QAAQ,EAAEG,QAAQ,CAAC,CAAC;AAC5E","ignoreList":[]}
1
+ {"version":3,"names":["React","NavigationBuilderContext","NavigationRouteContext","VISITED_ROUTE_KEYS","Symbol","shouldPreventRemove","emitter","beforeRemoveListeners","currentRoutes","nextRoutes","action","nextRoutesByKey","Map","map","route","key","filter","visitedRouteKeys","Set","beforeRemoveAction","reversedCurrentRoutes","reverse","has","isPrevented","undefined","add","event","emit","type","target","data","canPreventDefault","defaultPrevented","nextRoute","get","state","useOnPreventRemove","getState","addKeyedListener","useContext","routeKey","useEffect","nextState","routes"],"sourceRoot":"../../src","sources":["useOnPreventRemove.tsx"],"mappings":"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","ignoreList":[]}
@@ -1,4 +1,4 @@
1
- import type { NavigationAction, NavigationState, ParamListBase } from '@react-navigation/routers';
1
+ import type { NavigationAction, NavigationState, ParamListBase, PartialState } from '@react-navigation/routers';
2
2
  import * as React from 'react';
3
3
  import type { NavigationContainerEventMap, NavigationHelpers } from './types.js';
4
4
  export type ListenerMap = {
@@ -18,7 +18,7 @@ export type FocusedNavigationListener = <T>(callback: FocusedNavigationCallback<
18
18
  result: T;
19
19
  };
20
20
  export type GetStateListener = () => NavigationState;
21
- export type ChildBeforeRemoveListener = (action: NavigationAction) => boolean;
21
+ export type ChildBeforeRemoveListener = (action: NavigationAction, nextState: NavigationState | PartialState<NavigationState> | undefined) => boolean;
22
22
  /**
23
23
  * Context which holds the required helpers needed to build nested navigators.
24
24
  */
@@ -1 +1 @@
1
- {"version":3,"file":"NavigationBuilderContext.d.ts","sourceRoot":"","sources":["../../../src/NavigationBuilderContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,eAAe,EACf,aAAa,EACd,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,2BAA2B,EAAE,iBAAiB,EAAE,MAAM,YAAS,CAAC;AAE9E,MAAM,MAAM,WAAW,GAAG;IACxB,MAAM,EAAE,mBAAmB,CAAC;IAC5B,KAAK,EAAE,yBAAyB,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,YAAY,EAAE,yBAAyB,CAAC;CACzC,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,SAAS,MAAM,WAAW,EACpD,IAAI,EAAE,CAAC,EACP,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,KACrB,IAAI,CAAC;AAEV,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,SAAS,MAAM,gBAAgB,EAC9D,IAAI,EAAE,CAAC,EACP,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,gBAAgB,CAAC,CAAC,CAAC,KAC1B,IAAI,CAAC;AAEV,MAAM,MAAM,mBAAmB,GAAG,CAChC,MAAM,EAAE,gBAAgB,EACxB,iBAAiB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,KAC5B,OAAO,CAAC;AAEb,MAAM,MAAM,yBAAyB,CAAC,CAAC,IAAI,CACzC,UAAU,EAAE,iBAAiB,CAAC,aAAa,CAAC,KACzC,CAAC,CAAC;AAEP,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,EACxC,QAAQ,EAAE,yBAAyB,CAAC,CAAC,CAAC,KACnC;IACH,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,CAAC,CAAC;CACX,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,MAAM,eAAe,CAAC;AAErD,MAAM,MAAM,yBAAyB,GAAG,CAAC,MAAM,EAAE,gBAAgB,KAAK,OAAO,CAAC;AAE9E;;GAEG;AACH,eAAO,MAAM,wBAAwB;eACxB,CACT,MAAM,EAAE,gBAAgB,EACxB,iBAAiB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,KAC5B,OAAO;kBACE,WAAW;uBACN,gBAAgB;mBACpB,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI;sBAClB,CAAC,MAAM,EAAE,gBAAgB,EAAE,IAAI,EAAE,OAAO,KAAK,IAAI;iBACtD,CACX,KAAK,EAAE,2BAA2B,CAAC,kBAAkB,CAAC,CAAC,MAAM,CAAC,KAC3D,IAAI;qBACQ,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI;uBACvB,MAAM,OAAO;oBAChB,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI;kBAChC,MAAM,IAAI;eACb,KAAK,CAAC,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC;EAY9C,CAAC"}
1
+ {"version":3,"file":"NavigationBuilderContext.d.ts","sourceRoot":"","sources":["../../../src/NavigationBuilderContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,eAAe,EACf,aAAa,EACb,YAAY,EACb,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,2BAA2B,EAAE,iBAAiB,EAAE,MAAM,YAAS,CAAC;AAE9E,MAAM,MAAM,WAAW,GAAG;IACxB,MAAM,EAAE,mBAAmB,CAAC;IAC5B,KAAK,EAAE,yBAAyB,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,YAAY,EAAE,yBAAyB,CAAC;CACzC,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,SAAS,MAAM,WAAW,EACpD,IAAI,EAAE,CAAC,EACP,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,KACrB,IAAI,CAAC;AAEV,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,SAAS,MAAM,gBAAgB,EAC9D,IAAI,EAAE,CAAC,EACP,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,gBAAgB,CAAC,CAAC,CAAC,KAC1B,IAAI,CAAC;AAEV,MAAM,MAAM,mBAAmB,GAAG,CAChC,MAAM,EAAE,gBAAgB,EACxB,iBAAiB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,KAC5B,OAAO,CAAC;AAEb,MAAM,MAAM,yBAAyB,CAAC,CAAC,IAAI,CACzC,UAAU,EAAE,iBAAiB,CAAC,aAAa,CAAC,KACzC,CAAC,CAAC;AAEP,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,EACxC,QAAQ,EAAE,yBAAyB,CAAC,CAAC,CAAC,KACnC;IACH,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,CAAC,CAAC;CACX,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,MAAM,eAAe,CAAC;AAErD,MAAM,MAAM,yBAAyB,GAAG,CACtC,MAAM,EAAE,gBAAgB,EACxB,SAAS,EAAE,eAAe,GAAG,YAAY,CAAC,eAAe,CAAC,GAAG,SAAS,KACnE,OAAO,CAAC;AAEb;;GAEG;AACH,eAAO,MAAM,wBAAwB;eACxB,CACT,MAAM,EAAE,gBAAgB,EACxB,iBAAiB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,KAC5B,OAAO;kBACE,WAAW;uBACN,gBAAgB;mBACpB,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI;sBAClB,CAAC,MAAM,EAAE,gBAAgB,EAAE,IAAI,EAAE,OAAO,KAAK,IAAI;iBACtD,CACX,KAAK,EAAE,2BAA2B,CAAC,kBAAkB,CAAC,CAAC,MAAM,CAAC,KAC3D,IAAI;qBACQ,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI;uBACvB,MAAM,OAAO;oBAChB,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI;kBAChC,MAAM,IAAI;eACb,KAAK,CAAC,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC;EAY9C,CAAC"}
@@ -1,4 +1,4 @@
1
- import type { NavigationAction, NavigationState } from '@react-navigation/routers';
1
+ import type { NavigationAction, NavigationRoute, NavigationState, ParamListBase, PartialRoute } from '@react-navigation/routers';
2
2
  import { type ChildBeforeRemoveListener } from './NavigationBuilderContext.js';
3
3
  import type { EventMapCore } from './types.js';
4
4
  import type { NavigationEventEmitter } from './useEventEmitter.js';
@@ -7,11 +7,7 @@ type Options = {
7
7
  emitter: NavigationEventEmitter<EventMapCore<any>>;
8
8
  beforeRemoveListeners: Record<string, ChildBeforeRemoveListener | undefined>;
9
9
  };
10
- export declare const shouldPreventRemove: (emitter: NavigationEventEmitter<EventMapCore<any>>, beforeRemoveListeners: Record<string, ChildBeforeRemoveListener | undefined>, currentRoutes: {
11
- key: string;
12
- }[], nextRoutes: {
13
- key?: string | undefined;
14
- }[], action: NavigationAction) => boolean;
10
+ export declare const shouldPreventRemove: (emitter: NavigationEventEmitter<EventMapCore<any>>, beforeRemoveListeners: Record<string, ChildBeforeRemoveListener | undefined>, currentRoutes: NavigationRoute<ParamListBase, string>[], nextRoutes: (NavigationRoute<ParamListBase, string> | PartialRoute<NavigationRoute<ParamListBase, string>>)[], action: NavigationAction) => boolean;
15
11
  export declare function useOnPreventRemove({ getState, emitter, beforeRemoveListeners, }: Options): void;
16
12
  export {};
17
13
  //# sourceMappingURL=useOnPreventRemove.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useOnPreventRemove.d.ts","sourceRoot":"","sources":["../../../src/useOnPreventRemove.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,eAAe,EAChB,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EACL,KAAK,yBAAyB,EAE/B,MAAM,+BAA4B,CAAC;AAEpC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sBAAmB,CAAC;AAEhE,KAAK,OAAO,GAAG;IACb,QAAQ,EAAE,MAAM,eAAe,CAAC;IAChC,OAAO,EAAE,sBAAsB,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC;IACnD,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,yBAAyB,GAAG,SAAS,CAAC,CAAC;CAC9E,CAAC;AAIF,eAAO,MAAM,mBAAmB,GAC9B,SAAS,sBAAsB,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,EAClD,uBAAuB,MAAM,CAAC,MAAM,EAAE,yBAAyB,GAAG,SAAS,CAAC,EAC5E,eAAe;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,EAAE,EAChC,YAAY;IAAE,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,EAAE,EAC1C,QAAQ,gBAAgB,YA+CzB,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,EACjC,QAAQ,EACR,OAAO,EACP,qBAAqB,GACtB,EAAE,OAAO,QAoBT"}
1
+ {"version":3,"file":"useOnPreventRemove.d.ts","sourceRoot":"","sources":["../../../src/useOnPreventRemove.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,aAAa,EACb,YAAY,EACb,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EACL,KAAK,yBAAyB,EAE/B,MAAM,+BAA4B,CAAC;AAEpC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sBAAmB,CAAC;AAEhE,KAAK,OAAO,GAAG;IACb,QAAQ,EAAE,MAAM,eAAe,CAAC;IAChC,OAAO,EAAE,sBAAsB,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC;IACnD,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,yBAAyB,GAAG,SAAS,CAAC,CAAC;CAC9E,CAAC;AAIF,eAAO,MAAM,mBAAmB,GAC9B,SAAS,sBAAsB,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,EAClD,uBAAuB,MAAM,CAAC,MAAM,EAAE,yBAAyB,GAAG,SAAS,CAAC,EAC5E,eAAe,eAAe,CAAC,aAAa,EAAE,MAAM,CAAC,EAAE,EACvD,YAAY,CACR,eAAe,CAAC,aAAa,EAAE,MAAM,CAAC,GACtC,YAAY,CAAC,eAAe,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CACvD,EAAE,EACH,QAAQ,gBAAgB,YAqEzB,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,EACjC,QAAQ,EACR,OAAO,EACP,qBAAqB,GACtB,EAAE,OAAO,QAwBT"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@react-navigation/core",
3
3
  "description": "Core utilities for building navigators",
4
- "version": "7.21.11",
4
+ "version": "7.21.12",
5
5
  "keywords": [
6
6
  "react",
7
7
  "react-native",
@@ -83,5 +83,5 @@
83
83
  ]
84
84
  ]
85
85
  },
86
- "gitHead": "f92e18d5b5028eefb4f57a7066013868d7a08581"
86
+ "gitHead": "749aaf57b5189363194d63a6b09fe29bacc6740f"
87
87
  }
@@ -2,6 +2,7 @@ import type {
2
2
  NavigationAction,
3
3
  NavigationState,
4
4
  ParamListBase,
5
+ PartialState,
5
6
  } from '@react-navigation/routers';
6
7
  import * as React from 'react';
7
8
 
@@ -46,7 +47,10 @@ export type FocusedNavigationListener = <T>(
46
47
 
47
48
  export type GetStateListener = () => NavigationState;
48
49
 
49
- export type ChildBeforeRemoveListener = (action: NavigationAction) => boolean;
50
+ export type ChildBeforeRemoveListener = (
51
+ action: NavigationAction,
52
+ nextState: NavigationState | PartialState<NavigationState> | undefined
53
+ ) => boolean;
50
54
 
51
55
  /**
52
56
  * Context which holds the required helpers needed to build nested navigators.
@@ -1,6 +1,9 @@
1
1
  import type {
2
2
  NavigationAction,
3
+ NavigationRoute,
3
4
  NavigationState,
5
+ ParamListBase,
6
+ PartialRoute,
4
7
  } from '@react-navigation/routers';
5
8
  import * as React from 'react';
6
9
 
@@ -23,16 +26,18 @@ const VISITED_ROUTE_KEYS = Symbol('VISITED_ROUTE_KEYS');
23
26
  export const shouldPreventRemove = (
24
27
  emitter: NavigationEventEmitter<EventMapCore<any>>,
25
28
  beforeRemoveListeners: Record<string, ChildBeforeRemoveListener | undefined>,
26
- currentRoutes: { key: string }[],
27
- nextRoutes: { key?: string | undefined }[],
29
+ currentRoutes: NavigationRoute<ParamListBase, string>[],
30
+ nextRoutes: (
31
+ | NavigationRoute<ParamListBase, string>
32
+ | PartialRoute<NavigationRoute<ParamListBase, string>>
33
+ )[],
28
34
  action: NavigationAction
29
35
  ) => {
30
- const nextRouteKeys = nextRoutes.map((route) => route.key);
31
-
32
- // Call these in reverse order so last screens handle the event first
33
- const removedRoutes = currentRoutes
34
- .filter((route) => !nextRouteKeys.includes(route.key))
35
- .reverse();
36
+ const nextRoutesByKey = new Map(
37
+ nextRoutes
38
+ .map((route) => [route.key, route] as const)
39
+ .filter(([, route]) => route.key != null)
40
+ );
36
41
 
37
42
  const visitedRouteKeys =
38
43
  VISITED_ROUTE_KEYS in action && action[VISITED_ROUTE_KEYS] instanceof Set
@@ -44,30 +49,53 @@ export const shouldPreventRemove = (
44
49
  [VISITED_ROUTE_KEYS]: visitedRouteKeys,
45
50
  };
46
51
 
47
- for (const route of removedRoutes) {
52
+ // Call these in reverse order so last screens handle the event first
53
+ const reversedCurrentRoutes = [...currentRoutes].reverse();
54
+
55
+ for (const route of reversedCurrentRoutes) {
48
56
  if (visitedRouteKeys.has(route.key)) {
49
57
  // Skip if we've already emitted this action for this screen
50
58
  continue;
51
59
  }
52
60
 
53
- // First, we need to check if any child screens want to prevent it
54
- const isPrevented = beforeRemoveListeners[route.key]?.(beforeRemoveAction);
55
-
56
- if (isPrevented) {
57
- return true;
58
- }
59
-
60
- visitedRouteKeys.add(route.key);
61
+ if (!nextRoutesByKey.has(route.key)) {
62
+ // The route is not in next state, so it's being removed
63
+ // First, we need to check if any child screens want to prevent it
64
+ const isPrevented = beforeRemoveListeners[route.key]?.(
65
+ beforeRemoveAction,
66
+ undefined
67
+ );
68
+
69
+ if (isPrevented) {
70
+ return true;
71
+ }
72
+
73
+ visitedRouteKeys.add(route.key);
74
+
75
+ const event = emitter.emit({
76
+ type: 'beforeRemove',
77
+ target: route.key,
78
+ data: { action: beforeRemoveAction },
79
+ canPreventDefault: true,
80
+ });
61
81
 
62
- const event = emitter.emit({
63
- type: 'beforeRemove',
64
- target: route.key,
65
- data: { action: beforeRemoveAction },
66
- canPreventDefault: true,
67
- });
82
+ if (event.defaultPrevented) {
83
+ return true;
84
+ }
85
+ } else {
86
+ // The route is kept but its nested state changed, so propagate the check into the nested navigator
87
+ const nextRoute = nextRoutesByKey.get(route.key);
88
+
89
+ if (route.state != null && route.state !== nextRoute?.state) {
90
+ const isPrevented = beforeRemoveListeners[route.key]?.(
91
+ beforeRemoveAction,
92
+ nextRoute?.state
93
+ );
68
94
 
69
- if (event.defaultPrevented) {
70
- return true;
95
+ if (isPrevented) {
96
+ return true;
97
+ }
98
+ }
71
99
  }
72
100
  }
73
101
 
@@ -85,17 +113,21 @@ export function useOnPreventRemove({
85
113
 
86
114
  React.useEffect(() => {
87
115
  if (routeKey) {
88
- return addKeyedListener?.('beforeRemove', routeKey, (action) => {
89
- const state = getState();
90
-
91
- return shouldPreventRemove(
92
- emitter,
93
- beforeRemoveListeners,
94
- state.routes,
95
- [],
96
- action
97
- );
98
- });
116
+ return addKeyedListener?.(
117
+ 'beforeRemove',
118
+ routeKey,
119
+ (action, nextState) => {
120
+ const state = getState();
121
+
122
+ return shouldPreventRemove(
123
+ emitter,
124
+ beforeRemoveListeners,
125
+ state.routes,
126
+ nextState?.routes ?? [],
127
+ action
128
+ );
129
+ }
130
+ );
99
131
  }
100
132
  }, [addKeyedListener, beforeRemoveListeners, emitter, getState, routeKey]);
101
133
  }