Web Component Tutorial - Dropdown
Cory Rylan
In this sample from my new course at webcomponent.dev, we will learn how to build a simple Dropdown Web Component using vanilla JavaScript. This screen cast will cover many of the Web Component APIs such as Custom Elements, Shadow DOM, Custom Events, and content slots. If you want to learn more about Web Components check out my course on webcomponent.dev.
Transcript of Video
In this example we're going to build a simple drop-down web component. Here we have a drop-down that has a simple button and when clicked shows some dynamic content for our drop-down we'll be able to pass in a custom title for our button as well as any dynamic HTML that we'd like the drop-down to render. Taking a look at our drop-down template you can see we have a style tag. We style our div with a little bit of padding and a border that provides the drop-down box within our template. We have a simple button that we'll use to create a click handler to be able to toggle our content. In our template we have a div with our slot that will dynamically project our content from our user.
First we need to set up the ability to pass in a custom title into our button. To update the button title we need to set up the attributes and the properties for the title. First we need to implement the observed attributes static property. This returns a list of attributes that we want our component to watch for updates for. Here we're going to pass in just title so our component knows it should be watching for title changes. To store the information of the title we set up a get and set property that's going to store the value of title. We have a private property this stop underscore title. Whenever we get the title we'll return that value. Whenever we set the title we'll set that private title that we've created and then we're going to grab a reference to our button element and set the inner text of that button that way whenever the property or the attribute is updated our button reflects those changes.
To listen for attribute changes we need to implement the attribute change callback. This will pass in three parameters the attribute that changed the previous value and the new value. Here we do a simple check if the attribute is equal to title and the old value is different than the new value then we know to update it by setting the title property. We update the private underscore title as well as update the inner text of our button. Now that we can dynamically update our button we need to do a little bit of work to set up the click event. To be able to show and hide our content for our drop-down in our constructor we can see our title defaults to drop-down. So if we do not provide any kind of button text or title we'll just list drop down as the button. We create a property called show that will simply track whether or not it should show or hide our dynamic content.
We set up our shadow DOM and our template and then we query our template to be able to get reference to our button and our div element to be able to toggle and
show and hide our content. Here we get a reference to the button in our template
by using this dot shadow root query selector and now we can query our template.
Now that we have a reference to a button element we can set that inner text to our default title and also reference it when we set the title via a property. On our button element we're going to add a click listener so add event listener click and then call the method this dot toggle. Our toggle method will simply toggle the show property so this dot show will equal to the opposite of the stop show. We then use a reference to our content element which is the div element in our template with that div element we initially hide it by using some CSS to display:none and then when toggled we can check if the component is ready to show. We'll set to display block else we set the div to display:none now we can show and hide our dynamic content for our drop-down.
Whenever we open our close our drop-down we want to provide a custom event hook so users of our components can listen for when the drop-down was open or closed. To do that we can dispatch a custom event dispatch event new custom event show change d and then pass back that information to the user. So here on the conventional detail property we pass back whether or not the drop-down is showing. Now consumers of our components will be able to listen for when the user has opened or closed our drop-down. If we go to our index js we can query the Dom for our drop-down component and then we can start interacting with our drop-down. Because we set up the title property we can set the title via JavaScript so now we have custom title instead of using attributes. By implementing the attributes and the properties we give the most flexibility for our users they have the choice of using attributes in the HTML. We're using properties in the JavaScript note if you use attributes in the HTML you can only provide string values since we're in HTML.
With JavaScript we can pass any type of JavaScript value into the property. We also can now listen to our custom event listener that we set up so we do drop down that add event listener listen to the custom event show change and we just simply log the event here. So if we click our drop down we can see our event logged out and with custom events we get all kinds of information about the custom element itself as well as the value that we pass back. So on detail we we log out and we show whether or not the drop-down is visible. If we close the drop down we'll get a new event and we'll see that detail is false because we use a setter and getter to update the button inner text.
If we use a set timeout or some other asynchronous method of updating the title property we will be able to see that update reflect to the button. So here I have a set timeout after 3 seconds we'll update the title to new custom title. So if I save our title here after 3 seconds we'll see that our button is updated.