TextFieldについて - React Ariaの実装読むぞ
こんにちは、フロントエンドエンジニアの mehm8128 です。
今日は TextField について書いていきます。
使用例
ドキュメントからそのまま取ってきています。
function TextField(props: AriaTextFieldProps) {
let { label } = props;
let ref = React.useRef(null);
let {
labelProps,
inputProps,
descriptionProps,
errorMessageProps,
isInvalid,
validationErrors,
} = useTextField(props, ref);
return (
<div style={{ display: "flex", flexDirection: "column", width: 200 }}>
<label {...labelProps}>{label}</label>
<input {...inputProps} ref={ref} />
{props.description && (
<div {...descriptionProps} style={{ fontSize: 12 }}>
{props.description}
</div>
)}
{isInvalid && (
<div {...errorMessageProps} style={{ color: "red", fontSize: 12 }}>
{validationErrors.join(" ")}
</div>
)}
</div>
);
}
本題
WAI-ARIA はこちらです。
フィールドの a11y とバリデーション
React Aria ではフィールド系のコンポーネントにはラベルに加えて説明文とエラーメッセージを紐づけることができます。
説明文を入れている要素にはdescriptionProps
を、エラーメッセージを入れている要素にはerrorMessageProps
を渡すことで、useField
によって生成されている id を用いてaria-describedby
でテキストフィールドに紐づけることができます。
また、 React Hook Form などのライブラリと一緒に使うこともでき、そのバリデーション結果のエラーメッセージを、errorMessageProps
を渡している要素に入れることで紐づけます。
エラーメッセージにはaria-errormessage
が使われることもありますが、aria-errormessage
は現状スクリーンリーダーによっては上手く読み上げられないことがあるため、用いられていないようです。
aria-multiline
WAI-ARIA を見てみます。
NOTE の欄には、1 行のテキストフィールドであるinput
要素は Enter キーを押すとデフォルトではフォームが送信されるけど、複数行であるtextarea
要素は改行されるだけなので、それを区別するためにaria-multiline
があるという話が書かれています。
aria-multiline
をtrue
にするとスクリーンリーダーでは「複数行」という読み上げがされるので、それによって Enter を押したときにすぐに送信されてしまうか、改行されるだけかという判断がつく、という話だと理解しました。
ただ、複数行のときにはちゃんとtextarea
要素を使っていれば自動でaria-multiline="true"
の挙動になってくれるので、RTE を触るときなどに気にすることになりそうです。React Aria のuseTextfield
では下に載せたコードの部分でinput
かtextarea
要素のみを受け入れるようにしているので、実装に明示的に含まれてはいませんでした。
inputMode
input
要素にはtype
属性があり、単純な TextField ならtype="text"
、チェックボックスならtype="checkbox"
、数値ならtype="number"
など、用途に応じて指定することで入力フィールドの見た目や機能が変わったり、モバイル時に仮想キーボードが変化したりします。例えばtype="number"
だと、数字(と一部の記号)だけの仮想キーボードになります。スマホでロック画面解除のパスワードを入力するような画面を想像してもらうと分かりやすいと思います。
しかし、例えば郵便番号は数字だから数字を入力しやすいようにtype="number"
にしよう、というのは間違いです。デフォルトでtype="number"
には+/-ボタンのスピナーがつくのですが、郵便番号は数字を増減させて操作するタイプのものではないからです。
こういう場合に、type
属性ではなくてinputMode
を利用します。
inputMode
は、入力フィールドの見た目や機能を変えずに、仮想キーボードのみを変化させるためのものです。例えばtype="number"
のときに表示される仮想キーボードと同じものを表示させるには、inputMode="numeric"
を指定します。つまり、郵便番号の場合にはtype="text"
でinputMode="numeric"
を指定するのが適切だと考えられます。
それ以外にもtype="email"
のときに出てくる仮想キーボードはinputMode="email"
で表示できるなど、いくつかの種類があります。詳しくは下のリンクから HTML Standard をご覧ください。
ちなみにinputMode
は明日の記事でも登場します。
まとめ
明日の担当は @mehm8128 さんで、 NumberField についての記事です。お楽しみにー
Discussion