By: Niraj Dhungana
Jan 14 2022
Share:
You if are familiar with react-native then we have a built-in Modal component. We can use it like this.
1// works only in react native
2import {Modal} from 'react-native'
3const MyModal= ({ visible }) => {
4 return (
5 <Modal visible={visible}>
6 ...
7 </Modal>
8)}
9
Here we need to import the Modal component and we can pass the state like visible to show and hide the Modal. Now in this post we will see how we can create that same kind of modal inside React using Tailwind CSS.
1// our fianl project
2import {CustomModal} from './components'
3const App= () => {
4...
5 return (
6 <CustomModal visible={showModal}>
7 {/* your content */}
8 </CustomModal>
9)}
10
Let’s start coding.
First you have to create a project using React and Tailwind CSS. And I hope you already have those thighs setup. If not then you can follow this doc to create projects with react and tailwind css.
Now I hope you have initialized your project. Now let's create a button using which we can open and close a modal.
1export default function App() {
2 return (
3 <div className="w-screen h-screen flex items-center justify-center">
4 <button className="py-2 px-5 bg-blue-500 text-white">
5 Open Modal
6 </button>
7 </div>
8 );
9}
10
This is the code that I am using to create this button. Here I have this div with flex and justify-center and item-center also you can see we have this width and height full of screen and that is because I want to make this button at the center of this container.
Now you should see something like this.
Now we have our button it is time to create the model itself. I am going to create this model with fixed height and width which is going to appear at the top of any component.
For that inside Tailwind CSS there is this very interesting class called inset-0
. So let's see how we can use it.
1
2export default function CustomModal({children}) {
3 return (
4 <div
5 className="fixed inset-0 flex items-center justify-center bg-black bg-opacity-50 backdrop-blur-sm"
6 >
7 {children}
8 </div>
9 );
10}
11
Inside this custom modal component first of all I am accepting these children
as the prop
of this component. Now let me explain the meaning of these classes
.
First two or three classes
are self-explanatory but here what we are doing first we are making its position: fixed;
and giving this class
called inset-0
. Which means it will now cover the entire screen because it is fixed so it will appear at the top of any component.
And these flex
properties will render children at the center of this CustomModal
component. Then we have this class called bg-black
for background, bg-opacity-50
to give background an opacity of 50 and finally we have backdrop-blur-sm
to give our React Modal a blurry effect.
1...
2import CustomModal from "./components/CustomModal";
3
4export default function App() {
5 return (
6 <>
7 <div className="...">
8 <button className="...">
9 Open Modal
10 </button>
11 </div>
12 <CustomModal>
13 {/* here you can add your other components (JSX)*/}
14 </CustomModal>
15 </>
16 );
17}
18
19
Now you should see something like this. If you render this modal inside the App component like above. Also you can use any of your components.
Now we have our modal ready, let's handle the state so that we can show and hide this modal according to our need.
1export default function CustomModal({ children, visible }) {
2 if (!visible) return null;
3
4 return (
5 <div className="use above classes">
6 {children}
7 </div>
8 );
9}
10
Here we are accepting another prop called visible
which will be a boolean
value. And if this value is false
we are rendering null
which means nothing.
Now we have the prop
called visible
which we can use to show and hide our Modal. We can manage this state inside the component where we are rendering the Modal.
1import React, { useState } from "react";
2import CustomModal from "./components/CustomModal";
3
4export default function App() {
5 const [showModal, setShowModal] = useState(false);
6 return (
7 <>
8 <div className="...">
9 <button className="..."
10 onClick={() => setShowModal(false)}
11 >
12 Open Modal
13 </button>
14 </div>
15 <CustomModal visible={showModal}>
16 {/* here you can add your other components (JSX)*/}
17 </CustomModal>
18 </>
19 );
20}
21
22
Like here I can use this showModal
state inside the App
component because I am rendering the Modal inside App.js. And if you notice (line-10) I am using that onClick listenner to change the state or open the Modal component.
Now let’s see how we can close the modal for that. This time I will start with the App
component. Here I am going to pass a prop to our CustomModal called onClose
. Which will change the state of showModal
to false
. See code below.
1...
2export default function App() {
3 const [showModal, setShowModal] = useState(false);
4 return (
5 <>
6 <div className="...">
7 ...
8 </div>
9 <CustomModal
10 onClose={() => setShowModal(false)}
11 visible={showModal}
12 >
13 {/* here you can add your other components (JSX)*/}
14 </CustomModal>
15 </>
16 );
17}
18
19
Now we will get that onClose prop inside our CustomModal
and use it to hide the modal.
1export default function CustomModal({ children, visible, onClose }) {
2 if (!visible) return null;
3
4 const handleOnBackDropClick = (e) => {
5 if (e.target.id === "backdrop") onClose && onClose();
6 };
7
8 return (
9 <div
10 id="backdrop"
11 onClick={handleOnBackDropClick}
12 className="..."
13 >
14 {children}
15 </div>
16 );
17}
18
19
Here we are first destructuring the prop (onClose
) then calling it inside the handleBackdropClick
method if the clicked element has the ID called backdrop
. Because if you don’t check the ID our modal will close anywhere we click. This is called event bubbling.
Also you can create a separate close button to close the Modal.
And don’t forget to add that id=’backdrop’
inside the main container (line number 10).
Now if you render something inside the Modal like I am rendering this fake newsletter component. You will see something like this.
I hope you enjoyed reading this post and learned something new. If not then tell me how can I improve. @fsniraj