• #Miller Columns
  • #Vue
  • #UI設計
  • #ゲーミフィケーション
  • #コンポーネント設計
  • #eurekapu
開発eurekapu-nuxt4

Miller Columns UIコンポーネントの進化

朝イチでTheaterViewerの背景色を変えたら、そこからUIの改修が止まらなくなった。気づけば、スタイル微調整から始まった作業が4カラム化、全スライドナビゲーション、進捗バー実装まで膨らみ、最後にCodexレビューで空データクラッシュを突かれて修正する羽目になった。

TheaterViewer/MillerViewerのスタイル改善

背景色をダーク系に切り替え、コンテンツ領域の余白を詰めた。ステージ上の情報密度が上がり、スライド1枚あたりの視認性が変わった。名前もTheaterViewerからMillerViewerへ変更し、Miller Columnsとしての性格を明確にした。

グループ表示のタイムライン化

グループ(セクション)の進行状況をタイムラインで表現した。

  • 未到達ステップ: + 点線
  • 現在のステップ: + 点線
  • 通過済みステップ: + 実線化 + フェードインアニメーション

通過済みが実線に切り替わる瞬間にアニメーションを入れたことで、「進んだ」という手応えが視覚に届くようになった。

question表示の分離

例題(question)をメッセージラインに混ぜていたが、ステージ上部の独立領域に移した。メッセージラインはナビゲーション情報だけに絞り、例題はスライドコンテンツの一部として扱う形に。混在していた情報が2つのレイヤーに分かれて、目の動線が整理された。

SVGテキストの直接編集

教材SVG内の「当店」を「当社」に一括置換した。SVGはXMLベースのテキストファイルなので、<text> 要素の中身をエディタで直接書き換えられる。画像編集ソフトを開かずにテキスト修正が完結した。

<!-- SVG内のテキスト要素はそのまま編集できる -->
<text x="120" y="45">当社</text>

この発見は地味だが、今後SVGの文言修正で毎回Figmaを開く手間が消える。

用語解説セクションの分割とscrollStage

元々14枚のスライドにベタ並びだった用語解説を6セクションに分割した。各セクションの境界で scrollStage: true フラグを立て、セクション切り替え時にステージを先頭までスクロールさせる。長い解説を一気に流すのではなく、区切りごとに画面がリセットされる。

4カラム化

3カラム構成だったMiller Columnsに、小カテゴリーをColumn 3として独立させて4カラムにした。

Column内容
1大カテゴリー
2中カテゴリー
3小カテゴリー(新設)
4ステージ(スライド表示)

カテゴリーの階層が深くなっても、各カラムの項目数が絞られるので選択肢が探しやすくなった。

全スライドフラットナビゲーション

矢印キー(←→)で全65スライドを横断移動できるようにした。カテゴリーの壁を越えて、1つのフラットなシーケンスとして全スライドを行き来できる。

実装のポイントは、全スライドをフラットな配列に展開しておき、現在のインデックスを ±1 するだけの単純なロジックにしたこと。カラム間の状態同期は、インデックスからカテゴリー階層を逆引きして解決した。

進捗バー(ゲーミフィケーション)

画面上部に3カラム構成の進捗バーを実装した。

  • カラムごとに色分け(大カテゴリー=青、中カテゴリー=緑、小カテゴリー=紫)
  • 通過済みセグメント: 薄色
  • 現在のセグメント: 濃色

スライドを進めるたびにバーが塗り潰されていく。65スライド中の現在地が一目でわかり、「あと何枚」が見えることで最後まで進めたくなる仕掛けになった。

アスペクト比問題の解決

スライドのアスペクト比が崩れる問題に時間を取られた。

問題: ステージ領域の高さを自動検出してアスペクト比を維持しようとしたが、ウィンドウリサイズやキャプション行数の変動で計算がずれた。

解決: 自動検出をやめて max-height 方式に切り替えた。さらにステージ全体をflex layoutにし、キャプション領域が伸縮してもスライド本体の高さが固定されるようにした。キャプションが1行でも3行でも、スライドの位置がぴくりとも動かない。

コンポーネント化

肥大化していたページコンポーネントから MillerViewer.vue を抽出した。型定義も別ファイルに分離。

  • MillerViewer.vue: 表示ロジックとUI
  • types/miller.ts: カラム・スライド・グループの型定義

ページ側はデータの取得と受け渡しだけになり、見通しが良くなった。

Codexレビューでの指摘と修正

Codexレビューで2点指摘された。

  1. 空データクラッシュ: カテゴリーデータが空配列のとき、フラットナビゲーションのインデックス計算で配列外アクセスが起きる。length === 0 のガード条件を追加。
  2. モバイルビュー: 4カラムがモバイルで横に溢れていた。768px以下ではカラムをアコーディオン形式に折りたたむレスポンシブ対応を追加。

レビュー前は「動いているから大丈夫」と思っていたが、空データという最もシンプルなエッジケースを見落としていた。

振り返り

朝の「背景色を変えるだけ」が、夜には65スライドのフラットナビゲーションと進捗バーまで育った。UIの改修は一箇所を直すと隣が気になり、連鎖的に手が伸びる。

今日の収穫で一番大きかったのは、SVGのテキストをエディタで直接書き換えられると気づいた瞬間だった。今まで毎回Figmaを起動していた作業が、sedコマンド一発に変わる。

Codexレビューで空データクラッシュを指摘されたのも収穫。「動いている=正しい」ではなく、境界値を最初に潰す習慣をつけたい。