i18nについて - React Ariaの実装読むぞ
こんにちは、フロントエンドエンジニアの mehm8128 です。
今日は i18n について書いていきます。
React Aria の i18n
React Aria の i18n についてはこのページにまとめられています。
React Aria では主に、文字列の翻訳、日付と数値のフォーマット、RTL がサポートされています。
そしてこれらはブラウザに組み込まれている Intl
オブジェクトの各 API を利用して実装されています。
Intl については saji さんの 1 人アドベントカレンダーでまとめられているので、適宜参照しながら解説していきます。
Intl の全体像についてはこちらの記事をご覧ください。
文字列の翻訳
useLocalizedStringFormatter
を用いて現在の locale に基づいて翻訳されたテキストを取得できます。ここでは Intl は使われていません多分。
例えばuseNumberField
だと、+/-ボタンに振られているラベルが翻訳されています。
en-US.json
とja-JP.json
を見てみます。Increase
とDecrease
をそれぞれ「拡大」と「縮小」と訳すのはかなり微妙な気もするのですが、こんな感じに翻訳されています。
useLocalizedStringFormatter
関数内ではuseLocale
で現在の locale を取得し、その locale のテキストに翻訳するためのformat
メソッドを含むLocalizedStringFormatter
オブジェクトを返しています。
useColorPicker
でも、同じく翻訳用のパッケージが利用されていました。
数値のフォーマット
再びuseNumberField
の話です。useNumberField
では様々な数値のフィーマットに対応していて、ブログ記事にまとめられています。
Intl.NumberFormat
を用いて小数点や%や通貨、単位などのフォーマットをいい感じにしています。
Intl.NumberFormat
についてはここらへんの記事を読みましょう。
RTL
アラビア語など、右から左に文字を書く言語圏の locale の場合、画面内の要素もミラーリングする必要があります。
ただし、React Aria はスタイリングにまでは責任を持っていないので、React Aria は主にキーボード操作などのインタラクション部分で RTL サポートをしています。
useLocale
からdirection
というltr | rtl
の union 型の値を取得し、その値に応じてインタラクションの方向を変化させます。
例えばuseTabList
の場合、direction
をTabsKeyboardDelegate
というオブジェクトのコンストラクタに渡しています。
TabsKeyboardDelegate
はこれを受け取り、flipDirection
を定義するのに使います。flipDirection
はtrue
のときにキーボード操作を反転させます。
getKeyLeftOf
という関数では引数のkey
の 1 つ左のkey
を取得しますが、通常時(direction = ltr
のとき)は 1 つ左というのは 1 つ前のkey
ですが、flipDirection
時には 1 つ左は 1 つ次のkey
になるので(見た目がミラーリングされても ← キーを押したときには左に移動する、みたいになっています)、getNextKey
関数を使用しています。
Typeahead
useListBox
やuseGridList
、useMenu
では Typeahead が実装されています。
useListBox
の記事で軽く言及していました。が、Typeahead についての説明が抜けていたので説明すると、リストにフォーカスしているときに頭文字を入力するとその文字から始まるリストアイテムにフォーカスを移動できるというものです。
これはuseCollator
を用いて実装されていて、内部でIntl.Collator
を使っています。
Intl.Collator
についてはこちらの記事をご覧ください。
上記の 3 つの hooks で共通で使われているuseSelectableList
では、ここでuseCollator
を用いてcollator
を取得し、ListKeyboardDelegate
オブジェクトのコンストラクタに渡しています。
ListKeyboardDelegate
はこれを受け取り、getKeyForSearch
でリストアイテムの検索に用いてます。
日付のフォーマット
日付も地域によって様々なフォーマットがあるので、フォーマットされています。詳しくは明日の記事で書いたり書かなかったりするのですが、useDateFormatter
という hook が提供されていて、その中でIntl.DateTimeFormat
を利用しています。
useDateSegment
ではここらへんで使われています。
日付についての公式ブログ記事はこちらです。
Intl.DateTimeFormat
についてはここらへんの記事を読むといいです。
まとめ
明日の担当は @mehm8128 さんで、DateField についての記事です。お楽しみにー
Discussion