ハコヅミを作る #14:ギアの一覧に、バッジと状態のタブを付ける

前回(#13)のおすすめ度までで、ギアに載せる情報はひととおりそろいました。今回は、それを一覧でどう見せるかの改善です。

  • メーカー名とコンテナ名を、文字ではなくバッジで出す
  • 「欲しい」「廃棄済」のギアも、タブで切り替えて見られるようにする

どちらも Notion の「今後の機能強化」に挙げていた項目(「一覧のバッジ表示」「欲しいものリスト」)です。


できあがった画面

ギア一覧。上に「所有(52)」「欲しい(3)」「廃棄済(4)」のタブ。選んでいる「所有」のタブは白く、下の白いカードとつながっている。各ギアの製品名の後ろに、メーカー名(ベージュ)とコンテナ名(淡い緑)のバッジが並ぶ

ギアの一覧(上のほうを切り出したもの)。タブは件数付き、メーカーとコンテナはバッジ

画面は、この記事の時点のコードを手元で動かして撮ったものです。データは#7で Notion から取り込んだ実際のギアに、記事用の「欲しい」ギアを3つ足しています。


バッジ(#58)

これまでは「製品名(snowpeak)[カーゴ 30L-1]」のように、メーカー名やコンテナ名を括弧付きの文字で続けていました。製品名と見分けにくく、どこまでが製品名なのか、ぱっと見て分かりません。

そこで、小さな札(バッジ)にして、色で役割を分けました。

バッジ 色 意味
メーカー 控えめなベージュ 参考の情報
コンテナ 淡い緑(primary-soft) 積み込みに関わる情報。少し目立たせる

#11で作った UI 部品の置き場(src/lib/components/ui/)に Badge を1つ足し、ギアの一覧・持ち物チェック・コンテナの中身など、メーカーやコンテナを出しているところをすべてこれに置き換えました。色はトークンだけで決めているので、配色を変えればバッジの色もいっしょに変わります。

読み上げでは「メーカー snowpeak」「コンテナ カーゴ 30L-1」のように、何の札なのかが分かるようにしています。見た目は色で区別できても、読み上げでは色が伝わらないためです。

受入確認で直したこと

受入確認で、2点の指摘がありました。

  • 角丸がもう少し角っぽいほうがよい:最初はカードと同じ角丸(0.5rem)にしていました。バッジは小さいので、同じ半径だとほぼ楕円に見えます。0.375rem に変えました
  • プランの画面だけ、メーカー名が出ていない:プランの登録・編集画面のギアの選択肢に、メーカーのバッジを付け忘れていました

2つ目は、Issue の AC にはきちんと書いてあったのに、実装で抜けたものです。プランの画面は、もともとコンテナ名しか出していませんでした。そのため「今出している文字をバッジに置き換える」形で直すと、もともと出していないメーカーは抜けてしまいます。E2E もコンテナのバッジしか確かめていなかったので、テストは通っていました。受入確認で画面を見てもらう意味が、よく分かる例でした。


状態のタブ(#61)

ギアには「所有」「欲しい」「廃棄済」の状態があります。これまでの一覧は「所有」だけを出していて、欲しいものや手放したギアは、登録したあとで見る方法がありませんでした。

一覧の上にタブを置き、/gears?status=wanted のように URL で切り替える形にしました。

「欲しい(3)」のタブを選んだギア一覧。火器に「焚火台 グリルブリッジ」、宿泊に「ソリッドステーク 30」「ペグハンマー PRO.C」が並ぶ

「欲しい」のタブ。欲しいものリストとして使う

  • タブを URL で表すので、リロードしても、編集画面から戻っても、同じタブが開く
  • 決められた値以外の status が来たら「所有」にする(URL を手で書き換えられてもエラーにしない)
  • タブには件数を出す。どのタブにギアがあるか、開く前に分かる

Notion の構想では「欲しいものリスト:購入後はギアの方に自動登録される」と書いていました。ハコヅミでは欲しいものも gears の1行なので、買ったら状態を「所有」に変えるだけで、そのまま所有のタブに移ります。最初に「欲しいものリストは別テーブルにしない」と決めておいたことが、ここで効きました。

タブとカードを「つなげる」

最初の版は、タブをボタンのように並べ、その下にカードを置いただけでした。動きは問題なかったのですが、受入確認で次の指摘がありました。

タブと下の白い背景のエリアが繋がっているようなイメージにしたい

紙のフォルダのインデックスのように、選んでいるタブと中身が1枚につながって見える形です。まず見た目のイメージを作って見てもらい、そこでもらった直し(左端にそろえる、緑の線はいらない)を入れたイメージをもう一度見てもらって、次のように決めました。

  • 選んでいるタブ:カードと同じ白。下の辺の線を消し、カードの上の線に 1px 重ねて隠す
  • 選んでいないタブ:線の色を薄く敷いたベージュ。奥に重なった紙のタブのように見せる
  • 一番左のタブは、カードの左端にそろえる。カードの左上の角は丸めない(タブからカードまで、左の線が一直線になる)
  • 最初の案にあった、選んでいるタブの上の緑の線はなくす
<a
	href={tabHref(status)}
	aria-current={data.status === status ? 'page' : undefined}
	class={[
		'rounded-t-box border border-b-0 border-line px-4 py-1.5',
		// 選んでいるタブだけ、カードの上の線に1px重ねて線を隠す(つながって見える)
		data.status === status
			? 'relative z-10 -mb-px bg-surface-raised font-semibold text-primary'
			: 'bg-line/40 text-ink-muted hover:bg-primary-soft hover:text-ink'
	]}>{GEAR_STATUS_LABELS[status]}({data.counts[status]})</a
>

ポイントは、選んでいるタブだけに付けた relative z-10 -mb-px です。タブを 1px 下にずらしてカードの上の線に重ね、手前に出します。タブの背景はカードと同じ白なので、重なった部分の線が隠れて、つながって見えます。カードのほうは rounded-tl-none で左上の角だけ丸めず、一番左のタブと左の線をそろえています。色はすべてトークンで書いているので、パレットの色を直接書かないルール(Lint でチェックしている)にも引っかかりません。

見た目の調整は、言葉だけでやりとりするとずれやすいところです。今回は「再度イメージを提示して」と頼んで、直す前に案の画像を見てから PR に反映してもらいました。1回の PR の直しで済んだのは、このおかげだと思います。


おわりに

  • メーカーとコンテナはバッジに。色で役割を分け、読み上げでは「メーカー」「コンテナ」と名前を付ける
  • 状態はタブで切り替え、URL で表す。欲しいものリストは状態を変えるだけで所有に移る
  • タブとカードは、1px 重ねて下の線を消すと、1枚につながって見える
  • 見た目の直しは、PR にする前にイメージを見て決める

どちらもテーブルの変更はないので、受入確認が済んだ時点で Issue を閉じました。次回は、チェックリストを「キャンプ」に育てる話です。

← トップページに戻る