 Hey there, Polycasters. Rob here. Welcome back to the show. So today, we're going to be talking about something which we probably don't touch on enough, but which is crucially important for anybody who's building web components. And that is accessibility. And if you're building custom controls, custom elements, and things like that, accessibility is extremely important for you to factor into your application. Because when you make custom elements, you're basically creating a brand new tag in the browser, which means that that tag has no built-in semantics. It has no built-in keyboard support. And so it's up to us to add those features back in. So to do that, I'm going to split this into kind of like a three-part series. We're going to cover a few big topics in accessibility. Today, we're going to focus on keyboard support. So what we're going to build, if you follow me over here to my laptop, is this sort of checkbox component. And I've zoomed in the page, so it's like a giant checkbox. But you can see that I can click on it to toggle its state. I can also hit Tab to focus it. I can hit the spacebar on my keyboard to activate its state that way as well. So that's what we're going to cover today, just getting sort of the basic keyboard functionality working for this custom checkbox. Now, the first thing I'm going to do is go over to my code editor. And I've already gone ahead and created sort of a basic element, which I'm calling dash checkbox. What I want to do here is I want to start off by giving it just like a checked attribute that we can toggle back and forth so we know whether it's checked or not. To do that, I will go down to my elements definition. I will give it a properties object. And I'm going to create a property called checked. And checked is going to be a Boolean property. So we'll set the type to Boolean. We'll set the default value to false. And because I want this to reflect as an attribute, so I want it to actually show up in the DOM whenever it changes, I'm also going to set the reflectToAttribute property. I'm going to set that flag to true as well. Now, the next thing that I want to do is I want to listen for whenever the user taps on my checkbox. So when they actually click on it, I'm going to toggle that attribute on or off. To do this, I can add a listeners object to my element. And I will expand this a little bit to give it some more room to work with. So in this listeners object, I can actually listen for different events. So I could listen for tap or key down or something like that. So I will listen for tap. And I will give it a handler called onTap to run anytime someone taps on our element. And inside of onTap, this will be pretty straightforward, we're just going to say, hey, whatever the state of checked was, we'll say this.checked equals the opposite of whatever checked currently is. So we're basically just toggling that state back and forth. And that should then reflect to our attribute. Now, the last thing I need to do, so I can actually see this thing on screen, is just drop in a little bit of CSS. I've actually got some CSS that I've saved here. And you can see that I'm styling the host element. I'm setting it to display inline block. I'm giving it a little black 2 pixel border around it. I'm giving it some explicit width and height. So we're going to draw a box. And then when that checked attribute is set, you can see here I'm using an attribute selector inside of my host selector. When that checked attribute is set, we're going to set our background to this SVG image here, which is basically just a little check mark SVG that I've saved already. So I think this is actually ready to try out. So we can go over to our terminal. We can run polymer serve dash dash open. If you aren't familiar with this command, we covered it in a previous episode when we were talking about Polymer CLI. So you could run npm install dash g polymer dash CLI. This will get you the Polymer command line tool so you can run the local server and test out your elements. So I'm going to run polymer serve dash dash open. And that should open up the page. And now we can see our little check box here. And when I click on it, we can see our check mark showing up. Importantly, if we open up our dev tools and we inspect this guy and we sort of boost the page a little bit, we can see that that checked attribute is currently being applied. When I click it again, it goes away. OK, so far, so good. Now we've got this thing working for basically a mouse user, which is great. But I mentioned today our goal is to also make sure that we're adding proper keyboard support. And that's really important for anyone who might have repetitive stress injury, something like carpal tunnel syndrome, they might prefer not to use a mouse, or someone who might have a form of paralysis or limited range of motion who might be using something like a switch device to access the page. So for those users, we need to figure out what sort of keyboard support we need to add to a control like this. And a really, really useful resource here is the ARIA design patterns authoring practices doc. Now I'm going to talk about ARIA in the next episode. So you don't really need to worry about it for now. But basically you can think of this as a helpful guide that I'll sort of tell you, hey, based on this sort of UI that you're building, here is the kind of keyboard support and other sort of semantics you need to roll into that element. So I'm going to Google for ARIA authoring practices 1.1. The first result here is what I'm looking for. Over here on the left-hand side, you can see a bunch of UI patterns listed. And the one that we're interested in is checkbox. So we go and we click on that. And now we've got this whole big description that tells us all sorts of information about what a checkbox component should do in order to be accessible. The information that I'm interested in, particularly right now, is this keyboard interaction section. So it tells me when the checkbox has focus, pressing the space key should change the state of the checkbox. So the space key is kind of be like when our user goes and clicks on it with a mouse. Now there's two important points here that it's just made. One is that we need to make sure the element actually can be focused. And then the other is that we need to listen for the space key and toggle that checked state of our element. So let's get back to our code editor. And the first question is like, how are we going to make this thing focusable? Because by default, a custom element is basically like a span. There's nothing about a custom element that makes it implicitly focusable. It's not added to the tab order. And a user is not going to be able to reach it using their keyboard. So to do this, we can add a tab index attribute to our element. And tab index takes kind of like a range of values. You can have a tab index of 0, which will insert the element in the natural tab order. You can have a tab index of negative 1, which will not insert the element in the tab order, but it could still be programmatically focusable by calling it's focus method. You could also have a tab index of greater than 0. You could have a tab index of like 5 or something like that, which would jump your element ahead of everything in the tab order. But generally, that's kind of considered an anti-pattern. It can lead to sort of really confusing tab orders in your page. So I think the best option for us in this case is to give our element a tab index of 0. And that way, the user can just easily hit the tab key to reach it with their keyboard. To do this in Polymer, we actually have this really helpful property that we can add to our definition called host attributes. Host attributes is basically going to apply an attribute to an element. So it's self-applying an attribute. And I will say tab index should be 0. And now, if we go back to our application, we refresh the page, you can see over here in my inspector now, tab index of 0 is being self-applied. And if I press the tab key, now we see the focus ring around our element. Cool. So the last part is we just need to make sure that when the user presses the space bar, that it toggles the state of our element. And there's two ways that we could go about this. We could either add those event listeners ourselves kind of manually, and then make sure to remove those event listeners when we take the element out of the DOM. That would totally work. But I'm super lazy. I like writing as little code as possible. So the other thing we can do is we can use a very useful behavior created by the Polymer team called ironA11ykeysBehavior. A11y stands for accessibility. So what I'm going to do is I'm actually going to just install this behavior. So bower install dash dash save, PolymerElements, slash ironA11ykeysBehavior. OK, that's going to go out, fetch that, pull it into my project. Then I can just add that to my element definition. So we'll import that right after I import Polymer, ironA11y keysBehavior. And the last thing I want to do is add that to my behaviors array. So I'll say that I have behaviors array. We will add Polymer dot ironA11ykeysBehavior. And what this is going to do is it's going to make this key bindings object available to me. And this key bindings object is kind of like my listeners object down here. I can just use it to listen for different key presses and assign those to a handler. So I'll say key bindings. I will say I want to listen to the space key. And when I hear someone press the space key, I just want to run basically that same on tap command from before. So let's go back and test that in our project now. We'll refresh the page. We will hit tab to focus our element. We hit space. And now we've got our checkbox. And now we've got basic keyboarding support added to this element. Now, I mentioned that there were going to be two other sections to this series. We're going to talk about semantics. We're going to talk about labeling. But I think this is enough for today. So definitely go out there, play around with ironA11ykeysBehavior. Go out there and check out that ARIA Design Pattern Stock. It is full of super useful information. We're going to pick up here in the next episode and work on adding semantics to this element. So it'll start working for a screen reader. But that's it for today. If you have any questions, please leave them for me down in the comments below. Or hit me up on a social network or if you're choosing at hashtag askpolymer. As always, thank you so much for watching. And I'll see you next time.