Make an Animated Menu like Stripe with React, Tailwind, and AI

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
how does stripe make this awesome morphing menu animation I'll show you how to recreate this and react with just a few lines of logic and we'll use AI to generate all of the markup and the end result will be exactly what you see here let's start with a blank react app and let's use AI to take it from this to this with almost no work I'm going to start with these mockups in figma that I'll share at the end and I'm going to use AI to convert this to code using the builder. vgma plugin I hit generate code bu Builder will launch the AI will make this design nice and responsive and the AI will stream out my code in the framework and CSS library of my choice in this case I did react and Tailwind I'll copy it and I pasted that into my code base and I called it the stripe hero component and now will take my ugly hello world page and instead I will import stripe hero save and beautiful that's a much nicer starting point now I'm going to take out the links here and make it their own component because that's where our logic will live so back in our strip hero I'm going to copy this nav section with all the links I now pasted it into its own nav components and back over in my hero I'm just going to import nav and great now that we didn't have to waste time generating all that basic markup let's plug in the logic and make those nice interactions going back to stripe for a second looking at this animation there's really only three things we need to track we need to know what are we hovering I'll store that as a number we need to know the set left as in how far left or right this menu needs to sit and notice when I change to different menu items the menu wrapper itself resizes its height to match the contents so we're going to need to store the height as well so over in our nav component let's add these so we're going to track what we're hovering we'll make that a number or null we're going to track the left value of how far over on the screen this menu should live and we're going to track the height value each as their own piece of state now let's hook this up on Mouse enter we're going to want a set hovering to be the index of whatever link I just entered my mouse into so we'll call the first link zero we'll call this link one and so on and so forth now when we're hovering let's have a popover show at the bottom of this component I'll just say hovering and I'm find a div with some styling position absolutes a wide background in Tailwind a shadow Etc now when I hover I see this little overlay that looks good but it's not hiding when I Mouse away so let's go to our nav let's say on Mouse leave and we're going to set hovering to null so now it's there it's gone progress now let's make it so that when I move to different links the popover ships left and right to do that I need to set this popover left value what I'll do is on each Mouse enter I'll grab the event then I'll set the popover left to the event current target. offset left that's going to be the left side of where this link lives on the page I can add that to my others don't worry we will refactor this later and we'll set this as a style property on the popover itself there we go now you can see as I move my mouse the popover is following me progress now the next thing we need is something to live inside of this popover I'm going to go back to figma and I'll take each of these menu slides and import them with Builder again now we've got it in Builder and we're streaming the code with the AI I'm going to now copy the code and over in vs code I made these different menu 0 1 2 and three components for each of them I pasted the markup that was generated from the figma import and I also added a forward ref here I'll show you in a minute why this matters but using react forward ref allows us to use this menu components and still provide a reference to the underlying Dom element which we'll need to calculate the height for our menu transitions back over in our nav component inside of our popover we can add some logic to display the correct menu based on what's hovering here I added a check for hovering and show the correct menu this isn't the prettiest way to do that but we're going to refactor this later now in our react app this is looking pretty nice and now for the fun part we get to add the transitions the trick here is actually we're going to end up rendering all of the menu items at once they're going to be position absolutes we're going to animate which one is in view based on what link we're hovering the first thing we'll do is start wrapping these in position absolute and let's start by anim in the opacity of which one should be in view I'm going to use a handy utility called clsx that makes it a lot easier to dynamically add and remove classes and react and here I'm going to say if hovering is zero we want opacity 100 otherwise we want opacity zero and let's also add a transition opacity here I'm going to apply that to each of these layers and we're going to refactor this in a moment now in our react app we've got a fading transition but there's something wrong here here because each menu is position absolute it's overflowing the container and the popover is not capturing the right height so now back in our nav component we need to set this popover Heights this is a good time to recognize that our Mouse enter listeners are quite redundant so let's refactor this I'm going to create a mouse enter function that takes an index and an elements we're going to set hovering to the index set the popover left to the elements offset left then we'll add our popover height logic so now each of these can be on Mouse enter zero event Target one event Target you get the idea but to get the popover height we need to know the inner content height so that's where we need one more piece we need to keep track of the different references of the different menus so I'm going to use a react use ref and we'll have inside an array of HTML elements or null with this array we'll keep track of an index and an element reference for each of those menus so down below now that we added the forward ref you saw earlier the reference here is the root Dom element of the menu contents and we can set refs do currents and the index to the elements we'll do that for each element here and now the menu elements we can look up from our refs array by index if menu element exists we're going to set the popover height to the element's offset height as in the height of the element when rendered now let's add the height here and look at that our animations look pretty good but there's one more critical piece each of the Inner Elements we're going to fade left and right so it looks like each one is morphing into the next instead of just fading we're going to add some logic here to transform the menus left if it's before the current centered if it is current and right if it's after the current but first let's refactor this because this logic is getting redundant I'm going to bring this into a new slide wrapper component where we pass in the index as a prop which is being hovered and we'll take children so that we can render the insides provided I can now clean up the menu code to Look a Lot cleaner and repeat ourselves a lot less and now we're going to use the transform CSS properties translate X to shift our menu items left and right in a performant and GPU accelerated way the first I'm going to say if the hovering item is the current item we apply no transforms it's centered if the hovering item is larger or later than the current item we'll use Tailwind to shift us left a bit or otherwise we're going to shift right a bit now when I hover around we get this really cool morphing animation where one menu seems to slide and morph into the next it's almost as if the menu stayed static and our popover is just shifting around changing what we can see behind it let's do a little cleanup too and make sure when any menu is hidden we give it pointer events none so nothing is clickable and lastly right now the first item doesn't fade in so let's change this to be an animation so instead of this rendering only when we're hovering something I'm going to refactor this a bit and use clsx plus Tailwind to detect when we're hovering and transition Us in otherwise be hidden and now when the menu comes in we have a nice animation as well as when we pan around and we can click on anything inside as well with this technique you can make any type of dynamic fading menus and whatever sits inside this will perfectly fit to it you can see a more detailed walkthrough of what I just showed including the code Snippets and the figma designs you can convert to code in your favorite framework in CSS Library yourself in my latest blog post on the builder. blog also I want to make more of these breakdowns showing you how cool things you see on the web are made so if there's interesting sites that have cool interactions or animations or other effects let me know in the comments and I might make a video on it
Info
Channel: Steve (Builder.io)
Views: 11,817
Rating: undefined out of 5
Keywords:
Id: gWw-DsSZVrQ
Channel Id: undefined
Length: 8min 41sec (521 seconds)
Published: Mon Oct 30 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.