How To Create The YouTube Home Page With Tailwind, React, and TypeScript

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
here we have the standard YouTube website you're probably familiar with hover over a video it starts autop playing you have this really fancy sidebar that has a lot of stuff going on it's quite complicated and I'm going to show you how to rebuild all of this into your own version of YouTube that looks exactly like this you can see when we hover over a video it starts playing we have the same exact fancy sidebar that does all the crazy stuff that you think it needs to do and all of this is built with typescript react and Tailwind I'm going to show you how to build it from scratch in this video welcome back to web dev simplified my name is Kyle and my job is to simplify the web for you so you can start building your dream project sooner as you can see I'm going to show you how to build this entire clone of the YouTube website it essentially looks exactly the same now the important thing to note though is I'm only going to be building out the homepage so we're just going to be doing the homepage in this video and we're not actually going to be creating a back end that allows us to upload videos and view videos all the data we're going to be using for like these thumbnails and titles it's all just going to be inside of a Json file and that's because the main purpose of this video is to actually learn how to create this design how to use certain CSS and react techniques to create the design and to create all the different functionality because a lot of the functionality on this homepage looks simple but it's actually incredibly complex to implement trust me when we get to this navigation bar you're going to realize how much of a pain this Navar is even though it looks incredibly simple so for this I have a v application created and the only thing I've done is just remove all the starting code I just have an H1 that says YouTube as you can see this is what it looks like and I have a logo here that's going to be our own custom YouTube logo cuz I don't want to use YouTube's logo and get sued by them for using their assets so we just created our brand new logo that looks essentially exactly the same now since this project is going to be entirely built around Tailwind we're going to make sure we set up Tailwind in our project this is pretty easy to do we're just going to go to the Tailwind docks and go through step by step so first of all we need to actually create a project which we've already done then we need to install Tailwind so I'm just going to copy this command open up a new terminal and I'm just going to paste it in and this is just going to install all the different Tailwind stuff we need as well as initialized Tailwind so we have some Tailwind files to work with here I'm going to copy this into my Tailwind config which is being created right now by that initialization command so we're just going to paste that into there and then finally all we need to do is just copy these three lines into our index.css file which is already imported right into our application so let me make sure I import that we have index. CSS there we go so now hopefully if we go back to here and we refresh our page and we may actually need to restart our server so let's just do a full restart of our server real quick and now we'll give our page a refresh there we go you can now see that this font is much smaller and that's because the default Tailwind Styles have taken over and removed a bunch of the styles that CSS gives you by default in the browser now to get started with a project like this generally what I like to do is I like to look at the thing I'm trying to copy and figure out how it works so if we look through here you can see that when I scroll on the page all of this section on the very top stays where it is so this entire page header stays there these categories right here they stay at the top of my page and this sidebar stays stuck to the left of my page and if my sidebar is large you can see I can scroll it independent of the rest of the page also on a larger screen size you can see that this sidebar just stays there I can collapse it and expand it but on a smaller screen size obviously this sidebar doesn't expand it just becomes this pop out that shows up over top of the content this is part of why it gets really difficult to create this sidebar but I like to look at the overall structure of the page so we have this page header we have these cards right here for selecting different categories we have this sidebar and then we have this main content so we almost have like four distinct different sections and the important thing to note is three of those SE are stuck in place while all of our other content just fills into this one section and this is the only thing on the page that actually can scroll and actually just fills in whatever spaces left these other things are kind of stuck in one single place what I like to do when I look at a structure like this is I like to think about how I'm going to style this out in CSS now there's a bunch of different ways to go about doing this but in my opinion one of the easiest ways to create this style is going to be making it so that my entire page is a 100% of the height of the screen and then I can just make this one section of the page scrollable and everything else will just stay stuck in place cuz this is the only thing scrolling instead of the entire page scrolling you could also use sticky position to put things in places when I originally did this was sticky position it made things much more complicated than just making the whole page 100% height and then this section scrolling I'll show you exactly what I'm talking about by going into my app and actually getting started on what this project is going to look like so inside of our code here the very first thing I want to do is I want to wrap this inside of a div and this is the div that I'm going to make full screen so we're going to say our Max height here is going to be the size of the screen so that's 100 VH and I'm also going to use flex box to lay this out in a column Direction so now if I had two divs inside here for example one and if I had a column two inside of here there we go and we went and looked our application you can just see we have these divs stacked on top of each other now if we go back to YouTube and we look you'll kind of see that this page header actually takes up the full width on the top of the screen and then below that we have essentially two columns we have this left column for our sidebar and this right column for all of this other stuff inside here we can really see this if we expand all the way you can see that this page header takes up the full width sidebar is on the left and then the rest of this content is the middle so we kind of have those three distinct sections again that we need to work on so the very first section is going to be our page header which we can just have right here so let's just create a component called page header just like that and we'll come into here and we'll create that component and I'm actually going to put this in a folder called layouts and that's just because this is kind of like a page layout component so it's going to be for like laying out a specific section of the page you could put it in a components folder too it really doesn't matter so we have that page header TSX export that function there we go let's just for now return null and inside of our app let's import that so we can use it just to get rid of all of our different errors and now we're rendering that header but it's rendering out nothing so we need to focus on what we want to put in that header so again when I get to something like this I like to look at the source material and kind of see what it looks like I like to move around my screen on different sizes to really see how it interacts you notice this is essentially broken into three distinct sections the left side has this sidebar Button as well as the logo middle section has this search bar plus this microphone and the right section has all these other different icons and you can see as I resize my screen the middle section stays in the center and the other two sections stay on the side and the space in between them just kind of changes around as it needs to and then finally on really small screen sizes you can see that it becomes a different layout completely so we'll need to make sure we take all of that into account when we size this around but we essentially have a three section layout and this is a really great option for flexbox cuz we can easily space them out from one another so I'm going to create a single div and want to make sure I give it a class here that is going to be Flex to lay those items out and I know that they have a rather large gap between them but I know that also as I resize my screen the gap between these elements becomes larger on large screen sizes and smaller on the small screen sizes so I'm going to make sure I take that into account by using a gap of 10 on small screen sizes and on large screen sizes a gap of 20 so each my three different sections are going to be spaced out more on larger screen sizes and in order to make sure that they're spaced out from each other I can use the justify between property and that's just going to put as much space as possible between these elements and these gaps only come into account when they're squished down to the point where there's no more space to add between them so now what I can do is I can put some sections inside here so we have section one which we're going to put inside of a div and then we have section two which is the search bar and then finally section three so let's first focus on Section number one so for this section we need a button as well as the logo so that's relatively straight forward and I'm just going to use flexbox again to lay these elements out so we're going to come in here with a class name I'm going to use Flex on this I'm going to say a gap of four between these different elements and I'm going to make sure that they're centered vertically just so they line up really well with each other finally just to make sure that this section doesn't actually shrink at all I'm going to set Flex shrink to zero just so that my logo or anything doesn't get squished down as the size of the container shrinks down now that's really all we need to do right there so then inside of here we need to have our button so we can have a button like this and then we also need to have a link which is going to be for our image so this link is just going to go to the homepage so we'll just do an HF like that and if you were using something like react router you would use a react router link component or like a next you would use a next link this is mostly just for design purposes so we're just going to use a normal anchor tag then inside of here we want that image and the source of this image is going to be for our logo which comes from this assets folder so let me just import that up here we can import our logo from and this is going to be slash actually do dot slash and then assets SL logo so then inside of here we can use the logo as our Source close that off real quick and let's give it a specific size we'll say class name here is a height of six so real quickly if I give that a save and come over you can see we have our logo I'm super Zoomed In which is why it's so blurry but if I zoom out you can see it looks pretty good we obviously need to fix our spacing and stuff but we have our logo showing up which is great next we need to create our button and this button is actually going to have an icon inside of it you can see it has this menu icon I'm going to be using the Lucid react icons so we can say npmi Lucid react and and this is a huge Library full of a bunch of different icons that we can use in our case I want to use the menu icon so I'm going to come in here and I'm going to get that menu icon I'm going to make sure that gets imported from that lucid react library now if I come over here give this a save you can see that we now have this button with that menu icon now obviously I want this button to be styled in a specific way I'll Zoom it in so it's a little easier to see and to do that I'm actually going to create a component so we'll create a components folder and inside of there I'll create a button. TSX file so I'll export that button there we go and inside of here I'll obvious return a button we'll just close that off for now and in order to style out this button I'm actually going to be using a specific Library so I'm going to say npmi this library is called class variance Authority also known as CVA and I'm also going to use Tailwind merge to merge together all my CSS classes to make sure there's no conflicts so I'll show you what these libraries do in just a second but essentially I want to have different types of buttons cuz we look at YouTube this type of button you'll notice it has no background but when I hover it has a background this button over here has a background and when I hover it gets darker this button over here is just like a normal style looking button these buttons over here also have their own distinct style and same thing here they all have their own very distinct style there's like two or three different types of buttons that I want to be able to implement I'm going to be using this class variance Authority library for me to really easily toggle between these different types of buttons so to do that all I need to do is come up here I'm going to create a variable I'm going to call it my button Styles I'm going to use CVA which comes from that class variance Authority library now the way that this works is it takes two parameters the first is an array of classes that you add to every single button you create so in our case every single button is going to have a hover background which is going to be a background and we could come in here and say like gray 200 or something like that but in my case I want to actually have specific colors that I have defined so I can say like background secondary for example or background secondary hover and the way that we can do that is by going into our Tailwind config we need to extend our theme I want to extend the color theme here and I want to create my own color called secondary and I want to actually base that off of the colors built into Tailwind so we need to come up here and actually do an import so we'll say that we want to import colors from and we want to get that from Tailwind CSS colors that gives me access to all the colors so now for example my default secondary color can be colors. neutral and in my case I'll do neutral 200 then I can come down I can do my hover color so I'll say hover colors and this one's going to be neutral 300 so it's going to be slightly darker and the reason that I'm creating these different colors like this is because now I have consistency in my entire application if I wanted to swap from neutral to like slate I could do that in one place and it's going to update everywhere in my application which is really nice so here for the Border I want to have a neutral 400 as my color I'm then going to have a text color that we can use here which is going to be that secondary text that is going to be neutral 500 and then finally we're going to have a darker version because as you can see some of these buttons are this darker version of the button so we need to make sure we have a dark color as well so that's colors neutral and we're going to do 800 in this case and we're also going to give dark a hover so we'll say dark hover and in that case we're going to do just one level darker which is going to be that 900 color there we go that should be all the colors we need based on what YouTube is as you can see it's a mostly grayscale application there's really not much color used so it's pretty easy for us to implement the exact colors we need so now we actually have that background secondary hover and I'm getting nice Auto complete on that now the other class that I want to apply to every single one of my buttons is going to be a class of transition and I want to transition on the colors the reason I'm doing that is just to make sure that I have a nice transition between my different colors instead of it being a hard jump now the second property to this is an object and this object takes a variance property and this variance property determines what keys you want to be able to set so in our case if I wanted to have different sizes of buttons I could specify a size key and now what I can do inside of here is I can spe specify all the different types of sizes that I want so for example I can have a default sized button which is going to have its own classes and I could have an icon button which is going to have its own classes and you'll notice our icon buttons are essentially always Square shaped with this perfectly rounded Corners to them and here we have these normal buttons which are just you know more like a normal traditional button so we kind of have these multiple different types of buttons I want to be able to implement so we have two different size properties we can use then when we call this button Styles function all we'll do is we'll call it and we'll pass it in the things we want like for example we could say size is going to be an icon and what this is going to return to us is some classes and those classes are just a string of all the classes so it combines together all these classes with all the classes in the icon section so it's a really easy way to make sure we only apply the classes we want so in our case for our icon specific button we want this one to be a circle so we'll use rounded full to make it into a circle we'll also hardc code the width and the height to be 10 so we'll say width and height is 10 we're going to say we want this to be a fux we'll say that we want the items to be in the center and we'll say we want to justify it in the center and finally we'll give it a little bit of padding of 2.5 there we go this is just going to be making sure we have the icon that's perfectly centered with a little bit of padding around it we can get rid of this cuz we don't actually need that code for our default button it's going to be relatively simple we want it to be rounded and we want it to have a little bit less padding at padding of two and this is just me trying to match the YouTube design as closely as possible now finally I want to have two different variants of a button so this variance is like the actual thing that you need inside of this class variant Library we can also Define our own key for example I'm going to create a key called variant which is going to be for the different styles we want so in our case we're going to have a default style and we're also going to have a style that I'm going to call ghost and this ghost style is for the button that has no background until you hover it and default is just for a button that looks like a normal gray button with a background behind it so for our default we want to give it a background color which is going to be that secondary color and for our ghost it's not going to have any background so we don't Define it a backgr at all but when we hover it over we want the background to be a gray 100 and also this hover here should probably go inside of the default category just like that there we go that way it's only going to have this specific background when we hover over the default buttons now if we give that a save there should be all the Styles we need for this and we can actually use this inside of our button here so we can say our class name is going to be equal to calling button Styles and we can pass it in some props for example we can pass it in the variant and we can pass it in the size that we want we can take those in here so we can say variant and size are going to come into our button component and let's create our button props to get these button props is actually really easy so what we can do is we can say type button props is equal and we can use this fancy little handy function called variant props let me make sure I import that and all this does is it takes the type of our style that we just created and it's going to give us all the things we need so if I hover over this you can see it's going to be a variant that's either default ghost or null and same with our size default icon n or undefined so it just make sure we conform to the different things that we expect also inside of here I can specify default variants so here I have my variant set up I can specify my default variant which in my case my variant is going to be called default and I'm going to have my size which is also default just like that so that's going to be my two defaults that are used whenever I create something so if I don't pass a variant or a size it's just going to use the default ones that I've created also my button should probably be able to accept other things like normal button props for example children or other props so I can come in here I can get all the additional props you would get from a button normally I'll just pass those in like that and in order to combine those two different things up here we can use the handy dandy component props type pass it in the component we're using which in our case is a button and if I make sure to import this that'll just make sure we can add all of the normal button props to our custom button right here so if I do all of that we should at least have the groundwork for creating a button so if I go back over into here here you'll see we still have nothing really looking that great yet but if I go into my app and I change out or I'm sorry my page header and I change this out for my custom button there we go you'll see everything is still working but when I save immediately you'll notice we now get the standard version of our button which looks relatively good if I want I can change the variant to be that ghost variant and now you can see I get the ghost version and if I change it once again to have a size of Icon I now get a circle version instead so as you can see just by changing around these different things I can really change exactly what my button looks like now the final thing I want to be able to handle is sometimes I want to pass a custom class name into here for example let's just say I wanted to pass a margin of 10 that would add a huge amount of margin but you'll notice no margin is being added that's because currently I'm overwriting whatever my class name is in this section so I should pull out the class name so I don't overwrite it and I need to combine it with this class name here well the really nice thing about this is we can actually just pass in something called class name like this and I could set it equal to the class name and you can see those styles are added with the problem is it's now going to conflict with any Tailwind styles that I already have so for example if I tried to add an extra padding inside of here so I made my padding 10 you'll notice that it technically is applying but it's kind of overriding some of the other styles that I have inside of there which is not super ideal and it may not always override properly for example if I try to change my background to Red 500 and I click save you notice that did work but depending on the order of the actual CSS this may not actually apply so the thing that we can do to get around that is to use Tailwind merge so instead of passing our class name in here we can call this Tailwind merge function which is just tww merge let's make sure that we give that a quick import real quick there we go and this takes in the functions for all of our classes so this is our normal classes right here and then we're going to pass in our other class names as the second property and it's going to make sure to merge them together so they perfectly work that way if we wanted these button styles to apply first we could pass them in there like that and that way they're going to override whatever our class name is right here and in our case though we want our custom class names to override our button Styles which is what we have right here so now we can remove that class name cuz we don't actually need anything but now we can add those in in future scenarios which is really nice and that should be everything we really need to have for our custom button you can see it's relatively simple we just added all of these different variants up here which allow us to use it however we want to whether it's going to be a ghost button a normal button and so on now let's go back into our page header and let's actually try to style it a little bit so we have some better spacing so that we have some spacing on the Left Right top bottom and so on on cuz right now if I were to zoom this out you can see everything's kind of like squished up against the sides it doesn't look super good so what we want to do inside of this main div cuz this is our first section this one's done inside of our main div we can add some padding for example on the top We'll add a padding of two we'll also add some space on the bottom so we'll do like a margin bottom of six and let's do a margin on the sides of four as you can see that just spaces everything out a little bit better and it looks relatively good like that now if we look back over at YouTube you'll notice the next thing is this search bar and then we have this right hand section I'm actually going to do the right hand section next cuz as you can see it's very similar to the left- hand side section so it's going to be relatively easy for us to implement so the very first thing that I want to do is I want to put some buttons inside of here so we're going to use our custom button component that we've created before I know the size is going to be an icon button and the variant here is going to be a ghost variant so we'll say ghost just like that and inside of our button we need our icons so we have this create video icon we have this notifications icon and then we have our actual user information right here for our actual profile so for the upload icon I'm just going to use the icon which is called upload so we can just import that there we go give that a quick save pop over here you can now see we have an upload icon it looks different than the YouTube one there's no icon that looks exactly like this in the library we're using so I'm just using the closest analogous icon and I've done that in a couple places so now we're going to copy this over because we essentially want to do this three total times CU if we look over here you can see we have three different buttons that we can click on and so this one right here is going to be the Bell icon so let's import that icon and then finally here we we have our user icon so I'm going to import that now if we give that a quick save we can come over here and you can see that we have these three different icons they're currently vertically stacked we need to fix that but you can see it looks relatively good and they have all the styles that we want which is great now to lay out these things we're going to use flex box one of my favorite things in the world so we'll say Flex here we want to make sure it doesn't shrink as well so we'll say a flex of zero for the shrinking we're also going to add a gap in here we'll do medium for The Gap is two so on larger screen sizes we have a little bit of space between them but as our screen size shrinks down you notice the space between them goes away just to make it fit a little bit better on smaller screen sizes so now we come to the fun part a little bit more difficult part which is going to be this entire search bar and it's honestly not too tricky it looks a lot scarier than it is as you can see it really just sizes up and down as our screen size changes and it's not till we get to a relatively small screen size that it becomes an icon which when we click on gives us this full screen searching section which we'll Implement also so inside here we're actually going to use a form instead of a div because technically this is a form that we are submitting so we'll have a form inside of here and for this form I again pretty much want to use flexbox for this so we'll come in here we'll give it a class name in our case we're going to only focus on the large screen size and then we'll implement the smaller screen size next so what we'll do is we'll say we want to use flex we're going to have a gap of four between our items and that's because there's a pretty large gap between these two different items here then the next thing that we're going to want to have inited here is a flex of grow that way this section grows to be as large as it can we're going to justify everything in the center so we're going to say justify Center Center and then inside of here for our form we're going to have two sections the first section is going to be for our actual input and the next one is going to be for our button so we're going to have a div that wraps our input and then we're going to have our button and luckily the button is relatively easy we know that the size here is going to be an icon button and it's actually going to be our default style because you can see we want it to have that gray Background by default and inside of here we're going to use the mic icon so I'm just going to come in here and I'll put the mic icon and import that so we get that that save come over here you can at least see we now have the mic icon and it's perfectly centered also to make sure this button doesn't get squished down at all I'm going to come in here with a class name of flex strink of zero just again to make sure it doesn't get squished at all also I'm going to make this a type equal to button just because by default buttons are submit and I don't want this button to actually submit my form I want the search button here to submit my form instead so now let's focus on the actual input section inside of here I'm going to again use flexbox to lay out my two sections cuz we have an input section and we have this icon on the left right hand side of it so we're going to use flex we're going to say that this should grow so we'll give it the flex grow property so again this is the section that's growing nothing else and I'm also going to give it a Max width we're going to say 600 pixels is the largest this can be because as you can see if we increase our screen size a bunch you'll notice that eventually that search bar doesn't keep growing it eventually gets to its maximum size so we want to make sure we keep that in our design as well so inside of here we're going to have our input normally I would create create a custom component for this but you'll notice on the homepage this is the only input so there's really no point in creating a custom component if it's the only place we're going to be using it but again if you want to you can and then we're also going to create a button and this button is going to be for our search section right here so this button is going to be like this and we'll use the search icon inside of here and this button is actually going to have a bunch of custom styles on it because by default you notice it looks like this and we need to change it to look like this instead so it needs to be drastically overhauled before we get to that though I want to focus on the input first so I'm going to say that this is going to be a search input so we'll give it a type of search a placeholder is going to say search and then we need to add a bunch of class names to style it exactly like we want for example first of all I want the left hand side to be rounded in a full pill shape that will give us this rounding right here I also want to make sure we have a border we're going to use that secondary border color that we've already created there we go and you'll also notice something interesting about this is it actually has a very slight shadow on the top of this it might be hard for you to see try to zoom it in as as much as I can get this a little bit larger there's a very slight shadow on the top of this text box that we want to make sure we take into account in our design as well so the easiest way for us to do that is to use the built-in Shadow class and this Shadow class can be set to an inner Shadow we can also change the color of this Shadow to be our secondary color so it's a relatively consistent Shadow with the rest of the colors we're using so just by doing that alone if we look over here you can see we have our search input and it's starting to take shape but our padding's really messed up so let's go ahead and fix the padding next we'll come into here and we'll say we want some padding on the top and bottom of one and the padding on the left and right is going to be four also I'm going to use some larger text so we use a text of large and to make sure this fills the full width we'll give it a width of full that makes sure it takes up 100% width now you can see this is already looking a lot better now the final thing I want to do is you'll notice when you click inside of this it gives you this blue outline so I want to make sure we replicate that as well so I'm going to change our Focus State here to a border of blue 500 I'm going to remove the default outline on it so now when I click I can get this blue border instead of the normal default border now let's go ahead and focus on our button on the right to make sure that that looks correct as well so here we're going to give it some padding on the top and bottom of two and the left and right of four already that looks a lot better next we're going to fix the rounding so we're going to say rounded on the right is going to be full just like that you can see that's now fixed the rounding on the right hand side if we zoom in you can see it removed the rounding on the left hand side as well so they're perfectly mirrored up right next to each other I then want to use the exact same border so we'll say that we want to have our border be the secondary border just like that and we also need to add the Border class to make sure the Border applies and then we don't need to worry about having a border on the left so we'll say border left of zero just so we don't have two doubling up borders next to each other lastly I'll make sure this doesn't shrink At All by giving it a flex shrink of zero now if I zoom back to a normal screen size you can see that this button is entirely done and as our page grows you can see that the search bar gets to a certain size and then it stops and it shrinks down as our page gets to to a smaller size so that looks really really good really the last step we need to do is make sure when we're on a small screen size we get a better search bar than this because this is literally unusable so if we look at YouTube you'll notice when we're on a small screen size these two icons move over into our right hand section and our entire middle section disappears so this entire form needs to disappear on small screen sizes so our Flex property we're only going to have this specified when we're on medium screen sizes it's going to be a flex property so now if we give that a save and we also make sure we make it hidden by default on small screen sizes you notice on the small screen sizes it disappears and on large screen sizes it pops into place so we're just hiding and showing it as we need it which is great the next thing we need to do is to add these icons on the right hand side when we're on a small screen size so what I want to do is I want to just copy this button I'm going to paste it down to create a brand new button this one is going to be the same variant of ghost this is going to be a search button in our case though and if we give it a quick save you can see it shows up but the key is I only want it to show up on small screen sizes so on medium above this is going to be hidden so as you can see when I increase my screen size it hides as soon as this search bar shows up now I just need to make sure if we go over here we have an icon as well by shrink this down enough for this icon right here for the microphone so let's come over here and we'll work on that microphone icon next I'll just copy over essentially this entire button cuz it's going to be literally identical it's just going to use the mic instead now you can see we have all these icons showing up side by side on the small screen size next we need to work on interaction right now we've done a bunch of design but nothing's been interactive yet so I want to make it when I click on this button I get the exact same thing as what I get in YouTube so you can see when I click I get a full screen version of the search bar and apparently an incognito mode they give you the most ridiculous default search results but anyway continuing onward we just want to make sure we have that and also we have this back button showing up so we essentially want to create this full layout as well so all we need to do for that is create a state variable we'll come up here we'll say const and this is going to be show full withd search and set show full width search make sure I spelled this properly there we go that's going to be used state by default we're going to set this to false going import this so we can have it be usable and then what we do in our search button we can just have an onclick for this search button where we actually set that property so we set this to true so now this variable is going to be true when we click on that button and all we need to do is make sure that we just show this right here so whenever this is true we want to hide this entire right hand side section so I'm going to use some string interpolation in here so we can use a really quick if check inside of our code what I want to do is I want to say hey you know what if that show full width search bar is true well I want this to be hidden otherwise I want it to be a display of flex and we're going to remove this Flex property from here so essentially we're only showing this section if that button is not clicked so now when I click on this button you can see this entire right hand side has disappeared just like I want it to we'll just refresh that so we get it back to how we had it and I want to do the exact same thing up here as well so I'm actually just going to essentially copy this up so we're going to have inside of here all of that make sure I minimize that down we'll copy over this exact same code because we're going to be using the same code move the flex down into there make sure I get the dollar sign and there we go so now when I click you can see both the left and the right hand side have completely disappeared all we need to do next is make it so that the form in the middle actually shows up so let's do the exact same thing here there we go we're going to have that exact same code so if the sh full width search bar is true we want this to be a display of flex otherwise we want it to be hidden just like that now if we give that a quick save and we give this a refresh we should safely click this we have our search bar in the middle but we'll see it's still not showing up that's just because I need to remove this hidden class here there we go now it's showing up just like we expect also if I increase my screen size you notice it stays as that full width search bar which is exactly pretty much what we want if we want to be a little bit more explicit we can just move this medium of flex into here that way it's only going to be Flex on larger screen sizes otherwise it'll be hidden by default if this show full width search bar is not selected that way all of our styling for display is in one single place and the next thing that we need to do and pretty much the last thing is just add this back button because otherwise all of our functionality is still there so to add the back button we're just going to do it outside this div I'm going to copy this button over because it's going to be very similar between all these other buttons this one is going to be an arrow to the left and let's just import that and now if we give it a save you can see we have that showing up right here this one I believe should be a ghost icon though so let's actually change the variant to be ghost there we go and then finally we want to make it so when we click on this we actually just unset that variable so we can say set show full search witch to false there we go so now you can see we have this we click on it we go back to our normal view click on this there we go that's all working just fine and if we're on a large screen size we click back you can see it looks like it's working really this back button just shouldn't be there when we're showing the full width search bar so let's just shrink this down a little bit and here if we are showing our full width search then show the back button otherwise completely hide it so now that back button is hidden unless we are in the full screen search mode like this there we go that is perking perfectly and it looks like our entire header is completely done now if we go back to our app we have our header done and if we go back to YouTube you can see inside of this we essentially have a grid layout now for this next section as you can see our grid has two columns on the left hand side we have the sidebar that expands the entire height and on the right hand side we essentially have these categories as well as this entire main section for all of our videos and pretty much everything else so I'm actually going to create a div here that is going to be a grid layout and it's going to follow that exact same grid layout that I mentioned of two columns so we're going to have a grid and it's going to have two columns so we'll say columns like this the First Column is going to be an auto size and the second one is going to fill all of the remaining space that we have then what I want to do is I want to add just a couple other things inside here to make it work perfectly first of all I want this to be a flex grow of one cuz I want this entire bottom section to grow to fill the entire size of our screen and then finally I want to set the Overflow here to Auto and that's going to make sure that this section can actually scroll while the rest of our page stays static so if we get that a quick save we come over here you'll notice there's nothing that's really changed yet but as soon as we start to put a bunch of content inside of this div it'll give us the ability to do the scrolling like you can see here where it's just allowing us to scroll these sections independently of the rest of our page and everything else stays stuck just where we want it to be now if we go ahead and we look at YouTube you'll notice that the next thing we have either the sidebar or these categories I'm actually going to save this sidebar till later because that is the most complicated part by far so instead we're going to do these categories so to make sure our grid works fine I'm going to put in a div and this is going to essentially emulate what our sidebar would be so I just I put this text sidebar inside of here if I really want to for now and then after that I'm going to have another div and that's going to contain these two sections so we're going to have our categories here and then we're going to have this grid section down here so for our categories we want this to be stuck to the top of the page age so what we can do is we can make sure that we give this a class name here of sticky to make sure it sticks we can give it a top of zero so it sticks to the top background of white a z index of 10 that way it makes sure that it's stuck perfectly at the top and we'll add in some padding on the bottom of four to give it just a little bit of space from this content you can see it has this little bit of padding on the bottom so that'll make it look exactly like we want it to then what we can do is we can create a component called category pills just like that make sure I spell this here we go category pills and that's going to be for this entire section and let's create that component here export that function there we go for now I'll just return null and inside of here we'll make sure that we import that so we can use it there we go so now we should have no more errors everything's working and if I put some text inside of here we can see that that text is showing up right there now if we go ahead and look at YouTube you'll notice that as we shrink down our screen size you can see that we get these little arrows that show up on the right and the left hand side this is where almost all of the complicated code for this is going to come the rest of it is relatively straightforward to implement so let's go ahead and we're going to create a div that's going to wrap all of this I'm going to give this a class name of overflow X that's going to allow us to actually have these things I'm going to make this overflow hidden that's going to make it so we can actually have these arrows that toggle us side to side as we do here and also I'm going to make it so it's position relative that way we can actually position these on the left and the right overlapping everything absolutely so that's what those two classes are going to be doing for us and then I'm going to have a div that's going to wrap all of our different categories and we're going to use my favorite thing Flex box to do all this so we're going to come in here with a flex I want to make sure that there's no wrapping at all going on so I don't want any wrapping I'm going to give them a gap of three between them and also in order to do my transition I'm actually going to use essentially a translate property I'm going to do a transition on the transform property here to make it so that that when I actually do my sliding you can see it animates instead of just jumping to the next one finally I'm going to set the width here to Max content just to make sure that it fills the maximum space that it possibly can now inside of here we can actually go ahead and create our buttons for our different pills so for now I'm just going to hardcode one button and then we'll work on creating an array to do all of this I'm going to use our button class that we've created already and inside of here let's just put like the text all for example so now if we give that a quick save and we look over here you can see we have this all button showing up but it's not styled like we want it to so we need to add some custom styles to it so inside here for our Styles I'm want to say our padding in the y direction is one and our padding in the X direction is going to be three and then finally rounded large and again we don't want to have any wrapping so we're going to say white space is going to be no wrap give that a quick save come over here and now the pill is looking a little bit better let me copy this entire button so that we actually have two buttons and this second one we'll just have it say JavaScript there we go if we go over here you can see we we have these two buttons side by side and I want to make it so that this all button is actually a dark button but we don't really have a variant for that yet so I'm going to create a Vari for dark there we go and I'm going to come into my button let's create a brand new variant inside of here which is called dark and for this variant we want to have a couple classes so first of all I want my background to be secondary dark I want the background when we hover over it to be that hover background so we'll say background secondary dark hover and then finally I want my text to be a more white color so we'll use that text secondary class so now you can see we have this dark button showing up for the dark class and all the other buttons look normal which is great so now we can minimize out of that we can go back over into this pill section here and instead of hardcoding all these different pills I actually want to pull them in as a prop so we'll say that we have like some categories that are coming in so let's do our category pill props copy over that type there we go and this is going to be categories which is a string array there we go so now inside of our app when we call this we need to pass in our categories just like this and we'll pass it in as a variable called categories now normally you'd pull this from like some type of API using fetch or using like some kind of backend service but in our case we're just going to hard code this as a Json value just so we don't have to worry about implementing the full backend so I'll create a data variable or data folder here we'll create a file called home.ts and inside of here I'm just going to copy this over this is just going to export a bunch of categories as you can see I've just created a bunch of categories for us to use so now we can actually Loop through these categories inside here so we'll say map through each category and for each category I want to just render out that button so the button text is going to be this text right here and I'm going to have a key on here which is also going to be our category so we'll give that a quick save I'll remove this button down here make sure I save my app and import this categories as well now you see that are different cator ories are shown up obviously our Styles aren't like what we want them to be but you can see that they are here which is good they all are this hardcoded active style though and we want to make it so that they can be changed between active and not active based on what we click on so as you can see here when I click it changes which one is active so we want to make sure we Implement that as well so to do that we need to pass down the category into here so we'll say like selected category and then we also want to have some type of other property that we pass down as well for how we select it so in our case that would be an on select property just like that so here we're going to essentially create a state variable we'll just say like selected category and we'll say set selected category use State just like that and we'll just make it so that by default the very first category is the one that is selected so now we can pass down the selected category and we can also pass in our on select which is is just setting it like that there we go and now if we go into here we can make sure we take in the selected category and the on select which up here our selected category is just a string and on select is just a function that takes in a category which is a string and it returns void there we go so now we can compare down here what our variant is going to be based on if our selected category is equal to our current category well we know that that is the active one so that is our dark class otherwise it's going to be our default there we go so now you can see only the first one is that active class and now all I need to do is make it when I click on a button it calls that on select function with the correct category so we'll say on select with our category there we go so now if I click on any of these you can see it's toggling between them and I'm getting a nice little fade transition for my colors which is really cool so now let's go ahead and fix this scrolling problem that we have we're going to go back into our app page here to fix that problem right now we have this sticky section for our category we're actually missing a div that we should wrap this in to give it some spacing as well as to fix the Overflow problem so to fix the Overflow we're just going to say overflow X is hidden there we go close that off and I want to make sure I put my category pills inside of there give that a quick save and that at least got rid of the scroll bar which is really great also I'm going to give this some padding on the left and right as as well as on the bottom just to give it some space from the sidebar so already this is looking really good next we just need to add the ability for make us so we can scroll this section instead of just having it hidden by default so let's go ahead into our category pills section and we're going to minimize down this section CU that's just for rendering out our categories I'm going to create a new div here and this div is going to be for rendering the arrow on the left hand side so we're going to give it a div and inside here we want to have a Chevron left class or sorry icon is what we're going to use import that if we give that a save you can see what that icon looks like right there and we're going to add a ton of different styles to this div to make it work and also I'm going to put this inside of a button so we'll just say button like this and we'll put that Chevron inside of it and we'll give it all the classes we need for example variant is going to be a ghost button and it's going to be an icon Button as well and then finally we need to add a few other custom classes to this I want the height to be 100% I want it to be a square aspect ratio and I want the width to be automatic based on what the height is and then finally we'll add a padding of 1.5 reason I'm doing that is just so it's going to make sure it fits perfectly within the size of these buttons no matter what size those buttons are now we need to position this directly over top of this all button so that's where we're going to add a bunch of different classes to do so first of all absolute we're going to set the Left To Zero we're going to set the top to 1/2 and we're going to set a negative translate in the y direction of 12 as well by doing that we've essentially perfectly centered this inside there as you can see then what we want to do is we want to add a background gradient this background gradient is going to go to the right hand side it's going to start at White by saying from White it's going to start at that white color at 50% and then it's going to end at a transparent color all the way on the farthest right hand side now the last thing we need to do is just give it a width so we're going to say width 24 and height full as you can see now we have this nice gradient that is going from the white color to transparent as you can see it's kind of fading out it's a little bit hard to see but if I made it a little bit Wier for example if I made it 48 instead you can now see this really large white that is fading into a transparent color all the way on the right hand side and just by doing from 50% it just makes it so that the gradient starts farther off the side so it stays white for longer let's bring this back to 24 so it looks a little better and that is pretty much what we want our left hand side icon to look like we only want to show this some of the time so essentially I want to have some State variables I want to have an is left visible State variable that's going to determine if this left clicker button is visible so set is left visible and that's going to be using State and by default it'll be false and I'm going to do the exact same thing with the right hand side I'm going to actually make sure this is up here like it should be there we go and this should say is Right visible there we go get my capitalization correct and now we can make sure we only render this entire div if the left hand side should be visible there we go so now the button has disappeared and if I change this to true you can see it appeared so now essentially what I want to do is when I click on one of the buttons left or right if I just copy this I can essentially do my right button real quick so let's just come in here and real quickly do that so we at least have the right button so is Right visible let's make it true by default so we can at least see it you can see right now it's on the left hand side we'll change this to a Chevron right there we go we want to make it so that it's on the right hand side instead and we just want to swap around this gradient so that it goes to the left instead of to the right and then finally we want to make sure that our button is showing up all the way on the right hand side so an easy way to do that is just say flex and justify end and that'll push this all the way to the right hand side just like that so now our right hand button is looking really really good too so we can minimize these down for now let's make them both not visible by default and let's figure out how we want to determine if they're visible as well as determine what they do so essentially when I click on one of these buttons I want to translate this entire thing by a set number of pixels you can see every time I click it moves this by a set number of pixels in whichever direction I click on so I want to have a set number of pixels we'll just say like translate amount let's just say like 200 pixels by default that's how far I'm going to move it and I want to move it that much every single time I click on one of these buttons so let's start with the left hand side button first cuz that's the easiest to understand we'll come in here with with an onclick what we want to do is we want to set a state variable which in our case is going to be a translate variable so I'm just going to copy this down this is going to say translate set translate and by default we're not going to have any translate set at all so we're going to keep this as zero so here I want to modify that translate by calling set translate I want to get the current translate property just like that and then let's determine what our new translate is going to be so our new translate is just taking our current translate minus the translate amount so if we're translated at 300 pixels minus 200 will put us down to 100 pixels but I first want to check if we've gone too far cuz if this value is less than zero that means we're trying to move too far so we should just clamp it at zero so if our new translate is less than or equal to Z just make sure we return zero as our new value otherwise return our new translate value since it's larger than zero it means it's a valid value so this will allow us to move to the left 200 pixels at a time and in order to see what this translate looks like what we can do is we can just get rid of this real quick maximize this section and we just need to add a new style to this div so we can say we're going to have a style here and this style is going to be for a translate property in our case we need to be transform and we want to do the translate the X Direction and in our case we're going to use some string interpolation inside of here to figure exactly what that translate should be so we're going to take our translate value which is just translate convert that to pixels and then most importantly I'm going to make sure that I come into here and I make this a negative value so now if I give that a quick save and we set our translate to like 300 you notice that this is translated to the left 300 pixels and if I were to actually show this left button set this to true and I click it you'll see it now moves 200 pixels to the left and again it moves 200 pixels to the left 200 pixels to left until eventually at this point we're moved all the way to the left behind this is just the all button you can't see it cuz it's is covering it but we're as far left as we can possibly go and we would want to hide this icon and right now it's just hardcoded we can't really deal with that let's bring that back to zero though now our right button is going to be a little bit more complicated and that's because we need to determine what the size of our overall container is so I'm actually going to add a reference to this I'm going to call it container ref just like that and up here we'll just say const container ref equals use ref there we go put null inside of here we're going to make this an HTML div element since that's what it is and I want to make sure I spell const correctly so now we have our container F and for our right hand button on our onclick we need to do a very similar thing to what we did inside of our left button I'll actually just copy it cuz we have essentially the same exact formula we want to use but it's just going to be a different way of doing it so first of all we're going to get our new translate Ro is just great but before we do that we should put a check inside of here to make sure our container ref exists so we'll just say if it's equal to null return and that's because we're going to be using this container ref to determine the overall size to determine how far we have before we need to stop translating ESS what I need to figure out is when is this cof point going to be reached well the way that things work inside of JavaScript is we have a client width and a scroll width so let me just real quickly show you what I'm talking about the edge is going to be the scroll width so if we take our container ref container. current. scrollwidth that's going to tell me how wide this thing is as if it was scrolled all the way so this is telling me how wide it is from the left hand side all the way to the right hand side as if I had scrolled all the way so it's the entire full scrollable width while if I want to get just the visible width that's going to be my container ref. current. client width that's just the amount of width showing on the screen so from the edge of this all to the right hand side of this I on this function word that's what this width is so I want to determine do I have room to scroll so if my new translate plus the current width that I have shown on the screen is greater than or equal to the total amount of space possible this Edge well that means that I've gone too far across the screen I've overshot my end so instead I should return a new value here and this new value that I'm returning is just my Edge minus my width that's what my translate should be and that's going to make sure I'm always on the very edge of the container so now if I make it so that this is actually visible and I click this button you notice it's not working because I need to make sure that this right here is a plus instead of a minus there we go now if I go over here and click this I think part of the problem is inside of here where I'm doing my return this should just return the current translate instead also I notice part of my problem is I'm not actually calling set translate anywhere inside of here so this should call set translate and get my current translate and then do all of this code inside of there that should at least fix all my problems so now if I click right you notice it looks like it's still not working let's just add a simple console log in here so we'll console log our container reft as well as our translate just to see what this looks like so we'll inspect our page go over to our console we can just ignore these errors for now we'll click next and you notice that every single time we do have an element but our translate is always zero that's not ideal so it should be adding 200 to that and returning that as our new value this makes me think there's something wrong with our Edge and our width variables so let's check what those are we'll say Edge and width now we can give this a quick inspect go over to our console clear this out click next you notice that they're both set to the exact same value now if we scroll up I believe the problem is is because we set our ref on the wrong element our ref should be set here and that's because this element has a specific width this is the thing that is scrolling as you can see it's what has the Overflow hidden on it this is the thing that has that specific size while this div down here is not actually Limited in its size it can be as large as it wants this should actually fix the problem just by moving that as you can see when we click it is now fixed and when we get to the end you can see it stops letting us go to the side so now we just need to determine when do we show these different icons this may sound really tricky but it's actually just going to be one single use effect that is doing one single re resize Observer and we want to modify this resize Observer anytime our categories change and anytime our translate property changes because anytime we change either of those we want to determine if we need to show those icons again so inside of here first of all if our container is null we want to obviously return so we'll say if it's equal to null do a quick return right now then we'll do a new Observer and this is going to be a new resize Observer specifically and for now we're going to skip what's inside of here and we're just going to say that our Observer is is going to observe our container ref. current there we go and when we return down here I want to un observe so we're going to say observer. disconnect just like that so it's going to stop our Observer completely so now I'm pretty much saying whenever the size of this container changes run this code and it's also going to run the very first time that we set up this Observer as well so it's going to run on initial load and whenever the size changes and it's also going to rerun every time our categories or our translate property changes so it's going to rerun every time we click one of the buttons ideally inside of here what I want to do is I want to get my container which is going to be my container ref. current if that is equal to null then what I want to do is return and we could also get this from the entries for example I could just say entries of zero. Target that's also going to get the same thing so we'll just do it like this that's fine then I want to do set is left visible well the left is going to be visible anytime our translate is greater than zero that's a really easy one the more complicated one is if our right is going to be visible well this is only going to be visible if our translate plus our container. client width is less than our container. scroll width and this is essentially the exact same code that we wrote down here it's just written in a slightly different way let's get rid of that console blog as well so now we're only showing our right if we have space to move to the right so now if I give this a save you'll notice our right button is there when I click it you can see our left button shows up click back you can see it disappears if I go all the way to the end you can see that the right button disappears all the way to the left the left button disappears so all that code is working just like we expected to now the next thing I want to move on to is going to be the video section this entire section right here and that may look like by far the most complicated part but this is actually by far the easiest part of the entire project so let's minimize down that category section we don't really need that anymore and we're going to create a new div and this is again going to be a grid because this is a very simple grid layout that we have here so we're going to have a grid with a gap of four inside of it and we're going to do some grid columns and I'm going to be using an auto repeating setup here so I'm going to say repeat I want this to be autofill and it's going to be min max so the minimum size these could ever be is 300 pixels and the maximum size is 1fr what this code is saying is essentially make sure that my items are never less than 300 pixels wide and if it gets to the point where you can add more items on the row add more so as you can see when I resize my page as soon as I get to the point where I can add more items it's adding more and it's constantly doing that and it's shrinking them down as I go that's what that one single line of code is doing CSS grid is amazing and if you're not used to it I have a full video I'll link it in the cards and description for you so now inside of this grid we want to render out essentially a bunch of video items we'll call them video grid items just like this and we'll just pass in a bunch of props for our video but for now we'll just hardcode everything and we'll create this component so we'll come in here video grid item. TSX so let's create an export function video grid item just like that and if we look over at YouTube we can kind of see exactly what all the different items inside of here should be and we'll create a type for the props this video grid item props so the very first thing we're going to need to do is have an ID of the video so we can link to it somewhere else that's going to be a string we then going to have a title of the video we're going to need the channel and this is actually going to be a little bit of multiple information the channel is going to have an ID which is a string again for linking purposes it's going to have a name which is a string and it's going to have a profile URL which is going to be a string then we're going to need to determine the number of views of the video we're going to need to determine when it was posted at at so that's going to be our date here the duration in seconds we'll make that a number we're going to need the thumbnail URL which is a string and then we also need the video URL which is a string and that's cuz when you hover a video it starts Auto playing so we need to make sure we have that as well so in here we need to make sure we include all those things from our video grid item props so we have our ID our title our Channel our views our posted at duration thumbnail URL and our video URL we can use all that information we create the stuff inside of here let's go ahead and we'll create a single div this is a div that is going to have essentially a flex layout so we'll say class name is going to be Flex we use a column based layout with a gap of two and that's because this is going to be our image at the top and this entire bottom section that's our two elements inside this Flex container so we're going to use an anchor tag which is be our link for the video so we can come in here and we can say that this is going to go to the slatch page with a video ID equal to our ID that's just the URLs that Google uses and we'll add a class name we'll make this relative so we can do some automatic positioning of things like the duration inside the corner as well as the video and we're also going to set the aspect ratio to video so it gives us the right sizing for this element as well then inside here we need to put all of our image related code so let's create an image just like this the source is going to be that thumbnail URL and then we're going to have to add a bunch of class names for example we want this to be a display of block we want the width and height to be full so it stretches we want the object fit to be cover so we're going to say object cover and then that should be all we need to do right away we also want to have some rounded Corners so let's do rounded XL on here and we'll close that off we're going to add a bunch of other stuff in here in the future for handling like the video playing and stuff like that but for now that's all we need for our image and we can move on to the actual timestamp section next so let's create a div for that this is going to have quite a few different styles first of all we'll absolutely position it in the bottom right hand corner we're going to give it a background of this secondary dark we want it to be that dark dark color and the text is going to be that lighter secondary color it's also going to be relatively small and we're going to have a very small amount of5 padding and we'll round the corners as well now inside here we're going to put the duration but we're going to need to format this for now we'll just leave it as is though so right now we're not passing any of this information in like if I import this component you're going to notice we still get a bunch of Errors so what I'm going to do is again copy over some hardcoded data for us to use that's going to be all of this data that we have here so if I just go back into that data folder here this data file you can see just have a bunch of data that has all the different URLs and stuff and all the video information for all the different videos we want to render on our screen just so I don't have to typ All Out manually just so you don't have to watch that now if we go back into our app here we can say that we want to render out all these different videos so we can Loop through them by saying videos which we can get from that import we want to map through each video and what I want to do is I just want to pass in the video object so we'll say key is going to be the ID and then we just want to pass down everything related to that video into this item so now if we look over here you can see immediately all these different things are showing up we have the thumbnails showing up nothing else is showing up but we at least have the thumbnail showing up they have the rounded Corners they have the time stamp in the bottom it's looking pretty good so far now one problem I noticed is this padding should have a zero in front of it that way it actually looks correct there we go and now we can actually work on formatting this duration if we want I'm actually going to create a utils folder that's going to have these formatters so we'll say utils and inside of here we'll just have the format duration. TS file export function format duration now for formatting in a duration we need to account for hours minutes and seconds so first of all I'm going to create a leading zero formatter we'll say that's a new intl. number format where the local is undefined and then we're the make the minimum integer digits be equal to two that's just so it's always going to have at least two digits and that way as you can see here for example we have a 054 showing up just fine and if we had something that has like 12 seconds or I'm sorry like 9 seconds at the end of it it'll have that properly here you can see it's 2 minutes and 0 0 seconds so that'll make sure it shows 0 0 instead of just one single zero so here we want to format a duration that is a number and we want to get the hours from that as well as the minutes and the seconds so the hours is relatively easy we want to get the math floor of the duration divid by 60 twice because we're going to be converting seconds into hours and we want to get the minimum number of hours so we're essentially rounding down to get the minutes we essentially want to do a very similar thing we're going to take our duration and we're going to subtract the number of hours that we currently have time 60 * 60 just like that I'm going to make sure that's all inside of its own set of parentheses so essentially I'm just subtracting this number from right here so I'm left over with just the minutes and then I'm going to take that minutes value and divide it by 60 to get it into a minutes format so so converting seconds into minutes finally to get the remaining seconds is much easier I can just take my duration here and I can use the modulo operator here and 60 and that's just going to give me the remaining seconds that are left over now here if my hours is greater than zero I want to render it in one format otherwise I want to render it in a different format so here I'll render it when there's no hours so if there's no hours is just going to be our minutes followed by our seconds and we're going to make sure we use that leading zero formatter so we'll format our seconds like that and then for the hours we essentially want to do the exact same thing but here we want our minutes to have that leading zero format as well so I'm going to copy that in just like that and then we want to make sure we put our hours at the very start there we go and let's make sure that we return this just like that so now you can see if we go back over into here and we actually use that format duration function right here we pass in our duration you can now see that these are formatted as actual minutes hours seconds time stamps which looks much better now before we move on to making it so when we hover a video it starts autop playing I'm going to focus on the bottom section here so let's go back over to what this should look like and we'll just minimize this anchor tag section down for now we'll create a div again I'm going to be using Flex box for this with a gap of two and that's because I'm going to separate this left hand side from the right hand side and inside of here if I just make sure I get an actual div element we can have our anchor tag which is going to be for our image on the left hand inside and inside of this we're going to put our image just like that so for our anchor we're going to have an hre here and this href is going to go to a specific URL which is SL and then we want to do the channel ID just like that and that's just because that's the way that YouTube does things then we're going to have to do some classes and we'll set the flex shrink here to zero so again this doesn't shrink down at all now for our image we want to give it a specific size we'll do a width and a height of 12 and we'll make it a full ccle Circle by saying rounded is full there we go so now if we come over to here you can see that we have our icons but they don't quite look right that's just because we need to give them a source so here our source is our channel. profile URL now you can see all the different icons are showing up the next thing we need to work on is going to be the title the channel name as well as the view information at the bottom so the next thing we need is a div to render all of those and inside of here let's do that so we're going to have an anchor tag which is going to be an href here this is going to be for the video title so for our video title it's going to be slatch and it's going to be V is equal to whatever the ID of the video is then for the class name this has a font of bold and inside of here we can put the title now you can see we have the title showing up in that bold font let's move on to the channel name which is next this is an anchor tag here and it's essentially the same anchor tag so I'm just going to copy this just like that remove the image cuz we don't need that and we can remove this class CU we also don't need that instead we want to add our own class name which is text secondary because we want it to be a lighter text so we'll use that text secondary text and the text will be small finally let's put the channel name inside of here so we'll say channel. name there we go give that a save now you can see web dev simplified and so on and what I should probably do is change the class name here to flex and flex column so they stack vertically there we go last thing that we need to do is add in the view count as well as the time s the video was published so we can create a div for that and the class name for this div is going to be here text of secondary and we'll use a small text there we go and inside here I want to have a formatter for our views we'll just create that up here we'll say view formatter because this is actually a really easy formatter to create that's just CU we need the inl number formatter and this number formatter is going to be UND defined again and here we're going to have this notation and this is going to be the compact notation and this just does all of the hard workor for us of converting thousands and millions and so on so we can say we want to format our views just like that now if we go over here you can see this says 257,000 this says 223,000 this should also be text like that so it's a little bit easier to read so you can see 1.2 million 112 and so on it's perfectly rendering out that number next we want to have that dot symbol I'm actually just going to copy that do symbol over that's just cuz I copied it directly from the YouTube website so there we go 223,000 views with the do symbol and then finally we want to use the format time ago function which we're going to create in just a second which uses this posted at date so let's go ahead and create that in our utils folder we'll say format time ago. TS and I'm actually just going to copy all of this code over and the reason that I'm doing that is because I have actually a full blog article explaining exactly what all this code does in super mega depth to understand exact what's happening so instead of having you watch me actually type all this out if you're interested I'll link the blog article in the description of this video but now if we just import that function and we give it a quick save you notice when we go back over here it says things like 1 month ago two months ago 3 weeks ago 2 days ago this is using built-in functionality into JavaScript just the relative time formatter that's built in as well as a very small amount of custom code and now with all of this done we're pretty much left with just the final step of making a video play when we hover over it and doing all the animations related to so let's go back into here and we'll create a state variable to handle this we'll just say up here at the very top const is video plane set is video plane by default that Ed State variable is going to be set to false we're also going to need a reference to our video so we'll say video ref is equal to use ref and this is going to be an HTML video element and by default it'll be set to null now we're going to use a use effect to handle pretty much all of the plane information for us so here whenever our is video plane changes all we want to do is just toggle that for our video so if the video ref. current is equal to null then don't do anything otherwise if our video is plain well we want to take our video ref we want to take the play value and we want to just call that function we also want to reset the time of our Vari of our video to the start so we'll say current time equals z just so the video starts over because for example here if I hover over this video then I hover off and I re hover back over it starts over right at the very beginning again so this is just consistent with YouTube otherwise if the video is not playing we'll take our video ref. current and we will pause the video there we go just so it doesn't have any playing in the background that it doesn't need so right now that doesn't really help us we need to actually set up some event listeners so when we hover over this it actually changes our video between playing and not so on Mouse enter I'm going to set my is video plane to true and then on Mouse leave I'm going to set that to false so set that to false just like that so now at least I'm toggling between this all I need to do is add in the video element and then actually render it so let's go ahead and add the video element and we're going to specifically make sure that this shows up over top of everything else so we're going to give it the ref of video ref just like that and we'll close this off I'm going to make sure that this is muted I'm going to make sure that it plays in line that's just just make sure it doesn't go full screen on mobile devices and we'll set the source to our video URL then finally the last thing we need to do is add all of our different class names so we want to make this a display of block the height is going to be full height and we're going to use that same object cover and we want to absolutely position this with an inset of zero so it covers absolutely the entire section it is inside of finally we're going to add a transition property for opacity cuz we want this to fade in you look here you can see it has Ace nice fade effect and we want to make sure we replicate that and for our specific fade effect we'll give it a duration here of 200 now the last thing I want to do inside of here is just to make sure that we only make it visible if our video is actually playing so what we'll do inside of here we'll say is video plain if the video is plain our opacity should be set to 100% so we'll change that here otherwise if it's not plain our opacity should be zero so we'll give that a quick save and that'll at least make that work next what we need to do is actually make the rest of this work but you'll notice when I hover over this you can see immediately it's already doing it it just doesn't have any nice animations just just instantly changing between the two so we need to do is add some animations on this image here so for our class we come in here we'll just change this around so we can add some custom Styles inside of here based on our is video plain if the video is plain we want to have no rounding at all so we'll say rounded none otherwise we want to use this rounded extra large so we'll copy that into there then what we want to do is we want to add a transition on specific specifically the Border radius property we want this to be a duration of 200 so now when I hover over this it's at least going to do that Force you can see when I un hover the border is unring but we still have the problem with the opacity not fading in properly for this element here to fix that if we look over at YouTube you'll notice when we hover over a video it waits until the entire border is done becoming straight before the video actually starts playing it just gives it time to load so we can emulate that by adding in a delay so we can say we want to delay this by 200 so first the border is going to unround and then the video is going to show up if you'll notice when I un hover it still has a 200 millisecond DeLay So we only want this delay to be shown when the video is actually playing that way it only does the delay to play the video and when I un hover it instantly disappears just like it does over on YouTube so that is that entire functionality built in so now we finally moved on to the final section which is going to be our sidebar so instead of just having this hardcoded we're going to use a sidebar component just like that and before we do that I want to make sure all of our scrolling related stuff is working so as I scroll you can see that the only thing moving is this middle section and everything else is stuck in place just like we want it to be so let's create that sidebar we'll come into here inside of the layout folder we'll create our sidebar. TSX export function sidebar we'll just return null for now there we go and inside of here we'll import that sidebar it looks like I Ed lowercase there we go oops not from from the icons Library we'll import it from there there we go and right now it's just rendering null so there's nothing over there so let's get started with our sidebar by first adding in the aside tag that's what we're going to be using for our sidebar and for our class names we want to make this sticky to the top of our page and we want to make it so that our overflow in the y direction is set to Auto so it can scroll and we're also going to add in this tricky scroll bar hidden class here and that's just because we want to have custom scroll bars on our site so if I shrink this down a little bit more you'll notice how we have this really ugly scroll bar but on YouTube they have this kind of custom looking scroll bar and over here this scroll bar only shows up when you hover over it that's where this scroll bar hidden class is going to be we're going to implement that ourselves then what we need to do is add a little bit of padding so we'll say padding four for example we're going to flex it in the column Direction and we're also going to set the property here of flex and then finally a little bit of margin on the left hand side so give that a save we've added a little bit of space inside of here if I add some text you can see it showing up here and this very first decide that I'm going to create is going to be for this smaller version of the sidebar as you can see here this shrunk down version so that means I actually want this to be hidden on large screen sizes so on large screen sizes this will be hidden completely so now if I come over here as I increase my screen size it disappears it's only on the small screen sizes and inside of here I want to create a small sidebar item and this small sidebar item if I look over at YouTube essentially has an icon a URL for when I click on it as well as an actual text so we're going to have an icon which would be our icon that we want to use in our case we're going to use like the home icon so we're going to import that from the library we're going to have a title which is just home and then finally a URL which is just going to be equal to the homepage now let's create that function small sidebar item and that takes in an icon a title and a URL and that's going to be the props for this and let's create a type for that icon this is going to be an element type that's what it is from react since we're just passing in the name of the element and not the actual component our title is a string and our URL is a string so let's create what this will look like we'll do a quick return here we want to do an anchor tag so this will have an href which goes to our URL we're going to add a bunch of class names to it to make it look like our actual buttons for now I'll just leave that blank and then finally in here we want to render out our icon which is going to have a specific size so we'll say class name is equal to a width and a height of six and then finally we're going to have a div which contains our text so we'll say title and this is going to be a class name which is going to be text small since we don't want this to be a very large piece of text so immediately if we just look at what this looks like you can see here we have the home icon and we have the actual home text it looks relatively okay what we really want to do though is make this look just like our normal buttons cuz essentially this is just a button so to do that we can actually use the styles from our button component I can export this and use it anywhere I want with any element which is great so now we've exported these button Styles we can go back into our sidebar and we can actually use them for our class name here so I can say here I want to use my button Styles and in our case I want here the variant to be the ghost variant just like that now if I give that a quick save you notice that we're at least getting closer to what we want our style to look like I do want to add some custom classes though so I'll use tail and merge to add those classes in for me so we'll merge those together just like this I'll add them to the end and we essentially want to have a bunch of padding on the top and bottom a very small amount on the left and right we want this to be Flex spaced in the column Direction so that everything is going to be centered and we want to make them a little bit more rounded and let's say we'll have a gap of one between these items now as you can see this is looking relatively good and as we add in the rest of our small icons this is going to look even better so to save you the boredom of watching me type out each one of these icons I've just copied the icons directly from YouTube all four of these I've copied over I've gotten the best icons I possibly can so I'm just going to import these from the Lucid react icons Library give that a quick save and now you can see all four of our icons are showing up right here which looks really really good now that pretty much takes care of all of these different icons that we need and they look pretty much identical to what we have over here the next thing I want to work on is what the large sidebar is going to look like is a little bit more complex we'll come over to here and we'll work on that large sidebar next we're actually just going to put put this in line cuz the easiest way to create two things that are very different is just to show one on a small screen size and one on the other screen size so we're just going to have another aside here which is going to have specific class names to make it only visible on smaller screen or on larger screen sizes I'm sorry so for this one I'm going to hard code a width so it doesn't get too big I'm going to make it so that on large screen sizes this is going to be sticky to the top of the page I'm going to make it an absolute position otherwise and the reason for that is because we want to actually show this inside of a pop out like this on a smaller screen sizes and on larger screen sizes we want it to be stuck to the side just like this so that's part of the trickiness of this sidebar in YouTube so that's why I have those two different positions we have a top of Zero no matter what our overflow in the y direction is going to be Auto and we're going to have that same exact scroll bar hidden property here as well with some padding on the bottom of four we're going to make this a flex column layout a gap of two a padding on the left and right of two and then finally a flex for our actual display now in inside of here we essentially want to have a bunch of different sections if we open this up you can see we have this top section then this section then the subscriptions explore so on we have a bunch of different sections essentially we want to use so I'm going to create a component called large sidebar section and inside of here I'm going to have a bunch of large sidebar items so we're going to have like an item like this these are the two different things that I want and a section essentially can have a title and it can have a number of items that are visible for example here you can see after we get to five items it has a show more button and here after I get to like seven or so items it has a show more button but this just shows everything so there's like a dynamic amount of show more so we need to make sure we have that and we also have this title we can have in certain places or not so for our first large sidebar section you'll notice we show everything and we have no title so we can just leave this all blank for our sidebar items we want the same thing we want a URL an icon and we want some text also we need to determine which one of these is active as well so in our case what we can do is we can just copy all of this information it's going to be exactly the same same paste it into here and this one is going to be active so we'll just say is active just like that so let's create these different components we'll come down here function large sidebar section and a function for large sidebar item for the item we essentially want the same props we had here so I'm just going to copy those over and instead of this being small this will be large this will say large Side Bar item props the type for that is also going to be pretty much identical to this the only difference is we now have an is active property so is active is an optional Boolean we'll put it into here as well is active which is default to false inside of here we're just going to return an anchor tag which the hre is going to be whatever our URL is and for our class names we're going to be using those same button Styles but again I'm going to be using tail and merge so I might as well just put that in there right away so for our button Styles we want this to be a variant of ghost just like that and then for our extra Styles we want the width to be a full width button we want it to use flex for the display we're going to Center all of the items and we're going to put rounding of large on the sides we're going to have a large gap of four and then finally a bunch of padding of three around all the different sizes let's close this off for now and now what I want to do inside of here is I want to render out my icon class name here here is going to be a width and a height of six just like we've done for pretty much all of our different icons close that off and then finally here we're going to have a div that contains our title we'll give it a class name we want to make sure the white space does not wrap that way if there's any overflow it's just going to overflow and to make sure it's hidden we're going to set our overflow to Hidden and our text to ellipses that way it actually shows three dots at the end of it then we're going to render out our title inside of there so if we come over to here and we were to expand this a little bit you'll see we have have this section for all of our different information but nothing's quite rendering out yet the reason for that is because of a large sidebar section right now it's not rendering anything if we just rendered out the children directly so we just said children just like that you can now see at least that one thing is showing up right here but we should probably add our styles for what this should look like also we should make sure we deal with this is active as well so inside of our Styles let's just come in here we'll just immediately do some string interpolation so if we are in the active style what I want to do is I want to add in some specific styles of font bold let's just make sure we uh use undefined as well if we don't have anything so there we go undefined so we'll do a bold font for this the background will be a gray 100 and let's probably do neutral there we go a neutral 100 the hover will be background secondary just like that so now if we give that a save you can see that it has that slight gray background on the active version and if it's not active it won't have that so if we were to come in here with another large sidebar item that's not active so I'll just copy this exact one down you notice it looks slightly different than the active one now we should deal with our large sidebar section next we should get the props so let's just copy this over props is equal to we have our children which is just a react node we have our title which is an optional string we also have the visible item count which is an optional number as well of how many different items we should have visible at one time so let's set this to be equal to those props just like that we'll get our title from here as well as a visible item count which should default to essentially infinite so we'll do positive Infinity just like that now for rendering this out we should create a div with all of our different styles that we're going to need and inside of here is where we're going to render out all of our different children we're only going to render out the visible Ones based on our visible item count so we can get our visible children which is equal to just our children and we want to actually get a specific number of them but to convert this children to an array we can get our children array which is just equal to react. children. to array and that'll just convert your children to an array exactly as we want it now the last thing we need to do is since an array can have multiple arrays inside of it we want to flatten this so it's a one-dimensional array and we'll just import children directly from react just like that so now we have our children array and what we want to do is we want to just get the first so many so we're going to get the first all the way up to the visible number that we have then we can render these inside of here so for now if we just place these in there just like this you can see it's rendering out our two items if we were to change this section to only have one visible item you can see now it only renders at one item so that is working as we expect the next thing to work on is going to be what our title is going to look like inside of this section so here we have our div which has our visible items we also want to have a title so if we have a title we want to render it inside of a div and we're going to give it some specific classes like some margin on the left hand side on the top side we're going to make the text a little bit larger and we'll add a little bit of margin on the bottom and we'll put our title inside of that div there we go so now if we were to give this section a title of high you can see that title shows up and it looks relatively good lastly we just need to be able to deal with expanding so let's just say that our visible item count is actually equal to one we want to be able to add and expand collapse button inside of here so we're going to have a variable called show expanded or expand button and if that is true we're going to render out our expand collapse button now let's just increase the size of this so we can focus a little bit more on our code so we have our children array and we also need to have this const is expanded which is going to be a state variable just like that use state by default that's going to be equal to false and the way we can determine whether or not we want this to be expanded is with an expand button now we also need a variable for if we should show the expanded so show expanded button that's this variable right here and this is just equal to if our children arraylength is greater than the number of visible items that we're showing so if our visible item count is less than the number of children we have we should show our expand button also our visible children will depend on if we are expanded or not because if we're expanded we should just render the entire children array otherwise we should only render the ones that we want so let me just actually change this to be right there there we go so if we're expanded we're showing everything otherwise only show the visible ones so now inside this show expand button we can render out a button component we want to have the variant here equal ghost let's just close off our button just like that we can get rid of these curly brackets those shouldn't have been there and then what we want want to do is we want to add a few other things inside of here so let's add in a class name and we technically want this to look just like our large sidebar item so I can really just copy all of these different styles that we have inside of here and I can paste them into there directly so if we give that a save we expand this a little bit we don't have any button showing up yet and that's just because we don't have anything inside of our button right now so inside here we want to render a specific icon we'll call this our button icon and that's either going to be a Chevron up or Chevron down so if we're the expanded State we want to show the Chevron up which we'll import otherwise we want the Chevron down which is going to be the opposite way that it's pointing so let's render out that button icon inside of here and again let's make it the exact same class of a width of six and a height of six just like we did for everything else and then finally We'll add in a div that's going to have some text so we'll say if we are in the expanded state it will say show less otherwise it'll say show more there we go make sure this looks good if we just expand a little bit get rid of all the extra spacing we have code looks relatively good we should probably make it so that our button toggles this state so we'll set our expanded by just toggling this variable there we go now if we expand this over you can see we have this show more and show less and it's making sure it's based on this visible item count so if I remove it you can see that entire expanded section completely goes away bring this back to what we had before so it's a little bit easier to work with now for this very first section we only have one more item we need to add I'm just going to copy it over for us give that a quick save make sure that this is our icon there we go and you can see we have these two sections just like we have over here now we need a divider between these sections I'm just going to use an HR and that gives us a perfect divider between our sections and then we can work on another large sidebar section just like this and we can put all the other icons for example this entire section inside of here as well as this show more show less button so I'm just going to get started by copying over these so you don't have to watch me type them all out I'm just going to make sure that I update this to be the icons that we're using there we go give that a quick save and if I come over to here and I make sure here I also import the correct history I want to get the one directly from the Lucid react Library so let me make sure I do that that'll fix up this bug there we go now you can see that those icons are showing up as well and just so you don't have to watch me type them out the next thing we need is this entire playlist section as you can see over here we expand this out we have a section where it renders out all of our different playlists so we need to do that as well so if we come over here we can essentially just Loop through all of our different playlist by saying map for each playlist and we want to render them out and again I'm going to copy over this playlist Json data so if we come over here I'm just going to paste down this file for our sidebar you can see it contain contains all of our subscriptions as well as our playlist and that's because we have a subscription section and a playlist section so now we can actually use that inside of here and again it's just so you don't have to watch me type all that out manually so we're going to need a large sidebar item the key is going to be our playlist ID there we go and here for the title we're going to have our playlist name and then here we need the actual ID for our playlist to go into the URL so this is going to be playlist. ID give that a quick save now you can see those are showing up and we should just use the correct icon here this icon is called list video we'll just import that now you can see we get this perfect playlist icon showing up now the important thing is this section should only show five icons by default because if we actually collapse this down you can see it's only showing five different things so this should say visible item count is five now if we just collapse both these down so it's a little easier to read look over here you can now see it's only showing five click show more it shows the rest and then we can hide them again now let's add in another HR here to divide that up before we go into the subscription section right here so we need another large sidebar section this one is going to have a title of subscriptions and this one is going to be a little bit different because while we can render out one of these items I'm just going to copy it over you notice a problem is we don't have an icon instead we have a URL so let's go into our item here and instead of just having an icon we should have an icon or image URL so this could be an element type or a string I'm going to update all the places where I'm referencing this so inside of here it needs to be updated and then here it needs to be updated and all over this code we need to update all of those and in here we need to update both of these so by default all this is still working as before as you can see I give this quick refresh and I make sure down here I change this you can see it's still working as before but now we we have the option to pass in a string in case we want to render out a URL instead of an actual icon so here if the type of that variable is equal to a string well then we want to do something different otherwise we're just going to keep rendering what we had before so in the case of an actual string we want to render out an image instead so we'll say here we have an image where the source is that icon or image URL and the class name here is going to be the same width and height but this one I want to be rounded full so it's a complete and full circle so everything is still working just fine but now we have the ability to use URLs instead so up here inside this section we're going to do a simple Loop so we're going to come in here we're going to get all of our subscriptions which again come from that Json data for each one of our subscriptions I want to render out one of these items and the item here is going to have a key which is going to be equal to my subscription ID the icon is going to be equal to that image URL the title here is going to be subscription Dot and we're going to use the channel name and for the URL this is going to be a at slash and then whatever the channel ID is so we'll say ID just like that there we go give that to save and now you can see all these different subscriptions are rendering now we can finish off this final section of all these explore tabs inside of here as you can see in YouTube it has this big explore section it has even more after that but I'm just going to do this explore section as the last section just so you don't have to watch me type a bunch of this information large sidebar section and I'm just going to copy this over so I can come in here title is equal to explore I'm going to paste down this and I'm just going to get all of our icons imported so we're going to get like the flame icon shopping bag icon this music icon film icon radio this one and I tried to match these icons as close as I could to the YouTube icons they're not exactly the same but I'd say they're about 90 % of the way there get these last two imported there we go now if we give it a save you can see we have all of that showing up the last thing we have to do is just to make it so that we first of all have a divider between these there we go that has the divider and then lastly we want to make our scroll bar actually look correct and this is something we can't use Tailwind for we need to write our own custom CSS for it and remember I have that scroll bar hidden class that we added to these so modifying scroll bars is kind of a complex topic I have a full video covering it I'll link in the card in description for you but essentially what we want to do is when we have a hidden scroll bar we want to change our web kit scroll bar whoops webkit scroll bar thumb and we want to make the thumb essentially be transparent so we can apply the BG transparent class to it from Tailwind that'll make it completely transparent now to make it so that we actually render out a custom scroll bar we can apply this to all of our different elements we can say we want to use that web kit scroll bar and we want to get the thumb again and for our Thumb in this case we want to apply some styles of a background secondary dark and a rounded fold to round off the tops and the bottoms of that scroll bar finally we need another selector here and this one is going to be for actually making the scroll bar work so we'll use webkit scroll bar here this one is going to be for like the background of the scroll bar as well as just overwriting everything I'm going to set the transparent background to this and a width of two so now as you can see over here on the right hand side we have a scroll bar that's showing up right here we have no scroll bar in this hidden one because I made it transparent by default if I copy this though and instead I make it so when we hover over this that it shows up with a background secondary border now you can see when I hover that the scroll bar shows up and it's actually a different color because in YouTube they use a different color for both of their different scroll bars so in my application I'm also using a different color for both of the different scroll bars now this only works inside of chrome-based browsers so if you want to make it work inside of Firefox you don't have as much control but we can change the scroll bar width to thin and that at least will make it thin inside of Firefox and other browsers that support this property so now we have a lot of the Styles done but our actual sidebar isn't collapsible and doesn't do anything fancy the only thing it does is it's responsive for the most part but it looks like we still have a little bit of a bug with our scroll bar so let's go ahead and try to fix that real quick looks like the problem here is it should only be flexed on large screen sizes and on all other screen sizes it should be hidden there we go so now on large screen sizes if we increase this you can see it's there and on small ones it's hidden so we at least have that portion done but we need to make it so that we can expand and collapse it which is the hard part so I'm going to create a context that lets us handle this so I'm going to create a new folder context and inside of here I'm going to create our sidebar context. TSX and in here we'll export a function called sidebar provider which takes in some children sidebar provider props there we go and let's create a type for that provider props and that is just our children which is a react node there we go make sure I import that now next we need to create our context so we'll say sidebar context is equal to create context pass it in null as our default context which is something you should should always be doing and here we're going to return our sidebar context provider wrap it and we're going to pass in our children and by default we'll just give it an empty value as an empty object there we go so now we need to create the type for our sidebar context and I'm just going to call this sidebar context type and it could also be null by default so let's create that type sidebar context type and this is just determining everything related to our sidebar and this is where it gets confusing so for example on YouTube in this scenario when we're full screen you can see our sidebar is expanded and now it is collapsed but when we go down to mobile our sidebar has its own expand and collapse variable so on small screens and large screens the actual expand and collapse is independent from one another so we need to have both a is large open which is a Boolean and we need to have an is small open to determine if it's open on small screens as well so we can keep those independent from one another we also o need functions for toggling it so we can have a toggle function here and we should also have a close function so we can close it as well there we go that should be all that we need for our sidebar context inside of here we need to pass all that information in so we're going to use state for that so we're going to have an is large open and set is large open and that's going to be a use State variable of false and actually it's going to be true because by default on YouTube when you refresh this sidebar is open here is an is small open set is small open and this one is obviously going to be false by default so we can at least pass both of these in to our value and now all we're missing is our toggle and our close function so let's create a function called toggle and a function called close also we should probably come in here and we should create a function called is screen small and this will just allow us to determine if we're on the small screen or not and that's just window.in is less than 1024 it's a relatively easy measurement right there and this 1024 comes directly from Tailwind this is that large property so we'll have the cut off exactly perfect so if the is screen small then what we can do is we can set is small open to the opposite of what it currently is just like that otherwise if we're on a large screen we'll set this for the large screen so we'll set is large open to the opposite of large there we go I'm going to essentially do the exact same thing for close but instead here these will both just be set to false there we go and now we can pass in the toggle function and the close function and all this does is when I click toggle it'll allow me to toggle whichever screen size I'm currently on so I don't have to worry about making sure I keep track of that anywhere else it just does it automatically for me now pretty much the last thing I want to do inside of here is to create another function which is a ed sidebar function that allows us to actually use this context we'll call it use sidebar context sure it doesn't really matter and here when I get my value which is equal to use context of my sidebar context there we go make sure I don't import sidebar we don't actually need that if the value here is equal to null then we want to throw an error because we obviously can't use this cannot use outside of sidebar provider it must be inside the provider where you use this otherwise we're going to return our value so this is just allowing us to use our context other places so now in our application we can wrap the entire thing in our sidebar provider just like this move this all the way down to the very bottom and now inside of our page header we'll have access to this as well as inside of our sidebar so let's go into our page header and we can actually use that hook so we'll say const and we'll use that sidebar context now we have access to the ability to toggle this so we have that toggle function for example which is what we want to use inside of this top section on this button so on click we want to toggle this open en closed so this is what we want to be able to do now right now we don't have any Styles set around this but if we go into our sidebar we can consume this to use our Styles so we can say here use sidebar context and now we can actually get our styles for example is the large one open or is the small one open we have those abilities to use these so what I want to do with these is determine a essentially the position and the actual layout of these elements based on which one's open so for our smaller sidebar if we go over to YouTube on the small sidebar section you'll notice here this sidebar is shown by default on the small screens and it's showing when the large is not open so this exact same sidebar is shown on small screen sizes and when we have the large screen size collapsed so here what we want to do is we're going to add in some custom classes so we use string interpolation for this and what I want to do is if my large is open then I want to make sure that this is not showing at all so this should be hidden by default on those larger screens otherwise what I want to do is I want to make this showing on the larger screens as well so wherever I have large Hidden I can remove that completely because now that's taken care of right here so a little bit more explanation of exactly what this means essentially I'm saying okay no matter what's happening I don't have any display properties shown as you can see here there's no display properties so if my large is open then this should be hidden but it should only be hidden on large screen sizes because on small screen sizes it should always be a display of flex otherwise if my large is closed then that means I want to actually show this one instead so it's going to have a display of flex here now if I actually just mess around with this it won't quite work I mean it'll show up as you can see here but we still have the other sidebar showing up so clearly that's not super ideal so let's minimize this sidebar and move on to the other sidebar and we're going to add some custom classes inside of this one as well so we're going to come in here add in some custom classes and this one is going to be what happens if large is open so in our case if large is open then we want to have this be a display of flex only on the large screen sizes otherwise we want to have a display of hidden because if large is not open obviously it should be hidden but if the large is shown it should be a display of flex and we can remove this right here now we also want to have specific styles for if the small one is open as well so if small is open and I make sure that this is properly inside of my string there we go so in the case of small is open we want to do one thing otherwise we want to do something else so if the small is not open we want this to be hidden because that means we're on the small screen size but we haven't opened up the scroll bar or the sidebar yet in that case it's this is what it should look like and when I click this button then it should show up now in our case when we want this to show up we want it to be a specific style in our case we want it to show up so we want it to be a flex property here we also want to make sure that the Z index is very large so we'll just just do like Z index of 999 so it shows up the background should be white and it should also fill the full screen size so we'll say the max screen size here is going to be the max H screen and that's because we also have this page header at the top that we need to have show up as well so if we give that a quick save we can kind of see what we have working let's go to the full screen and we collapse you can see it collapses down to the small one and opens up to the large one on the small screen size we have our own independent button here and right now it doesn't really do anything when I click on it that's because I need to remove this hidden style right here here so now when I click on this you can see it opened up the full screen version off to the side which is really great I have no way to close it right now because I don't have that implemented but you can see that this is looking up and the only reason it closed is cuz I clicked on a link you can see if I click somewhere else it's not closing let's just do a quick refresh so what I want to do when I open this up is I want to essentially show this entire section of my page header so in the page header I'm actually going to take that top section which is this entire first div right here I'm going to move this into its own component so we'll say function page Ed first section and I'm just going to return this right here and then we'll make sure up here we render that out so here we're going to render out that section and as you can see I have a few different things we have this show full width search that we need to worry about so that's just kind of like a hidden property so do we want to hide this or not so if hidden is true then that's going to be there so we'll say here hidden is equal to show full width there we go and then what we want to do is we have this toggle inside here as well now this toggle is coming directly from this sidebar context so we can just paste that down into here and there we go looks like everything is working as we expect and this button is still toggling between different things the next thing we need to do is add in our different props so we can have here our page header first section props type is that hidden is going to be a Boolean just like that there we go now it looks like we have maybe some problem with our spacing here so let me make sure I put this in the correct location looks like I put it inside my form instead of outside there we go now it looks like things are working as we expect this expand collapse is working and on small screen sizes this is still working we just need to now render this page first section up inside of our sidebar so in our sidebar inside of this larger section that we have the very first thing I want to do is render out that page header we want to make sure we export that so we can actually use it so export that there we go we can go back into our sidebar page header first section and I want to render that out inside of here and of course we don't want to have this hidden so we're going to make that hidden property optional and we'll default it to false there we go so now if we open this up you can see we have that header section up here we obviously want to add some Styles because we don't want it to show up on our large screen sizes obviously and on our small screen sizes we want to get our padding correct so let's wrap this inside of a div just like that and we can add some classes inside of here so first of all on large screen sizes I want it to be hidden that way we don't have that double header problem I want to add a padding on the top some padding on the bottom and some padding in the X Direction and if we give that a quick save and we click on this button you can see it looks like it's just working perfectly fine the one problem though is we want to make sure it's stuck to the top so we'll say sticky of that top of zero and a background of white now when we scroll you can see it stays stuck to the top on larger screen sizes you can see there's no problem at all it doesn't have any duplication and on smaller screen sizes you can see that that is staying expanded just fine now we just want to gray out our background and also make it so that when we click on that background it closes out so what we can do is right here we can add in a section if our small is open then we want to render out that darker gray background around everything so here we can render out a giant div and this div can just have an onclick on it that will close out so we'll call that close function and then we can add a bunch of class names to make this positioned exactly where we want it so we can say here we want it to be the class name so we'll put that inside of here there we go so we want this to be hidden on large screen sizes it should never show up otherwise we want it to be fixed in place with an inset of zero so it takes up the entire space we want a z index oops Z of 999 just like that we want the background to be our dark background color and we'll give it like an opacity of 50 or so now you can see we get that nice darker color when we click on it you can see it should be closing out of this but it doesn't look like it is also we can make this div self-closing just to make it a little bit easier to work with so we'll come in here we make that div self closing as you can see when we're clicking on this it doesn't look like it's closing out of this like it should most likely we forgot to import our close as you can see that is the case so here import that close function so now when I click you can see it closes out of that section just like we expected to now it may look like everything's working but there's actually one minor problem for example let's say that we have our sidebar open right here and then we go and we minimize our screen that's working but let's say we have it open here now we maximize our screen and now we minimize it again and you can see the sidebar is still open while on YouTube if we have this open and we maximize and then we minimize you notice it doesn't reopen the sidebar which is nice it shouldn't reopen that sidebar so inside of our context we can actually deal with this by using essentially a resize event listener so here I have a use effect and inside of this use effect we want this to only run one single time and then what we can do is we can create a Handler function just like this and this is going to be on a window. addevent listener for resize so every time we resize we want to call this Handler and in this Handler if our window.in width is going to be greater than or equal to 1024 or essentially we can just say are we not on a small screen so not small screen then we're going to set is small is open to false so anytime that we go to a large screen we just want to make sure we close our small model that is open right here that's all we're trying to do here then we can set up a simple return function just like that and that's just going to remove our event listener there we go so now we have it open we expand our screen and as soon as we get to this point this code right here ran and it made it set to false so now when we shrink down our screen you notice it doesn't actually open up the sidebar so we can start it as open Go full and go small and it doesn't actually open up which is really nice and you notice it saves my preferences based on what screen size I'm on and that has how you create a complete clone of the YouTube homepage if you enjoyed this video definitely let me know and I'll try to create more videos like this but they're incredibly timec consuming you want to see some other large projects I've created I'll have them linked right over here with that said thank you very much for watching and have a good day
Info
Channel: Web Dev Simplified
Views: 54,445
Rating: undefined out of 5
Keywords: webdevsimplified, youtube home page project, youtube clone, how to build youtube, reactjs project, react project, reactjs tailwind typescript, typescript project, react typescript projects, reactjs typescript tailwindcss project
Id: ymGB1lqP1CM
Channel Id: undefined
Length: 109min 7sec (6547 seconds)
Published: Tue Oct 10 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.