Build A Responsive Sidebar using Next.js 14, React, shadcn/ui, and Tailwind CSS

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
so hello there everybody welcome back to another video and today we are going to build this responsive sidebar and if you remember in the previous video I showed you how to make a sidebar like this this is basically the sidebar that Twitter has and now let's make a responsive version of this if you were to go on a mobile view this is how it looks like looks terrible all right so coming back to our code let's hide this one first off we need a few components from Shad C and UI the first component we'll need is the sheet and if I were to just show you a demo this is how it looks like this is basically the sheet and this is this will be our sidebar and the next component we will need is the drawer because I'll explain but basically the drawer is just something that opens up from the bottom to the top so we can use the drawer in place of the popover so if you look at this pop over on mobile phone I don't think this is the appropriate thing to show so instead of the popover we are going to use the drawer so let's go ahead and add this I'm going to open up a new terminal over here and I'm going to say pnpm DLX Shad CN UI add and let's add the sheet and the pop uh sorry sheet and the drawer once these components are added let's go inside of the sidebar. TSX this component that we had previously which if I were to give a recap we just created a sidebar items that includes this array called links that includes all these links and icons then we have had extras which is basically the other two links this is the button and this is the other button and so this is going to be as it is we are not going to touch this so first of all let's do sort of a toggle between Side by desktop and mobile and for that we will use a custom hook called use media query and for that we will need a package now there is a wonderful package called use hooks DTS this includes a lot of useful custom hooks that we can import and use directly so let's install this use hooks TS package or library and what we can do is we can just go ahead and import something from use hooks DTS and yeah so we will need the use media query hook as simple as that now what we can do is we can go to the sidebar component itself and we can say const um let's say const is desktop and we can say equals to use media query with the minwidth and we can set that minwidth to 640 pixels this is what I finalized upon after a lot of trial and error so so this is not exactly desktop this is this may be tablet as well and if you want to change it you can go ahead and change it now what this hook basically does is it will take a look at this media query that if you remember in CSS we use media queries for responsiveness so it will look at this media query and it will return to plus a Boolean now if we are on the desktop version we want to return this desktop sidebar as simple as that we can just say if is desktop then we just return the sidebar desktop now what tells if we are on the mobile version what do we do now so for now I'm just going to return a div and I'm just going to call this uh I'm just going to say mobile that's all I'm going to say and we go back this is how it looks like no problem and when we switch to this view you see we got mobile over here we don't have the sidebar anymore but we have the mobile so some progress made moving on let's work on the sidebar mobile component so I'm going to go ahead and create a new component I'm going to call this sidebar D mobile. TSX and it is going to have similarities with sidebar desktop so first off this is going to be a client component because we are going to use this use path name that we used in the desktop version as well so let's just say use client and let's just say export function sidebar mobile sidebar mobile as simple as that let's return now similar to the desktop version it's going to also take in some props for uh we'll need the sidebar items of course so let's go ahead and copy this interface and we're going to paste this interface it's going to be sidebar items and we're going to import them of course so let's rename this to sidebar mobile props and let's just say props is going to be sidebar mobile props as simple as that now let's work on the return statement so now this whole thing is going to be in a sheet component so we can use sheet and we can import it from UI sheet so let's go ahead and say sheet then we need the sheet trigger and this is going to be a button component so let's just say button like this we import the button component I'm just going to say open sidebar for now and we because we are using a button component inside of the sheet trigger we'll need to make this as child right so we put the as child so now everything will work just fine once we have sheet trigger let's have sheet content all right and I'm just going to say sidebar content for now hit save now let's go ahead and go to the sidebar component the parent component and in here we are going to return the sidebar mobile that will Auto Import it and the sidebar items is equal to sidebar items as simple as that and actually let's just put this into curly braces so that you know it's better on this view so while editing the video I realized that there was a little vault in the code if you look at the code right over here it's actually failed straightforward you have is desktop which has used media query and if it's desktop then you show the desktop sidebar else you show the mobile sidebar okay that's very straightforward and it should work but next as is a server side rendering framework so it renders every react code on the server now that applies the same for cl client components because this component is a client component it should be rendered on the client but it's not rendered on the client it's actually hydrated on the client so what actually happens is this code is being run on the server as well and on the client side it is being hydrated so it sort of rerun not exactly but it sort of rerun the code whatever the is desktop and media query stuff is so when you go ahead and refresh the page right this is the development server when you refresh the page you'll see we get the sidebar button right over here in the top left for a split second and then we get this and then we get three errors in the bottom left and it says hydration failed because the initial UI does not match what was rendered on the server now this is one of those hydration errors in nextjs where you have a certain stuff that is rendered on the server and some stuff is rendered on the client so they don't match and that's why it throws you the error because the server rendered HTML is different from the client HTML so on the server side we get sidebar mobile and then on the client side it changes to sidebar desktop so how do we fix it well because we are using the use media query Hook from use hooks DTS I went to the docs and let's just go to the documentation and we have used media query what I realized is that it has these options and these options have two and there are two options actually default value and initialized with value if you read here if true which is the default value if true if you set this case is go ahead onto the SE uh sheet content and let's say the side is going to be left right hit save you click on it it opens up from the left perfect now one other thing I want is I want my custom close button I don't want this little close button I don't want this small close button I want to keep my own close button but unfortunately we don't have any way to say that hey I I want I don't want to have this closed button so what you can do is go to the sheet content itself and this is the power of shat CN UI is that you can literally customize everything over here so you can go to the sheet content right and you can simply add a prop so I'm just going to call this prop hide close all right now it says it does not exist on the type so let's go to the heat content props right over here in in this interface and let's just say hide close is going to be an optional Boolean so we can choose not to pass it as well right so it's optional so it will be undefined if not passed in that means false right a falsey value so we got hide close right this is an optional Boolean is a Boolean or undefined so what you can do is you see this sheet primitive do close we can just go ahead and say if not hide close right if the user passes it as false or it's just not passed in then only we show this close button so I'm just going to cut this out and put it right over here what we essentially did is we take another prop right we make it optional so it can be skipped and if the user passes in height close meaning we just want to hide this close button right if the user passes in hide close this condition goes false and this does not render I'll explain so right now we don't have high close over here and you see we have this close button right we just want to hide this close button we added the prop over here and what we can do is go to the sheet content and say hide close hit save you see the button is gone so now we click outside to close it but we are going to have our custom Button as well all right now let's work on the main content so I'm just going to take this out um let's take this out sidebar content and I'm going to say the sheet header is the thing we need right in the sheet header we are going to have the title which is Twitter and then the close button so let's just say in the class name let's say Flex right and then we need Flex row which will basically have a flex direction of row then we need justify between then we need item Center that will just have space in between these items and that's it let's just go ahead and add a span tag and I'm going to say Twitter right over here so this will be basically our header let's just add some Styles so let's say class name text LG font semi bold text foreground for the color foreground and margin X3 so that will have a little bit margin from the left and right it's save let's take a look at it open sidebar you see Twitter it looks perfect but there is a lot of padding you see there is a lot of padding on the sheet itself so we can go over to the sheet content and let's add some class name and we can just say well hey I want the PX to be three so padding on the X x axis to just be three and py to be four so on the y- axis it should be four hit save you see now it looks a lot better we have more control over the spacing inside rather than outside once we have this Twitter text set up now we need the close button which is very straightforward we just have the button component and inside the button component I'm going to have the X icon so now this x comes from loose side react right over here x from lose side react just say x and let's set the size to 15 yeah let's just take a look at it so this is what it looks like not good of course let's set the variant to ghost that's the first step and then let's go ahead and set the class name height should be seven width should be seven and padding should be zero hit save you see now it looks a little better but you see these are not aligned properly if you look closely you'll notice that there is some spacing on the top and that's because of some spacing applied on the sheet Header by default what we can do is we can just say space y0 right hit save you see now everything every spacing that we had previously is gone so now everything is perfectly aligned but when we click it it does not close well that's a simple solution we can just use the sheet close component right sheet close and wrap this button inside of sheet Clos and the only thing we need to do is as child because we're using a custom button component hit save and let's click on this the sheet closes like magic as simple as that now this open sidebar looks ridiculous to me so let's just go ahead and have a good trigger now first off we don't want any text over here we want a menu icon so we can import menu from lde react the size is going to be 20 for the menu hit save this is how it looks like not perfect we're going to fix it the size of this button is going to be icon hit save that how it looks like the variant will be ghost again that looks better but it's sticky right over here you see it's stuck on the top left with no spacing with no margin so what we're going to do is we're going to change it up a little bit we're going to set uh let's just set the class name to be fixed right so this button sorry this yeah this little button is going to be fixed and we're going to fix it to the top left so what we do is we say top three left three so it will be three units away from the top and three units away from the left and hit save you see now it looks a little bit better so when I click on it it opens up and that's how sidebar should look like also we don't want all this spacing we added all of this margin when we were in the desktop view but it is also in the mobile view so let's go over to the layout. TSX file where we added this margin left 300 pixels turn out we don't want it every time we only want it after the small screens right so we can just add this SM breakpoint hit save you see now the margin is gone but if you were to go to the desktop view it is over here which is perfect but it still overlaps with the button so what we can do is we can first of all say MX5 so margin on the x axis should be five and then we need to increase we need to move the content down a little bit so we have mt3 instead let's just say Mt six that moves it down a little bit or let's just keep it three and we're going to say three is going to be for the desktop so after the small break point desktop comes so margin top three will be for the small for the larger screen sizes and other than that on mobile we're going to have margin top 16 so now this looks a lot better all right that's uh a lot of responsiveness now let's work on the actual sidebar content so after this sheet header is done done let's just collapse it after the sheet header is done let's create a div and then another div inside of that now this is where we're going to have all of our sidebar items or sorry sidebar links so let's say props do sidebar items. links. map so we get access to each link and we have the index of course and we are going to use the link component from next SL link again let me show you this import link from next link make sure to import that one only and it's going to have a key props let's say key is going to be index and href is going to be link. HF all right and we have the link component now let's have the sidebar button that we also used in the sidebar desktop so we have sidebar button and you know what I'm just going to go back to the desktop and I'm going to copy this sidebar button so we don't need to rewrite all of it copy and paste so all right it asked for the path name which is again as simple as having just ConEd path name path name equals to use path name now use path name comes from next / navigation again remember that so we have if if the path name if this link is active we highlight this hit save and let's just click on this so we got all of these links perfect now they are stuck all together so let's add some Styles first first off let's start with this div I'm just going to add some class name first off there will be margin top of five then we can have Flex Flex column a width of full and a gap of one so now all of them have some Gap in between also on this div let's just set class name of height to be full so now we can put anything we want we also want things at the bottom and when I click on any of these it works just fine but there is one little problem you see when I click on any of the links it it redirects me to that page you see this is the messages page if I click on list this is the list page but the sidebar does not close and the sidebar needs to close when I click on any of the links for that what we can do is we can just go ahead go over to the sidebar button over here in in this component right over here and we can create we can export another function so let's say export function sidebar button sheet all right now this is again going to take in props which will be the same as as as these props like all of these so we just going to take in the default props nothing else we're just going to return the sheet close component right if you remember I showed you the sheet close component over here when we implement the close button and it's just going to have the sidebar button in here and all of the props that we get will be passed in over here as simple as that now again we are using another component in here so so we need to use as child on the sheet close now instead of importing this component let's import this component so let's go to the top we have the sidebar button so instead we need the sidebar button sheet and let's just say as sidebar button so the code looks a lot more similar so now this has a sheet close on top of it so when I click on any of this you see the sheet or the sidebar closes perfect moving on to the next part we also need the extras which will which were the last two buttons that we had so what we can do is you can just uh go back to the sidebar desktop and we just had extras like this let's copy that and paste it right over here it save you see that's how it works we just have more and tweet and we don't want the sidebar to close over here if you want you can Implement that but these are only for the show now we want the bottom part so if I were to expand this you see this little pop over and stuff let's add this all right so once we are done with uh this div let's just collapse it now after this is done let's create another div for the bottom part and because we want it at the very bottom what we can do is we can position this absolute Yes you heard that right position absolute we can set the width to full let's say the bottom let set that to 12 right so it will be a little Away From The Bottom the padding X will be one and let's set the left to zero and let's just add anything content doesn't really matter you see this is at the very bottom perfect now first of all what we want is a little separator so let's just go right over here and let's use the separator component and we can set the class name let's say class name again this is also going to be absolute let's just set it to Absolute and let me show you how it looks like this is how it looks like but we want it a little more upwards so we can set minus top to three right so it will move the uh the separator a little up then we need the left to be zero as well the separator is a little longer so we set left to zero and finally width should be full so this is our separator now it's very subtle now let's add the drawer so just like we added the popover right in the separator after the separator in the desktop version just like we added the pop over we need the drawer right that's the only difference so I'm just going to copy all of this popover stuff go back over here and just paste it right over here now we need to import all of these things so let's just instead of poer I'm going to say drawer right so instead of importing draw from wall let's import drawer then we need the drawer trigger right let's just import it properly and this part is going to be the same Avatar let's just import that stuff all right this again more horizontal this icon is going to be imported and instead of Pop hour content this is going to be drawer content the icon settings so let's just import settings let's import log out and that looks just right let's hit save and you see we have this little thing over here when I click on it this is how it looks like not perfect of course because we have the styles of the popover so coming to the draw content we don't need a lot of this stuff so we don't need the width to be 56 we don't need it to be rounded we just need the padding to be two hit save this looks like a lot better than before so when I click on it this is how it looks like on mobile devices we can also improve this part a little bit so instead of having just space y1 we can say Flex Flex call you can say space Y2 and we can add some margin top of two right so now it's a little bit more space out and I think I moved everything a lot more upwards so let's just go ahead and set this bottom to be maybe 10 or a little less let's just say 7 5 6 oh four yeah this looks a lot better so now if I were to go to the if I were to click on it this is how the drawer opens up and if I were to close this and let's go to the full screen this is our sidebar now again I'm going to show you how it works on mobile actually so let's go ahead and switch to the mobile view all right right like this and this is how the sidebar looks like you open it up you go to homepage you can go to any page you want so because we are zoomed in 100% we cannot see that button we added at the bottom so let's switch to 75% and now you can see this is how it looks like if I were to go to let's say iPad Air maybe and here we get the prop the normal sidebar if I switch to this phone Samsung phone you see this is how it looks like this is how it works and that's it for today's video If you enjoyed it smash the like button smash the Subscribe button comment below what are your thoughts on this sidebar and of course the code will be available on the GitHub repository so that's it for this video take care [Music] [Laughter] bye-bye oh
Info
Channel: Max Programming
Views: 1,249
Rating: undefined out of 5
Keywords: javascript, typescript, react, js, web development, node js, nodejs, javascript tutorial, javascript course, learn javascript, web development full course, web development course, web development roadmap, next js, next js tutorial, next js project, next js 14, shadcn ui, shadcn ui nextjs, shadcn ui react, nextjs shadcn ui, tailwind css, tailwind nextjs, tailwind nextjs 13, tailwind next js sidebar, sidebar shadcn, sidebar shadcn ui, nextjs shadcn sidebar, responsive sidebar
Id: FYBC3TjRULo
Channel Id: undefined
Length: 24min 30sec (1470 seconds)
Published: Sat Mar 30 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.