はじめに
「アクセシビリティ対応はしたいけれど、キーボード操作やスクリーンリーダー対応まで自前で実装する時間がない」——そんな悩みを抱えたことはないでしょうか。フォーカス管理、ARIA属性の付与、キーボードナビゲーション、スクリーンリーダーへの読み上げ対応など、アクセシブルなUIコンポーネントを正しく作るには非常に多くの知識と検証が必要です。
React Ariaは、この面倒な部分をすべて肩代わりしてくれるライブラリです。見た目のスタイルには一切関与せず、振る舞いとアクセシビリティだけを提供するため、デザインの自由度を保ったまま「動作面で正しいUI」を手に入れられます。
React Ariaとは
React Ariaは、Adobeが開発・メンテナンスしているオープンソースのUIライブラリで、50種類以上のコンポーネント・フックを提供しています。W3CのARIA Authoring Practices Guideに準拠したセマンティクスを内部で実装しており、マウス・タッチ・キーボード・スクリーンリーダーのすべての操作方法に対応した「world-class accessible」なコンポーネントを、自分のデザインシステムの上に構築できます。
主な特徴
- スタイルフリー設計 - CSSやTailwind、CSS-in-JSなど任意のスタイリング手法と組み合わせ可能で、見た目を制約しません
- 高度なインタラクション対応 - ドラッグ&ドロップ、キーボードでの複数選択、フォームバリデーション、テーブル列のリサイズなど、ネイティブアプリ並みの操作性を実現します
- 国際化対応済み - 30言語以上の翻訳、複数の暦・数値体系、右から左書き言語(RTL)まで標準でサポートしています
- 3段階のカスタマイズレベル - 手軽に使える高レベルコンポーネント、コンテキストを利用した部分カスタマイズ、完全な制御が可能な低レベルHook APIまで、必要に応じて使い分けられます
インストール
もっとも手軽に始められる、コンポーネント形式で提供されるreact-aria-componentsパッケージをインストールします。
# npm
npm install react-aria-components
# yarn
yarn add react-aria-components
# pnpm
pnpm add react-aria-components
より低レベルな制御が必要な場合は、フックのみを提供するreact-ariaパッケージも利用できます。
npm install react-aria react-stately
基本的な使い方
まずはボタンコンポーネントから試してみましょう。onPressはクリックだけでなく、タッチやキーボード操作にも対応したイベントハンドラです。
import { Button } from "react-aria-components";
function App() {
return (
<Button
className="rounded-md bg-blue-600 px-4 py-2 text-white hover:bg-blue-700"
onPress={() => console.log("clicked!")}
>
送信する
</Button>
);
}
次に、バリデーション付きのフォーム入力を作ってみます。isRequiredを指定するだけで、未入力時のエラー表示までReact Aria側で処理してくれます。
import { Form, TextField, Label, Input, FieldError, Button } from "react-aria-components";
function ContactForm() {
return (
<Form onSubmit={(e) => e.preventDefault()}>
<TextField name="email" type="email" isRequired>
<Label>メールアドレス</Label>
<Input className="border rounded-md px-3 py-2" />
<FieldError className="text-red-600 text-sm" />
</TextField>
<Button type="submit" className="mt-4 rounded-md bg-blue-600 px-4 py-2 text-white">
登録する
</Button>
</Form>
);
}
このコードだけで、Tabキーでのフォーカス移動、スクリーンリーダーへのラベル読み上げ、エラー時のaria-invalid付与などが自動的に行われます。
実践的なユースケース
実務でよく使うセレクトボックスを作成してみましょう。Selectはキーボードでの選択肢移動やタイプアヘッド検索(文字入力で候補を絞り込む機能)にも標準対応しています。
import {
Select,
SelectValue,
Label,
Button,
Popover,
ListBox,
ListBoxItem,
} from "react-aria-components";
const frameworks = [
{ id: "react", name: "React" },
{ id: "vue", name: "Vue.js" },
{ id: "svelte", name: "Svelte" },
];
function FrameworkSelect() {
return (
<Select className="flex flex-col gap-1">
<Label>使用フレームワーク</Label>
<Button className="border rounded-md px-3 py-2 text-left">
<SelectValue />
</Button>
<Popover className="border rounded-md bg-white shadow-lg">
<ListBox items={frameworks}>
{(item) => (
<ListBoxItem
key={item.id}
id={item.id}
className="px-3 py-2 hover:bg-gray-100 cursor-pointer"
>
{item.name}
</ListBoxItem>
)}
</ListBox>
</Popover>
</Select>
);
}
こうしたSelectやComboBox、Table、DatePickerといった複雑な挙動を伴うコンポーネントほど、React Ariaの恩恵は大きくなります。自前で実装すると数百行になりがちなキーボード操作やフォーカストラップのロジックを、意識せずに手に入れられるのが大きな魅力です。
デザインシステムを構築中で、既に確立されたスタイルガイドがある場合は、React Ariaのコンポーネントをラップして自社用のコンポーネントライブラリを作るという使い方も相性が良いでしょう。振る舞いはReact Ariaに任せ、見た目だけを自社ブランドに合わせて実装できます。
まとめ
React Ariaは、アクセシビリティ対応という「正しく作るのが難しく、後回しにされがちな部分」をライブラリに委ねられる点が最大の価値です。スタイルには一切干渉しないため、既存のデザインシステムやTailwind CSSとも自然に組み合わせられます。
まずはButtonやTextFieldといったシンプルなコンポーネントから置き換えてみて、SelectやComboBoxなど複雑なUIへと徐々に適用範囲を広げていくのがおすすめです。公式サイトにはコンポーネントごとの詳細なドキュメントとサンプルコードが用意されているので、実装時にはあわせて参照してみてください。