Futuristic workspace with developers using React Aria

Elevating UI Development with React Aria's Accessibility Toolkit

The Orange Cat
The Orange Cat

React Aria is a powerful library that provides developers with a set of unstyled React components and hooks, designed to help build accessible, high-quality UI components for applications or design systems. By offering pre-built accessibility, internationalization, and interaction features, React Aria allows developers to focus on creating unique designs and styles without compromising on user experience.

Features

React Aria boasts an impressive array of features that set it apart from other UI libraries:

  • Accessibility: Built-in support for screen readers and keyboard navigation, ensuring your components are usable by everyone.
  • Adaptability: Optimized for various devices and interaction methods, including mouse, touch, and keyboard.
  • Internationalization: Out-of-the-box support for over 30 languages, right-to-left layouts, and localized date and number formatting.
  • Customizability: Provides behavior and interactions without imposing any specific styling or DOM structure.
  • High-quality interactions: Carefully crafted to feel responsive and natural on every platform.

Installation

To get started with React Aria, you can install it using npm or yarn:

npm install react-aria-components

or

yarn add react-aria-components

Basic Usage

Let’s explore some basic usage examples to see how React Aria can be implemented in your projects.

Button Component

Here’s a simple example of creating an accessible button using React Aria:

import { useButton } from 'react-aria';
import React from 'react';

function Button(props) {
  let ref = React.useRef();
  let { buttonProps } = useButton(props, ref);

  return (
    <button {...buttonProps} ref={ref}>
      {props.children}
    </button>
  );
}

// Usage
<Button onPress={() => alert('Button pressed!')}>Press me</Button>

This example demonstrates how easy it is to create a fully accessible button component with React Aria. The useButton hook provides all the necessary props to make the button accessible, including proper ARIA attributes and keyboard interactions.

Select Component

Let’s create a more complex component, such as a select dropdown:

import { useSelect, useButton, useSelectState } from 'react-aria';
import { Item } from 'react-stately';
import React from 'react';

function Select(props) {
  let state = useSelectState(props);
  let ref = React.useRef();
  let { labelProps, triggerProps, valueProps, menuProps } = useSelect(props, state, ref);

  return (
    <div style={{ display: 'inline-block' }}>
      <div {...labelProps}>{props.label}</div>
      <button {...triggerProps} ref={ref}>
        <span {...valueProps}>
          {state.selectedItem ? state.selectedItem.rendered : 'Select an option'}
        </span>
        <span aria-hidden="true" style={{ paddingLeft: 5 }}>▼</span>
      </button>
      {state.isOpen && (
        <ul {...menuProps}>
          {[...state.collection].map((item) => (
            <li key={item.key}>{item.rendered}</li>
          ))}
        </ul>
      )}
    </div>
  );
}

// Usage
<Select label="Favorite Animal">
  <Item key="cat">Cat</Item>
  <Item key="dog">Dog</Item>
  <Item key="elephant">Elephant</Item>
</Select>

This example showcases how React Aria handles more complex UI patterns. The useSelect, useButton, and useSelectState hooks work together to create a fully accessible and interactive select component.

Advanced Usage

React Aria’s flexibility allows for advanced customization and complex UI patterns. Let’s explore some more sophisticated use cases.

Drag and Drop

React Aria supports accessible drag and drop functionality:

import { useDrag, useDrop } from 'react-aria';
import React from 'react';

function DraggableItem(props) {
  let { dragProps, isDragging } = useDrag({
    getItems() {
      return [{ 'text/plain': props.text }];
    }
  });

  return (
    <div {...dragProps} style={{ opacity: isDragging ? 0.5 : 1 }}>
      {props.text}
    </div>
  );
}

function DropZone(props) {
  let ref = React.useRef();
  let { dropProps, isDropTarget } = useDrop({
    ref,
    onDrop(e) {
      let items = e.items.filter(item => item.kind === 'text');
      for (let item of items) {
        item.getText('text/plain').then(text => {
          console.log('Dropped text:', text);
        });
      }
    }
  });

  return (
    <div
      {...dropProps}
      ref={ref}
      style={{
        padding: 20,
        border: '2px dashed',
        borderColor: isDropTarget ? 'blue' : 'gray'
      }}
    >
      {props.children}
    </div>
  );
}

// Usage
<>
  <DraggableItem text="Drag me!" />
  <DropZone>Drop here</DropZone>
</>

This example demonstrates how React Aria’s drag and drop hooks can be used to create accessible and interactive drag and drop interfaces.

Date Picker

Creating an accessible date picker is often challenging, but React Aria simplifies the process:

import { useDatePicker, useButton, useCalendar, useCalendarGrid, useCalendarCell } from 'react-aria';
import { useDatePickerState, useCalendarState } from 'react-stately';
import { createCalendar } from '@internationalized/date';
import React from 'react';

function DatePicker(props) {
  let state = useDatePickerState(props);
  let ref = React.useRef();
  let {
    labelProps,
    groupProps,
    buttonProps,
    dialogProps,
    calendarProps
  } = useDatePicker(props, state, ref);

  return (
    <div>
      <span {...labelProps}>{props.label}</span>
      <div {...groupProps} ref={ref}>
        <input
          value={state.inputValue}
          onChange={(e) => state.setInputValue(e.target.value)}
        />
        <button {...buttonProps}>🗓</button>
      </div>
      {state.isOpen && (
        <div {...dialogProps}>
          <Calendar {...calendarProps} />
        </div>
      )}
    </div>
  );
}

function Calendar(props) {
  let { locale } = props;
  let state = useCalendarState({
    ...props,
    createCalendar
  });

  let { calendarProps, prevButtonProps, nextButtonProps, title } = useCalendar(props, state);

  return (
    <div {...calendarProps}>
      <div>
        <h2>{title}</h2>
        <button {...prevButtonProps}>◀</button>
        <button {...nextButtonProps}>▶</button>
      </div>
      <CalendarGrid state={state} />
    </div>
  );
}

function CalendarGrid({ state, ...props }) {
  let { gridProps, headerProps, weekDays } = useCalendarGrid(props, state);

  return (
    <table {...gridProps}>
      <thead {...headerProps}>
        <tr>
          {weekDays.map((day, index) => <th key={index}>{day}</th>)}
        </tr>
      </thead>
      <tbody>
        {state.getDatesInMonth().map((week, rowIndex) => (
          <tr key={rowIndex}>
            {week.map((date, columnIndex) => (
              <CalendarCell
                key={columnIndex}
                state={state}
                date={date}
              />
            ))}
          </tr>
        ))}
      </tbody>
    </table>
  );
}

function CalendarCell({ state, date }) {
  let ref = React.useRef();
  let {
    cellProps,
    buttonProps,
    isSelected,
    isOutsideVisibleRange,
    isDisabled,
    formattedDate
  } = useCalendarCell({ date }, state, ref);

  return (
    <td {...cellProps}>
      <div
        {...buttonProps}
        ref={ref}
        hidden={isOutsideVisibleRange}
        style={{
          background: isSelected ? 'blue' : 'transparent',
          color: isDisabled ? 'gray' : isSelected ? 'white' : 'black'
        }}
      >
        {formattedDate}
      </div>
    </td>
  );
}

// Usage
<DatePicker label="Event date" />

This comprehensive example shows how React Aria’s various hooks work together to create a fully accessible and customizable date picker component.

Conclusion

React Aria is a powerful tool for developers looking to create accessible, adaptive, and customizable UI components. By providing a robust set of hooks and unstyled components, it allows developers to focus on design and user experience while ensuring that their applications are inclusive and usable by all.

Whether you’re building a new design system from scratch or looking to enhance the accessibility of your existing React applications, React Aria offers a flexible and powerful solution. Its support for internationalization, various interaction modes, and complex UI patterns makes it an invaluable asset in the modern web development toolkit.

By leveraging React Aria, you can create user interfaces that are not only beautiful but also truly accessible to everyone, regardless of their abilities or the devices they use. As web applications continue to evolve and accessibility becomes increasingly important, React Aria stands out as a forward-thinking library that empowers developers to build the inclusive web of tomorrow.

Comments