Words by Vernacchia

React Aria Exploration (Pt. 1)


I started following Devon Govett on Twitter well before 2.0. I was looking at alternatives to webpack that would allow me to set up sample projects in seconds, not days (sorry webpack 😓).

Note: For those of you that don’t know, he’s the creator of Parcel and a slew of other things that you likely use everyday in the JS community.

So, I’m trolling Twitter one day (lurker status), and I see him tweet about something called “React Aria.” I had an initial look and thought, “Damn, this would’ve helped solve so many problems we previously had in our design system. How can we potentially look at integrating this into ours so we don’t have to roll our own??”

Fast forward ~2 years. I still hadn’t looked at the library 😬. During that time I had been promoted (🕷️👨), added a second team to my responsibilities, and, you know, had life things going on. Well here we are now. Let’s give it the good ole college try.

Accessibility Matters

Let me repeat, accessibility matters! I want everyone to be able to use the web. Nothing should stop someone from using one of the greatest resources known to humankind.

In order to keep true to that statement, as developers/engineers we need to do our best to ensure everyone can access the things on which we’re working.

If you can’t get behind the altruistic reasoning (sans benefits), then let’s think about it this way. The more people you have using your site, the more potential customers you have.

Just because someone may have a bit more trouble using the web (browsers, phone, etc.) doesn’t mean they don’t want to purchase a product (i.e. give you money).

There are many groups of people looking to improve accessibility on the web. Have a look at the content below if you want to learn more.

  1. W3C Web Accessibility Initiative (WAI)
    • Responsible for publishing standards like WCAG
  2. Accessible Rich Internet Application (ARIA) Authoring Practices Guide (APG)
  3. UK Public Sector Accessibility Requirements
    • Spoiler, based on the WCAG standards

React Spectrum

Let’s start at the beginning. Adobe, yes the people responsible for Photoshop, have a design system called Spectrum.

They then have different implementations of the design system that include:

  1. Spectrum CSS
  2. React Spectrum
  3. Spectrum Web Components

You can probably guess what each focuses on based on the name.

I’ll be discussing the React Spectrum here, which is A React implementation of Spectrum, Adobe’s design system.

Well, duhhh… But, the cool thing is that there’s actually a group of libraries (React Spectrum Libraries) that

help you build adaptive, accessible, and robust user experiences.

They include:

  1. React Spectrum - design system itself (uses these other libraries below)
  2. React Aria - A library of React Hooks that provides accessible UI primitives for your design system.
  3. React Stately - A library of React Hooks that provides cross-platform state management for your design system.
  4. Internationalized - Two framework-agnostic internationalization libraries for the web.
    • Dates and times + Numbers

Now that we know that, let’s get a move on!

React Aria

React Aria is pretty cool IMHO (and the fact that Adobe open sourced it)! It’s designed to be flexible and integrated into any design system. So, that means you don’t have to use React Spectrum to get the accessibility benefits if you don’t want to.

🙌🏻 A huge step forward for accessibility on the web.

So, let’s get right into it. I got set up quite quickly using Vite and Storybook. I looked around for a bit to see what the current, defacto way to set these things up, but got lost and settle on this. I’ll write a whole other blog post on that topic. I’ve published my repository to Github.

Creating a Component

I started with the “easiest” component in any design system, the Button (joking about the easy part).

I used the default Button generated by Storybook when first initialising it. And then I went about creating an “React Aria” version of it. A super simple one.

If you have a look at them, they’re pretty close to the same. Let’s go through the differences…

useButton requires a ref and props

No biggie, created the ref and initialised the default props a different way. This hook then returns props that you spread over the component. They can be seen below:

All good so far!

usePress

So, you’ve looked through the examples and you’re noticing a major difference. The “React Aria” Button doesn’t have an onClick method defined in the props/types. If you go looking a bit deeper, you’ll realise that it’s not defined anywhere (not even on the AriaButtonProps types).

What gives??

Well, this is where usePress comes in, which aims to make “pressing something” across loads of environments easier. Instead of an onClick method there is an onPress method. This will used create the proper props that the Button will use (see above).

Different events?

Now that we’ve talked about how React Aria uses the onPress handler (or some variation of it), let’s talk about the events.

Turns out, a standard onClick handler and the onPress handler receive different events. Hmmm…

The onClick event handler will receive a React SyntheticBaseEvent. That’s what we’re used to in React.

But, the onPress event handler will receive a PressEvent which looks like:

export interface PressEvent {
    /** The type of press event being fired. */
    type: "pressstart" | "pressend" | "pressup" | "press";
    /** The pointer type that triggered the press event. */
    pointerType: PointerType;
    /** The target element of the press event. */
    target: Element;
    /** Whether the shift keyboard modifier was held during the press event. */
    shiftKey: boolean;
    /** Whether the ctrl keyboard modifier was held during the press event. */
    ctrlKey: boolean;
    /** Whether the meta keyboard modifier was held during the press event. */
    metaKey: boolean;
    /** Whether the alt keyboard modifier was held during the press event. */
    altKey: boolean;
}

From the looks of it, this is just a paired down version of SyntheticBaseEvent with some helpful things like pointerType and the type (event type). Don’t worry, the event target is still there and won’t stop you from using event.target.WHATEVER in your code!

You may also notice there are not a lot of callable events, like preventDefault. Well React Aria handles this for you as well. No need!

The Final Output

With this, we’ve create a very generic button, with accessibility in mind, that can be used in a design system. We will leave the testing across a myriad of devices and environments to the React Aria team (thank you!).

To make sure we’re following the standards and guidelines, we could add the accessibility extensions to Storybook (maybe one for next time)!

I’m going to continue to explore it a bit more over the next couple weeks and will post more about it!

Until next time...