Slide 1

Slide 1 text

React Aria で実現する次世代の アクセシビリティ まっつー / @ryo_manba 2024/09/07 Web Developer Conference 2024

Slide 2

Slide 2 text

自己紹介 まっつー ● サイボウズ フロントエンドエンジニア ● NextUI チームメンバー ● React Aria コントリビューター ● 𝕏: @ryo_manba ● GitHub: @ryo-manba 2

Slide 3

Slide 3 text

This Talk React Aria のドキュメントやブログ記事、ソースコードを ベースに React Aria の特徴や活用方法を解説。 実際に業務で利用して得られた知見や課題についても話しま す。 3

Slide 4

Slide 4 text

ウェブアクセシビリティとは ● 利用者の障害の有無や年齢、利用環境にかかわらず、 あらゆる人々が情報にアクセスし利用できること ● サポート例 ○ 色覚に配慮した色を利用する ○ キーボードだけで操作できる ○ 画像や写真に代替テキストをつける 4

Slide 5

Slide 5 text

ウェブアクセシビリティの課題 ● リソースが足りない ○ 人手不足でアクセシビリティ対応が進められない ● 様々な企業で重複した実装をすることになる ○ 一般的なコンポーネントのセマンティクスやキーボードでの振る 舞いは、W3C の ARIA Authoring Practices Guide (APG) で指 定されている 5

Slide 6

Slide 6 text

React Aria の登場 6

Slide 7

Slide 7 text

React Aria とは ● Adobe が提供する Headless UI ライブラリ ● APG に従ってセマンティクスとキーボード操作が実装 ● モバイルや支援技術での振る舞いもサポート 7

Slide 8

Slide 8 text

React Aria の活用事例 ● Apple の iCloud で一部使用されている ● デジタル庁のデザインコンポーネントで、React Aria が 推奨されている(他に Radix UI など) ● サイボウズでも導入経験あり https://blog.cybozu.io/entry/2024/05/22/090000 8

Slide 9

Slide 9 text

Adobe (Spectrum) が提供するライブラリ ● React Aria ● React Stately ● React Aria Components ● React Spectrum ● Internationalized 9

Slide 10

Slide 10 text

Adobe (Spectrum) が提供するライブラリ ● React Aria ● React Stately ● React Aria Components ● React Spectrum ● Internationalized この3つを使う 10

Slide 11

Slide 11 text

● アクセシビリティと 振る舞いを提供 ● DOM 構造とスタイルを 自由にカスタマイズ可能 React Aria Hooks 11

Slide 12

Slide 12 text

● 各コンポーネントに特化 した状態管理を行う ● 基本は React Aria Hooks と組み合わせて 使う React Stately 12

Slide 13

Slide 13 text

13 React Stately が管理する状態に基づいて、React Aria Hooks が ARIA を設定する 押されてない 押された React Aria Hooks と React Stately の連携

Slide 14

Slide 14 text

● Hooks 内部で State をもと に ARIA を動的に設定 ● 呼び出し元では props を そのまま DOM に渡す React Aria Hooks と React Stately の連携 14

Slide 15

Slide 15 text

完全に理解した! コンポーネント作ってみよう! 15

Slide 16

Slide 16 text

DatePicker を作るぞ! 16

Slide 17

Slide 17 text

思ったより難しい... props 群はどう作用 する?一部を変えた い時はどうする? Dialog や Calendar はどこ からでてきた? 17

Slide 18

Slide 18 text

Hooks だけでは実装が大変 ● React Aria Hooks と React Stately を適切に組み合わせ て、コンポーネントを作るのはやや難易度が高い ● RadixUI や Ark UI のような Headless UI コンポーネント ライブラリのほうが気軽に使える... 18

Slide 19

Slide 19 text

React Aria Components がリリース https://react-spectrum.adobe.com/releases/2023-12-20.html 19

Slide 20

Slide 20 text

React Aria Components 20 ● React Aria Hooks と React Stately を組み合わせて構築 された Headless UI コンポーネント ● 40以上のカスタマイズを可能なコンポーネントを提供

Slide 21

Slide 21 text

課題が解決された ● React Aria Hooks: 振る舞いとアクセシビリティを提供 ● React Stately: コンポーネント特有の状態管理 React Aria Components の登場により学習難易度が高い問 題が解消される→ 基本はコンポーネントを組み合わせてスタ イルを当てるだけ 21 学習難易度が高い...

Slide 22

Slide 22 text

React Aria を使いこなす 22

Slide 23

Slide 23 text

React Aria の特徴 ● アクセシビリティ ● スタイリング ● コレクション ● フォーム ● 拡張性に優れた設計 ● 多言語対応 ● ドラッグアンドドロップ 23

Slide 24

Slide 24 text

React Aria の特徴 ● アクセシビリティ ● スタイリング ● コレクション ● フォーム ● 拡張性に優れた設計 ● 多言語対応 ● ドラッグアンドドロップ 24

Slide 25

Slide 25 text

APG は仕様ではない ● APG の目的は ARIA 1.2 の適切な仕様を説明すること ● APG のコードを本番で使用する際は各ブラウザと支援技 術の組み合わせでテストすることが望まれる 25 https://www.w3.org/WAI/ARIA/apg/practices/read-me-first

Slide 26

Slide 26 text

React Aria のテスト状況 複数のデバイスとブラウザ、スクリーンリーダーを組み合わ せてテストを実施している 26 デバイス ブラウザ スクリーンリーダー macOS Safari, Chrome VoiceOver Windows Firefox, Chrome JAWS, NVDA iOS Safari VoiceOver Android Chrome TalkBack https://react-spectrum.adobe.com/react-aria/accessibility.html

Slide 27

Slide 27 text

なぜ Adobe が力を入れているのか ● 数百を超える製品があり UI の一貫性やアクセシビリ ティ、国際化、使いやすさなど高い基準が設定されてい る ● React Aria を OSS としてコミュニティに共有し、 Web アプリケーションの水準を共に高めようとしている 27 https://react-spectrum.adobe.com/blog/introducing-react-spectrum.html

Slide 28

Slide 28 text

React Aria の特徴 ● アクセシビリティ ● スタイリング ● コレクション ● フォーム ● 拡張性に優れた設計 ● 多言語対応 ● ドラッグアンドドロップ 28

Slide 29

Slide 29 text

● Vanilla CSS, TailwindCSS, Styled Components, Panda CSS, etc.. ● Framer Motion などの JavaScript アニメーション ライブラリも使える 任意の CSS フレームワークが使用可能 29

Slide 30

Slide 30 text

● Vanilla CSS と Tailwind CSS のサンプル実装が Storybook にまとまっ ている ● ソースコードは Zip で 落とせる 充実した Starter Kits 30

Slide 31

Slide 31 text

data 属性を使ったスタイルの適用 ● :hover や :active などを data 属性で公開している ● マウス、タッチ、キーボードといった異なる操作方法で も一貫した動作を保証する 31

Slide 32

Slide 32 text

CSS 擬似クラスが問題になる例 ● :active がブラウザによって異なる ● タッチデバイスで :hover が残り続ける 32 https://github.com/whatwg/html/issues/7578 https://issues.chromium.org/issues/40364091

Slide 33

Slide 33 text

Demo https://codesandbox.io/p/sandbox/lively-sky-2d6ync 33

Slide 34

Slide 34 text

どのように解決しているか ● usePress, useHover, useFocus などの hooks で状態を管 理している ● 詳しくは Spectrum のブログを読んでみてください ○ Building a Button Part 1: Press Events ○ Building a Button Part 2: Hover Interactions ○ Building a Button Part 3: Keyboard Focus Behavior 34

Slide 35

Slide 35 text

Render props で動的にスタイルを設定 状態に応じてクラスやスタイルを動的に切り替えられる 35

Slide 36

Slide 36 text

Render props の仕組み 36 Hooks から状態 を受け取る 状態を使用して 関数を実行

Slide 37

Slide 37 text

props は各コンポーネントの docs に記載 Render props で使用できるプロパティは各コンポーネント の docs に記載されている 37

Slide 38

Slide 38 text

スタイリングのまとめ ● CSS 疑似クラスの代わりに data 属性を活用し、デバイ スやブラウザ間で一貫したスタイルを実現 ● renderProps パターンで動的にクラスやスタイルを設定 可能 ● 他に Slots や独自の CSS variables などもある 38

Slide 39

Slide 39 text

React Aria の特徴 ● アクセシビリティ ● スタイリング ● コレクション ● フォーム ● 拡張性に優れた設計 ● 多言語対応 ● ドラッグアンドドロップ 39

Slide 40

Slide 40 text

Collection の概要 ● Menu や Listbox などの複数の要素を組み合わせたコン ポーネントを一貫して扱うための JSX ベースの API ● 大規模なコレクションでもパフォーマンスが低下しない ように設計されている ● 静的コレクションと動的コレクションの2種類がある 40

Slide 41

Slide 41 text

Static Collection ● 時間の経過とともに変化しないコレクション ● メニューのようにユーザーの操作などで変更されること がないコンポーネントに使用する 41

Slide 42

Slide 42 text

Dynamic Collection ● API のレスポンスやユーザー操作など動的に変化する データを扱う ● キャッシュを元に差分があった箇所をレンダリングする 42

Slide 43

Slide 43 text

Array.map ではだめなの? 配列に変更があるたびに全体が再レンダリングされてしまう ため、パフォーマンス低下につながる 43 アイテムを追加 するごとに ListBox 全体が 再レンダリング される

Slide 44

Slide 44 text

Dynamic Collection のキャッシュの仕組み 44 WeakMap で item の レンダリング結果を キャッシュしている

Slide 45

Slide 45 text

差分があった箇所のみレンダリングされる 45 追加したアイテム のみがレンダリン グされる

Slide 46

Slide 46 text

React Aria の特徴 ● アクセシビリティ ● スタイリング ● コレクション ● フォーム ● 拡張性に優れた設計 ● 多言語対応 ● ドラッグアンドドロップ 46

Slide 47

Slide 47 text

React Aria のフォーム ● ネイティブと独自のバリデーションが利用できる ● 自動的にアクセシブルなフォームを実現する仕組みが組 み込まれている 47

Slide 48

Slide 48 text

自動でアクセシブルなフォームを実現 48 Label と Description が Input に関連付けられ、ス クリーンリーダーで正しく 読み上げられる

Slide 49

Slide 49 text

ネイティブのバリデーションが利用可能 ● ネイティブの制約検証が使用可能 ○ min/max, required, minlength/maxlength, etc. ● ブラウザのデフォルトの UI ではなく、カスタムのエラー メッセージを表示できる 49

Slide 50

Slide 50 text

カスタムバリデーション Form で使用するコンポーネントにカスタムバリデーション を組み込むことも可能 50

Slide 51

Slide 51 text

様々なライブラリと組み合わせられる React Server Actions や Remix actions, React Hook Form, Zod など様々なライブラリとの組み合わせられる 51 https://react-spectrum.adobe.com/react-aria/forms.html

Slide 52

Slide 52 text

React Aria の特徴 ● アクセシビリティ ● スタイリング ● コレクション ● フォーム ● 拡張性に優れた設計 ● 多言語対応 ● ドラッグアンドドロップ 52

Slide 53

Slide 53 text

コンテキストを利用して柔軟 に機能追加できる Context と Provider を利用した機能拡張 https://zenn.dev/cybozu_frontend/articles/react-aria-component-design 53

Slide 54

Slide 54 text

React Aria の特徴 ● アクセシビリティ ● スタイリング ● コレクション ● フォーム ● 拡張性に優れた設計 ● 多言語対応 ● ドラッグアンドドロップ 54

Slide 55

Slide 55 text

多言語対応 ● 30を超える言語のサポート ● 左右のミラーリング ● aria-label などの組み込み文字列の翻訳 ● ローカライズされた日付と数値の書式設定 55

Slide 56

Slide 56 text

DatePicker の例 ● 年月日や曜日、aria-label の文言をローカライズ ● 13種類の異なる暦システムをサポート 56

Slide 57

Slide 57 text

@internationalized/date ● 国際化サポートするにあたり、Date オブジェクトだと 難しかったため、日付操作ライブラリをフルスクラッチ で作成している ● Zag.js、Ark UI、Melt UI (Svelte)、Bits UI (Svelte)、 Kobalte (Solid) などの多くのUIライブラリで使用されて いる 57

Slide 58

Slide 58 text

余談:DatePickerの作成からブログ公開までに3年 ● DatePicker に着手していると投稿があったのが 2019年6月6日 ○ https://x.com/devongovett/status/1136402636754673664 ● DatePicker のブログを公開したのが 2022年6月21日 ○ https://react-spectrum.adobe.com/blog/date-and-time-pic kers-for-all.html 58

Slide 59

Slide 59 text

React Aria の特徴 ● アクセシビリティ ● Styling ● Collection ● Form ● 多言語対応 ● 拡張性 ● ドラッグアンドドロップ 59

Slide 60

Slide 60 text

ドラッグアンドドロップの課題 ● ブラウザ間の互換性 ○ HTML Drag and Drop API のイベントの順序や挙動がブラウザ によって異なる ● アクセシビリティへの制約 ○ キーボードとスクリーンリーダーのサポートが欠けている ● APG に記載がない 60

Slide 61

Slide 61 text

ドラッグアンドドロップの RFC が作成 ● React Ariaでドラッグアンドドロップをサポートするた めの API とインタラクションを定義 ● マウスやタッチ操作だけでなく、キーボードとスクリー ンリーダーの完全なサポートも目指す 61 https://github.com/adobe/react-spectrum/blob/main/rfcs/2020-v3-dnd.md

Slide 62

Slide 62 text

RFC を元に実装 ● マウスとタッチでは HTML Drag and Drop API を使用 し、キーボードとスクリーンリーダー向けのインタラク ションをフルスクラッチで実装 ● 13種類以上のブラウザバグの対処 ● 確立されたパターンではないため、多くの実験と試行錯 誤を経て完成した 62 https://react-spectrum.adobe.com/blog/drag-and-drop.html

Slide 63

Slide 63 text

キーボードとスクリーンリーダーで操作可能に 63

Slide 64

Slide 64 text

業務で利用してみて 64

Slide 65

Slide 65 text

どのように運用していたか ● 刷新プロジェクトで全面的に React Aria を導入 ● はじめはメンバーで勉強会を開催 ○ Collection を理解する会、拡張の仕方を学ぶ会など ● 初期は React Aria Hooks と React Stately の組み合わせ ● 途中から React Aria Components をメインで活用 65

Slide 66

Slide 66 text

大変だったこと ● 初期は React Aria hooks と React Stately を組み合わせ て作成していたため、学習コストがかかった ● React Server Components との組み合わせにも多少問題 があった(現在は改修されている) 66

Slide 67

Slide 67 text

刷新に向かないこともある ● アクセシブルなコンポーネントを実現するためにそもそ ものデザインを変えないと正しく使えないこともある ○ 例:ドラッグアンドドロップのドロップゾーンが最初に表示され ていない ● デザイン変更なしで刷新第一優先の場合だとフル活用で きない可能性もある 67

Slide 68

Slide 68 text

それでも使ってよかった ● 読み上げやキーボードサポートなどのアクセシビリティ 対応をライブラリ側に隠蔽することで本来注力したい開 発に力を入れられる ● 一般的なパターンから逸脱していないのであれば最大限 に活用できる 68

Slide 69

Slide 69 text

まとめ ● React Aria を活用することで最大限のアクセシビリティ が得られる ● すべての機能をフル活用する必要はないので、最小限で 使ってみて徐々に便利機能を導入していくと良さそう ● 開発組織が強いので今後もさらなる改善に期待 69