Log of QDelft

React Accessibility


Tooling and techniques

  • Almero Steyn
  • QDelft B.V.
  • almerosteyn.com
  • twitter.com/kryptos_rsa

React

React logo
"A JavaScript library for building user interfaces." - React docs

React syntax


import React from 'react';
import Content from './Content';

const Root = ({headerText, onLogout}) => (
     

{ headerText }

<Content onLogout={ onLogout }/>
); export default Root;

Everything in JavaScript?

Image of koala expressing shock at React being all JavaScript

JS-Zilla destroys a11y!!

Image depicting JavaScript as a destructive monster

It can be a friendly monster...

Image depicting JavaScript as cute monster

create-react-app


yarn global add create-react-app
create-react-app my-react-app
cd my-react-app
yarn start
  1. Webpack development and production build.
  2. ESLint with some a11y rules.
  3. Progressive app by default.
  4. Supports code splitting.
  5. Unit tests + coverage with JSDOM.

JSX

HTML-like syntactic JavaScript sugar.


        <label htmlFor={nameId}>{nameLabelText}</label>
        <input id={nameId} type="text" />
    
Renders to HTML in the DOM.

         
         
    

JSX and ARIA

All ARIA attributes are valid JSX props!


            <input id={nameId} aria-label={accessibleLabel} type="text" />
    

IntelliSense in supported IDEs.

ARIA attribute IntelliSense in JSX with WebStorm

eslint-plugin-jsx-a11y

"Static AST checker for a11y rules on JSX elements."
https://github.com/evcohen/eslint-plugin-jsx-a11y

eslint-plugin-jsx-a11y

More than 30 ESLINT a11y checks.

Image of some rules in the eslint-jsx-a11y plugin

eslint-plugin-jsx-a11y

Rules are configurable.


       {
         "rules": {
           "jsx-a11y/rule-name": "warn"
         }
       }
    

Extending config in create-react-app.


        {
          "extends": ["react-app", "plugin:jsx-a11y/recommended"],
          "plugins": ["jsx-a11y"]
        }
    

eslint-plugin-jsx-a11y

A11y issues become build warnings.

Shows eslint-jsx-a11y error feedback in create-react-app build

eslint-plugin-jsx-a11y

IDE integration.

Shows eslint-jsx-a11y error feedback in an IDE

react-axe

"Accessibility auditing for React.js applications."
React-axe uses axe-core. Shows axe-core logo. https://github.com/dequelabs/react-axe

react-axe

Setting up react-axe.


import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

if (process.env.NODE_ENV !== 'production') {
    const axe = require('react-axe');
    axe(React, ReactDOM, 1000);
}

ReactDOM.render(<App />, document.getElementById('root'));

react-axe

Browser console feedback.

Shows the react-axe console feedback for accessibility errors in Chrome

Combining the tools

Summary of console errors for React, aslint-jsx-a11y and react-axe

Focus control

Setting focus with refs.


componentDidMount(){
    this.nameInput.focus();
}

render(){
    return(
        
<input id="demoId" type="text" ref={(input) => {this.nameInput = input;}}/>
); }

Lazy loading components


class App extends Component {
    state = { LazyBlock: null };

    async componentDidMount() {
        const { default: LazyBlock } = await import('./LazyBlock');
        this.setState({ LazyBlock: <LazyBlock/> });
    }

    render() {
        return ( <main aria-busy={!this.state.LazyBlock}>
                    {this.state.LazyBlock || 

Loading...

} </main> ); } }

Lazy loading components

Splitting code files.

JavaScript code bundles after webpack async-await import and build
Image of captain kirk showing thumbs up to Spock. Accessibility is logical.

Questions


Presentation online at:

http://almerosteyn.com/slides/
  • Almero Steyn
  • QDelft B.V.
  • almerosteyn.com
  • twitter.com/kryptos_rsa