こんにちは!DOGO プロジェクトでソフトウェアエンジニアとして活動している @nissy_dev です。
DOGO プロジェクトでは、React Aria を活用してアクセシビリティの改善を行っています。
今回の記事では、React Aria を国内にもっと広めて行きたいということで、React Aria を利用することに決めた理由を振り返りつつ、React Aria について簡単に紹介します。
目次
OSS を活用した効率なアクセシビリティの改善
DOGO プロジェクトでは、フロントエンドの刷新を進めていく中でアクセシビリティの改善についても取り組んでいます。 具体的な事例などについては、次の記事も参考にしてもらえればと思います。
各画面のアクセシビリティを改善するには、画面を構成するコンポーネントのアクセシビリティが重要になりますが、アクセシブルなコンポーネントをフルスクラッチで実装するには非常にコストがかかります。 たとえば、リストボックスのようなコンポーネントでは、アクセシビリティのために次のような考慮が必要となります。
- ESC キーや Enter キーなどによる操作
- カーソルキーでの選択の切り替え
- フォーカス制御
- スクリーンリーダーによる読み上げ
スクリーンリーダーなどの支援技術のサポートに重要な WAI-ARIA に関しては、ARIA Authoring Practices Guide (APG) の Read Me First に "No ARIA is better than Bad ARIA" とあるように、誤って使うことで何も設定しないよりも悪影響を及ぼしてしまう可能性があります。 APG の Patterns を参考に実装するとしても一筋縄ではいきません。
これらのコストと DOGO チームに所属するエンジニアは 5 名程度なこともふまえて、OSS のライブラリを活用することに決定しました。
ライブラリの選定
DOGO では基本的に既存の画面の見た目を変えないで刷新を行う方針をとっているため、スタイルを柔軟に変更できる点が重要です。 機能やアクセシビリティのみを提供し、スタイルをもたない Headless UI ライブラリに着目して、次の 4 つのライブラリを検討しました。
Headless UI や Radix は、DatePicker のような複雑な UI パーツが提供されていない点を考慮して採用を見送りました。 Ark UI は、検討時 (2023 年の9月) においてバージョンが 0.1.0 であり、安定性を考慮して採用を見送りました。
React Aria については、Adobe によって安定して開発が行われており、DatePicker のような複雑な UI パーツを提供している点が採用の決め手となりました。 モバイル端末などのマルチデバイス対応やコンポーネント単位で多言語対応が組み込まれてる点についても好印象でした。 Button コンポーネントの実装だけで 3 つのブログを公開してたことからも力の入れ具合が伝わってきます。
- Building a Button Part 1: Press Events – React Spectrum Blog
- Building a Button Part 2: Hover Interactions – React Spectrum Blog
- Building a Button Part 3: Keyboard Focus Behavior – React Spectrum Blog
React Aria の概要
React Aria は、アクセシブルなコンポーネントを実装するためのライブラリとして次の 4 つを提供しています。
react-aria
(@react-aria/xxx
)- アクセシビリティを考慮したコンポーネントの振る舞いに関する React Hooks の実装
- キーボード操作などもこのライブラリが提供する Hooks を利用して実装できる
react-stately
(@react-stately/xxx
)- コンポーネントの状態管理に関する React Hooks の実装
- Web だけでなく、他のプラットフォーム向けにも利用できる
react-aria-components
- react-aria と react-stately を組み合わせた Headless UI ライブラリ
@adobe/react-spectrum
- Adobe の Design System の実装
React Aria では、デザインシステム間における実装の再利用性を高めるために、それぞれのコンポーネントからデザインシステムに依存しない共通の振る舞いや状態管理をそれぞれ react-aria や react-stately の形で切り出しています。この観点については、次の「Architecture」のページに詳しく書かれているので、利用を考えている場合は一度読んでおくことをおすすめします。
今回検討した他のライブラリと比較しても、react-aria
や react-stately
を使ってユーザー側で柔軟にカスタマイズできる点は大きな特徴になっています。
一方で、カスタマイズには学習コストもかかることから、DOGO では主に react-aria-components
を利用しつつ、必要に応じて react-aria
や react-stately
が提供する React Hooks も利用するようにしています。
React Aria のより詳しい概要については、Nihonbashi.js という勉強会で同じチームのまっつー(@ryo-manba)が登壇したときのスライドも参考にして貰えればと思います。
Next.js App Router との相性
DOGO では、Next.js の App Router を使って刷新を行っています。
React Aria Components を使う際は、利用するコンポーネントが基本的に Client Components である必要がありますが、hooks と一緒にフォーム内の UI パーツなどで使う場面が多く困ってないのが現状です。
<Link>
コンポーネントのように Next.js 側が提供しているコンポーネントを利用する場合にも、先述の react-aria
や react-stately
を組み合わせた独自の Wrapper コンポーネントを用意することで、期待するアクセシビリティを実現できています。
以前は tree shaking が効かない問題や一部のコンポーネントが React Server Components で利用できない問題などもあったようなのですが、これらは着実に解消されています。 Server Actions との連携も進んでおり、App Router との使い勝手も非常に考えられているライブラリだと思います。
終わりに
今回の記事では、DOGO プロジェクトで React Aria を選定した理由を振り返りつつ、React Aria についての簡単な紹介を行いました。 React Aria は、最近だと Apple の iCloud など身近な製品でも利用されているようです。
DOGO でも React Aria を採用してから半年以上が経過し、実際にアクセシビリティの改善ができた事例もいくつかあるので、今後もブログで発信していくつもりです。 また、こちらの記事と合わせて以前 DOGO のチームメンバーが書いた、React Aria に関する次の記事も合わせてご覧ください。