Skip to content

fix: 質問ダイアログの選択肢ラベル・説明を折返して全文表示する - #76

Merged
takecchi merged 1 commit into
mainfrom
codiva/task-10
Jul 31, 2026
Merged

fix: 質問ダイアログの選択肢ラベル・説明を折返して全文表示する#76
takecchi merged 1 commit into
mainfrom
codiva/task-10

Conversation

@takecchi

Copy link
Copy Markdown
Owner

概要

セッションで質問(AskUserQuestion)が出たとき、選択肢のラベル(左側の文字)が長いと途中で途切れて読めない問題を修正しました。説明文も同様に切れていたので、こちらも折返して全文出すようにしています。

原因

ラベルと説明を同じ行(row の Box)に 2 つの <Text> として並べていたため、幅が足りないと Yoga が両方を縮め、ラベルも説明も途中で切り捨てられていました。

直し方

ログ描画(core/scroll.tslogLines)と同じ方針に揃えました。

  • core/choice-lines.ts(新規・純粋): 選択肢 1 件(ラベル + 説明)を、表示幅(CJK/絵文字は 2 セル)ベースで物理行へ展開。継続行は prefix(, ❯ [x] )の表示幅ぶん字下げしてラベルの桁に揃える。説明はさらに 2 セル深く字下げ。
  • core/layout.ts: dialogContentWidth(columns) を追加(ビューの padding + 枠 + ダイアログの paddingX = 6 セルを引く。極端に狭い端末で縦に爆発しないよう下限あり)。
  • ui/choice-row.tsx(新規・共有 presentational): 1 行 1 <Text> で描画(ラベル行はカーソル色、説明行は dim)。質問ダイアログと /model のモデル選択の両方で使用。
  • ツール許可ダイアログの入力要約(JSON 先頭 200 文字)も 1 行切り詰めから折返しへ。
  • ダイアログの枠に flexShrink={0}: 縦が足りないときに縮んで潰れる役は、内部スクロールを持つログ/一覧に任せる。

表示例(80 桁)

 ╭────────────────────────────────────────────────────────────────────────────╮
 │ 質問 (1/1) 永続化方式のとても長いヘッダー文字列です                        │
 │ どの方式で永続化しますか?                                                 │
 │                                                                            │
 │ ❯ SQLite に移行して state.json を廃止する(かなり長いラベルの選択肢)      │
 │     better-sqlite3 を追加し、セッションのメタデータをテーブルに持つ。復元  │
 │     は SELECT だけで済むが、ネイティブ依存が増えるので配布サイズと初回イン │
 │     ストールが重くなる。                                                   │
 │   JSON のまま                                                              │
 │     今の state.json を維持する。実装コストはゼロ。                         │
 │   自分で入力する                                                           │
 │                                                                            │
 │ ────────────────────────────────────────                                   │
 │   これについて相談する                                                     │
 │                                                                            │
 │ ↑↓: 選択 ・ Enter: 決定                                                    │
 ╰────────────────────────────────────────────────────────────────────────────╯

テスト

  • core/choice-lines.spec.ts(新規・テーブルドリブン): 折返し・字下げ・表示幅(日本語)・改行入り説明・説明なし・極端に狭い幅
  • core/layout.spec.ts: dialogContentWidth の段階(下限含む)
  • ui/permission-dialog.spec.tsx: 長いラベル/説明が 1 文字も欠けないX×150 / Y×260 の出現数を数える)、説明がラベルの次の行に字下げして出る
  • ui/model-select.spec.tsx: 長い説明が切り詰められない
  • npm run lint / npm run typecheck / npm test / npm run build
  • 実端末での体感確認(TTY + Claude 認証が必要なためユーザーにお願いします。80 桁・24 行など狭い端末での見た目)

補足: tests/update.test.tsx は本 PR とは無関係に元々タイミング依存で不安定です(変更前の tree でも再現)。単体で回すと通ります。

セッションの質問(AskUserQuestion)ダイアログで、選択肢のラベルと説明を
同じ行(row の Box)に並べていたため、Yoga が両方の <Text> を縮めて長い
文言が途中で切れて読めなくなっていた。

- `core/choice-lines.ts` を追加: 選択肢 1 件を表示幅ベースで物理行へ展開する
  純関数(継続行は prefix の幅ぶん字下げしてラベルの桁に揃える)。
- `core/layout.ts` に `dialogContentWidth(columns)` を追加: 枠・パディングを
  引いた本文幅(極端に狭い端末向けに下限あり)。
- `ui/choice-row.tsx` を追加(共有 presentational): 1 行 1 <Text> で描き、
  説明は dim。質問ダイアログとモデル選択(/model)の両方で使う。
- ツール許可ダイアログの入力要約も 1 行切り詰めから折返し表示に変更。
- ダイアログの枠に flexShrink={0}: 縦が足りないときに縮んで潰れる役は
  内部スクロールを持つログ/一覧に任せる。
@takecchi
takecchi merged commit 7fd9267 into main Jul 31, 2026
1 check passed
@takecchi
takecchi deleted the codiva/task-10 branch July 31, 2026 00:51
takecchi added a commit that referenced this pull request Jul 31, 2026
docs/ARCHITECTURE.md の core ファイル一覧で #76 の choice-lines.ts と
本 PR の composer-layout.ts を両方残す形でコンフリクトを解消。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant