【React】ヘッドレスUIのReactAriaの紹介

はじめに

この記事の概要

こんにちは、株式会社TOKOSのスギタです!
今回はAdobe社が提供している、ヘッドレスUIライブラリの「ReactAria」の紹介をします。
他のヘッドレスUIライブラリと比較も行ったので、技術選定する際の参考にしていただければと思います。

対象読者

  • WEB開発を行っている方
  • Reactを使用している方
  • ヘッドレスUIライブラリを検討している方

各ヘッドレスUIライブラリの比較(2024年6月)

今回は下記ライブラリで比較します。

  • React Aria
  • Radix UI
  • Headless UI

また、一般的なライブラリ選定する際の項目とUIライブラリを選定する際に必要であろう項目で比較します。
下記が項目になります。
今回比較ライブラリが全てTree Shakingを採用しているため、バンドルサイズでの比較は考慮しません。

  • Weeklyダウンロード数
  • 最終更新日
  • Star数
  • 用意されているコンポーネント数

Weeklyダウンロード数

React AriaRadix UI(radix-ui/primitive)HeadlessUI(headlessui/react)
490,4346,684,2621,720,831

圧倒的にRadixに軍配が上がります!

最終更新日

React AriaRadix UI(radix-ui/primitive)HeadlessUI(headlessui/react)
1か月前4日前2日前

ここでは3つとも継続的にメンテされている、印象です!

Star数

React AriaRadix UI(radix-ui/primitive)HeadlessUI(headlessui/react)
12,08314,76424,916

ここではHeadlessUI/reactに軍配が上がりますが、大差は有りません!

コンポーネント数

React AriaRadix UI(radix-ui/primitive)HeadlessUI(headlessui/react)
443716

ここではReactAriaに軍配が上がります!
Radixはコンポーネント以外にも、LayoutやUtilsやThemeなどが有り他のライブラリより幅広い印象です!
ですが、コンポーネント数で見たらReactAria一択ではないでしょうか!
ModalやForm系の拡充はもちろん、DropZoneやDatePickerなど他のライブラリでないコンポーネントも用意されています!
またカスタムHookもかなりの数用意されております、一度見てみることをおすすめします!

ReactAriaの特徴

まずはなんといっても高レベルなアクセシビリティの配慮です。
さまざまなデバイスやプラットフォームで動作する高品質のインタラクションを実現できます。
ポインタイベントの配慮やキーボードとフォーカスの動を始め作支援技術のサポートまで配慮されています。
下記OSとブラウザでのテストも徹底されているみたいです!

  • macOS、Windows、Android 上の Chrome
  • macOS および Windows 上の Firefox
  • macOS、iOS、iPadOS 上の Safari
  • Windows 上の Edge

もう一つはグローバルに使用されるアプリケーションにも対応できる所です!
様々なロケールに対応しています!
またRTL(Right To Left)対応も対応しています。
下記は例になります。

import {useLocale} from 'react-aria-components';

function YourApp() {
  let {locale, direction} = useLocale();

  return (
    <div lang={locale} dir={direction}>
      {/* your app here */}
    </div>
  );
}

ルートの要素では、ユーザー インターフェイスをどの言語と方向でレンダリングするかをブラウザーが認識できるようにlang属性とdir属性にReactAriaのカスタムHookのuseLocaleを使用します。
これでロケール対応が可能になります!

ReactAriaを使用するだけで、アクセシビリティの配慮や要件次第ではグローバル使用を考慮したアプリケーションを作成できる土台となると感じます!

ライブラリの使用例

今回がButtonコンポーネント作成例をお見せします!

開発環境は下記になっております

  • react : 18
  • clsx : 2.1.1
  • react-aria-components : 1.2.1
  • tailwindcss-react-aria-components : 1.1.3
  • tailwindcss : 3.4.1
  • typescript : 5

今回スタイリングはtailwindとclsxを使っています!

コードの紹介

今回は汎用的なボタンコンポーネントを想定しています!
ReactAriaのButtonコンポーネントを使用して作ります。
Propsとして色を受取、ComponentsPropsでよりコンポーネントを抽象化しています!

import clsx from "clsx"
import { ComponentProps } from "react"
import { Button as AriaButton } from "react-aria-components"

const colorClasses = {
  red: "bg-[##FA0000]",
  blue: "bg-[#1D00FA]",
  green: "bg-[#00FA30]",
} as const
type Color = keyof typeof colorClasses

type Props = {
  color: Color
} & ComponentProps<typeof AriaButton>

export function Button({ color, ...rest }: Props) {
  const colorClass = colorClasses[color]

  return (
    <AriaButton
      {...rest}
      className={clsx(
        "rounded px-5 py-4 text-white",
        colorClass,
      )}
    />
  )
}

import名の名前の衝突を避けるためasを使用し名前import名の衝突を回避しています!
これだけでアクセシビリティに配慮したボタンを作成することができます!
なんだかんだアクセシビリティ要件を満たすことは正直難しいし後回しになりがちなので、これだけで土台ができることはかなり開発者体験が良いです!

さいごに

今回はReactAriaの紹介と汎用的なボタンコンポーネントを作成いたしました!
今回はButtonの紹介でしたが、他にも様々なコンポーネントが拡充されておりますので、一度ドキュメントを見ていただければと思います!
以上となります。
ヘッドレスUIの選定のお助けになれば幸いです!