Skip to content

Commit 8c4273a

Browse files
authored
fix(FabricExample): Wrap some components with SAV to prevent hiding behind navigation bar (#3944)
## Description Important for e2e tests. Some pressabels weren't working on Android 10, because were hidden behind old-style navigation bar. Also changing the approach for Toast #3942 , becaue after internal discussion we decided that we shouldn't rely on `react-native-safe-area-context` and use our SAV with proper edges configuration. ## Changes - add paddingBottom to ScrollView content - revert changes from #3942 - wrap ToastProvider with SAV ## Before & after - visual documentation | Before | After | | --- | --- | | <img width="592" height="1228" alt="Screenshot 2026-04-28 at 10 32 21" src="https://github.com/user-attachments/assets/7bfcfceb-cb7b-4c3a-a18d-0922aa7bf7e3" /> | <img width="610" height="1224" alt="Screenshot 2026-04-28 at 10 31 47" src="https://github.com/user-attachments/assets/6873399a-a591-49c4-bf89-04cb6634d431" /> | ## Test plan ScrollView from SFT -> Tabs ## Checklist - [ ] Included code example that can be used to test this change. - [ ] For visual changes, included screenshots / GIFs / recordings documenting the change. - [ ] For API changes, updated relevant public types. - [ ] Ensured that CI passes
1 parent ff39900 commit 8c4273a

2 files changed

Lines changed: 50 additions & 65 deletions

File tree

apps/src/shared/Toast.tsx

Lines changed: 14 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,10 @@ import {
66
Dimensions,
77
View,
88
ViewStyle,
9+
Platform,
910
} from 'react-native';
1011
import { nanoid } from 'nanoid/non-secure';
11-
import {
12-
SafeAreaProvider,
13-
useSafeAreaInsets,
14-
} from 'react-native-safe-area-context';
12+
import { SafeAreaView } from 'react-native-screens/experimental';
1513

1614
interface ToastProps {
1715
index: number;
@@ -67,30 +65,6 @@ const ToastContext = createContext({
6765
},
6866
});
6967

70-
const ToastContainer = ({
71-
toasts,
72-
remove,
73-
}: {
74-
toasts: IToast[];
75-
remove: (id: string) => void;
76-
}) => {
77-
const insets = useSafeAreaInsets();
78-
79-
return (
80-
<>
81-
{toasts.map((toast, i) => (
82-
<Toast
83-
index={i}
84-
key={toast.id}
85-
style={{ bottom: insets.bottom + 5 + i * 25 }}
86-
{...toast}
87-
remove={remove}
88-
/>
89-
))}
90-
</>
91-
);
92-
};
93-
9468
interface ToastProviderProps {
9569
children: React.ReactNode;
9670
}
@@ -108,15 +82,22 @@ export const ToastProvider = ({ children }: ToastProviderProps) => {
10882
};
10983

11084
return (
111-
<SafeAreaProvider>
85+
<SafeAreaView edges={{ bottom: Platform.OS === 'android' }}>
11286
<ToastContext.Provider value={{ push }}>
11387
<>
11488
{children}
115-
{/* Render the internal container */}
116-
<ToastContainer toasts={toasts} remove={remove} />
89+
{toasts.map((toast, i) => (
90+
<Toast
91+
index={i}
92+
key={toast.id}
93+
style={{ marginBottom: i * 25 }}
94+
{...toast}
95+
remove={remove}
96+
/>
97+
))}
11798
</>
11899
</ToastContext.Provider>
119-
</SafeAreaProvider>
100+
</SafeAreaView>
120101
);
121102
};
122103

@@ -127,6 +108,7 @@ const styles = StyleSheet.create({
127108
flex: 1,
128109
position: 'absolute',
129110
alignSelf: 'center',
111+
bottom: 5,
130112
},
131113
alert: {
132114
alignItems: 'center',
Lines changed: 36 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import React, { useMemo } from 'react';
2-
import { ScrollView } from 'react-native';
2+
import { Platform, ScrollView } from 'react-native';
33
import type { Scenario, ScenarioGroup } from './helpers';
44
import { ScenarioButton } from './ScenarioButton';
55
import { createNativeStackNavigator } from '@react-navigation/native-stack';
66
import {
77
NavigationContainer,
88
NavigationIndependentTree,
99
} from '@react-navigation/native';
10+
import { SafeAreaView } from 'react-native-screens/experimental';
1011

1112
function ScenarioSelect(props: {
1213
scenarios: Record<string, Scenario>;
@@ -41,38 +42,40 @@ export default function ScenarioSelectionScreen(props: {
4142
const Stack = useMemo(() => createNativeStackNavigator(), []);
4243

4344
return (
44-
<NavigationIndependentTree>
45-
<NavigationContainer>
46-
<Stack.Navigator screenOptions={{ headerShown: false }}>
47-
<Stack.Screen
48-
key="Main"
49-
name="Main"
50-
options={{
51-
headerShown: true,
52-
headerLargeTitleEnabled: true,
53-
headerTitle: props.scenarioGroup.name,
54-
}}>
55-
{() => (
56-
<ScenarioSelect
57-
scenarios={props.scenarioGroup.scenarios}
58-
groupName={props.scenarioGroup.name}
59-
/>
60-
)}
61-
</Stack.Screen>
62-
{Object.values<Scenario>(props.scenarioGroup.scenarios).map(
63-
(ScenarioComponent: Scenario) => {
64-
const { key } = ScenarioComponent.scenarioDescription;
65-
return (
66-
<Stack.Screen
67-
key={key}
68-
name={key}
69-
component={ScenarioComponent}
45+
<SafeAreaView edges={{ bottom: Platform.OS === 'android' }}>
46+
<NavigationIndependentTree>
47+
<NavigationContainer>
48+
<Stack.Navigator screenOptions={{ headerShown: false }}>
49+
<Stack.Screen
50+
key="Main"
51+
name="Main"
52+
options={{
53+
headerShown: true,
54+
headerLargeTitleEnabled: true,
55+
headerTitle: props.scenarioGroup.name,
56+
}}>
57+
{() => (
58+
<ScenarioSelect
59+
scenarios={props.scenarioGroup.scenarios}
60+
groupName={props.scenarioGroup.name}
7061
/>
71-
);
72-
},
73-
)}
74-
</Stack.Navigator>
75-
</NavigationContainer>
76-
</NavigationIndependentTree>
62+
)}
63+
</Stack.Screen>
64+
{Object.values<Scenario>(props.scenarioGroup.scenarios).map(
65+
(ScenarioComponent: Scenario) => {
66+
const { key } = ScenarioComponent.scenarioDescription;
67+
return (
68+
<Stack.Screen
69+
key={key}
70+
name={key}
71+
component={ScenarioComponent}
72+
/>
73+
);
74+
},
75+
)}
76+
</Stack.Navigator>
77+
</NavigationContainer>
78+
</NavigationIndependentTree>
79+
</SafeAreaView>
7780
);
7881
}

0 commit comments

Comments
 (0)