こんにちは。小学生向けのニュースサイト、こどもニュースをつくっています。
このサイトの記事には、表示を切り替える小さなボタンが並んでいます。ふりがなの有無、文字の大きさ、書体、縦書きか横書きかです。
読者は小学生なので、UI は分かりやすくしたいところです。トグルボタンの見せ方で少し試行錯誤しました。
現在値だけを出すと分からない
最初は、いまの状態だけを表示していました。「かなあり」と書かれたボタンです。
小学生に使ってもらうと、押されませんでした。押すと何が起きるか分からないからです。
「かなあり」と書いてあるボタンは、押すと「かなあり」になるのか、「かなあり」の状態を表しているのか、どちらとも読めます。大人でも迷います。
選択肢を全部出す
そこで、選択肢を全部並べることにしました。選択中を通常サイズで、他を小さく灰色で表示します。
かなあり なし
太い文字が現在の状態、薄い文字が押したときになる状態です。1 つのボタンの中に両方が入っています。
/** 全選択肢を固定順で並べ、選択中だけ通常サイズ・他は小さくグレーで示す。
* 表示位置が固定なので、切替してもラベルが並び替わらない。
* 選択中の span には .kn-opt-selected を付ける(E2E の契約にも使用)。 */
export function OptionsLabel({ options, selected }: { … }) {
return (
<>
{options.map(option => (
<Box
component="span"
className={option.value === selected ? 'kn-opt-selected' : undefined}
sx={{
…
...(option.value === selected ? {} : { fontSize: '.74rem', color: 'text.disabled' }),
}}
>
{option.label}
</Box>
))}
</>
);
}
選択中かどうかで、フォントサイズと色を変えるだけです。
並びが変わらないようにする
ここで気をつけたのが、押しても順序が変わらないことでした。
素朴に実装すると、「選択中を先頭に出す」としたくなります。そうすると、押すたびにラベルが入れ替わります。同じ位置を続けて押すと、目が追いつきません。
順序を固定すると、押しても位置が変わりません。太字の位置が左右に移るだけです。何が起きたかが直感的に分かります。
ただし、状態によって並びを変えている箇所もあります。
options={kanaGrade === 'off'
? [{ value: 'off', label: 'かななし' }, { value: 'all', label: 'あり' }]
: [{ value: 'all', label: 'かなあり' }, { value: 'off', label: 'なし' }]}
これは並び替えではなく、ラベルの文言を変えています。選択中の側に「かな」という語を付けて、何の設定かが分かるようにしています。選択中は必ず先頭に来る形なので、位置は動きません。
幅を固定する
もう 1 つ、ボタンの幅が変わらないようにしています。
// ボタン幅はラベル幅基準(余り幅は均等配分)
'& > button': {
flex: '1 1 auto',
},
文字数が変わると幅が変わり、隣のボタンの位置も動きます。押したいボタンが動くのは、UI として最悪です。
flex の伸縮で、余った幅を均等に配分しています。ラベルの長さが多少変わっても、全体としては同じ位置に収まります。
選択肢が多いときは別の形にする
この見せ方が使えるのは、選択肢が 2〜3 個までです。
ふりがなの設定は、後から学年別(1〜6 年)の選択肢が加わりました。8 択になるので、全部を並べることはできません。
そこは、ボタンの隣に小さな三角のボタンを足して、メニューで選ぶ形にしました。ボタン自体は「すべてふる / ふらない」のトグルのままです。
return (
<Box component="span" className="kn-opt-selected" …>
{`かな${kanaGrade}年`}
</Box>
);
学年が選ばれているときは、選択肢を並べずに現在値だけを出します。8 択の一部だけを見せても意味がないからです。
同じコンポーネントで、選択肢の数によって見せ方を変えます。UI の一貫性は保ちつつ、無理のない範囲で全選択肢を見せています。
テストで契約にする
選択中の要素には、クラスを付けています。
選択中の span には .kn-opt-selected を付ける(E2E の契約にも使用)。
E2E からは、このクラスで選択中の値を取ります。表示テキストで判定すると、ラベルの文言を変えたときに落ちます。
「見た目の状態」をテストから確認したいときは、そのための目印を明示的に付けておくのが安定します。スタイル(太字かどうか)で判定するのは避けました。計算されたスタイルは環境で変わりうるためです。
まとめ
- 現在値だけを出すトグルは、押すと何になるか分からない
- 選択肢を全部並べて、選択中だけ通常サイズにすると、状態と行き先が同時に分かる
- 押しても並びが変わらないよう、順序は固定する。動くと目で追えない
- ボタンの幅も固定する。押したい対象が動かないようにする
- 選択肢が増えたら別の形(メニュー)に逃がす。無理に全部を並べない
- 選択中の目印をクラスとして付け、テストはそれを見る