@react-navigation/core 7.0.0-alpha.6 → 7.0.0-alpha.7

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 (81) hide show
  1. package/lib/commonjs/BaseNavigationContainer.js +6 -1
  2. package/lib/commonjs/BaseNavigationContainer.js.map +1 -1
  3. package/lib/commonjs/index.js +27 -3
  4. package/lib/commonjs/index.js.map +1 -1
  5. package/lib/commonjs/theming/ThemeContext.js +12 -0
  6. package/lib/commonjs/theming/ThemeContext.js.map +1 -0
  7. package/lib/commonjs/theming/ThemeProvider.js +20 -0
  8. package/lib/commonjs/theming/ThemeProvider.js.map +1 -0
  9. package/lib/commonjs/theming/useTheme.js +18 -0
  10. package/lib/commonjs/theming/useTheme.js.map +1 -0
  11. package/lib/commonjs/types.js.map +1 -1
  12. package/lib/commonjs/useDescriptors.js +79 -16
  13. package/lib/commonjs/useDescriptors.js.map +1 -1
  14. package/lib/commonjs/useNavigationBuilder.js +10 -3
  15. package/lib/commonjs/useNavigationBuilder.js.map +1 -1
  16. package/lib/commonjs/useNavigationCache.js +55 -14
  17. package/lib/commonjs/useNavigationCache.js.map +1 -1
  18. package/lib/commonjs/useOnAction.js +3 -1
  19. package/lib/commonjs/useOnAction.js.map +1 -1
  20. package/lib/commonjs/usePreventRemove.js +2 -2
  21. package/lib/commonjs/usePreventRemove.js.map +1 -1
  22. package/lib/module/BaseNavigationContainer.js +6 -1
  23. package/lib/module/BaseNavigationContainer.js.map +1 -1
  24. package/lib/module/index.js +4 -1
  25. package/lib/module/index.js.map +1 -1
  26. package/lib/module/theming/ThemeContext.js +4 -0
  27. package/lib/module/theming/ThemeContext.js.map +1 -0
  28. package/lib/module/theming/ThemeProvider.js +12 -0
  29. package/lib/module/theming/ThemeProvider.js.map +1 -0
  30. package/lib/module/theming/useTheme.js +10 -0
  31. package/lib/module/theming/useTheme.js.map +1 -0
  32. package/lib/module/types.js.map +1 -1
  33. package/lib/module/useDescriptors.js +79 -16
  34. package/lib/module/useDescriptors.js.map +1 -1
  35. package/lib/module/useNavigationBuilder.js +10 -3
  36. package/lib/module/useNavigationBuilder.js.map +1 -1
  37. package/lib/module/useNavigationCache.js +55 -14
  38. package/lib/module/useNavigationCache.js.map +1 -1
  39. package/lib/module/useOnAction.js +3 -1
  40. package/lib/module/useOnAction.js.map +1 -1
  41. package/lib/module/usePreventRemove.js +1 -1
  42. package/lib/module/usePreventRemove.js.map +1 -1
  43. package/lib/typescript/src/BaseNavigationContainer.d.ts +1 -0
  44. package/lib/typescript/src/BaseNavigationContainer.d.ts.map +1 -1
  45. package/lib/typescript/src/NavigationStateContext.d.ts +2 -18
  46. package/lib/typescript/src/NavigationStateContext.d.ts.map +1 -1
  47. package/lib/typescript/src/findFocusedRoute.d.ts +1 -9
  48. package/lib/typescript/src/findFocusedRoute.d.ts.map +1 -1
  49. package/lib/typescript/src/index.d.ts +4 -1
  50. package/lib/typescript/src/index.d.ts.map +1 -1
  51. package/lib/typescript/src/theming/ThemeContext.d.ts +3 -0
  52. package/lib/typescript/src/theming/ThemeContext.d.ts.map +1 -0
  53. package/lib/typescript/src/theming/ThemeProvider.d.ts +8 -0
  54. package/lib/typescript/src/theming/ThemeProvider.d.ts.map +1 -0
  55. package/lib/typescript/src/theming/useTheme.d.ts +2 -0
  56. package/lib/typescript/src/theming/useTheme.d.ts.map +1 -0
  57. package/lib/typescript/src/types.d.ts +47 -1
  58. package/lib/typescript/src/types.d.ts.map +1 -1
  59. package/lib/typescript/src/useDescriptors.d.ts +106 -54
  60. package/lib/typescript/src/useDescriptors.d.ts.map +1 -1
  61. package/lib/typescript/src/useNavigationBuilder.d.ts +57 -64
  62. package/lib/typescript/src/useNavigationBuilder.d.ts.map +1 -1
  63. package/lib/typescript/src/useNavigationCache.d.ts +52 -2
  64. package/lib/typescript/src/useNavigationCache.d.ts.map +1 -1
  65. package/lib/typescript/src/useNavigationHelpers.d.ts +8 -55
  66. package/lib/typescript/src/useNavigationHelpers.d.ts.map +1 -1
  67. package/lib/typescript/src/useOnAction.d.ts.map +1 -1
  68. package/lib/typescript/src/usePreventRemove.d.ts +1 -1
  69. package/lib/typescript/src/usePreventRemove.d.ts.map +1 -1
  70. package/package.json +3 -3
  71. package/src/BaseNavigationContainer.tsx +6 -1
  72. package/src/index.tsx +4 -1
  73. package/src/theming/ThemeContext.tsx +7 -0
  74. package/src/theming/ThemeProvider.tsx +14 -0
  75. package/src/theming/useTheme.tsx +15 -0
  76. package/src/types.tsx +66 -1
  77. package/src/useDescriptors.tsx +148 -34
  78. package/src/useNavigationBuilder.tsx +18 -4
  79. package/src/useNavigationCache.tsx +84 -23
  80. package/src/useOnAction.tsx +6 -1
  81. package/src/usePreventRemove.tsx +1 -1
@@ -2,6 +2,7 @@ import type {
2
2
  NavigationAction,
3
3
  NavigationState,
4
4
  ParamListBase,
5
+ PartialState,
5
6
  Router,
6
7
  } from '@react-navigation/routers';
7
8
  import * as React from 'react';
@@ -14,6 +15,7 @@ import {
14
15
  import { NavigationContext } from './NavigationContext';
15
16
  import { NavigationRouteContext } from './NavigationRouteContext';
16
17
  import { SceneView } from './SceneView';
18
+ import { ThemeContext } from './theming/ThemeContext';
17
19
  import type {
18
20
  Descriptor,
19
21
  EventMapBase,
@@ -33,14 +35,23 @@ export type ScreenConfigWithParent<
33
35
  > = {
34
36
  keys: (string | undefined)[];
35
37
  options: (ScreenOptionsOrCallback<ScreenOptions> | undefined)[] | undefined;
38
+ layout: ScreenLayout | undefined;
36
39
  props: RouteConfig<ParamListBase, string, State, ScreenOptions, EventMap>;
37
40
  };
38
41
 
42
+ type ScreenLayout = (props: {
43
+ route: RouteProp<ParamListBase, string>;
44
+ navigation: any;
45
+ theme: ReactNavigation.Theme;
46
+ children: React.ReactElement;
47
+ }) => React.ReactElement;
48
+
39
49
  type ScreenOptionsOrCallback<ScreenOptions extends {}> =
40
50
  | ScreenOptions
41
51
  | ((props: {
42
52
  route: RouteProp<ParamListBase, string>;
43
53
  navigation: any;
54
+ theme: ReactNavigation.Theme;
44
55
  }) => ScreenOptions);
45
56
 
46
57
  type Options<
@@ -54,7 +65,8 @@ type Options<
54
65
  ScreenConfigWithParent<State, ScreenOptions, EventMap>
55
66
  >;
56
67
  navigation: NavigationHelpers<ParamListBase>;
57
- screenOptions?: ScreenOptionsOrCallback<ScreenOptions>;
68
+ screenOptions: ScreenOptionsOrCallback<ScreenOptions> | undefined;
69
+ screenLayout: ScreenLayout | undefined;
58
70
  onAction: (action: NavigationAction) => boolean;
59
71
  getState: () => State;
60
72
  setState: (state: State) => void;
@@ -83,6 +95,7 @@ export function useDescriptors<
83
95
  screens,
84
96
  navigation,
85
97
  screenOptions,
98
+ screenLayout,
86
99
  onAction,
87
100
  getState,
88
101
  setState,
@@ -92,6 +105,7 @@ export function useDescriptors<
92
105
  router,
93
106
  emitter,
94
107
  }: Options<State, ScreenOptions, EventMap>) {
108
+ const theme = React.useContext(ThemeContext);
95
109
  const [options, setOptions] = React.useState<Record<string, ScreenOptions>>(
96
110
  {}
97
111
  );
@@ -122,7 +136,12 @@ export function useDescriptors<
122
136
  ]
123
137
  );
124
138
 
125
- const navigations = useNavigationCache<State, ScreenOptions, EventMap>({
139
+ const { base, navigations } = useNavigationCache<
140
+ State,
141
+ ScreenOptions,
142
+ EventMap,
143
+ ActionHelpers
144
+ >({
126
145
  state,
127
146
  getState,
128
147
  navigation,
@@ -133,27 +152,20 @@ export function useDescriptors<
133
152
 
134
153
  const routes = useRouteCache(state.routes);
135
154
 
136
- return routes.reduce<
137
- Record<
155
+ const getOptions = (
156
+ route: RouteProp<ParamListBase, string>,
157
+ navigation: NavigationProp<
158
+ ParamListBase,
138
159
  string,
139
- Descriptor<
140
- ScreenOptions,
141
- NavigationProp<
142
- ParamListBase,
143
- string,
144
- string | undefined,
145
- State,
146
- ScreenOptions,
147
- EventMap
148
- > &
149
- ActionHelpers,
150
- RouteProp<ParamListBase>
151
- >
152
- >
153
- >((acc, route, i) => {
160
+ string | undefined,
161
+ State,
162
+ ScreenOptions,
163
+ EventMap
164
+ >,
165
+ overrides: Record<string, ScreenOptions>
166
+ ) => {
154
167
  const config = screens[route.name];
155
168
  const screen = config.props;
156
- const navigation = navigations[route.key];
157
169
 
158
170
  const optionsList = [
159
171
  // The default `screenOptions` passed to the navigator
@@ -165,18 +177,35 @@ export function useDescriptors<
165
177
  // The `options` prop passed to `Screen` elements,
166
178
  screen.options,
167
179
  // The options set via `navigation.setOptions`
168
- options[route.key],
180
+ overrides,
169
181
  ];
170
182
 
171
- const customOptions = optionsList.reduce<ScreenOptions>(
183
+ return optionsList.reduce<ScreenOptions>(
172
184
  (acc, curr) =>
173
185
  Object.assign(
174
186
  acc,
175
187
  // @ts-expect-error: we check for function but TS still complains
176
- typeof curr !== 'function' ? curr : curr({ route, navigation })
188
+ typeof curr !== 'function' ? curr : curr({ route, navigation, theme })
177
189
  ),
178
190
  {} as ScreenOptions
179
191
  );
192
+ };
193
+
194
+ const render = (
195
+ route: RouteProp<ParamListBase, string>,
196
+ navigation: NavigationProp<
197
+ ParamListBase,
198
+ string,
199
+ string | undefined,
200
+ State,
201
+ ScreenOptions,
202
+ EventMap
203
+ >,
204
+ customOptions: ScreenOptions,
205
+ routeState: NavigationState | PartialState<NavigationState> | undefined
206
+ ) => {
207
+ const config = screens[route.name];
208
+ const screen = config.props;
180
209
 
181
210
  const clearOptions = () =>
182
211
  setOptions((o) => {
@@ -189,24 +218,74 @@ export function useDescriptors<
189
218
  return o;
190
219
  });
191
220
 
192
- const element = (
221
+ const layout =
222
+ // The `layout` prop passed to `Screen` elements,
223
+ screen.layout ??
224
+ // The `screenLayout` props passed to `Group` elements
225
+ config.layout ??
226
+ // The default `screenLayout` passed to the navigator
227
+ screenLayout;
228
+
229
+ let element = (
230
+ <SceneView
231
+ navigation={navigation}
232
+ route={route}
233
+ screen={screen}
234
+ routeState={routeState}
235
+ getState={getState}
236
+ setState={setState}
237
+ options={customOptions}
238
+ clearOptions={clearOptions}
239
+ />
240
+ );
241
+
242
+ if (layout != null) {
243
+ element = layout({
244
+ route,
245
+ navigation,
246
+ // @ts-expect-error: in practice `theme` will be defined
247
+ theme,
248
+ children: element,
249
+ });
250
+ }
251
+
252
+ return (
193
253
  <NavigationBuilderContext.Provider key={route.key} value={context}>
194
254
  <NavigationContext.Provider value={navigation}>
195
255
  <NavigationRouteContext.Provider value={route}>
196
- <SceneView
197
- navigation={navigation}
198
- route={route}
199
- screen={screen}
200
- routeState={state.routes[i].state}
201
- getState={getState}
202
- setState={setState}
203
- options={customOptions}
204
- clearOptions={clearOptions}
205
- />
256
+ {element}
206
257
  </NavigationRouteContext.Provider>
207
258
  </NavigationContext.Provider>
208
259
  </NavigationBuilderContext.Provider>
209
260
  );
261
+ };
262
+
263
+ const descriptors = routes.reduce<
264
+ Record<
265
+ string,
266
+ Descriptor<
267
+ ScreenOptions,
268
+ NavigationProp<
269
+ ParamListBase,
270
+ string,
271
+ string | undefined,
272
+ State,
273
+ ScreenOptions,
274
+ EventMap
275
+ > &
276
+ ActionHelpers,
277
+ RouteProp<ParamListBase>
278
+ >
279
+ >
280
+ >((acc, route, i) => {
281
+ const navigation = navigations[route.key];
282
+ const customOptions = getOptions(route, navigation, options[route.key]);
283
+ const element = render(
284
+ route,
285
+ navigation,
286
+ customOptions,
287
+ state.routes[i].state
288
+ );
210
289
 
211
290
  acc[route.key] = {
212
291
  route,
@@ -220,4 +299,39 @@ export function useDescriptors<
220
299
 
221
300
  return acc;
222
301
  }, {});
302
+
303
+ /**
304
+ * Create a descriptor object for a route.
305
+ *
306
+ * @param route Route object for which the descriptor should be created
307
+ * @param placeholder Whether the descriptor should be a placeholder, e.g. for a route not yet in the state
308
+ * @returns Descriptor object
309
+ */
310
+ const describe = (route: RouteProp<ParamListBase>, placeholder: boolean) => {
311
+ if (!placeholder) {
312
+ if (!(route.key in descriptors)) {
313
+ throw new Error(`Couldn't find a route with the key ${route.key}.`);
314
+ }
315
+
316
+ return descriptors[route.key];
317
+ }
318
+
319
+ const navigation = base;
320
+ const customOptions = getOptions(route, navigation, {});
321
+ const element = render(route, navigation, customOptions, undefined);
322
+
323
+ return {
324
+ route,
325
+ navigation,
326
+ render() {
327
+ return element;
328
+ },
329
+ options: customOptions as ScreenOptions,
330
+ };
331
+ };
332
+
333
+ return {
334
+ describe,
335
+ descriptors,
336
+ };
223
337
  }
@@ -72,7 +72,8 @@ const getRouteConfigsFromChildren = <
72
72
  State,
73
73
  ScreenOptions,
74
74
  EventMap
75
- >['options']
75
+ >['options'],
76
+ groupLayout?: ScreenConfigWithParent<State, ScreenOptions, EventMap>['layout']
76
77
  ) => {
77
78
  const configs = React.Children.toArray(children).reduce<
78
79
  ScreenConfigWithParent<State, ScreenOptions, EventMap>[]
@@ -95,6 +96,7 @@ const getRouteConfigsFromChildren = <
95
96
  acc.push({
96
97
  keys: [groupKey, child.props.navigationKey],
97
98
  options: groupOptions,
99
+ layout: groupLayout,
98
100
  props: child.props as RouteConfig<
99
101
  ParamListBase,
100
102
  string,
@@ -103,6 +105,7 @@ const getRouteConfigsFromChildren = <
103
105
  EventMap
104
106
  >,
105
107
  });
108
+
106
109
  return acc;
107
110
  }
108
111
 
@@ -125,7 +128,8 @@ const getRouteConfigsFromChildren = <
125
128
  ? groupOptions
126
129
  : groupOptions != null
127
130
  ? [...groupOptions, child.props.screenOptions]
128
- : [child.props.screenOptions]
131
+ : [child.props.screenOptions],
132
+ child.props.screenLayout ?? groupLayout
129
133
  )
130
134
  );
131
135
  return acc;
@@ -259,7 +263,15 @@ export function useNavigationBuilder<
259
263
  | NavigatorRoute
260
264
  | undefined;
261
265
 
262
- const { children, layout, screenOptions, screenListeners, ...rest } = options;
266
+ const {
267
+ children,
268
+ layout,
269
+ screenOptions,
270
+ screenLayout,
271
+ screenListeners,
272
+ ...rest
273
+ } = options;
274
+
263
275
  const { current: router } = React.useRef<Router<State, any>>(
264
276
  createRouter(rest as unknown as RouterOptions)
265
277
  );
@@ -679,7 +691,7 @@ export function useNavigationBuilder<
679
691
  getStateListeners: keyedListeners.getState,
680
692
  });
681
693
 
682
- const descriptors = useDescriptors<
694
+ const { describe, descriptors } = useDescriptors<
683
695
  State,
684
696
  ActionHelpers,
685
697
  ScreenOptions,
@@ -689,6 +701,7 @@ export function useNavigationBuilder<
689
701
  screens,
690
702
  navigation,
691
703
  screenOptions,
704
+ screenLayout,
692
705
  onAction,
693
706
  getState,
694
707
  setState,
@@ -727,6 +740,7 @@ export function useNavigationBuilder<
727
740
  return {
728
741
  state,
729
742
  navigation,
743
+ describe,
730
744
  descriptors,
731
745
  NavigationContent,
732
746
  };
@@ -29,22 +29,25 @@ type Options<
29
29
  emitter: NavigationEventEmitter<EventMap>;
30
30
  };
31
31
 
32
- type NavigationCache<
32
+ type NavigationItem<
33
33
  State extends NavigationState,
34
34
  ScreenOptions extends {},
35
35
  EventMap extends Record<string, any>,
36
- > = Record<
36
+ > = NavigationProp<
37
+ ParamListBase,
37
38
  string,
38
- NavigationProp<
39
- ParamListBase,
40
- string,
41
- string | undefined,
42
- State,
43
- ScreenOptions,
44
- EventMap
45
- >
39
+ string | undefined,
40
+ State,
41
+ ScreenOptions,
42
+ EventMap
46
43
  >;
47
44
 
45
+ type NavigationCache<
46
+ State extends NavigationState,
47
+ ScreenOptions extends {},
48
+ EventMap extends Record<string, any>,
49
+ > = Record<string, NavigationItem<State, ScreenOptions, EventMap>>;
50
+
48
51
  /**
49
52
  * Hook to cache navigation objects for each screen in the navigator.
50
53
  * It's important to cache them to make sure navigation objects don't change between renders.
@@ -54,6 +57,7 @@ export function useNavigationCache<
54
57
  State extends NavigationState,
55
58
  ScreenOptions extends {},
56
59
  EventMap extends Record<string, any>,
60
+ ActionHelpers extends Record<string, () => void>,
57
61
  >({
58
62
  state,
59
63
  getState,
@@ -64,20 +68,72 @@ export function useNavigationCache<
64
68
  }: Options<State, ScreenOptions, EventMap>) {
65
69
  const { stackRef } = React.useContext(NavigationBuilderContext);
66
70
 
71
+ const base = React.useMemo((): NavigationItem<
72
+ State,
73
+ ScreenOptions,
74
+ EventMap
75
+ > &
76
+ ActionHelpers => {
77
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
78
+ const { emit, ...rest } = navigation;
79
+
80
+ const actions = {
81
+ ...router.actionCreators,
82
+ ...CommonActions,
83
+ };
84
+
85
+ const dispatch = () => {
86
+ throw new Error(
87
+ 'Actions cannot be dispatched from a placeholder screen.'
88
+ );
89
+ };
90
+
91
+ const helpers = Object.keys(actions).reduce<Record<string, () => void>>(
92
+ (acc, name) => {
93
+ acc[name] = dispatch;
94
+
95
+ return acc;
96
+ },
97
+ {}
98
+ ) as ActionHelpers;
99
+
100
+ return {
101
+ ...rest,
102
+ ...helpers,
103
+ addListener: () => {
104
+ // Event listeners are not supported for placeholder screens
105
+
106
+ return () => {
107
+ // Empty function
108
+ };
109
+ },
110
+ removeListener: () => {
111
+ // Event listeners are not supported for placeholder screens
112
+ },
113
+ dispatch,
114
+ getParent: (id?: string) => {
115
+ if (id !== undefined && id === rest.getId()) {
116
+ return base;
117
+ }
118
+
119
+ return rest.getParent(id);
120
+ },
121
+ setOptions: () => {
122
+ throw new Error('Options cannot be set from a placeholder screen.');
123
+ },
124
+ isFocused: () => false,
125
+ };
126
+ }, [navigation, router.actionCreators]);
127
+
67
128
  // Cache object which holds navigation objects for each screen
68
129
  // We use `React.useMemo` instead of `React.useRef` coz we want to invalidate it when deps change
69
130
  // In reality, these deps will rarely change, if ever
70
131
  const cache = React.useMemo(
71
132
  () => ({ current: {} as NavigationCache<State, ScreenOptions, EventMap> }),
72
133
  // eslint-disable-next-line react-hooks/exhaustive-deps
73
- [getState, navigation, setOptions, router, emitter]
134
+ [base, getState, navigation, setOptions, emitter]
74
135
  );
75
136
 
76
- const actions = {
77
- ...router.actionCreators,
78
- ...CommonActions,
79
- };
80
-
81
137
  cache.current = state.routes.reduce<
82
138
  NavigationCache<State, ScreenOptions, EventMap>
83
139
  >((acc, route) => {
@@ -91,9 +147,6 @@ export function useNavigationCache<
91
147
  // If a cached navigation object already exists, reuse it
92
148
  acc[route.key] = previous;
93
149
  } else {
94
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
95
- const { emit, ...rest } = navigation;
96
-
97
150
  const dispatch = (thunk: Thunk) => {
98
151
  const action = typeof thunk === 'function' ? thunk(getState()) : thunk;
99
152
 
@@ -124,6 +177,11 @@ export function useNavigationCache<
124
177
  }
125
178
  };
126
179
 
180
+ const actions = {
181
+ ...router.actionCreators,
182
+ ...CommonActions,
183
+ };
184
+
127
185
  const helpers = Object.keys(actions).reduce<Record<string, () => void>>(
128
186
  (acc, name) => {
129
187
  acc[name] = (...args: any) =>
@@ -138,19 +196,19 @@ export function useNavigationCache<
138
196
  );
139
197
 
140
198
  acc[route.key] = {
141
- ...rest,
199
+ ...base,
142
200
  ...helpers,
143
201
  // FIXME: too much work to fix the types for now
144
202
  ...(emitter.create(route.key) as any),
145
203
  dispatch: (thunk: Thunk) => withStack(() => dispatch(thunk)),
146
204
  getParent: (id?: string) => {
147
- if (id !== undefined && id === rest.getId()) {
205
+ if (id !== undefined && id === base.getId()) {
148
206
  // If the passed id is the same as the current navigation id,
149
207
  // we return the cached navigation object for the relevant route
150
208
  return acc[route.key];
151
209
  }
152
210
 
153
- return rest.getParent(id);
211
+ return base.getParent(id);
154
212
  },
155
213
  setOptions: (options: object) => {
156
214
  setOptions((o) => ({
@@ -175,5 +233,8 @@ export function useNavigationCache<
175
233
  return acc;
176
234
  }, {});
177
235
 
178
- return cache.current;
236
+ return {
237
+ base,
238
+ navigations: cache.current,
239
+ };
179
240
  }
@@ -131,7 +131,12 @@ export function useOnAction({
131
131
  }
132
132
  }
133
133
 
134
- if (typeof action.target === 'string' || navigationInChildEnabled) {
134
+ if (
135
+ typeof action.target === 'string' ||
136
+ // For backward compatibility
137
+ action.type === 'NAVIGATE_DEPRECATED' ||
138
+ navigationInChildEnabled
139
+ ) {
135
140
  // If the action wasn't handled by current navigator or a parent navigator, let children handle it
136
141
  // Handling this when target isn't specified is deprecated and will be removed in the future
137
142
  for (let i = actionListeners.length - 1; i >= 0; i--) {
@@ -14,7 +14,7 @@ import { useRoute } from './useRoute';
14
14
  * @param preventRemove Boolean indicating whether to prevent screen from being removed.
15
15
  * @param callback Function which is executed when screen was prevented from being removed.
16
16
  */
17
- export function UNSTABLE_usePreventRemove(
17
+ export function usePreventRemove(
18
18
  preventRemove: boolean,
19
19
  callback: (options: { data: { action: NavigationAction } }) => void
20
20
  ) {