UI デザインを AI エージェントを使って模索する(その2)

ホーム画面だと要素が少ないので、カテゴリと商品注文の画面を使って模索してみる。

branch: ui-design-004

くら寿司の注文画面を作って Claude Code で作成してもらいます。

ちなみに、画面設計.md の カテゴリと商品一覧のページは次のように作られています。

## 画面 2:カテゴリ・商品一覧(`/categories`)

### 概要

メニューカテゴリの一覧と、選択カテゴリの商品一覧を表示する。カートへの追加もこの画面で行う。

### レイアウト(カテゴリ選択ビュー)

┌─────────────────────────────────────────────────────────┐
│  [← 戻る]  メニューを選ぶ           🛒 カート(3)→    │
│            (赤ヘッダー)                                  │
├─────────────────────────────────────────────────────────┤
│                                                         │
│  メニューカテゴリを選択してください                       │
│                                                         │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐               │
│  │ 握り寿司 │ │ 巻き寿司 │ │ 軍艦巻き │               │
│  │  6品     │ │  4品     │ │  4品     │               │
│  └──────────┘ └──────────┘ └──────────┘               │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐               │
│  │ 海鮮丼  │ │ 特選寿司 │ │サイドメニュー│             │
│  │  3品     │ │  4品     │ │  3品     │               │
│  └──────────┘ └──────────┘ └──────────┘               │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐               │
│  │  汁物   │ │デザート  │ │  飲み物  │               │
│  │  2品     │ │  2品     │ │  3品     │               │
│  └──────────┘ └──────────┘ └──────────┘               │
│  ┌──────────┐                                          │
│  │ 季節限定 │                                          │
│  │  2品     │                                          │
│  └──────────┘                                          │
└─────────────────────────────────────────────────────────┘

### レイアウト(商品一覧ビュー)

┌─────────────────────────────────────────────────────────┐
│  [← 戻る]  メニューを選ぶ           🛒 カート(3)→    │
├─────────────────────────────────────────────────────────┤
│                                                         │
│  握り寿司                                               │
│  ┌─────────────────────────────────────────────────┐   │
│  │ [商品画像]  まぐろ                  ¥580          │   │
│  │             旨みのある赤身          [カートに追加] │   │
│  └─────────────────────────────────────────────────┘   │
│  ┌─────────────────────────────────────────────────┐   │
│  │ [商品画像]  サーモン                ¥480         │   │
│  │             脂のりが抜群            [カートに追加] │   │
│  └─────────────────────────────────────────────────┘   │
│  ...                                                   │
└─────────────────────────────────────────────────────────┘

### UI 要素

| 要素 | 内容 | 備考 |
|------|------|------|
| ヘッダー | 赤背景、戻るボタン、カートバッジ | カート数が更新リアルタイム反映 |
| カテゴリグリッド | 3カラムグリッド | カテゴリ選択でビュー切り替え |
| 商品カード | 商品名・価格・説明・追加ボタン | 画像はプレースホルダー |
| カート追加ボタン | 赤ボタン | 押すたびに数量 +1 |

### カテゴリ一覧

| ID | カテゴリ名 | 商品数 |
|----|-----------|--------|
| 1 | 握り寿司 | 6 |
| 2 | 巻き寿司 | 4 |
| 3 | 軍艦巻き | 4 |
| 4 | 海鮮丼 | 3 |
| 5 | 特選寿司 | 4 |
| 6 | サイドメニュー | 3 |
| 7 | 汁物 | 2 |
| 8 | デザート | 2 |
| 9 | 飲み物 | 3 |
| 10 | 季節限定 | 2 |

### インタラクション

1. カテゴリカード押下 → 商品一覧ビューに切り替え
2. 「カートに追加」押下 → カートに商品追加(localStorage 更新)
3. 「←戻る」押下(商品ビュー)→ カテゴリビューに戻る
4. 「🛒 カート」押下 → `/cart` へ遷移
5. API エラー時 → ダミーデータで表示継続(エラーは無視)

律儀にカテゴリーの内容が記述してありますが、まあ、デモ画面としてはこれでよいかなと。実際は PHP で作った laravel-webapi の Web API を呼び出すので、そのコードを切り替えないといけません。

切り替え自体は、docs/openapi.yaml に OpenAPI 仕様があるので、次のプロンプトで切り替えられます。

docs/openapi.yaml の OpenAPI 仕様に従って、order-tablet のカテゴリ・商品一覧の画面を実装して

このレポジトリは web api の laravel-webapi とサンプルクライアントの order-tablet 等が混在しているので、対象となるプロジェクトを指定しないといけないのが面倒です。実際はクライアントとサーバーで別のレポジトリに分けるので、混乱は少ないと思います。
ただ、その分、設計書関係(agents/画面設計.md や 概要設計.md)が別フォルダーに配置されることになるので、このあたりのフォルダー構造は悩みどころ。

実際の Web API を呼び出して、「握り寿司」カテゴリーから商品一覧がでるようになっています。
openapi.yaml さえ作成してしまえば、クライアントサイドの lib/api.ts は AI エージェントで自動生成できるので、この部分は比較的簡単です。実際はサーバーのシステムが出来上がっていないことが多いので、なんらかのモックアップ用のサーバーを作ることになるのですが。Web API の仕様をクライアント側からチェックしたいときに使うとよいです。

branch: ui-design-005

サイゼリヤアプリのように、商品画像を表示せず、商品番号を入力する方式の画面を作ります。

src/order-tablet の 画面設計.md を対象とする。
カテゴリ・商品一覧から商品画像を削除する。
商品番号を直接入力する方式に変更。

画面設計.md にからカテゴリ一覧を削除します。

カテゴリ一覧を削除する。

トップ画面からのジャンプ先をカテゴリ一覧から商品一覧へと変更します。

ホーム画面から「カテゴリ一覧」ではなく、「商品一覧」に遷移する
商品一覧は /products とする。

このあたり、 /app/categories/page.tsx を /app/products/page.tsx に変更する形になるので、手作業だとちょっと大変なところですね。画面設計.md としては、「カテゴリ一覧」を「商品一覧」に変更してくれます。

## 画面 2:商品一覧(`/products`)

### 概要

メニューカテゴリの一覧と、選択カテゴリの商品一覧を表示する。カートへの追加もこの画面で行う。

### レイアウト(商品一覧ビュー)

┌─────────────────────────────────────────────────────────┐
│  [← 戻る]  メニューを選ぶ           🛒 カート(3)→    │
├─────────────────────────────────────────────────────────┤
│                                                         │
│  握り寿司                                               │
│  ┌─────────────────────────────────────────────────┐   │
│  │ No.001  まぐろ                          ¥580     │   │
│  │         旨みのある赤身                            │   │
│  └─────────────────────────────────────────────────┘   │
│  ┌─────────────────────────────────────────────────┐   │
│  │ No.002  サーモン                        ¥480    │   │
│  │         脂のりが抜群                              │   │
│  └─────────────────────────────────────────────────┘   │
│  ...                                                   │
├─────────────────────────────────────────────────────────┤
│  商品番号: [ No.___ ]  数量: [ 1 ]  [ カートに追加 ]    │
└─────────────────────────────────────────────────────────┘

### UI 要素

| 要素 | 内容 | 備考 |
|------|------|------|
| ヘッダー | 赤背景、戻るボタン、カートバッジ | カート数が更新リアルタイム反映 |
| カテゴリグリッド | 3カラムグリッド | カテゴリ選択でビュー切り替え |
| 商品カード | 商品番号・商品名・価格・説明 | 画像なし |
| 商品番号入力欄 | 数値入力(`No.XXX` 形式) | 画面下部に固定 |
| 数量入力欄 | 数値入力(デフォルト 1) | 1〜99 |
| カート追加ボタン | 赤ボタン | 商品番号・数量を検証してカートに追加 |

### インタラクション

1. カテゴリカード押下 → 商品一覧ビューに切り替え
2. 商品番号入力欄に `No.XXX` を入力 → 該当商品をハイライト
3. 数量入力欄に数量を入力(デフォルト 1)
4. 「カートに追加」押下
   - 商品番号が存在しない場合 → 「商品番号が正しくありません」エラー表示
   - 正常時 → カートに商品追加(localStorage 更新)、入力欄をリセット
5. 「←戻る」押下(商品ビュー)→ カテゴリビューに戻る
6. 「🛒 カート」押下 → `/cart` へ遷移
7. API エラー時 → ダミーデータで表示継続(エラーは無視)

番号の入力が、キーボードで入力できるように変更されています。

これは、番号ボタンに変えたいので、実装してから修正していきます。

コードを生成すると、カテゴリを表示した後に商品を選ぶのと、商品番号は左下で入力する方式になっているので、ちょっとイメージと違いますね。この部分は、画面設計.md で直接手作業で直したほうが早そうです。

## 画面 2:商品一覧(`/products`)

### 概要

商品を3桁の番号ボタンを使って選択する。
「注文追加」ボタンで、数量を指定するダイアログを出す。
「OK」ボタンで、カートに追加する

### レイアウト(商品一覧ビュー)

┌─────────────────────────────────────────────────────────┐
│  [← 戻る]  メニューを選ぶ           🛒 カート(3)→    │
├─────────────────────────────────────────────────────────┤
│                                                         │
│  商品番号: [ No.___ ]              
│  [ 1 ] [ 2 ] [ 3 ]
│  [ 4 ] [ 5 ] [ 6 ]
│  [ 7 ] [ 8 ] [ 9 ]
│        [ 0 ] [削除]
|
│             [注文追加]

└─────────────────────────────────────────────────────────┘

### UI 要素

| 要素 | 内容 | 備考 |
|------|------|------|
| ヘッダー | 赤背景、戻るボタン、カートバッジ | カート数が更新リアルタイム反映 |
| 商品カート | 商品番号・商品名・価格・説明 | 画像なし |
| 商品番号入力欄 | 数値入力(`No.XXX` 形式) | 画面上部に固定 |
| 数量入力欄 | 数値ボタン | 000 ~ 999 |
| 注文追加ボタン | 赤ボタン | 数量入力のダイアログを表示 |

### インタラクション

1. ホーム画面から商品一覧ビューに切り替え
2. 商品番号入力欄に `No.XXX` を入力 → 該当商品をハイライト
3. 数量入力ボタン欄に数量を入力
4. 注文追加ボタンで、数量ダイアログを表示
4. 「カートに追加」押下
   - 商品番号が存在しない場合 → 「商品番号が正しくありません」エラー表示
   - 正常時 → カートに商品追加(localStorage 更新)、入力欄をリセット
5. 「🛒 カート」押下 → `/cart` へ遷移
6. API エラー時 → ダミーデータで表示継続(エラーは無視)

まだ商品一覧表がでてきたり、なかなか狙った通りの画面になりませんが、何回かプロンプトを書き変えてできあがりまました。

できあがったら、画面設計.md も更新しておきます。

動作にあわせて 画面設計.md を修正して。

画面設計.md が書き変えられます。

## 画面 2:商品一覧(`/products`)

### 概要

数値ボタン(キーパッド)で商品番号を入力して商品を選択する。
「注文追加」ボタンで数量入力ダイアログを表示し、「OK」でカートに追加する。

### レイアウト

┌─────────────────────────────────────────────────────────┐
│  🍣 お寿司注文                       🛒 カート(3)→    │
│  テーブル: T-001                      (赤ヘッダー)     │
├─────────────────────────────────────────────────────────┤
│                                                         │
│              商品番号                                    │
│         ┌──────────────┐                               │
│         │   No.031     │  ← 入力中(一致なし: 赤枠)   │
│         └──────────────┘                               │
│         商品番号が正しくありません                        │
│                                                         │
│         ┌──────┐ ┌──────┐ ┌──────┐                   │
│         │  1   │ │  2   │ │  3   │                   │
│         ├──────┤ ├──────┤ ├──────┤                   │
│         │  4   │ │  5   │ │  6   │                   │
│         ├──────┤ ├──────┤ ├──────┤                   │
│         │  7   │ │  8   │ │  9   │                   │
│         └──────┘ ├──────┤ ├──────┤                   │
│                  │  0   │ │ 削除 │                   │
│                  └──────┘ └──────┘                   │
│                                                         │
├─────────────────────────────────────────────────────────┤
│              [ 注文追加 ]  (常に表示・赤ボタン)         │
└─────────────────────────────────────────────────────────┘

### 数量入力ダイアログ

┌──────────────────────────┐
│     数量を入力            │
│  ┌────────────────────┐  │
│  │ No.001  まぐろ      │  │
│  │        ¥150        │  │
│  └────────────────────┘  │
│  ┌────────────────────┐  │
│  │    1  個           │  │
│  └────────────────────┘  │
│  [ 1 ] [ 2 ] [ 3 ]       │
│  [ 4 ] [ 5 ] [ 6 ]       │
│  [ 7 ] [ 8 ] [ 9 ]       │
│        [ 0 ] [削除]       │
│  [ キャンセル ] [  OK  ]  │
└──────────────────────────┘

### UI 要素

| 要素 | 内容 | 備考 |
|------|------|------|
| ヘッダー | 赤背景、カートバッジ | カート数がリアルタイム反映 |
| 商品番号ディスプレイ | `No.___` 形式(最大3桁) | 一致商品あり: 赤枠・商品名と価格を表示 |
| キーパッド | 1〜9・0・削除 の数値ボタン | 削除は1桁ずつ消去 |
| 注文追加ボタン | 赤ボタン | 画面下部に常時固定表示 |
| 数量ダイアログ | 選択商品情報・数量キーパッド・OK/キャンセル | 数量0は OK 不可 |

### インタラクション

1. ホーム画面から `/products` へ遷移
2. 数値ボタンで商品番号を入力(最大3桁)
   - 一致する商品がある場合 → ディスプレイを赤枠にして商品名・価格を表示
3. 「削除」ボタン → 1桁ずつ削除
4. 「注文追加」押下
   - 商品番号が存在しない場合 → 「商品番号が正しくありません」エラー表示
   - 正常時 → 数量入力ダイアログを表示
5. ダイアログ内でキーパッドを使って数量を入力
6. 「OK」押下
   - 数量が 0 の場合 → 「数量を入力してください」エラー表示
   - 正常時 → カートに追加(localStorage 更新)・ダイアログを閉じる・入力欄リセット
7. 「キャンセル」押下 → ダイアログを閉じる
8. 「🛒 カート」押下 → `/cart` へ遷移
9. API エラー時 → ダミーデータで表示継続(エラーは無視)

このあたり、プロンプトを残しておくか、設計書として残しておくかの選択が必要なのですが、AI スパイラル開発(仮)としては、プロンプトで試行錯誤、本実装へは仕様書ベースで(設計→実装の順)ということになるので、ところどころ設計書を更新しておきます。
手書きのところががっつりと消されることもあるのですが、それは「AI が再実装できるような設計書」を作るということで AI 自身に書いて貰います。

branch: ui-design-006

今度は、商品一覧がずらっと横に並んでいるパターンを考えます。
カテゴリに分けてあるのではなくて、横に「次のページへ」で捲っていくパターンです。

画面設計.md を更新する

- カテゴリ一覧のページを削除する
- 商品一覧を、縦2 x 横3 ずつページにする。
- 「前へ」「次へ」ボタンでページをめくる
- 商品の上にカテゴリが表示される。

画面設計.md が書き換わったところで、実装を開始します。

## 画面 2:商品一覧(`/menu`)

### 概要

全カテゴリの商品を 2行×3列(6品)単位でページ表示する。各商品カードの最上部にカテゴリ名を表示する。カテゴリ選択画面は存在しない。

### レイアウト

┌─────────────────────────────────────────────────────────┐
│  [← 戻る]  メニューを選ぶ           🛒 カート(3)→    │
│            (赤ヘッダー)                                  │
├─────────────────────────────────────────────────────────┤
│                                                         │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐             │
│  │ 握り寿司 │  │ 握り寿司 │  │ 巻き寿司 │             │
│  │[商品画像]│  │[商品画像]│  │[商品画像]│             │
│  │ まぐろ   │  │ サーモン │  │ 鉄火巻き │             │
│  │  ¥580   │  │  ¥480   │  │  ¥450   │             │
│  │[カートへ]│  │[カートへ]│  │[カートへ]│             │
│  └──────────┘  └──────────┘  └──────────┘             │
│                                                         │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐             │
│  │ 巻き寿司 │  │ 軍艦巻き │  │ 海鮮丼  │             │
│  │[商品画像]│  │[商品画像]│  │[商品画像]│             │
│  │ ねぎとろ │  │ いくら  │  │ 海鮮丼  │             │
│  │  ¥420   │  │  ¥550   │  │  ¥980   │             │
│  │[カートへ]│  │[カートへ]│  │[カートへ]│             │
│  └──────────┘  └──────────┘  └──────────┘             │
│                                                         │
│        [← 前へ]    1 / 6ページ    [次へ →]             │
└─────────────────────────────────────────────────────────┘

/categoires が /menu に切り替わっているのが気になるところですが、このままいきます。

変更に従って実装して。

「前へ」「次へ」でページ送りができるようになっています。

これをもとにカテゴリが混在しないようにページを分けていきましょう。

メニューページを変更する

- カテゴリ単位で商品をページで区切る
- 画面の下部に「カテゴリー」を表示させて、カテゴリーをクリックすると商品の先頭にジャンプする

AI にうまく意図が伝わるかどうか不安だったのですが、ひとまず意図通りに動きができあがっています。

細かい動きは page/menu/page.tsx を確認することになるのですが、ここでは UI デザインの試行錯誤が目的なのでコードの内容は問わないことにします。

3つの試作を比較検討する

ここで商品表示の仕方を具体的に動かして比較してみます…と言いつつ、ブランチに分かれてしまっているので同時に動かせないのが難点なのですが。まあ、色合いは兎も角として、それぞれの画面をぽちぽちと動かしてみて、どの方式にするのかを選ぶことができます。いつもであれば、UI デザインとか全体のフォーマットを決めないとなかなか動くものが出て来ないのですが、AI エージェントを使えばそれなりのスピードで動くものが出てきます。

ただし、注意しないといけないのが

  • 動くものができたのだが、ちょっとニュアンスが違う部分をそのままにしてはいけない
  • AI が出したちょっと違ったものを「動くから、まあ、これでもいいか」と受け入れてはいけない

というのがあります。どうも、いままで実装をするまでに結構時間が掛かったので(それでも React とか Vue とかのフレームワークを使うと圧倒的に早いのですが)、細々とした UI を直す手間を開発者(私も含む)は惜しんでしまいそうになります。そういうといいは、「なんとしても、UI デザインにあわせる」という仕事的な努力が必要なのですが…そのあたりは、自分自身ではなくてデザイナーの力に頼ることになりそうですね。

おそらく、AI がデザインする UI にしても、典型的なパターンはいけそうなのですが、それ以上となると結構大変そうです。そういう意味では、HTML/CSS をこねくり回さなくても一定の画面がでてくるのが AI の良いところでもあり、それ以上に踏み込めない(デザイナーの人が AI を使ってデザインすると、変わるかも?)領域となりそうなので、この点に関しては、私はここでギブアップです。

逆に言えば、

  • そこそこ動作する画面は、AI エージェントを使って動作確認できるまではいける
  • 果たして、デザイナーが思い描いた UI デザインに AI エージェントは近づけられるのか?

という線引きがあります。ちなみに後者についていえば、経験上ですが、UI デザインに合わせるときはドット単位で手作業であわせていくのでプログラマでできないことはないです。ただし、非常に時間がかかります。なので、工数削減という意味では(あるいは、早期リリースや省力化による低価格化)前者の「AI によってそこそこ生成できる」部分と、「標準的なパーツを組み合わせて画面を構成する」という従来の画面作成のスタイルが踏襲できるといいですね。

サンプルコード

https://github.com/moonmile/webapi-sample-ai

  • branch: dev/order-tablet/ui-design-004
  • branch: dev/order-tablet/ui-design-005
  • branch: dev/order-tablet/ui-design-006

カテゴリー: 開発 パーマリンク

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

*