 So, good morning, everyone. My name is Vikas Parashar and I'm a front-end engineer at HECA Rank. So, today we'll be talking about building accessible reactive like what is accessibility in brief and why we need to make our products accessible and how we are doing it at HECA Rank and how it should be done, right? So, let's get started. First thing is when we say building accessible rate apps is like accessibility. So, what is web accessibility? How many people are like aware of web accessibility? Many are, right? So, I don't need to like go into detail. So, for those who don't know, so accessibility just means like making your products accessible to everyone regardless of their disability. So, make whatever you are building, make it accessible and usable for as many people as possible. So, the challenge is to make our HECA Rank product accessible to as many people as possible and why we need to do that, right? Why we need to make our websites and our apps accessible? So, there are many reasons for this. I'll go through this in like summary and this is not very exhaustive list. This is like very some common reason why we should make our products accessible. One is it improves user experience like accessibility when you make your product accessible? A button looks like a button and works like a button. It's not an anchor tag with on click handler, right? So, if user sees a button and clicks on it and actually works like a button instead of navigation, that's a good user experience, right? And when you use semantic HTML, your content is ordered and user can skim through it easily. So, which is good for our user experience. And there are many other things like proper form and proper labeling the form which can proper error message. These all are also US but also makes our products accessible. The second thing is benefits SEO. So, how do the web crawlers like know about our site content? They know by crawling our site the same way as skin reader software use. The skin reader is a software which people with visual impairment use to access our website. We'll see a demo later. So, if you are not providing alternate test to your images or transcription for your video files, the web crawler can't see it, right? So, they can't index it. And that's like affects your SEO. So, if you are using semantic markup and when you are doing a navigation, you are using an anchor tag and you are providing transcription for your video, the crawler can go through an index page properly. When you provide a site map, crawler can see what are the pages. A site contains and index them properly. And a site map also helps with people to navigate your site properly. So, when you make your products accessible, you also improve the SEO. And expand user base. So, they are like normally people don't focus about people with different kind of disabilities. Like they say there is a user group. But if you make your products accessible, you make your product available for a user base which not everybody stepping. So, that's how you expand your user base. And more enterprise customers. So, if you are in a, if your business is like B2B where you sell your products to other companies, they might require even the public and private companies to be your products, to make your product accessibility compliant for respective country. So, if your product is not accessibility compliant, you might not get that customer. And there are like many customers in US and India which need this accessibility compliant. So, if you are making your products accessible, you get more customers. And the legal reasons. So, in US and European Union and even in India, there is a law for the right of disabilities. And I don't remember the exit title. But in every country, there are laws which require your products to be accessible. And you, if you haven't heard, like Domino's, Apple and many other major companies have been sued when their products were not accessible. And they had to like pay fine and made their products accessible later on. So, why not just do it from the beginning and don't wait for it to get sued? And I will share the comprehensive list of all the laws and policies in different countries so you can go through them later. So, now we know, like, why we want to make our products accessible. So, the next question comes is how? So, normally, like, when you work on a product website on an app, the process is normally you get the design when the all specs are ready. You get a design, then you write code, then you test it, and then you go back and forth based on whatever the outcome is. So, we wanted to, before we make a start fixing our existing products and building new products, we wanted to set up a tool chain so we can catch the issues when we are fixing them. So, we are not actually making it worse because sometimes people will just throw area level attribute everywhere and see, okay, we fixed it. So, that's not how it works. So, we wanted to set up a tool chain first. So, when we are start fixing problems, we do it the right way. So, first we are going to do this design. So, for this, I will just show the demo here. So, you can see here, this is like a screenshot of our internal UI kit library. So, here we have like internal two color contrast checker. So, they are like, WCAG is like guidelines which tells you how to make your products accessible. So, they are like different checklist and different rules which you should pass. So, there is a level like the color, background color and the text color should have enough contrast. There are like two levels, level A, double A and triple A which is like double A is like enhanced contrast and triple A is like, no, double A is like minimum contrast required and triple A is like enhanced contrast. You are like, you are providing more than just the enough. So, here we can see like, we can change the background color. Here I am changing the background color and in our library we can see that which level criteria we are meeting with our primary color. So, designers internally use this to when they are designing the mockup to see whatever background color and the text color is meeting the criteria or not and the font size is enough or not. So, this helps when the design level to make sure our designs are and the colors are accessible. Once that is done, we start the coding. Yeah, before that, like if if you, because that is an internal tool, you can also go to on this site, color safe.co and if you enter some color combo here, if that doesn't have enough color contrast, it will provide generated color palette of related color combos and you can pick colors from them. So, it is very helpful. You should bookmark it. Right. So, now we started coding. So, this is like a screenshot of VS code editor and I have an linter enabled which is called JSX A11Y. A11Y stands for accessibility. So, what it does is, here we can see we are adding an on click handler on an element. How many of us have done it? Like, we have done it. So, this is not accessible. It is not cementing markup because when the skin reader go to this element, they don't know it's a button. They will just pass through it. They won't announce to skin reader user that it is an element. Also, when the wavecrawler goes to this part, they don't know that it's a button or it has some action. So, when users search for something related to this action, it won't show up. So, our linter tells us that there are some problems that, since it is a div, it doesn't have key press handler. The button, you can tab on it but you are clicking on click handler so you can only use it with the mouse, which like most of our users are. So, we don't actually think of the keyboard users. But they might actually want to focus on it but they won't be able to. So, this tells us like we should have one keyboard listener and it doesn't have role. Role is like one array attribute which tells the browser and the parser like what role we are promising for this element. So, when we say role equal to button, we are telling them this element will work like a button. Assume it is a button. But so, we should do this. So, when we, if we fix this issue, we will have one keyboard listener, one role, then we need to provide tab index so it gets focused step or we can just use button element instead, right? And it will fix all of this issue. So, this linter helps us like catching issues while we are writing the code so we can fix them before even like testing it. And so, we have written the test. So, now we go and test it in the browser right on development server. So, there are many extensions which you can 11 like even the lighthouse, it's a built-in auditing tool in the Chrome where you can just run it on your site and see all the accessibility issues. But there is a problem like you have to run it every time and it does the whole page reload. So, in React F, you click on a button and something happens, the whole page doesn't re-renders, right? So, how do we catch the issues which are introduced by those changes? So, we are using a library ReactX, I will share the link later. So, and this is like some basic code which just says like don't run it in the production and run it behind a flag. And in our index file or the root component, we call this utility on every component did update method. So, anywhere in your page any update happens, this will get called. And normally, we will do NPM start or JAN start. Now, when we want to check with the logger, we will do enable accessibility equal to one NPM start or JAN start. And that's how the output we get. We really need neatly arranged with the level of seriousness, which we need to fix first, which we can handle later and which element is causing the issue. And so, we can see this like it will get in our console in like Firefox and Chrome or any other browser you use. So, it's like browser independent, any browser you can use for it. And you will get all the issues. So, you can now start fixing them, which you didn't catch in the linter. So, there's one demo for it. Here, you can see there's a small icon. When I hover on it, it just tells us like you like it, where content has keyboard full. So, okay, this is like next demo. In previous demo, we saw like when you hover on that icon, the small icon, the black icon, it highlights the UI, which is causing the issue. So, you can easily debug it and fix those accessibility issues. So, this way, during the development, we can catch the issues and fix them before the code goes to production. Now, so, we have like, we have the proper mock-ups. We fix the issues which we found in the editor. Then, we tested in the browser and found some more issues. We fix them. Now, we want to future proof it. So, now, that's what unit touch does like. We have written a component and if somebody changes it, which breaks some functionality, our unit touch fails, right? So, we can go and fix those problems so our test should pass. So, this is one utility we have written ourselves, audit accessibility. It's a wrapper on xcore plugin. Again, I will share the link for that. And we have a custom method which just says to be accessible. So, we just passed any component we want to test with the props and all. And it will actually render it. And we can just expect it to be accessible. So, if there are any issues, we will get like this. So, when the test fails, we will get proper numbered issues which like your estimate markup head. So, in our example code, we had a button element and inside it was an image source element. So, we have the first rule which we are working is button must have discernible text. So, what actually happens is let's say we have a download button. So, what we do is in the button inside, we have an image element and we provide the download image in it. So, image renders inside the button. And cited user or mouse user, keyboard user can see the download button and they can use it. But for the skin reader users or for the web crawlers, the button doesn't have any content. So, they just get past it because they just see it as a button and they don't know what this button is about. So, this is not helpful, right? So, we should fix this. So, there are many methods. It suggests for us, like we should provide a text for it or we can provide area label or we can reference it to another test element with the area labeled by. There are many solutions, any of us, any one of it we can pick and fix this problem. There's another issue it has reported for the same component that MOH doesn't have any alternative text, which is like very common known issue, like we should provide alternative text. So, when the image doesn't load or for the skin reader users or for the web crawlers, they know what the image is about. So, this way we can find the issues and fix them and then in future somebody changes it. So, they will find the issues if they introduce any. And this is a unit test is required because in linter, as we have seen, it does the static analysis, right? So, whatever code is in the browser, it can see only it will analysis that. So, if you are using any component which itself has some issues, but we are just using the component and writing code, we will go and see those issues in the linter. But, when we write this test, it actually renders the whole react code into HTML and find any issues which are even on the document level. Even if your page title doesn't have any title element, it will throw us an issue. So, this is like a good idea to have test for your components. So, if you have written an accessible component, write and test. So, it is future proofed. So, now we have set up the tooling for design process and development and testing. So, now we decided like now we should start fixing our components. So, here I will be demoing like few UI kit components we have fixed and why we first start fixing UI kit component. Before that, I would just like a quick introduction to ARIA which is like accessible rich internet application. So, you know with the introduction with HTML5, we have some semantic elements like section, article, button, right? It tells the browser and the screen reader users what this HTML element represents. But, and when you use that, when you use the proper headings, screen reader software and web crawlers and everyone can understand what your page is about. But, some UI patterns are not that simple, right? When you are creating a dialogue, there is no semantic markup for that, but you want to tell screen reader users that it is a dialogue. So, for that, we have a specification which is called ARIA and it provides us some roles and attributes which we can use to tell the semantics of our content to the assistive text. For example, we wanted to create a toolbar or a setting section where people can toggle some settings. So, we add a role toolbar, then we, in button, we add a role switch and another attribute ARIA press 2. So, what it does is when we said role toolbar, we are telling about the structure of our content. When we say role switch, we are talking like whatever widget actually does. So, role switch overrides the property of role button. So, now it is actually called a switch and not button. And we are telling about the current state or the behavior of our widget, which is, it is currently true. So, you can use it for like dog-themed toggle or something where you say, okay, this current state is true. When you click on it, it will be false and it will toggle. So, yes. So, we decided to first fix our UIKit library and improve the accessibility of our existing and new components. Because with your common library, what happens is when you fix an issue in one place, it gets fixed on every instance where it is used in your across the products, right? So, that is like the first place you should fix your components. So, that way, you get more benefits at once and then you can start fixing individual products. So, first in line is button element. Button is like the most common misused and mixed up element with the anchor tag. Like, we use them interchangeably without any thinking. So, how many of us has used anchor tag with the onclick handler without actual navigation? Like, it doesn't go anywhere, we just do something on onclick, right? Okay, nobody's raising hand, but many of us. And with button, we have done with onclick handler, with router, we just do the navigation, right? We don't do anything on button, there is no actual action is happening. We click the button and with the router, we say, okay, router.push and we navigate the page. So, this is like common mix up happens and some use case in our code base was like this, we have router link component. So, what people would do, they will wrap it, wrap the button element with it. So, now it works like navigation. But this is actually not cementically correct because interactive element like anchor tag should not have any other interactive element decided. And other most common cases on button, onclick handler and then navigate it with JavaScript. So, these are like incorrect use. So, how do we fix it? We introduced one prop, which is called roll. And if the prop is roll, then we use the roll is link, then we use the link component from the rear router. Otherwise, we use the HTML button element. And so, easy to fix, right? Doesn't take much effort and now our code looks like this. When you want to navigate, so let's say we have the CTA, which actually looks like a button and you can't argue with designer that it should look like link, they will make it look like a button. So, you have to just make it work like button. So, we just pass the roll link and then every other prop, our link component accept and it will look like a button, but actually it will be cementically correct link and web crawlers and skin users and visual users, everybody will be able to use it properly. And with button, we don't have to do anything. We just pass onclick handler, nothing else needs to be done. So, this way, our button component is fixed. Now, everybody when they want to use it for the navigation, they just pass the roll link. Next is the dialogue component. So, dialogue is actually very complex UI component. It has like many functionality. It should close on escape key press. So, have you seen experience of models which doesn't close on escape key press and you have to just close using. Imagine your mouse is broken or somehow it is not working. And you open the model and now you are trapped inside it. The only way to get rid of it like reload the whole page. So, that should not be the behavior, right? So, that's like a point of accessibility. It's not just fixed for things for people with disabilities, it's fixed for everyone. So, there's another thing, focus should be inside once open. So, as soon the model or dialogue is open, the focus should be inside it. So, the screen reader software knows like where to go from it, otherwise they wouldn't know. And focus should be returned to the triggering element when the dialogue will close. If you have a very long page and on clicking a button, the dialogue is open. And when you close it, focus is returned to some other element. Screen reader users and the keyboard users for them it is like a very bad experience, right? It takes a lot of effort to tap and go to a button and then the focus is lost. You again tap and go to that button. So, it should return to the triggering element. So, escape key press, that's like easy to implement and you won't event listener. We won't be seeing the code for that. We'll be seeing code for the focus tapping and how to make it visible for the screen reader with using proper ARIA attributes. So, here what we are doing is we are just querying like for any interactive element like the elements which can have focus input, select, text area. And we are saying don't select the button which is like a close button. So, what is actually happened is as soon as the dialogue open, it will look for any input field or any button and it will focus on that. And if we don't have any of such element, then we select the element which is the close button for the dialogue. And this focus trap code simply tells if our model is open and the focus is not inside the model, then focus on the element which we have previously queried. It can either be any interactive element or the close button. Let's see the demo first. Then I will show you the slides with the markup and then you will have more context what this attributes to. So, currently, everybody can see the text, right, in the bottom. Voice over on Safari, UIKit window, UIKit web content. So, web content is keyword here that skin leader software, the voice over is telling that we are on a web content which is basically a website. So, here we can see like when you use proper button element as we have used here, it announces with the text and says the type of element that it's a button. Let's say if we have used like some anchor tag, it would say open dark dialogue link. Now it is confusing where we are going, right? So, use semantic element. Here, the keyword is web dialogue. So, we have made our UI such that when the dialogue is open, skin leader actually knows that it's a dialogue and then it's announcing what the title of the dialogue is and the focus is currently on the close button. So, that's now we'll see the markup like how we do this. So, first in the section that is like top level of dialogue, we said it is, we provided a role which is a dialogue. Then, we provide another area attribute which is area model true. We'll see what it does in later slide and we provided one more attribute to like area level by. It references to the ID of your title which is an H1 element. It's a title of your dialogue. What there was like section, you can have anything like do you want to continue or anything. So, what those attributes were? So, role dialogue, it tells the assistive text that the container is for a dialogue. So, as soon as the dialogue will be open, the skin leader software will know that the dialogue has been open and they will be able to announce it. When we don't provide this role, what actually happens is dialogue will be open but the skin leader software wouldn't know a dialogue has been opened. It will just continue whatever in the background. So, the user wouldn't know they need to perform some action in the dialogue. Area model 2, what it tells the assistive text that anything under the dialogue is not available for interaction. So, skin leader software won't actually go and navigate to those interactive elements behind the dialogue. And this is relatively new attribute which doesn't have proper support. So, it has to be used with the role dialogue or role dialogue. And the other thing if not area model 2, what we can do is provide area hidden true to every interactive element which is not in the dialogue. That way, and keyboard user or the skin leader software user won't be able to focus on it. And area level Y is very commonly used. What it does is like when you don't want to explicitly pass a text, what you do is you reference to a text. So, in our case, we referenced it to our heading of the dialogue. So, we pass that ID. So, when the dialogue was opened, it took the text from there and announced it, like a sample dialogue. So, that was like very short code and dummy code. There are many other things which we need to focus when working on dialogue. But that just gets you the general idea like why adding some lines of code, which is not much effort, we can make our UI components accessible. Another is tab component. So, tab component we have seen. It has like some buttons which we call tab. And whole list is called tab list. And when you click on any of the tab, the content for it shows up in the tab panel. So, for the assistive text, assistive screen reader software, the minimum requirement is when you focus on the container, it should announce that it is a set of tabs. And when you focus on a tab, is it an active tab or it is a selected tab. And when you click on a tab, it should show the tab panel associated with it and announce it that it has been activated. So, again, first let's see the demo of a proper accessible tab component. So, here we can see end here that as soon as we focus on the tab, screen reader software told the user, okay, you are on a tab which is like fruits. And when we focus on the selected tab, it says mango, selected tab, one of four. So, now the user know there are like four tabs and user can navigate to any of those tabs. So, we don't have word mango in the tab panel, like it has the content, the content for the tab mango. But since we associate it with the tab, it is announced that mango tab panel. So, this tab panel is for the mango. End of mango tab panel, end of fruits. And in the end, when you are like about to exit that whole widget, it announces that end of fruits tab group. So, we are exiting the tab. So, when we don't have it, the UI is broken, the user doesn't know it's a tab group. So, how do we make it work like this? So, this is like a react component. It takes and title examples which used to announce the title for our tab group. Then, we have some component like tab.list. You pass an area of object for your tab list. And in the tab.content, we render the tab content. First, the tab. So, tab is very simple. We pass an area level attribute and the role tab list. And in the list component, where the each individual button is rendered, we pass the role tab, we pass the area selected true. It should be dynamic. When the tab is active, it should set to true. Otherwise, the tab should set to false. Then, we pass an ID. We'll see where it referenced to. And we have area control, which is referring to one ID, which is associated with the tab panel. That's how the screen readers often know which tab panel is associated with the which tab. And we have onclick handler to actually change the tab. And in the content, we make it focusable by providing tab index. We provide a role and an ID and area level bar. So role tab list, what it does actually is, it tells the assistive test that the container is a set of tab, as we saw in the demo. As soon as we focus on this element, which has a role tab list, it will be announced that it is a tab. And role tab panel indicates that element is a container for a tab panel. And with the passing our area control, we can associate it with the tab. And role tab indicates that the element serve as a tab control and provides the title for the associate tab panel, as we saw in the demo, how it was announced. And should be used with the button element. The key element it should be. Why we use it with the button element? Because we get the default focus and over styling. But you can also use a span or any other element. Since we are passing the role tab, the semantic meaning of the button is overridden anyways. So you can also use any other element with it. So these were like very quick demos of some UI component we have working on. The main is and also in product we have improved accessibility. So what is next? First thing is like what we are trying to do is integrate react router file. So there is the reach router many people I think should be aware of. Reach router. Yeah. So reach router is developed by the developer who developed like react router. So reach router is like has more focus on accessibility. And in react router 5 they are merging it. So now react router will have the same functionality. So how skin reader software normally works is when the page reloads they know the new page has been added. So when you click on a link which is not like single page app the page will reload. Like you click on a link and the page reloads. So skin reader software knows where to focus because page has changed. But in react apps what happens if you click a button and the page navigates the focus and the button is still part of the page. The focus will still on that button and not on the new element which has come. So react router 5 helps us with that focus management. And we also are trying to use integrate some tools for our pull request. So if people miss any issues so we can report it on the pull request so people can fix it before merging it in the code base. And we also want to raise more awareness inside the company and outside it like and this talk is like one effort for that where we want to like tell people like we should work on accessibility and improve the accessibility of our products because we should think about everyone and not just the people who can see right or people who have the mouse learnings. First thing is no area is better than bad area and I am not quoting this this sentence is actually from the specs official space where the first thing they tell is no area is better than bad area because once you introduce people that okay there are area attributes you can use for skin and software they will do things like this like okay we have an anchor tech and it has some link text what we'll do we'll add read more in the area level so skin reader software will see the read more too but what actually happens is area attributes supersede the HTML elements so when you say provide area level read more skin reader software won't read the link text it will just announce read more link and now skin reader user don't have any idea what the link is about so we should not do this right if you want to include read more have a better copy for your anchor tech and include in there another thing is like we have some icon for like as we saw in the previous example instead of image we have some icon and to make it accessible what we do we provide one area level and it says close so it will work no issues with that but what happens some people like as I said accessibility is like very broad spectrum so some people might not be like comfortable with the language your code is in or your copy is in they might use some translation tool to translate your site and major translation tools miss the area attributes to translate so what will happen everything in your website will be translated but this piece of code will be announced as it is so now again the broken experience for skin reader software so instead of that what we can do we can create one util class like SR only is very famous bootstrap class and what it does is like it visually hides the element but it is actually in the markup so this way skin reader software will see the close and it will get translated with the tools and it is also accessible and it is visually hidden so your UI is like not broken this is again the example from the first slide where we saw the lintel that if you want to make and development properly accessible you have to do you have to add and roll you have to on click handler that is like most common thing people add then we also need to head on key down handler which not many people add if you don't have the lintel enabled most probably you will never add it and we need to provide tab index zero so it gets focused in the when people try to tap through it and you do all this then you write test for all this so instead of this what we can do is we can just use a button element and it will have all of this functionality inbuilt and you that reduce your code maintainability and complexity and tooling helps casting issues as we saw when you have the tooling in the place you can fix the issues and instead of improve so you actually improve accessibility of your code and not make it worse by just randomly adding RA attribute or doing something also we need to treat accessibility as a requirement and not as a feature because what happens when you have written a markup and when you try to fix it there will lot of code change and then you will not get benefit from your product manager like it is a very big task and it is very complicated when you are doing it as an afterthought so better make it as a requirement like unit test it takes some time in the beginning but it gets easier with the time and automated tests are good but user testing is a must because automated tests just go through the code so up to 30% of code is accessibility issues can be found with the automated testing but you should actually use with the real software and with the real users and these are the resources which I mentioned ReactX is a logger which we are using XCore is a library we are using for unit test and ESLintPlugin is a plugin which you can use for your ESLint laws and policies you can go ahead and read for policies if your product is in that country ColorSafe is the URL I mentioned you can see the demo code on this link thank you thanks you guys