So You Think You Can Build A Dropdown? - Pedro Duarte - (Next.js Conf 2021)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey everyone my name is pedro duarte peduarte on twitter i'm a dx engineer at modules what does dx mean fair question let me explain it's like ux but as if my users are developers like you i focus on api design documentation community things like that recently i've been focusing on two of our open source libraries radix and stitches radix is a library of low level accessible and unstyled components and stitches is a css engine solution the title of my talk today is so you think you can beat a drop down that's a question but that's not a challenge and in this talk we're going to dive deep into the complexities of designing and building a fully featured accessible drop down menu we're also going to do a live demo on how we can use redix to help you make faster drop down components when i was younger i used to think i could build a drop down to explain what i mean i'd like to replay one of the many conversations i've had with colleagues in the past it goes like this so one morning i'm just sitting on my desk when i got a message from alex showing me the new design of a page we already had and i'm looking at this part here and i can tell it's a new component but nothing to worry about we need it for tomorrow's client demo that's okay i know i can do it young pedro would always deliver so 45 minutes later all done alex is happy he thinks he works great and i'm feeling pretty proud but let's just stop here for a second today with a lot more experience and a lot more care i would like to take another look at this page so i remember that i made a button that when clicked i would show a position absolute element with three items inside and that's what i was calling a drop down menu i also remember that i made it so when you clicked outside it would close and that's where i stopped i did nothing more and nothing less this component has absolutely no keyboard navigation so if i open it and i press the down arrow notice how the down arrow just scrolls the page and up scrolls back up what if i press escape nothing happens there is no type ahead so if i start typing in edit for example nothing happens now apart from all of these features that left out there is absolutely no accessibility let me show you how voice over interprets this entering web content button you are currently on a button inside web content to click this button press control option space to exit this web area press control option shift up arrow so far the only thing the voiceover knows is that this is a button that's because i'm using the button element but it has no idea what this button does so what happens if i press enter you see how the dropdown opens but nothing happens in voiceover he doesn't even know the drop down menu showed up okay so i think we've seen enough on how broken this component actually is let's just go back to the chat okay so one hour before the demo alex reached out again and he said to me here's the tweak design and i remember looking at this and thinking this is not a tweak design this is a whole new thing and i have no idea how i'm gonna be able to deliver this for the demo that's happening in one hour and that's exactly when i started to freak out to be fair i still think i could do it just not by tomorrow it would take so much time we need time to research all of its features we need to read the white iris spec we then need to implement all of those features and accessibility concerns we need to worry about complex logic such as positioning type ahead after that we've got to test everything and once we finish with the testing we may have to repeat these things again and again and again when we don't have enough time we end up shipping a broken component we see this type of broken dropdowns everywhere on the web most drop-downs are problematic even for sighted users who don't rely on keyboard navigation but in many situations they're completely inaccessible there are so many cases to consider from positioning logic accessibility features sub-menu separators labels icons checkable items the list goes on it turns out that building a drop down is really hard i'm not the only one that thinks that this is a massive problem and it's a bottleneck because all we want to do is focus on our product our challenges and our users the platform has made a ton of progress recently and it'd be nice to use it but it's still catching up with some of the needs of modern web apps so here we are if building components is such a challenging task and it takes such a long time and the platform is still catching up what can we do luckily for us there are libraries we can delegate to who focus explicitly on solving this problem they focus on building accessible primitives for the web by using our library we'll have more time to focus on our product and that's exactly why we built radix primitives let me show you how it works so we can visit the radix website by going to ratings.ui.com and then we click on primitives and we're taking to the introduction page but i'm going to give you a quick intro here so in a nutshell redix is a library of ui components that are completely accessible and unstyled these components can be used as a base for your design system or you can use them incrementally to make your current application more accessible so just to recap when you render a radix component you're going to get all of its functionality and accessibility features out of the box but you're going to get no stylings you can then apply the styles using your favorite styling solution radix includes lots of components and we're working on lots more today we're going to be focusing on the drop down menu but as you can see there are also lots of other stuff like pop overs and sliders scroll areas so let's talk about the drop down menu when you go to the drop down menu page you're going to see a demo that you can play with you're going to see a list of all its features and then you're going to see steps for how you can install how we can use it and then documentation for all of the api okay so today we're going to be doing a live demo so instead of taking you through the docs we're actually going to get practical cool so we're going to be using next.js as our framework and we can install that by going npx create next app and because radix is built with typescript we're going to use the typescript template we'll call our app radix demo and then we'll go into that new directory and we're almost good to go now we're just going to install the radix ui react drop down menu we copy that and we paste it in here all right so first thing we want to do is we want to just render a basic radix drop down menu straight out of the box and see how that works so we can see here in the anatomy section this is where it tells us the order of which the parts go together so we know that we need to render the root first and then the trigger this would be the button essentially and as a sibling of the trigger there's a content and inside the content there are many parts that we can render okay well let's go ahead and do that then we import drop down menu from radix nice then we'll do drop down menu dot root that's the first thing we need to render then we're going to do dot trigger we can just say settings here now we're going to do content and inside content we're gonna render an item and we can say new tab and another item will say new window and then new private window okay saved hot module reloaded and now we've got a button here that would be the trigger and when i click on it you can see that it opens all the items are being focused i can click outside to close and everything is completely unstyled this is radix straight out of the box so even though we haven't had to write a single piece of logic everything just works and everything is fully accessible if we inspect the element we can see that the trigger has the right area attributes and if we open it we get a portal over here the inside is where the content lives and inside here there's also a bunch of area attributes so screen readers or assistive technologies in general know how to interpret this component okay so now that we know that we can render radix components just by rendering its parts how do we style them so for the sake of this demo i'm going to keep things very simple and we're just going to do some basic styling with vanilla css the first thing i'll do here in the styles folder i'll create a file called dropdown.css and i'm going to import it over here in the app dropdown.css okay so you can see there's not much going on here we've just got a empty css file and let me make a little bit more space and here we've got the drop down markup so let's add some stars to the trigger some basic styles to the content and some basic styles to the items so we can style this the same way would style any html element we'll just create a selector and create a css rule i'm going to give it a color let's just make a color red like this so it's very obvious what we're doing and then we can apply that over here and save and there we go the color is red if we inspect we can see dropdownmenu.trigger is literally just a button and all we've done is added a class name to it in the same style we can do content and in the content we can say let's do background color white for the radius of 6 pixels and box shadow let's add a bit of pop shadow here the opacity there we go and finally we do an item and for the item we're simply going to do some padding and we can do 5 pixels 10 pixels and then when the item is being focused we're going to change the background color to gainsborough okay now we can add the class names to the right parts so here will be content and the items will be item okay we can open this we can see the content is showing up we can see the box shadow and as i hover them we can see the background color as well as the default browser outline that's perfect so that's how we add styles to the redix parts now that we know that adding styles to radix parts is exactly the same as adding styles to any other html element i'm just gonna put in some styles that i've pre-written that look a little bit nicer another thing i've done is i've updated the markup below to create a more realistic example okay so let's have a look at the code you can see that this is almost just like writing html there's no crazy logic there's nothing special going on it's just adding the right part in the order that we want so for example this is our trigger with the hamburger menu icon then we create a content as we've covered that previously the content is a sibling of trigger and inside content is where we add all of our items as well as sub menus so here are the first three items and then we are nesting a drop down menu route inside a drop down menu root that's how we do nested menus and that would be this over here so then we can add separators we can add groups we can add labels at this point it's up to you to decide what you want to add based on your requirements all right cool so let's start having a look at the features shall we um by now the most basic features have been covered because i've been using my mouse up until now so we know that i can hover over these menus and i can open sub menus all of that with my pointer but what if i rely on keyboard navigation well you'd be glad to know that the radix drop down menu supports full keyboard navigation first thing we can try is you see how right now the focus is on the button i can press either enter or space to open it so here i press enter and as i do that you can see how the first item is already focused i can use my up and down arrows to navigate across these items in the case of a sub menu i can press my right arrow to open the sub menu and the left arrow to close by the way this can be configured if you're using right to left reading direction as i continue pressing down you can see how i can cycle across all of the items but when you get to the last item and i keep pressing down it stops there well as i've explained radix is quite customizable so one of the things we can do we can add a loop prop to the content part and by doing that we should be able to loop through all of the items whether you're going down or whether you're going up for more information you can always look at the documentation where we explain all the props that each part accepts right now we just use the loop prop okay so let's talk about type ahead type ahead is the feature that allows us to jump directly to an item by typing in the label of the item so let's say we want to go from here directly to the item print we can simply start typing in print and as you can see it's jumped straight there but on the way it stopped in paste because the first letter we typed in was p so we jumped to paste first the second letter was r so then you went to print let's try and do that a little bit slower p r that's nice so type ahead works with every item in your drop down menu even items containing a space so let me just explain that a little bit earlier we covered that when we press space or enter you actually select the item so if i press space here we've just selected the item new window but what if i want to jump directly to new window and a space exists between these two words or type ahead is smart enough to know what your intention is so if i start typing new space window space will be taken into account in the type ahead instead of selecting the item another cool feature of type ahead is that if i keep pressing the same letter over and over again then type ahead will cycle over all of the items that begin with that letter so for example if i keep pressing the letter n notice how type ahead keeps cycling over all of the items that begin with n another thing that's pretty cool is that the radix item part contains a prop called text value this prop is extremely useful if inside your menu you have an icon for example in no text you can still tell what text you want type ahead to search for redix primitives also work with assistive technology for example here's how it works with voiceover settings menu popup button new tab command t ment new window command n new private window shift command history collapsed menu item you are currently on a menu item to choose this menu item press ctrl option space to close this menu press escape versal menu item menu history 3 items stitches menu item modals menu item history collapsed menu item cut menu copy men paste menu hide print command p fine command f menu item you are currently on a menu item settings menu pop-up button voice over off so that's how radix primitives work with voiceover all right we're making really good progress so far we've covered so many things and there's only a few more left but i did tell you the drop down menus were complex this feature is called collision aware positioning let me show you how it works when you open a menu by default it's positioned below the trigger and center aligned you can change this behavior using the side and align props but this is the default so i'll be using that for the demo in the case of when there's not enough space for the menu to fit below the button it's going to get positioned above and when there's not enough space on the sides the menu will also be repositioned for example in this case there's not enough space on the right so the menu will get pushed a little bit more and if you go to the left there's not enough space you'll get pushed a little bit more what about sub menus well sub menus by default will show up based on your reading direction in my case my reading direction is left to right so they show up on the right if there's not enough space on the right then the sub menu will get moved to the left and the moment that there is more space you move to its ideal position again this is how collision aware positioning works another cool feature of the radix drop down menu is something that we call sub menu pointer grace this basically allows us to keep the sub menu open even if the pointer is moving away from the item trigger so check this out if i move up notice how it closes straight away and if i move down it also closes straight away as long as i'm moving towards the sub menu you'll remain open sometimes you may want to add an arrow pointing towards the trigger the radix drop down menu contains a part called arrow and this is how we can use it the arrow goes inside of the content so i'm going to put an arrow in the main content drop down menu dot arrow i'm going to close it now when we open it we can see a black arrow using css we can style the arrow the same way we styled all of the other parts so let me make this a bit bigger and here we can do class name arrow this is a class i've already created and now when i open it you can see that there's a white arrow pointing towards the trigger now you also may realize that this arrow is actually touching the trigger we may want to give a little bit more space we can do that by adding a side offset property to the content and here we can say 10 and there we go if you think that's too much which i do we can just change it to 5. that's nice now a cool thing about the arrow is that when collision happens and your menu gets repositioned the arrow points towards the new direction the last thing i want to talk about is animations you can animate the radix drop down menu the same way you can animate any redix primitive either with css or with the javascript animation library like framer motion or react spring so what i've done here i've created two css animation keyframes and i'm adding them to the content based on the side i'm either going to animate up or animate down so check this out by default because we want the menu to appear below the button it animates down because it's dropping down but if there is a collision and we know the menu is going to be repositioned we wanted to animate up this is collision aware animation so we are able to use these data attributes the radix exposes to us and we can apply different animations depending on the side even when collisions have taken place while we're on the topic of animations there's one last thing i want to show you and this is what we call origin aware animation basically it allows you to animate your menu based on the computed origin of the menu taking into account its size its side offset it's a line a line offset and any collision that may have happened so check this out i've created a scale animation keyframe and i'm applying it over here in the content part i'm setting the origin of the animation to be this special css variable exposed to us by radix i then just give it the animation the duration and the easy so let's open this up and see how it looks you can see how it's scaling from this point over here but if there is a collision and the menu is going to get repositioned then it's scaling from this point over here this also works with sub menus you see how the origin of the sub menu is the top left but if there is a collision and the menu no longer fits on this side and i open it again now it's the top right and this happens based on every possible combination of collision detected the drop down we just built was so easy and so painless but behind the scenes it's taken us over 2 000 hours across 6 months 50 code reviews and literally thousands of commits to recap on radix it's a library of unstyled primitives you can use your favorite styling solution whether it's vanilla css or css and js like stitches or even a library of atomic classes like taowin it's accessible so it supports full keyboard navigation and is screen reader tested radix primitives are customizable so you can make it work for your use case to wrap it all up why does all of this matter building good ui components takes such a long time it distracts us from focusing and shipping on our products it costs companies hundreds of thousands of dollars poor quality y can reduce both customer acquisition and retention and now products like superhuman stripe discord linear and figma are raising the bar for ui quality and accessibility on that note shipping accessible components is the new normal businesses are even being fined for having inaccessible uis we're all responsible when we build and ship broken ui components we're collectively contributing to a broken web we're making the web difficult for everybody to use but especially for less able-bodied people developers are tired of having to reinvent the wheel over and over again ui components are like table stakes it's undifferentiated work if i need the drop down i just want to use a drop down i don't want to have to build it that takes us to our last point it's absolutely fine to delegate i promise your products will be more functional more accessible and you'll have more time to focus on your unique product features to learn more about redix you can visit redickstashui.com and follow us on twitter redix underscore ui cheers [Music]
Info
Channel: Vercel
Views: 13,505
Rating: undefined out of 5
Keywords:
Id: pcMYcjtWwVI
Channel Id: undefined
Length: 25min 43sec (1543 seconds)
Published: Wed Oct 27 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.