`<wa-textarea>` に文字数カウント機能を追加
<wa-textarea> に with-count 属性が追加され、テキストエリア下部に入力済み文字数または残り文字数を表示できるようになりました。スクリーンリーダー対応のライブリージョンと25言語以上の翻訳を含む、アクセシビリティファーストな実装です。
背景
文字数制限付きフォームにおける文字数カウンターは、ユーザーが自分で文字数を数えなければならない maxlength のネイティブ動作に比べて、はるかに優れたUXを提供します。#573 でこの機能が要望されており、文字数制限のあるフォームでカウンターを表示したいというニーズへの対応です。
Issue #573では「文字数制限があるフォームにカウンター機能があると非常に便利」という要望が寄せられており、今回のPRはその要望を受けた実装です。
技術的な変更
with-count 属性と LocalizeController の導入により、文字数表示とアクセシビリティ対応が実現されています。
textarea.ts では、with-count プロパティの追加とともに、LocalizeController をインポートして翻訳キー numCharacters / numCharactersRemaining を使ってカウントテキストを生成します。maxlength が設定されている場合は残り文字数(maxlength - value.length)を表示し、設定されていない場合は入力済み文字数(value.length)を表示します。
アクセシビリティのために announcedCountText という @state() プロパティと countAnnounceTimeout によるデバウンスが導入されています。ユーザーが入力するたびに即座にライブリージョンを更新するのではなく、一定時間後に遅延アナウンスすることで、スクリーンリーダーが過剰に読み上げるのを防いでいます。視覚的な表示と読み上げ用テキストを分離し、後者は visuallyHidden スタイルで非表示にした要素に格納しています。
スタイル面では textarea.styles.ts に .footer クラスが追加されました。ヒントと文字数カウンターを横並びに配置するレイアウトです。
.footer {
display: flex;
align-items: baseline;
gap: 1em;
}
.footer.has-count [part='hint'] {
flex: 1 1 auto;
min-width: 0;
}
.count {
flex: 0 0 auto;
color: var(--wa-form-control-hint-color);
font-weight: var(--wa-form-control-hint-font-weight);
line-height: var(--wa-form-control-hint-line-height);
margin-block-start: 0.5em;
font-size: var(--wa-font-size-smaller);
margin-inline-start: auto;
}
ヒントが存在する場合、.has-count [part='hint'] に flex: 1 1 auto が適用され、ヒントテキストが利用可能なスペースを占有します。カウンター(.count)は flex: 0 0 auto で幅を固定し、margin-inline-start: auto によって右端に配置されます。カウンターのフォントスタイルはヒントと同一のCSS変数(--wa-form-control-hint-color など)を使用しており、視覚的な一貫性が保たれています。
翻訳ファイルには numCharacters と numCharactersRemaining の2つのキーが25言語以上に追加されました。言語ごとに複数形のルールが丁寧に実装されており、たとえばアラビア語(ar.ts)では0・1・2・3〜10・11以上の5段階、ロシア語(ru.ts)やポーランド語(pl.ts)では mod10/mod100 を用いたスラブ語族特有の複数形ロジックが組み込まれています。
設計判断
視覚表示とスクリーンリーダーへのアナウンスを分離した設計が採用されています。
[part='count'] として公開されたカウンター要素は視覚的なカウント表示を担い、別途 visuallyHidden な要素がライブリージョンとして機能します。視覚的なカウントをそのままライブリージョンに使う実装も考えられますが、デバウンスによる遅延アナウンスとの分離により、「表示はリアルタイム・読み上げは適切な頻度」という挙動を実現しています。
カウンターのスタイルにはコンポーネント固有の値ではなく、ヒントと共通の --wa-form-control-hint-* CSS変数が使われています。これにより、ヒントとカウンターの外観をテーマレベルで一括制御でき、コンポーネントの設定値を増やさずに済むトレードオフが選択されています。
まとめ
with-count 属性の追加は単純な文字数表示にとどまらず、スクリーンリーダー対応・多言語複数形ロジック・フレキシブルレイアウトを包含した実装です。ヒントとカウンターを同一フッター領域に共存させながら、翻訳システムに乗ることで25言語以上の即時対応を達成しており、コンポーネントの国際化基盤の成熟度が改めて示されています。