@react-navigation/native-stack 8.0.0-alpha.4 → 8.0.0-alpha.40

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/index.js.map +1 -1
  2. package/lib/module/navigators/createNativeStackNavigator.js +4 -8
  3. package/lib/module/navigators/createNativeStackNavigator.js.map +1 -1
  4. package/lib/module/utils/useAnimatedHeaderHeight.js +1 -1
  5. package/lib/module/utils/useAnimatedHeaderHeight.js.map +1 -1
  6. package/lib/module/utils/useInvalidPreventRemoveError.js +1 -1
  7. package/lib/module/utils/useInvalidPreventRemoveError.js.map +1 -1
  8. package/lib/module/views/NativeStackView.js +39 -25
  9. package/lib/module/views/NativeStackView.js.map +1 -1
  10. package/lib/module/views/NativeStackView.native.js +99 -68
  11. package/lib/module/views/NativeStackView.native.js.map +1 -1
  12. package/lib/module/views/useHeaderConfigProps.js +71 -21
  13. package/lib/module/views/useHeaderConfigProps.js.map +1 -1
  14. package/lib/typescript/src/index.d.ts +3 -3
  15. package/lib/typescript/src/index.d.ts.map +1 -1
  16. package/lib/typescript/src/navigators/createNativeStackNavigator.d.ts +10 -15
  17. package/lib/typescript/src/navigators/createNativeStackNavigator.d.ts.map +1 -1
  18. package/lib/typescript/src/types.d.ts +145 -148
  19. package/lib/typescript/src/types.d.ts.map +1 -1
  20. package/lib/typescript/src/utils/getModalRoutesKeys.d.ts +1 -1
  21. package/lib/typescript/src/utils/getModalRoutesKeys.d.ts.map +1 -1
  22. package/lib/typescript/src/utils/useInvalidPreventRemoveError.d.ts +1 -1
  23. package/lib/typescript/src/utils/useInvalidPreventRemoveError.d.ts.map +1 -1
  24. package/lib/typescript/src/views/FooterComponent.d.ts +1 -1
  25. package/lib/typescript/src/views/FooterComponent.d.ts.map +1 -1
  26. package/lib/typescript/src/views/NativeStackView.d.ts +3 -2
  27. package/lib/typescript/src/views/NativeStackView.d.ts.map +1 -1
  28. package/lib/typescript/src/views/NativeStackView.native.d.ts +3 -2
  29. package/lib/typescript/src/views/NativeStackView.native.d.ts.map +1 -1
  30. package/lib/typescript/src/views/useHeaderConfigProps.d.ts +1 -1
  31. package/lib/typescript/src/views/useHeaderConfigProps.d.ts.map +1 -1
  32. package/package.json +18 -19
  33. package/src/index.tsx +1 -0
  34. package/src/navigators/createNativeStackNavigator.tsx +11 -47
  35. package/src/types.tsx +206 -186
  36. package/src/utils/useAnimatedHeaderHeight.tsx +1 -1
  37. package/src/utils/useInvalidPreventRemoveError.tsx +2 -1
  38. package/src/views/NativeStackView.native.tsx +148 -89
  39. package/src/views/NativeStackView.tsx +61 -41
  40. package/src/views/useHeaderConfigProps.tsx +100 -36
@@ -6,7 +6,7 @@ export const AnimatedHeaderHeightContext = React.createContext<
6
6
  >(undefined);
7
7
 
8
8
  export function useAnimatedHeaderHeight() {
9
- const animatedValue = React.useContext(AnimatedHeaderHeightContext);
9
+ const animatedValue = React.use(AnimatedHeaderHeightContext);
10
10
 
11
11
  if (animatedValue === undefined) {
12
12
  throw new Error(
@@ -8,7 +8,8 @@ export function useInvalidPreventRemoveError(
8
8
  ) {
9
9
  const { preventedRoutes } = usePreventRemoveContext();
10
10
  const preventedRouteKey = Object.keys(preventedRoutes)[0];
11
- const preventedDescriptor = descriptors[preventedRouteKey];
11
+ const preventedDescriptor =
12
+ preventedRouteKey == null ? undefined : descriptors[preventedRouteKey];
12
13
  const isHeaderBackButtonMenuEnabledOnPreventedScreen =
13
14
  preventedDescriptor?.options?.headerBackButtonMenuEnabled;
14
15
  const preventedRouteName = preventedDescriptor?.route?.name;
@@ -6,7 +6,10 @@ import {
6
6
  HeaderShownContext,
7
7
  useFrameSize,
8
8
  } from '@react-navigation/elements';
9
- import { SafeAreaProviderCompat } from '@react-navigation/elements/internal';
9
+ import {
10
+ ActivityView,
11
+ SafeAreaProviderCompat,
12
+ } from '@react-navigation/elements/internal';
10
13
  import {
11
14
  NavigationProvider,
12
15
  type ParamListBase,
@@ -44,19 +47,16 @@ import { useHeaderConfigProps } from './useHeaderConfigProps';
44
47
 
45
48
  const ANDROID_DEFAULT_HEADER_HEIGHT = 56;
46
49
 
47
- function isFabric() {
48
- return 'nativeFabricUIManager' in global;
49
- }
50
-
51
50
  type SceneViewProps = {
52
51
  index: number;
53
52
  focused: boolean;
54
- shouldFreeze: boolean;
55
53
  descriptor: NativeStackDescriptor;
56
- previousDescriptor?: NativeStackDescriptor;
57
- nextDescriptor?: NativeStackDescriptor;
58
- isPresentationModal?: boolean;
59
- isPreloaded?: boolean;
54
+ previousDescriptor?: NativeStackDescriptor | undefined;
55
+ nextDescriptor?: NativeStackDescriptor | undefined;
56
+ isPresentationModal: boolean;
57
+ isNextScreenTransparent: boolean;
58
+ isInactive: boolean;
59
+ isBeforeLast: boolean;
60
60
  onWillDisappear: () => void;
61
61
  onWillAppear: () => void;
62
62
  onAppear: () => void;
@@ -70,14 +70,20 @@ type SceneViewProps = {
70
70
 
71
71
  const useNativeDriver = Platform.OS !== 'web';
72
72
 
73
+ const TRANSPARENT_PRESENTATIONS = [
74
+ 'transparentModal',
75
+ 'containedTransparentModal',
76
+ ];
77
+
73
78
  const SceneView = ({
74
79
  index,
75
80
  focused,
76
- shouldFreeze,
77
81
  descriptor,
78
82
  previousDescriptor,
79
83
  isPresentationModal,
80
- isPreloaded,
84
+ isNextScreenTransparent,
85
+ isInactive,
86
+ isBeforeLast,
81
87
  onWillDisappear,
82
88
  onWillAppear,
83
89
  onAppear,
@@ -91,6 +97,7 @@ const SceneView = ({
91
97
  const { route, navigation, options, render } = descriptor;
92
98
 
93
99
  const {
100
+ inactiveBehavior = 'pause',
94
101
  animation,
95
102
  animationDuration,
96
103
  animationMatchesGesture,
@@ -123,7 +130,6 @@ const SceneView = ({
123
130
  statusBarStyle,
124
131
  unstable_sheetFooter,
125
132
  scrollEdgeEffects,
126
- freezeOnBlur,
127
133
  contentStyle,
128
134
  } = options;
129
135
 
@@ -147,9 +153,9 @@ const SceneView = ({
147
153
  // Modals are fullscreen in landscape only on iPhone
148
154
  const isIPhone = Platform.OS === 'ios' && !(Platform.isPad || Platform.isTV);
149
155
 
150
- const isParentHeaderShown = React.useContext(HeaderShownContext);
151
- const parentHeaderHeight = React.useContext(HeaderHeightContext);
152
- const parentHeaderBack = React.useContext(HeaderBackContext);
156
+ const isParentHeaderShown = React.use(HeaderShownContext);
157
+ const parentHeaderHeight = React.use(HeaderHeightContext);
158
+ const parentHeaderBack = React.use(HeaderBackContext);
153
159
 
154
160
  const isLandscape = useFrameSize((frame) => frame.width > frame.height);
155
161
 
@@ -226,6 +232,15 @@ const SceneView = ({
226
232
  headerBack,
227
233
  });
228
234
 
235
+ const headerContainerRef = React.useRef<View>(null);
236
+
237
+ React.useLayoutEffect(() => {
238
+ headerContainerRef.current?.measure((_x, _y, _width, height) => {
239
+ animatedHeaderHeight.setValue(height);
240
+ setHeaderHeight(height);
241
+ });
242
+ }, [animatedHeaderHeight]);
243
+
229
244
  const onHeaderHeightChange = hasCustomHeader
230
245
  ? // If we have a custom header, don't use native header height
231
246
  undefined
@@ -265,7 +280,8 @@ const SceneView = ({
265
280
  if (
266
281
  Platform.OS === 'android' &&
267
282
  headerHeight !== 0 &&
268
- headerHeight <= ANDROID_DEFAULT_HEADER_HEIGHT
283
+ // On some devices, height maybe slightly off (e.g. 56.17 instead of 56)
284
+ Math.round(headerHeight) <= ANDROID_DEFAULT_HEADER_HEIGHT
269
285
  ) {
270
286
  // FIXME: On Android, events may get delivered out-of-order
271
287
  // https://github.com/facebook/react-native/issues/54636
@@ -285,18 +301,96 @@ const SceneView = ({
285
301
  }
286
302
  );
287
303
 
304
+ const activityMode =
305
+ // Render focused screens normally
306
+ // Unpause preloaded and retained screens so updates are visible
307
+ // This lets effects on those screens run
308
+ // We don't need to handle inert as it'll be handled natively
309
+ inactiveBehavior === 'none' ||
310
+ focused ||
311
+ isInactive ||
312
+ isNextScreenTransparent
313
+ ? 'normal'
314
+ : inactiveBehavior === 'unmount' &&
315
+ !isBeforeLast &&
316
+ !('state' in route && route.state)
317
+ ? 'unmounted'
318
+ : 'paused';
319
+
320
+ const content = (
321
+ <AnimatedHeaderHeightContext.Provider value={animatedHeaderHeight}>
322
+ <HeaderHeightContext.Provider
323
+ value={headerShown !== false ? headerHeight : (parentHeaderHeight ?? 0)}
324
+ >
325
+ {headerBackground != null ? (
326
+ /**
327
+ * To show a custom header background, we render it at the top of the screen below the header
328
+ * The header also needs to be positioned absolutely (with `translucent` style)
329
+ */
330
+ <View
331
+ style={[
332
+ styles.background,
333
+ headerTransparent ? styles.translucent : null,
334
+ { height: headerHeight },
335
+ ]}
336
+ >
337
+ {headerBackground()}
338
+ </View>
339
+ ) : null}
340
+ {header != null && headerShown !== false ? (
341
+ <View
342
+ style={[
343
+ styles.header,
344
+ headerTransparent
345
+ ? [
346
+ styles.absolute,
347
+ // Specify an explicit min height for Android screen readers
348
+ { minHeight: headerHeight },
349
+ ]
350
+ : null,
351
+ ]}
352
+ >
353
+ <View
354
+ ref={headerContainerRef}
355
+ onLayout={(e) => {
356
+ const headerHeight = e.nativeEvent.layout.height;
357
+
358
+ animatedHeaderHeight.setValue(headerHeight);
359
+ setHeaderHeight(headerHeight);
360
+ }}
361
+ style={{ pointerEvents: 'box-none' }}
362
+ >
363
+ {header({
364
+ back: headerBack,
365
+ options,
366
+ route,
367
+ navigation,
368
+ })}
369
+ </View>
370
+ </View>
371
+ ) : null}
372
+ <HeaderShownContext.Provider
373
+ value={isParentHeaderShown || headerShown !== false}
374
+ >
375
+ <HeaderBackContext.Provider value={headerBack}>
376
+ {render()}
377
+ </HeaderBackContext.Provider>
378
+ </HeaderShownContext.Provider>
379
+ </HeaderHeightContext.Provider>
380
+ </AnimatedHeaderHeightContext.Provider>
381
+ );
382
+
288
383
  return (
289
384
  <NavigationProvider navigation={navigation} route={route}>
290
385
  <ScreenStackItem
291
386
  key={route.key}
292
387
  screenId={route.key}
293
- activityState={isPreloaded ? 0 : 2}
388
+ activityState={isInactive ? 0 : 2}
294
389
  style={StyleSheet.absoluteFill}
295
390
  aria-hidden={!focused}
296
391
  customAnimationOnSwipe={animationMatchesGesture}
297
392
  fullScreenSwipeEnabled={fullScreenGestureEnabled}
298
393
  fullScreenSwipeShadowEnabled={fullScreenGestureShadowEnabled}
299
- freezeOnBlur={freezeOnBlur}
300
394
  gestureEnabled={
301
395
  Platform.OS === 'android'
302
396
  ? // This prop enables handling of system back gestures on Android
@@ -353,62 +447,21 @@ const SceneView = ({
353
447
  ]}
354
448
  headerConfig={headerConfig}
355
449
  unstable_sheetFooter={unstable_sheetFooter}
356
- // When ts-expect-error is added, it affects all the props below it
357
- // So we keep any props that need it at the end
358
- // Otherwise invalid props may not be caught by TypeScript
359
- shouldFreeze={shouldFreeze}
360
450
  >
361
- <AnimatedHeaderHeightContext.Provider value={animatedHeaderHeight}>
362
- <HeaderHeightContext.Provider
363
- value={
364
- headerShown !== false ? headerHeight : (parentHeaderHeight ?? 0)
451
+ {activityMode === 'unmounted' ? null : (
452
+ <ActivityView
453
+ mode={activityMode}
454
+ visible={
455
+ // We don't need to hide the content since it's handled natively
456
+ // Hiding may also cause flash due to lag after native tab switch
457
+ // So we leave it always visible
458
+ true
365
459
  }
460
+ style={styles.content}
366
461
  >
367
- {headerBackground != null ? (
368
- /**
369
- * To show a custom header background, we render it at the top of the screen below the header
370
- * The header also needs to be positioned absolutely (with `translucent` style)
371
- */
372
- <View
373
- style={[
374
- styles.background,
375
- headerTransparent ? styles.translucent : null,
376
- { height: headerHeight },
377
- ]}
378
- >
379
- {headerBackground()}
380
- </View>
381
- ) : null}
382
- {header != null && headerShown !== false ? (
383
- <View
384
- onLayout={(e) => {
385
- const headerHeight = e.nativeEvent.layout.height;
386
-
387
- animatedHeaderHeight.setValue(headerHeight);
388
- setHeaderHeight(headerHeight);
389
- }}
390
- style={[
391
- styles.header,
392
- headerTransparent ? styles.absolute : null,
393
- ]}
394
- >
395
- {header({
396
- back: headerBack,
397
- options,
398
- route,
399
- navigation,
400
- })}
401
- </View>
402
- ) : null}
403
- <HeaderShownContext.Provider
404
- value={isParentHeaderShown || headerShown !== false}
405
- >
406
- <HeaderBackContext.Provider value={headerBack}>
407
- {render()}
408
- </HeaderBackContext.Provider>
409
- </HeaderShownContext.Provider>
410
- </HeaderHeightContext.Provider>
411
- </AnimatedHeaderHeightContext.Provider>
462
+ {content}
463
+ </ActivityView>
464
+ )}
412
465
  </ScreenStackItem>
413
466
  </NavigationProvider>
414
467
  );
@@ -425,46 +478,49 @@ export function NativeStackView({ state, navigation, descriptors }: Props) {
425
478
 
426
479
  useInvalidPreventRemoveError(descriptors);
427
480
 
428
- const modalRouteKeys = getModalRouteKeys(state.routes, descriptors);
481
+ const activeRoutes = state.routes.slice(0, state.index + 1);
482
+ const modalRouteKeys = getModalRouteKeys(activeRoutes, descriptors);
429
483
 
430
484
  return (
431
485
  <SafeAreaProviderCompat>
432
486
  <ScreenStack style={styles.container}>
433
- {state.routes.concat(state.preloadedRoutes).map((route, index) => {
487
+ {state.routes.map((route, index) => {
434
488
  const descriptor = descriptors[route.key];
489
+
490
+ if (descriptor == null) {
491
+ throw new Error(
492
+ `Couldn't find a descriptor for route '${route.key}'.`
493
+ );
494
+ }
495
+
435
496
  const isFocused = state.index === index;
436
- const isBelowFocused = state.index - 1 === index;
437
- const previousKey = state.routes[index - 1]?.key;
438
- const nextKey = state.routes[index + 1]?.key;
497
+ const previousKey = activeRoutes[index - 1]?.key;
498
+ const nextKey = activeRoutes[index + 1]?.key;
439
499
  const previousDescriptor = previousKey
440
500
  ? descriptors[previousKey]
441
501
  : undefined;
442
502
  const nextDescriptor = nextKey ? descriptors[nextKey] : undefined;
443
503
 
444
- const isModal = modalRouteKeys.includes(route.key);
445
- const isModalOnIos = isModal && Platform.OS === 'ios';
504
+ const nextPresentation = nextDescriptor?.options.presentation;
446
505
 
447
- const isPreloaded = state.preloadedRoutes.some(
448
- (r) => r.key === route.key
449
- );
506
+ const isNextScreenTransparent =
507
+ nextPresentation != null &&
508
+ TRANSPARENT_PRESENTATIONS.includes(nextPresentation);
450
509
 
451
- // On Fabric, when screen is frozen, animated and reanimated values are not updated
452
- // due to component being unmounted. To avoid this, we don't freeze the previous screen there
453
- const shouldFreeze = isFabric()
454
- ? !isPreloaded && !isFocused && !isBelowFocused && !isModalOnIos
455
- : !isPreloaded && !isFocused && !isModalOnIos;
510
+ const isModal = modalRouteKeys.includes(route.key);
456
511
 
457
512
  return (
458
513
  <SceneView
459
514
  key={route.key}
460
515
  index={index}
461
516
  focused={isFocused}
462
- shouldFreeze={shouldFreeze}
463
517
  descriptor={descriptor}
464
518
  previousDescriptor={previousDescriptor}
465
519
  nextDescriptor={nextDescriptor}
466
520
  isPresentationModal={isModal}
467
- isPreloaded={isPreloaded}
521
+ isNextScreenTransparent={isNextScreenTransparent}
522
+ isInactive={index > state.index}
523
+ isBeforeLast={index === activeRoutes.length - 2}
468
524
  onWillDisappear={() => {
469
525
  navigation.emit({
470
526
  type: 'transitionStart',
@@ -544,6 +600,9 @@ const styles = StyleSheet.create({
544
600
  container: {
545
601
  flex: 1,
546
602
  },
603
+ content: {
604
+ flex: 1,
605
+ },
547
606
  header: {
548
607
  zIndex: 1,
549
608
  },
@@ -6,6 +6,7 @@ import {
6
6
  useHeaderHeight,
7
7
  } from '@react-navigation/elements';
8
8
  import {
9
+ ActivityView,
9
10
  SafeAreaProviderCompat,
10
11
  Screen,
11
12
  } from '@react-navigation/elements/internal';
@@ -15,7 +16,7 @@ import {
15
16
  useLinkBuilder,
16
17
  } from '@react-navigation/native';
17
18
  import * as React from 'react';
18
- import { Animated, Image, StyleSheet, View } from 'react-native';
19
+ import { Animated, StyleSheet, View } from 'react-native';
19
20
 
20
21
  import type {
21
22
  NativeStackDescriptorMap,
@@ -35,20 +36,30 @@ const TRANSPARENT_PRESENTATIONS = [
35
36
  ];
36
37
 
37
38
  export function NativeStackView({ state, descriptors }: Props) {
38
- const parentHeaderBack = React.useContext(HeaderBackContext);
39
+ const parentHeaderBack = React.use(HeaderBackContext);
39
40
  const { buildHref } = useLinkBuilder();
40
41
 
42
+ const activeRoutes = state.routes.slice(0, state.index + 1);
43
+
41
44
  return (
42
45
  <SafeAreaProviderCompat>
43
- {state.routes.concat(state.preloadedRoutes).map((route, i) => {
46
+ {state.routes.map((route, i) => {
44
47
  const isFocused = state.index === i;
45
- const previousKey = state.routes[i - 1]?.key;
46
- const nextKey = state.routes[i + 1]?.key;
48
+ const previousKey = activeRoutes[i - 1]?.key;
49
+ const nextKey = activeRoutes[i + 1]?.key;
47
50
  const previousDescriptor = previousKey
48
51
  ? descriptors[previousKey]
49
52
  : undefined;
50
53
  const nextDescriptor = nextKey ? descriptors[nextKey] : undefined;
51
- const { options, navigation, render } = descriptors[route.key];
54
+ const descriptor = descriptors[route.key];
55
+
56
+ if (descriptor == null) {
57
+ throw new Error(
58
+ `Couldn't find a descriptor for route '${route.key}'.`
59
+ );
60
+ }
61
+
62
+ const { options, navigation, render } = descriptor;
52
63
 
53
64
  const headerBack = previousDescriptor
54
65
  ? {
@@ -66,6 +77,7 @@ export function NativeStackView({ state, descriptors }: Props) {
66
77
  const canGoBack = headerBack != null;
67
78
 
68
79
  const {
80
+ inactiveBehavior = 'pause',
69
81
  header,
70
82
  headerShown,
71
83
  headerBackIcon,
@@ -79,11 +91,33 @@ export function NativeStackView({ state, descriptors }: Props) {
79
91
 
80
92
  const nextPresentation = nextDescriptor?.options.presentation;
81
93
 
82
- const isPreloaded = state.preloadedRoutes.some(
83
- (r) => r.key === route.key
84
- );
94
+ const isNextScreenTransparent =
95
+ nextPresentation != null &&
96
+ TRANSPARENT_PRESENTATIONS.includes(nextPresentation);
85
97
 
86
- return (
98
+ const isInactive = i > state.index;
99
+
100
+ const isBeforeLast = i === activeRoutes.length - 2;
101
+
102
+ const activityMode =
103
+ // Render focused screens normally
104
+ isFocused
105
+ ? 'normal'
106
+ : // Unpause preloaded and retained screens so updates are visible
107
+ // This lets effects on those screens run
108
+ inactiveBehavior === 'none' ||
109
+ isInactive ||
110
+ isNextScreenTransparent
111
+ ? 'inert'
112
+ : inactiveBehavior === 'unmount' && !isBeforeLast && !route.state
113
+ ? 'unmounted'
114
+ : 'paused';
115
+
116
+ if (activityMode === 'unmounted') {
117
+ return null;
118
+ }
119
+
120
+ const content = (
87
121
  <Screen
88
122
  key={route.key}
89
123
  focused={isFocused}
@@ -117,18 +151,7 @@ export function NativeStackView({ state, descriptors }: Props) {
117
151
  {...rest}
118
152
  label={headerBackTitle ?? label}
119
153
  tintColor={tintColor}
120
- backImage={
121
- headerBackIcon !== undefined
122
- ? () => (
123
- <Image
124
- source={headerBackIcon.source}
125
- resizeMode="contain"
126
- tintColor={tintColor}
127
- style={styles.backImage}
128
- />
129
- )
130
- : undefined
131
- }
154
+ icon={headerBackIcon}
132
155
  onPress={navigation.goBack}
133
156
  />
134
157
  )
@@ -138,22 +161,13 @@ export function NativeStackView({ state, descriptors }: Props) {
138
161
  />
139
162
  )
140
163
  }
141
- style={[
142
- StyleSheet.absoluteFill,
143
- {
144
- display:
145
- (isFocused ||
146
- (nextPresentation != null &&
147
- TRANSPARENT_PRESENTATIONS.includes(nextPresentation))) &&
148
- !isPreloaded
149
- ? 'flex'
150
- : 'none',
151
- },
152
- presentation != null &&
164
+ style={{
165
+ ...StyleSheet.absoluteFill,
166
+ ...(presentation != null &&
153
167
  TRANSPARENT_PRESENTATIONS.includes(presentation)
154
168
  ? { backgroundColor: 'transparent' }
155
- : null,
156
- ]}
169
+ : null),
170
+ }}
157
171
  >
158
172
  <HeaderBackContext.Provider value={headerBack}>
159
173
  <AnimatedHeaderHeightProvider>
@@ -164,6 +178,17 @@ export function NativeStackView({ state, descriptors }: Props) {
164
178
  </HeaderBackContext.Provider>
165
179
  </Screen>
166
180
  );
181
+
182
+ return (
183
+ <ActivityView
184
+ key={route.key}
185
+ mode={activityMode}
186
+ visible={isFocused || isNextScreenTransparent}
187
+ style={StyleSheet.absoluteFill}
188
+ >
189
+ {content}
190
+ </ActivityView>
191
+ );
167
192
  })}
168
193
  </SafeAreaProviderCompat>
169
194
  );
@@ -194,9 +219,4 @@ const styles = StyleSheet.create({
194
219
  contentContainer: {
195
220
  flex: 1,
196
221
  },
197
- backImage: {
198
- height: 24,
199
- width: 24,
200
- margin: 3,
201
- },
202
222
  });