Make a Dropdown Menu in React | Beginners Tutorial

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
in this video we'll be learning how to make an animated drop down in react the drop down can also be closed by clicking anywhere outside it because we'll be using event listeners and since we'll be making this component reusable and using best react practices we can put anything inside the dropdown over here such as this login form and by using Advanced react and CSS Concepts we'll be adding a cool feature where the positioning of the drop down is dynamic based on the Y position of the drop down so that it never renders outside the page so without much further Ado let's get started so we have vs code open and a basic boilerplate react project in index. CSS we're basically setting the margin and padding zero for everything in app.jsx we just have some items we aren rendering out right now but we have two divs and then inside that just some text and in app.css we're basically centering everything on the page and adding some background color so before we get started we need to install a library for Icon so we'll say npm install react Das icons and then once that's done we can run npm run Dev to start our application and on the right hand side we have our application up and running so the next thing we want to do is create a few components which we'll be using so we'll go into the SRC folder and create a components folder and our drop down will contain a few components inside it so let's just make folders for them the first folder will be the entire dropdown itself which is the entire container we'll have another component called the drop-down button which is what you actually see before the drop down is open we'll have the drop-down content which is the content that is rendered out once the drop down opens and then we'll add another item the drop-down item which is each individual element inside the drop- down content inside the dropdown menu and then for each of these we'll create the jsx and CSS file so we'll say dropd down. jsx dropd down. CSS so now that we're done making the files and the folders we'll firstly go into dropd down. Js s x and this will be our main container for our entire drop down so we'll just write down rafc and then we'll go back into app.jsx and replace this text by writing drop down and Auto Import that and save it and we see that it's being rendered out on the right hand side now so our dropdown will take in two props first will be the button text and this is the text that gets rendered out before the drop down is open so we'll just say drop down button and the second thing it'll take in is the content so this can be any uh react object any HTML that we want to enter over here so for now we'll just send a P tag which says hello world and save that so of course it's not being rendered out right now because we need to go into our drop down and right now we just have this text but instead we're supposed to have two children firstly is the button which gets rendered out on the top and then the drop down down content which will be rendered Out Below that so in drop down button. jsx we'll write down R fce and save that and same with drop down content now we can go back into dropd down. jsx the first thing we'll add is the drop-down button and the second thing we'll add below that is the drop- down content and we can go ahead and save that we see that just the text is being rendered out over here so the next thing we want to do is take in the two props which we were sending to the dropdown which is the button text and then the content and then what we can do is we can pass it straight to the children so the button text we'll pass as a child to the drop- down button and then the content we'll pass straight to the drop- down content component firstly let's focus on the button over here so you'll see by passing in the button text via the curly braces between the two tags and the way to accept that is to go into the drop- down button component and it'll have a special prop called children and what we can do is inside this div just render out the children prop and now we see we have the drop- down button text which we were sending from app.jsx another thing we want to add is an icon on the right hand side which either points down or up based on whether the drop down is open or closed so after the children we'll create a span and for now we'll say fa a Chevron down and this is an icon which we can get from the library which we installed so we'll say import fa Chevron down from react Das icons SL fa and now we see we have the text being sent to us as well as a down icon so we're rendering everything we want inside the drop- down button let's go to the drop- down content and similarly we'll take in the children prop passed to us and then between the divs we'll render the children and now we see we are rendering the P tag which we were getting from from app.jsx so you'll see both the button text and the content is being rendered now so next let's add some styling we can begin with the drop down button so on the outermost div we'll give it a class name and we'll give it a class name of dropd down- BTN and for the span over here we'll give it a class name of toggle Das icon then we can import the CSS at the top so we'll say import do/ dropdown button. CSS so first we'll Target the drop down- BTN we'll say it should be display Flex align items to the center the width should be able to fit the content the padding should be one RM the background color we want that to be white the Border radius we'll set that to be 0.5 RM we'll give it a box Shadow and that will be an rgba value of 149 157 165 5 and 0.2 and then for the Box Shadow we also want to give it 0 pixels 8 pixels and 24 pixels of blur and then we also want the cursor to be a pointer whenever we hover over the drop down and now we see we have a drop down being rendered with the styling next we'll Target the toggle Das icon so we'll say display Flex align items Center justify content to Center and margin left of one remm and our drop- down button looks a lot better now let's go to the drop down content and all we need to do is give the div a class name of dropdown Das content and import SL dropdown content. CSS over here for the drop-down content we'll give it a position of absolute minimum width should be 100% we'll make it a display Flex Flex Direction column we'll align the items to the center we give it a padding of one R we'll give it a margin on the top of 0.5 RM we'll give it a background color of white border radius of 0.5 RM we'll give it a box Shadow and this will be the same as before so we can just copy it from here since we never want the drop down to be to go outside the page we also give it a Max height and we'll set that to be 40% of the viewport height so it'll never go outside the page once we're done with all of the features where we calculate the dynamic positioning overflow y we want it to scroll in case there are more items than the height of the drop down and then we don't want the scroll bar to be visible so we'll say scroll bar width to be none and then just so it works on every browser we'll say Ms overflow style none and we'll save that we need to add another style to make sure that the scroll bar doesn't appear so we say drop down content colon colon D webkit Das scroll bar and say width is zero and height is zero and now it fully disappears and the last thing we have to do is just go into our dropd down. jsx give the outermost div a class name of dropdown import do/ dropdown docss and here just Define dropdown and position relative this will just help the positioning of the content later on so now we're ready to add some state to our drop down so we'll come to the top of the drop- down component and say const open and set open is equal to use State and we'll set that initially to false we need both our button and the content to change based on if it's open or not so we'll just pass in both as the open prop and then we'll create a function called const toggle dropdown and inside that all we'll do is set open get in the previous open value and make it equal to the new open value which is the opposite and since the button will be controlling whether the drop down is open or not we can send it over as a prop so we'll make a prop called toggle and we'll pass in toggle drop down let's first go into drop down button and with the children we're also taking in the open prop and the toggle prop which we just got and firstly we'll say on click just call the toggle function then we need to change The Styling of our button based on whether the open value is true or not so instead of using a plain string we'll use string interpolation over here and after drop down- BTN we'll use these curly braces for some JavaScript logic and we'll check if it's open then add another style called button- open otherwise don't add any other style so null similarly for the icon over here if it's open then we want to render the fa Chevron up icon otherwise we want to renter the down icon so now if we click on it we see that the icon is changing from up and down now let's add some styling to the button as well so that we know that it's in the open state so for that we need to go into drop down button. CSS and just say do button- open in that case add a border with RGB value 147 1 97 253 it should be 2 pixels and solid and now we see we have a clear open and close state to our button similarly in drop down content. jsx we take in the open prop and add in similar logic as before so we'll replace the string and add some uh string interpolation if open then also add the content Das openen class otherwise add null and then in drop down content. CSS for do content Das open we want to give the opacity a one and then back here in the drop down- content we want to give it the opacity of zero so now if we click on the button we see that the drop down opens and closes so right now we're still rendering the hello world uh so let's work on the drop down item so ra fce it'll take in two props children and on click for the div we'll just say class name is equal to dropdown Das item and then on click is equal to on click and then instead of drop down item we'll render out children and save that and we'll import do/ dropdown item. CSS in drop down item. CSS we'll say drop down- item padding of 0.5 RM margin of 0.1 RM width of 100% border radius of 0.5 RM cursor of pointer and then when we hover over the item so drop down- item colon hover he will change the background color so we'll set it to RGB 240 249 255 and save that that and now we need to actually use it so we'll go into app.jsx and if you see the items over here it's an array from 1 to 8 so what we'll do is go inside content and delete the P tag we have over here and create an empty fragment inside that we'll add some curly braces and we'll say Items Map get the current item and we'll return drop-down item the key will be equal to the item value and inside we'll render some curly braces and we'll say with string inter play item and the given item and we'll render that out and as you can see it's being rendered out over here and when we hover over it it changes the background color and hopefully now you see the benefit of the content prop because we can basically pass in anything over here such as this list of items or we could pass in a login form or anything you want by the way if you're liking the video Until Now do subscribe and join the Discord server link down in the description and comments down below so now that we have the proper content being rendered out we're ready to add some animation and all we want to do is whenever the drop- down opens up we want the content to slightly change in opacity as it loads in and move in from top to bottom by 5% so to do that first we'll go into drop down- content and set its initial transform equal to Translate Y and make that minus 5% so it starts off initially a bit higher than it it should land up and then in content Das open we want the the same Translate Y but we want to set that to zero and save that now of course it won't be visible uh right now and to do uh to make it visible the animation we want to add a transition property and we want to say for the transform property take 150 Ms and do ease Das in- out and for opacity similarly do 100 Ms and ease Das in- out and now we can see when we open the drop down it's slightly animates by going down and increasing in opacity now one thing to note is that the drop- down content will be overlapping the button since it's at at a y of minus 5% initially and it might be hard to click on the buttons in some cases so in this case we'll set pointer events equal to none so that the cursor can't really click on it when it's in this state but when it's open we'll set the pointer events equal to all so that when it's once it's open we can click on the items but once it's closed it doesn't interfere with clicking on the Buton so as of now the only way to close the drop down is by clicking on the button itself but we want it to be closable if we click outside anywhere so to do that we'll need to go inside dropd down. jsx and we'll need to import use effect and use ref from react so what we'll do is firstly create a reference to the dropdown so we'll say const dropdown ref is equal to use ref and on this outermost div we'll just say ref is equal to drop down ref and what this lets us do is basically attach a variable to an element or a component inside react and this helps us detect whether this has been clicked or not so to do that we'll firstly create a use effect and this is just some code which will get run whenever the drop- down ref gets attached to this element and what we'll be doing inside this use effect is adding a Handler to our application which will detect for clicks and whenever a click happens it will check if the drop down has been clicked or not and if anywhere outside the drop down has been clicked then it will detect that and it will close down the drop down so we'll Define the handles we'll say const Handler is equal to taken an event and check if drop down ref. current so there is something attached to the dropdown ref and the dropdown ref do current do contains is not equal to event. Target so whenever a click happens it will release an event and we want to check that The Click event did not happen on the drop-down component which we have so if a click did happen but it wasn't clicked on the dropdown that means we want to close our drop down so we'll say set open equal to false so that's our Handler defined then we'll go inside here and we'll say document. add event listener listen to any click event on the document and then call the Handler function when that happens which will check what was clicked and Clos accordingly now in react whenever you're adding an event handle like this it's good to clean it up once your component is not no longer on the page so use effect allows us to return cleanup functions which which are run whenever the component is removed from the page so all you want to do is say document. remove event listener on the click we want to remove the given Handler and save that and now if we click on the drop down we see that we can close it as before but we can also click outside and it gets closed as well because we've added this click event listener now the last thing we want to do is take care of the instances where our drop down will be down too low and if we open it it'll render out outside the page and to do that we'll need to calculate the position of the drop down dynamically so the first step in that is that we need to attach references to both the content and the button as we did for the drop down in the previous step so see how we use the drop down D over here we need to do that for both the button and the content and we'll need to use it over here in a drop down component so we'll create two more uh dfts we'll call it button ref is equal to use ref and we'll say const content ref is equal to use ref now we will pass it down over here we'll say ref is equal to button ref and then for the content we'll say ref is equal to content ref now if I save that you'll see an error on the right hand side where it says that components don't accept a ref property unless you use something called react. forward ref so what we need to do in this case is since the these aren't actual HTML tags they're components we'll need to go inside dropdown button. jsx and instead of it being a normal react functional component we need to wrap it inside a function called forward ref from react and we'll also wrap the end with parenthesis the props which we were taking in won't be taken anymore instead forward ref takes in two props which are props and ref and what we can do is at the top we can say const whatever props we have is is equal to props and destructure the props value which we're getting over here inside forward ref and then we can attach this ref value which we get to the outermost div we can do the same thing inside drop- down content. jsx so we'll say this is equal to forward ref from react remove this props object take in the props and the ref close the parenthesis here and at the top say const this object is equal to props and save that and then we need to attach the ref to the outermost diff and now we can go back into drop down. jsx and to the actual calculation of the Y position so we'll go to the toggle dropdown function and we'll only need to calculate the position of the dropdown once we're opening it or closing it so if where if it's not open that means it's closed and it's going to open we need to calculate the Y position so what we'll do first is we'll calculate the space remaining below the drop- down button so we'll say const space remaining and that will be equal to the window. inner height which is basically the height of the viewport and we'll subtract the button ref. current. get bounding client rect dot bottom so that's a very long line but that basically means we're getting the current button and we're getting the bounding rectangle around it and we're getting the value of the bottom POS the bottommost position of the div so if you taken the full height of the viewport and you subtract the bottom position of of the button you get the remaining space below it then we'll calculate the const content height this will equal to content ref do current. client height so this is just the height of the content which will be rendered below the button once it's open then we need to calculate something called the const top position we first check if the space remaining is greater than the content height which means means there's more than enough space for it so we don't need to make it render any special way if that is the case then the top position will just be null if there isn't enough space remaining that means that the content has to be moved up and since it's absolutely positioned it'll have to be moved up negatively so the top position will be a negative value and it'll be calculated by taking the space that's remaining and subtracting the content height because obviously that's how much you need to move it up by so that it's not going outside the page and we'll save that now we need to add a stateful variable which decides the top position of our content so we'll say const drop down top and set drop down top is equal to use State and initially it'll be zero but over here once we calculate top position we'll say set drop down top and set that equal to the top position which we just calculated now we're not currently using this so what we need to do is go down into drop- down content and say top is equal to drop down top we'll go into drop down content and take in the top prop and since we want to change the styling right here we'll use the style property so we'll say style is equal to the top value is equal to First we'll check if top exists because if you remember it can be null if we don't want to do any changes so if it does exist what we want to do is set the Top Value to some string interpolation so we'll say dollar sign top which is the variable we got and that many pixels if if it doesn't exist just set that to 100% And now if we check it obviously opens up as normal if it's at the center of the page or at the top of the page but if it's below here it'll render up a bit higher so that it's not going outside the page as it was before so that's about it you learned how to make an animated drop down in react which you can control by either opening and closing through the button clicking outside which can takeen basically any child inside the menu and also has a dynamic y position based on the position of your drop down I hope you like this tutorial and learned something new if you did please do subscribe like the video and share it and do join the Discord server linked in the comments and the description down below until next time thanks for [Music] watching
Info
Channel: Code Complete
Views: 2,749
Rating: undefined out of 5
Keywords: react dropdown menu, dropdown menu, react project, web development, react menu
Id: q6HevBxsPUM
Channel Id: undefined
Length: 22min 52sec (1372 seconds)
Published: Mon Feb 12 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.