Peter Ekene Eze Learn, Apply, Share

Build more accessible forms with React Icons

4 min read 1385

Taking extra measures to build more accessible React apps can be a time-consuming process. However, it’s something we need to do in order to create a more inclusive web for everyone.

The goal of this post is to help you understand how to build more accessible React forms by using the popular react-icons library and the very accessible React components made available by the ReachUI library.

Why React Icons?

React Icons provides thousands of free, open-source icons. It includes ten popular open-source icon libraries, including Font Awesome and Material Design. It utilizes ES6 imports that allow you to include only the icons that your project is using. We use react-icons for a number of reasons, mostly to target user inputs and add visual descriptions to form fields. Here are some benefits:

  • The quick installation process (it can be installed via npm)
  • All react-icons are optimized for accessibility by default
  • Finding variations of numerous icons are easier
  • Memory friendly, it doesn’t leave a big footprint in your bundle
  • It ensures minimal file size with SVG (scalable vector graphics) options
  • It’s open-source so it can be used on both commercial and non-commercial projects

Building an accessible React form

Prerequisites

  • Prior knowledge of React will be helpful but not mandatory
  • You should have Xcode or Android Studio installed to run the simulator/emulator
  • You should have Node 10+ installed

What we’ll build

For demonstration purposes and to give you a more practical experience, we’ll build a contact form to collect the details of a new friend. We’ll make this form accessible using Reach UI’s components and React Icons. Here’s a visual output of the end product.

finished ui with icons

Getting started

The most common way to start a React project is by using the create-react-app CLI tool. If you haven’t done this before, go ahead and run the following commands to install the necessary packages and start the local development server:

npx create-react-app accessible-form
cd accessible-form
npm start

If you check your browser on localhost:3000, you should see your project live.

Icons have become an integral part of creating a great user interface. They help present your content in a clear and concise manner that would make navigating your website or application easier for your users.

Building the contact form

To build the form fields we make use of the components made available to us from ReachUI. To find out more of ReachUI’s components, visit ReachUI components.

We made a custom demo for .
No really. Click here to check it out.

Dependencies

To help us build this project, we’ll reuse some existing libraries:

  1. ReachUI — For building and styling the form in the most accessibility-friendly way
  2. React Icons — To provide the necessary icons for the form fields
  3. Bootstrap — To build a more responsive form across all kinds of screen sizes
  4. React DatePicker — A simple component that helps implement date picking in React apps

To install these libraries, open a terminal and run the following commands in the project’s root folder:

npm install --save react-icons react-datepicker bootstrap

In the root directory of the sample project we created, create a new
src/components/Contact.js file. In this file, we’ll set up our contact form and use react-icons to improve its accessibility and overall experience. Open it up and update it with the code below:

import React, { Component } from "react";
import { Combobox, ComboboxInput } from "@reach/combobox";
import { Menu, MenuList, MenuButton, MenuItem } from "@reach/menu-button";
import {
  MdPhone,
  MdPermIdentity,
  MdLocationOn,
  MdEmail,
  MdExpandMore,
  MdEvent
} from "react-icons/md";
import DatePicker from "react-datepicker";
class Contact extends Component {
  render(){
    return(
      <>  
      //Form here
      </>
    );
  }
}

Here, we’ve imported a few of the external components that we installed earlier to help us implement the functionalities needed in this application. Let’s take a closer look at their respective features:

  • <Combobox>: This is an accessible input box component made available by the ReachUI library. Like every other component from the ReachUI library, it is accessible by default and abides by all ARIA element specifications
  • <Menu/>: The ReachUI Menu component is used to provide dropdown selection functionalities in web apps. In our form, we’ll have a dropdown menu that allows users to select the locations they reside in. Using the <Menu/> component gives us accessibility out of the box and also makes the menu items keyboard accessible. Finally, the menu options are well suited for assistive technologies
  • <React Icons/>: The icons we imported into this project are all from material design icons made available to us by the react-icons library. It makes our form fields more visually descriptive
  • React DatePicker: This a reusable Datepicker component made specifically for building React applications. We’ll use this component to render the date picker for the birthday selection field. It is keyboard accessible and renders the date efficiently

Having imported all the necessary external libraries, we can go ahead and define the return() function in our Contact.js file. In it, we’ll use the components we’ve imported to build out the desired form fields.

The name input field

This is the form field that collects the name of the user. To set this up, we’ll update the previous snippet with the code below:

// imports
class Contact extends Component {
  render(){
    return(
      <>  
        <form onSubmit={this.handleSubmit}>
          <Combobox>
            <div>
              <label for="userName">
                <MdPermIdentity />
              </label>
            </div>
            <div>
              <ComboboxInput
                className="form-control"
                id="userName"
                aria-label="user name"
                name="userName"
                value={this.state.userName}
                placeholder="Name"
                onChange={this.handleChange}
              />
            </div>
          </Combobox>        
        </form>
      </>
    );
  }
}
export default Contact    

combo box

Here, we used the <Combobox/> component to define the field that collects the user’s name. While rendering the MDPermIdentity icon, we wrapped it inside a HTML label tag to add more visual accessibility to the form input using the for attribute it provides. Finally, to render the text input component for the field, we used the ComboboxInput component which takes in the aria-label attribute to provide audio accessibility to users who make use of screen-readers.

We’ve also applied the same functionality across all other fields that enable users to input text such as the phone number field, the address field, and the email field.

The area input field

This is the field where we’ll allow users to select a residential location based on a predefined list of locations. We’ll use the <Menu/> component from ReachUI to accessibly power this functionality. Here’s how we implement that in the Contact.js file:

// imports
class Contact extends Component {
  render(){
    return(
      <>  
        <form onSubmit={this.handleSubmit}>
          <div>
            <Menu>
                <MenuButton aria-label="menu button for area">
                  {(this.state.userArea == '') ? ('Area') : (this.state.userArea)}
                  <span aria-hidden><MdExpandMore /></span>
                </MenuButton>
                <MenuList>
                  <MenuItem onSelect={() => this.handleSelect('Ajah', 'userArea' )}>
                    Ajah
                  </MenuItem>
                  <MenuItem onSelect={() => this.handleSelect('Apapa', 'userArea' )}>
                    Apapa
                  </MenuItem>
                  <MenuItem onSelect={() => this.handleSelect('Festac', 'userArea' )}>
                    Festac
                  </MenuItem>
                  <MenuItem
                    onSelect={() => this.handleSelect('Gbagada', 'userArea' )}>
                    Gbagada
                  </MenuItem>
                  <MenuItem onSelect={() => this.handleSelect('Lekki', 'userArea' )}>
                    Lekki
                  </MenuItem>
                  <MenuItem
                    onSelect={()=> this.handleSelect('Victoria Island', 'userArea' )}>
                    Victoria Island
                  </MenuItem>
                </MenuList>
              </Menu>
            </div>
          </div>
        </form>
      </>
    );
  }
}
export default Contact

The Menu component has some extended accessibility features, however, it is still practically a wrapper around the usual HTML elements in the following ways:

  • <Menu /> component — HTML <select /> HTML element
  • <Menubutton /> — HTML <button /> element
  • <MenuItem/> — HTML <option/> attribute for <select/> elements
  • <MenuList /> — wrapper for the <MenuItem />

Once again, we’ve used the aria-label to provide audio accessibility for screen-readers.

Conclusion

finished app

Congratulations! You just finished building an accessible contact form in React using React Icons and ReachUI. The goal is to help you get an immediate hands-on approach to building accessible React forms. We didn’t cover the styling of the form in detail so as not to divert attention from the more important aspect of this post. However, you can find the source code with all the styles in the project repository.

You come here a lot! We hope you enjoy the LogRocket blog. Could you fill out a survey about what you want us to write about?

    Which of these topics are you most interested in?
    ReactVueAngularNew frameworks
    Do you spend a lot of time reproducing errors in your apps?
    YesNo
    Which, if any, do you think would help you reproduce errors more effectively?
    A solution to see exactly what a user did to trigger an errorProactive monitoring which automatically surfaces issuesHaving a support team triage issues more efficiently
    Thanks! Interested to hear how LogRocket can improve your bug fixing processes? Leave your email:

    Full visibility into production React apps

    Debugging React applications can be difficult, especially when users experience issues that are difficult to reproduce. If you’re interested in monitoring and tracking Redux state, automatically surfacing JavaScript errors, and tracking slow network requests and component load time, try LogRocket.

    LogRocket is like a DVR for web apps, recording literally everything that happens on your React app. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app's performance, reporting with metrics like client CPU load, client memory usage, and more.

    The LogRocket Redux middleware package adds an extra layer of visibility into your user sessions. LogRocket logs all actions and state from your Redux stores.

    Modernize how you debug your React apps — .

    Peter Ekene Eze Learn, Apply, Share

    Leave a Reply