Building a Modal with NextJS, TailwindCSS, and Typescript

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey YouTube what's up welcome back to another video this week I'm going to show you how to add a reusable modal component to your next.js project using typescript and Tailwind CSS if you've been following along with my other videos then you'll know that I've been building a Pomodoro application it's also sort of a game but you can learn more about that in my other videos as a user is running a timer on that application I wanted to have a prompt to let them know that if they were going to cancel their current timer that their progress would be lost this is what I came up with so it's a reusable modal component again in xjs using typescript and tailwind and let's take a look at the code all right so the first thing that you need to do on your wherever you're calling this modal is that you need to have some piece of state that is controlling whether or not that modal is open so I have a use state that is a Boolean that is named con confirmation modal open and that is purely tracking whether or not this modal is open and you can see on the handle clothes we're just setting the state of that confirmation mode will open to the opposite of what it currently is and then everything in between this component here uh starting on line 182 is uh the custom HTML or jsx that you can pass into this modal component how does this work and how do modals work in next.js so a lot of tutorials are going to tell you to permanently add a div on to the document file in your next Js uh project I don't like this approach because then you permanently have a div that is only sometimes needed on your website at all times instead I'll show you the way that I did it and I'll also include the links to the article that I sort of followed along with that's from log rocket I'll include that in the description as well because I found that very very helpful the problem was that that tutorial or article was in JavaScript and I pretty much only use typescript but it wasn't a huge difference and I'll show you what I changed so again this is all the jsx that's getting passed into my custom react component and then here is my confirmation folder confirmation modal file sorry so I did add an interface that is the confirmation modal props it takes three arguments children which is either a children or a child that's the typing for that if you're curious is opium which is open which is a Boolean that is exactly the same as the confirmation modal open in the previous file I showed you and then a handle close we are saying that this function takes in one argument which is an object of these three properties and that is typed to the confirmation modal props which is an object that has those same properties if you have trouble with typescript hopefully that's a clear explanation I have two use effects here I'll Circle back to those but then if is open is not true we're just returning no so we return nothing inside of this return statement if if the modal isn't open however these use effects will still be called and that is why when I have this confirmation modal here I make sure to wrap that in braces and then attach it to whether or not the Boolean is true because even if this component is returning no the JavaScript that is above the return statement is still going to run and I don't want these use effects permanently running on my main page I only want them running when the modal is open essentially so I have them tied to uh any return of any um code from this component is tied to whether or not the modal is open so going back to these use effects we have one listening to the handle close and that is handling our Escape key so a user does not have to press close they can also just press escape and the modal will close and that's what this is doing and the other use effect we have is to disable the scroll so if we pop back into our website when the modal is up if I try to scroll nothing happens and you'll also see that everything underneath the modal is grayed out and not selectable or clickable and this is pretty important when you're working with modals so you don't get any weird behavior on your website and I'll show you how I did that this use effect is adding a style to the body when is open is set to true and then when is open is set to false or in the return statement so this is the the cleanup function on this use effect we're removing it uh the hidden property from the document body overflow Style okay so then what about this gray area that comes up underneath the modal so this confirmation modal component that I built is going to return a react portal and then that portal is going to have only one child which is a an element here a react element and then we have two divs in the first div which is set to fix top zero left zero width of the screen height of the screen Z index of 40 that's important background whatever opacity 50. so that is the background element here and because that sits over top of our entire website with the Z index to 40. foreign going to block any selection of elements underneath that element and then the modal itself is the second div here and that's pretty straightforward we're just passing the children underneath the close button so then what's important here is this react portal component so portals are special earlier I said I don't like having a an extra div permanently attached to the document file because if you use your portals correctly they should create an extra div you can see here in my elements tab in my Chrome Dev tools here all of the next stuff is inside of this div here let me have some other like next stuff here iframe script tag for next whatever but then we have an extra div at the very bottom of our body wrapper that is the react portal modal container and if I were to close that that div disappears so when I toggle the modal an additional div is being appended to the bottom of our body which is where modals are supposed to go semantically according I think to the HTML spec but if I'm wrong on that someone's definitely going to let me know in the comments but I'm pretty sure that that's um the best for accessibility's sake so that happens in this react portal function component I should say so this is the code for that again I am adding some typing on top of that log rocket article that I follow children this could be children or I could type this the same as I type the confirmation model but it's working the way it is that's fine we have one use State here that's basically saying whether or not a wrapper element has been created and then we use a use layout effect hook which is semantically more correct than a use effect and we're just saying the element is this wrapper ID if it exists and then we haven't created it but if it doesn't exist set the system created to true and then we're going to call this function which is to create a new wrapper and a PIN to body and that function exists outside of our component because there's just not a need to put it inside of this use layout effect and we will have an uh problem in next.js if it is not inside of a hook because it does reference the document directly and I'm getting around the problem that we were having index.js just sort of like covering myself here by saying if there's no document just returned no uh but this code shouldn't run if it's inside of a hook so it should be a non-issue and yeah that's pretty straightforward so this create wrapper and a PIN to body is exactly what is going to create this additional div element here where our code is going to be contained so hopefully that makes sense we're also using this create portal hook that comes straight from react the documentation says we pass the children and then the wrapper element that we're attaching the portal to and that's pretty much it hopefully you found this video helpful and useful if you have any questions about typescript or nexjs or Tailwind please let me know in the comments and I'll be happy to help you out if you've been following along the week to week I really appreciate the comments and liking the videos it means a lot to me so thanks for watching I appreciate it and I'll see you the next one
Info
Channel: Yugen
Views: 12,578
Rating: undefined out of 5
Keywords:
Id: a92IhR92aEY
Channel Id: undefined
Length: 9min 35sec (575 seconds)
Published: Sat Nov 26 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.