Open go-sean-go opened 2 years ago
You can change topOffset default in
/node_modules/react-native-toast-message/lib/src/useToast.js
I have set it at 55.
A better way to do this is to create a custom layout and add at least 10 to the top margin of the various toast components.
This probably isn't the best way, but we could check for the exact dimensions of the iPhone 14 Pro screen and adjust the top offset in useToast.ts like this.
const { height, width } = Dimensions.get("screen")
...
topOffset: (Platform.OS === 'ios' && height === '2556' && width === '1179') ? 55 : 40,
Facing a similar issue in iPhone 14 Pro
simulator as well.
@kiran-kumar011 you can add extra spacing to your custom layout for now. See my previous post.
On my side, with an iPhone 14 Pro, the display spot is perfect, but I can't see the borders (green or red, depending toast type). Any idea?
You can use import {useSafeAreaInsets} from 'react-native-safe-area-context';
Just weighing in as OP to clarify my intent with this issue:
For future readers/searchers, certainly the solutions above are reasonable (i.e. custom layout), but it is clearly the intention of the library to account for Safe Areas (hence the default value of topOffset
being 40
).
I think it would be a very valid solution for the library to be naive to Safe Areas, but in this case the default topOffset
should be 0
. This way, it will be immediately obvious to consumers of the library that they need to account for it manually, and consumers can add Safe Area support as needed (this could/should also be added to the README, since the solution of using the safe area library is so simple).
Of course, imo, the more reasonable solution is to account for Safe Areas using a common, well-supported community library (see above). This is what react-navigation
does, for example - and I would argue a 'toast' library is even more UI-oriented than a navigation library (so thus should make dealing with different idioms easier, not harder).
Either way - discarding Safe Area support completely, or supporting it completely - some decision should be made by a maintainer. The fix either way is very easy.
You can use
import {useSafeAreaInsets} from 'react-native-safe-area-context';
Can you explain how, please?
You can use
import {useSafeAreaInsets} from 'react-native-safe-area-context';
Can you explain how, please?
You can use this hook inside your main navigation component. For example:
const App = () => {
useEffect(() => {
SplashScreen.hide();
}, []);
return (
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<I18nextProvider i18n={i18n}>
<SafeAreaProvider>
<BottomSheetModalProvider>
<StatusBar
backgroundColor={'transparent'}
barStyle={'dark-content'}
translucent
/>
<Router />
</BottomSheetModalProvider>
</SafeAreaProvider>
</I18nextProvider>
</PersistGate>
</Provider>
);
};
const toastConfig = {
success: (props: BaseToastProps) => (
<BaseToast {...props} style={styles.baseToast} />
),
error: (props: BaseToastProps) => (
<ErrorToast {...props} style={styles.errorToast} />
),
};
const Router = () => {
const {top} = useSafeAreaInsets();
const isLogin = useAppSelector(state => state.auth.isLogin);
const initialRouteName = isLogin ? 'Tabs' : 'Auth';
return (
<>
<View style={styles.container}>
<NavigationContainer ref={navRef} theme={THEME}>
<RootStack.Navigator
screenOptions={SCREEN_OPTIONS}
initialRouteName={initialRouteName}>
<RootStack.Screen name="Auth" component={AuthStack} />
<RootStack.Screen name="Tabs" component={TabsStack} />
<RootStack.Screen name="Order" component={OrderStack} />
<RootStack.Screen
name="Modal"
options={{
gestureEnabled: true,
cardShadowEnabled: false,
cardOverlayEnabled: true,
gestureResponseDistance: s(150),
animationTypeForReplace: 'pop',
...TransitionPresets.ModalPresentationIOS,
}}
component={ModalStack}
/>
</RootStack.Navigator>
</NavigationContainer>
</View>
<Toast config={toastConfig} topOffset={top} />
</>
);
};
in my case. When I want to show toast position: 'top' on iPhone with dynamic island, I pass topOffset like this:
import { useSafeAreaInsets } from 'react-native-safe-area-context';
const insets = useSafeAreaInsets();
Toast.show({
type: 'notification',
position: 'top',
text1: title,
text2: body,
visibilityTime: MESSAGE_TIMEOUT,
topOffset: insets.top,
});
Describe the bug The default value for
topOffset
is 40, when really it should respect and read from the Safe Area. For reference, the notch on iPhone 13 and earlier was 47pt high, but the SafeArea on the new iPhone 14 Pro with Dynamic Island is 59pt high.I can't find any part of the library's code that takes Safe Area into consideration, but maybe I'm missing it. No matter the implementation: Toasts now show under or bordering on the physical elements on the iPhone 14 Pro, and may intrude on the Safe Area of other devices by default.
Steps to reproduce Steps to reproduce the behavior:
Expected behavior Toast message avoids the physical aspects of the phone and displays below the Safe Area. (I tend to use some minimum offset when
safeArea.bottom == 0
.)Screenshots Difficult to screenshot because the Dynamic Island/notch are not included in device screenshots.
Code sample Any should work. Please let me know if you cannot repro easily/reliably on an iPhone 14 Pro simulator/device and I can take the time to create one.
Environment (please complete the following information):
Additional context Add any other context about the problem here.