Open JLLLinn opened 7 years ago
+1
is there any solution now?
Hi @zzyjiaxinmomo @iooi @Oct4Pie, Can you provide small snack example ?
Hi @zzyjiaxinmomo @iooi @Oct4Pie, Can you provide small snack example ?
Hello, @Viraj-10. Here it is:
import React from "react";
import {
Text,
HStack,
Center,
Switch,
useColorMode,
NativeBaseProvider,
extendTheme,
VStack,
Modal,
Input,
FormControl,
Button,
useToast,
} from "native-base";
const config = {
useSystemColorMode: false,
initialColorMode: "dark",
};
export const theme = extendTheme({ config });
export default function App() {
const [show, setShow] = React.useState(false);
const toast = useToast();
return (
<NativeBaseProvider>
<Center
_dark={{ bg: "blueGray.900" }}
_light={{ bg: "blueGray.50" }}
px={4}
flex={1}
>
<VStack space='3' >
<Modal onClose={() => setShow(false)} isOpen={show}>
<Modal.Content>
<Modal.CloseButton />
<Modal.Header>Sign In</Modal.Header>
<Modal.Body>
Please enter your credentials to proceed
<FormControl mt={{
'base': '3',
'lg': '4',
'2xl': '5',
}}>
<FormControl.Label>Email</FormControl.Label>
<Input />
</FormControl>
<FormControl mt={{
'base': '3',
'lg': '4',
'2xl': '5',
}}>
<FormControl.Label>Password</FormControl.Label>
<Input />
</FormControl>
</Modal.Body>
<Modal.Footer>
<Button onPress={() => {
toast.show({
// variant: "solid",
description: "You are signed in!",
})
// setShow(false);
}}>
Sign In
</Button>
</Modal.Footer>
</Modal.Content>
</Modal>
<VStack space={8} alignItems="center">
<Button w="104" onPress={() => {
setShow(!show);
}}>
Sign In Modal
</Button>
</VStack>
<ToggleDarkMode />
</VStack>
<SignInModal />
</Center>
</NativeBaseProvider>
);
}
const SignInModal = () => {
const [show, setShow] = React.useState(false);
const toast = useToast();
return <VStack space='3' >
<Modal onClose={() => setShow(false)} isOpen={show}>
<Modal.Content>
<Modal.CloseButton />
<Modal.Header>Sign In</Modal.Header>
<Modal.Body>
Please enter your credentials to proceed
<FormControl mt={{
'base': '3',
'lg': '4',
'2xl': '5',
}}>
<FormControl.Label>Email</FormControl.Label>
<Input />
</FormControl>
<FormControl mt={{
'base': '3',
'lg': '4',
'2xl': '5',
}}>
<FormControl.Label>Password</FormControl.Label>
<Input />
</FormControl>
</Modal.Body>
<Modal.Footer>
<Button onPress={() => {
toast.show({
variant: "solid",
description: "You are signed in!",
})
// setShow(false);
}}>
Sign In
</Button>
</Modal.Footer>
</Modal.Content>
</Modal>
<VStack space={8} alignItems="center">
<Button onPress={() => {
setShow(!show);
}}>
Sign In Modal (component)
</Button>
</VStack>
</VStack>;
}
function ToggleDarkMode() {
const { colorMode, toggleColorMode } = useColorMode();
return (
<HStack space={2} alignItems="center">
<Text>Dark</Text>
<Switch
isChecked={colorMode === "light"}
onToggle={toggleColorMode}
aria-label={
colorMode === "light" ? "switch to dark mode" : "switch to light mode"
}
/>
<Text>Light</Text>
</HStack>
);
}
As you can see, useToast
does not work in the default
App function. I need the modal to be in App
since the state variables must be passed to other screens. I couldn't find a way to solve this issue and wrote a similar component to toast, but it's not as efficient.
Hi All, Let me explain what's going on internally.
On Android, we use RN Modal
and on IOS we use Overlay Component which is View with absoluteFill
Styling.
Since IOS doesn't support multiple Modal we have to render an Overlay.
Now, whenever you render RN modal
on android it mounts on top of the application but toast is again an overlay. So it renders below RN Modal
.
Solution
Complete remove RN Modal and use Overlay instead. (Difficulties Accessibility).
Is there any solution to this yet?
that solution worked in my case https://github.com/calintamas/react-native-toast-message/blob/main/docs/modal-usage.md just add "Toast" tag inside the Modal component
I've been struggling with this for a while and found a pretty acceptable solution! 🥳
Toast
component receives its properties, I found that the component could receive a property called _overlay
And the Overlay
component receive a style
prop
_overlay
.const theme = extendTheme({
{...}
components: {
Toast: {
defaultProps: {
_overlay: { style: { zIndex: 999 } }
}
}
}
});
then, by passing a high zIndex, the toast is displayed above the Modal! 🎉
note: using Modal
& Toast
both from native-base
v3.4.23
"useRNModalOnAndroid: false", default for component "Modal" helped
const theme = extendTheme({
components: {
Modal: {
defaultProps: {
_overlay: {
useRNModalOnAndroid: false,
},
},
},
}
});
"useRNModalOnAndroid: false", default for component "Modal" helped
const theme = extendTheme({ components: { Modal: { defaultProps: { _overlay: { useRNModalOnAndroid: false, }, }, }, } });
your initial problem was in android or iOS?
calintamas/react-native-toast-message it is very simple and easy to use.
it's 2023, any updates to fix this bug?
In short, no...they slowly (and quietly) moved on to another project - https://ui.gluestack.io/
After trying everything here and with no luck, I still kept struggling with this for a long time, and after checking how Toast works multiple times I've come across a workaround that finally worked for me.
So under the hood it is using useContext
and there is a Provider that is also exported in native-base
called ToastProvider
, and when you use it Inside the Modal it works as expected.
Here's a sample code:
Container.tsx
import { useState } from "react";
// components
import { Button, Center, VStack, useToast } from "native-base";
import ModalToast from "./ModalToast";
const Container = () => {
const toast = useToast();
const [isOpen, setIsOpen] = useState(false);
const closeModal = () => {
setIsOpen(false);
};
const openModal = () => {
setIsOpen(true);
};
const showToast = () => {
toast.show({ title: "A Regular Toast In App" });
};
return (
<Center flex={1}>
<VStack space={5}>
<Button onPress={openModal}>Open Modal</Button>
<Button onPress={showToast}>Show Outer Toast</Button>
</VStack>
<ModalToast isOpen={isOpen} onClose={closeModal} />
</Center>
);
};
export default Container;
ModalToast.tsx
import {
Button,
Center,
HStack,
Modal,
ToastProvider,
useToast,
} from "native-base";
const ModalContent = ({ onClose }: { onClose: () => void }) => {
const toast = useToast();
const showToast = () => {
toast.show({ title: "A Toast over the modal" });
};
return (
<Center flex={1}>
<HStack space={4}>
<Button onPress={showToast}>Show Toast</Button>
<Button onPress={onClose}>Close Modal</Button>
</HStack>
</Center>
);
};
interface ModalToastProps {
isOpen: boolean;
onClose: () => void;
}
const ModalToast = ({ isOpen, onClose }: ModalToastProps) => (
<Modal
isOpen={isOpen}
animationPreset="slide"
bg="gray.200"
onClose={onClose}
safeAreaBottom
>
<ToastProvider>
<ModalContent onClose={onClose} />
</ToastProvider>
</Modal>
);
export default ModalToast;
The only issue is that the App toast still stays under the modal, as the one inside the modal is another provider so it displays whole other Toast.
https://github.com/GeekyAnts/NativeBase/assets/86891301/7af924fd-6ff1-4d2a-8315-b2ba122b98a9
Using both Modal
& Toast
from native-base
v3.4.28
Hope this will be of help.
A workaround is to set RNModal to false
<Modal
_overlay={{
useRNModal: false,
useRNModalOnAndroid: false,
}}
>
I mean, realistically, NativeBase is abandoned. I've just moved all Toast to react-native-toast-message. Bit by bit, I'm slowly removing native-base from my project.
I'll never go to gluestack if this how they handle projects. They'll abandon gluestack too as soon as a new shiny thing coming down the line.
Can we get the refund?
I have my own separate context provider for toasters, which wraps the parts of my application I need. And as I see, everything now works as it should on iOS devices. And for Android, the setup that astaninivan1 suggested helped me. https://github.com/GeekyAnts/NativeBase/issues/985#issuecomment-1511680753 But the fact that the NB has not been updated for a year makes me sad...
react-native, react and native-base version
RN: 0.45.1 React:16.0.0-alpha.12 native-base: 2.1.5
Expected behaviour
Toast to be shown in react native Modal
Actual behaviour
The toast is not shown in react native Modal
Steps to reproduce (code snippet or screenshot)
Do Toast.show() in a Modal
Is the bug present in both ios and android or in any one of them?
No that I know of. This was working with RN on 0.44 and native-base on a lower version (I can't remember exactly which one, either 2.1.4 or 2.1.3)