Accessibility in React Dialog

4 Sep 202617 minutes to read

The React Dialog component follows the accessibility guidelines and standards, including ADA, Section 508, WCAG 2.2, and WCAG roles that are commonly used to evaluate accessibility.

The accessibility compliance for the React Dialog component is outlined below.

Yes - All features of the component meet the requirement.
Intermediate - Some features of the component do not meet the requirement.
No - The component does not meet the requirement.
Accessibility Criteria Compatibility
WCAG 2.2 Support Yes
Section 508 Support Yes
Screen Reader Support Yes
Right-To-Left Support Yes
Color Contrast Yes
Mobile Device Support Yes
Keyboard Navigation Support Yes
Accessibility Checker Validation Yes
Axe-core Accessibility Validation Yes

WAI-ARIA attributes

The React Dialog features complete ARIA accessibility support, enabling access for screen readers and other assistive technology devices. The component is designed based on the guidelines provided in WAI-ARIA Accessibility Practices.

The React Dialog component uses the Dialog role and the following ARIA properties on its elements based on their state.

ARIA attribute Description
aria-describedby It indicates the React Dialog content description is notified to the user through assistive technologies.
aria-labelledby The React Dialog title is notified to the user through assistive technologies.
aria-modal For modal React Dialog its value is true and non-modal React Dialog its value is false.
aria-grabbed For a draggable React Dialog, its value is true while dragging and false when the drag stops. Note: aria-grabbed is deprecated in the WAI-ARIA 1.1/1.2 spec; the React Dialog still applies it for backward compatibility.

Keyboard interaction

The keyboard interaction of the React Dialog component is designed based on WAI-ARIA Practices described for React Dialog. Users can use the following shortcut keys to interact with the React Dialog.

Keyboard shortcut Action
Esc Closes the React Dialog. This functionality can be controlled by using closeOnEscape.
Enter When the React Dialog button or any input (except text area) is in focus state, pressing the Enter key triggers the click event of the focused button (or the primary button). The Enter key does not trigger the click when the React Dialog content contains a text area with initial focus; this is a documented behavior to allow newline input within the text area.
Ctrl + Enter When the React Dialog content contains a text area and it is in focus state, press Ctrl + Enter to call the click event function associated with the primary button.
Tab Moves focus to the next focusable element within the React Dialog.
Shift + Tab Moves focus to the previous focusable element within the React Dialog. When focus is on the first focusable element, pressing Shift + Tab moves focus to the last focusable element.

When the React Dialog is modal, focus is trapped within the React Dialog elements — Tab and Shift + Tab cycle through the focusable elements inside the React Dialog without returning focus to the underlying page.

[Class-component]

import { DialogComponent } from '@syncfusion/ej2-react-popups';
import * as React from "react";
class App extends React.Component {
    dialogInstance;
    buttons = [{
            buttonModel: {
                content: 'Submit',
                cssClass: 'e-flat',
                isPrimary: true,
            },
            'click': () => {
                this.dialogInstance.hide();
            }
        }];
    handleClick() {
        this.dialogInstance.show();
    }
    render() {
        return (<div className="App" id='dialog-target'>
          <button className='e-control e-btn' id='targetButton1' role='button' onClick={this.handleClick = this.handleClick.bind(this)}>Open</button>
  
          <DialogComponent width='400px' target='#dialog-target' header='Feedback' showCloseIcon={true} buttons={this.buttons} ref={dialog => this.dialogInstance = dialog}>
          <form>
              <div className='form-group'>
                  <label htmlFor='email'> Email:</label>
                  <input type='email' className='form-control' id='email'/>
              </div>
              <div className='form-group'>
                  <label htmlFor='comment'>Comments:</label>
                  <textarea className='form-control' id='comment'/>
              </div>
          </form>
          </DialogComponent>
      </div>);
    }
}
export default App;
import { DialogComponent } from '@syncfusion/ej2-react-popups';
import * as React from "react";

class App extends React.Component {
  public dialogInstance: DialogComponent;

  public buttons: any = [{
      buttonModel: {
          content: 'Submit',
          cssClass: 'e-flat',
          isPrimary: true,
      },
      'click': () => {
          this.dialogInstance.hide();
      }
  }];
  
  public handleClick() {
      this.dialogInstance.show();
  }
  
  public render() {
      return (
      <div className="App" id='dialog-target'>
          <button className='e-control e-btn' id='targetButton1' role='button' onClick={this.handleClick = this.handleClick.bind(this)}>Open</button>
  
          <DialogComponent width='400px' target='#dialog-target' header='Feedback' showCloseIcon={true}  buttons={this.buttons} ref={dialog => this.dialogInstance = dialog!}>
          <form>
              <div className='form-group'>
                  <label htmlFor='email'> Email:</label>
                  <input type='email' className='form-control' id='email'/>
              </div>
              <div className='form-group'>
                  <label htmlFor='comment'>Comments:</label>
                  <textarea className='form-control' id='comment'/>
              </div>
          </form>
          </DialogComponent>
      </div>);
  }
}
export default App;

[Functional-component]

import { DialogComponent } from '@syncfusion/ej2-react-popups';
import * as React from "react";
function App() {
    let dialogInstance;
    let buttons = [{
            buttonModel: {
                content: 'Submit',
                cssClass: 'e-flat',
                isPrimary: true,
            },
            'click': () => {
                dialogInstance.hide();
            }
        }];
    function handleClick() {
        dialogInstance.show();
    }
    return (<div className="App" id='dialog-target'>
          <button className='e-control e-btn' id='targetButton1' role='button' onClick={handleClick.bind(this)}>Open</button>
  
          <DialogComponent width='400px' target='#dialog-target' header='Feedback' showCloseIcon={true} buttons={buttons} ref={dialog => dialogInstance = dialog}>
          <form>
              <div className='form-group'>
                  <label htmlFor='email'> Email:</label>
                  <input type='email' className='form-control' id='email'/>
              </div>
              <div className='form-group'>
                  <label htmlFor='comment'>Comments:</label>
                  <textarea className='form-control' id='comment'/>
              </div>
          </form>
          </DialogComponent>
      </div>);
}
export default App;
import { DialogComponent } from '@syncfusion/ej2-react-popups';
import * as React from "react";

function App() {
  let dialogInstance: DialogComponent;
  let buttons: any = [{
      buttonModel: {
          content: 'Submit',
          cssClass: 'e-flat',
          isPrimary: true,
      },
      'click': () => {
          dialogInstance.hide();
      }
  }];
  
    function handleClick() {
        dialogInstance.show();
    }
  
    return (
      <div className="App" id='dialog-target'>
          <button className='e-control e-btn' id='targetButton1' role='button' onClick={ handleClick.bind(this)}>Open</button>
  
          <DialogComponent width='400px' target='#dialog-target' header='Feedback' showCloseIcon={true}  buttons={buttons} ref={dialog => dialogInstance = dialog!}>
          <form>
              <div className='form-group'>
                  <label htmlFor='email'> Email:</label>
                  <input type='email' className='form-control' id='email'/>
              </div>
              <div className='form-group'>
                  <label htmlFor='comment'>Comments:</label>
                  <textarea className='form-control' id='comment'/>
              </div>
          </form>
          </DialogComponent>
      </div>
    );
}
export default App;

Ensuring accessibility

The React Dialog component’s accessibility levels are ensured through an accessibility-checker and axe-core software tools during automated testing.

The accessibility compliance of the React Dialog component is shown in the following sample. Open the sample in a new window to evaluate the accessibility of the React Dialog component with accessibility tools.

See Also