refactor(sidebar): レイアウト刷新と親子ハイライト#513
Conversation
intent(sidebar): repo / wt / task の視覚階層を反転 (repo を強調・wt をコンパクト) し、task は 2 行表示可能に decision(task-sort): `task.createdAt` 昇順 (append 順) — state や `lastActivityAt` のような動的キーで行位置が入れ替わる挙動を廃止し、wt / repo の append 順方針と統一 rejected(task-sort): state 優先順 (asking > working > done > idle > resumable) + `lastActivityAt` — Claude 活動ごとに行が動き空間記憶を破壊する。state は行頭アイコン、活動時刻は右端表示で既に可視化済みのため位置で二重表現する必要なし rejected(task-sort): `createdAt` 降順 (新しい順) — 新規 task 作成のたびに既存 task が 1 行下にズレるため append 順を選択 decision(wt-row): grid `[auto_1fr_auto_auto]` → flex + `flex-1` — 4 列目が空のとき phantom gap (8px) が残り status badge の右端が TaskRow の "21m" 右端より内側にズレるため decision(menu-button): wt 行の relative wrapper 内に absolute 配置 — task 行を含む article 全体を基準にすると task 追加で縦中央位置が下方にずれる decision(hierarchy): icon サイズで階層を表現 — repo `size-5` / wt `size-3.5` (size-5 wrapper で列幅は統一しラベル左端 x=28px に揃える) / task `size-5` decision(highlight): active wt header + focused task の両方を同時にハイライト — 「どの wt のどの task に focus があるか」を 2 軸で識別可能に decision(folder-icon): collapsed → `lucide--folder` / expanded → `lucide--folder-open` — git repo か否かの差分 (`folder-git-2` vs `folder`) は wt 行の branch icon と git status badge で表現済みなので repo header で重複させない constraint(padding-ssot): サイドバー横余白の責務は RepoSection の `p-2` に集約 — SidebarPane の `px-3` および section の旧 `p-1` を撤去 learned(grid-gap): CSS Grid の `gap` は track 間に常に予約される。`grid-cols-[auto_1fr_auto_auto]` で最後の auto 列が空でも gap-2 (8px) は維持され、右端コンテンツの x 座標が他の grid 構成 (3 列) とズレる原因になる
intent(sidebar): wt と task を親子構造として表現したい。task focus 時に wt 全体も同時にハイライトすることで「どの wt のどの task に focus があるか」を 2 軸で識別する
decision(highlight): article (= wt ブロック全体) に `bg-blue-500/10` の薄塗り + task active に `bg-blue-500/30` の中濃 capsule — 同色相の濃度差 (10% / 30%) で親子の階層を表現
decision(active-text): wt header / repo header の active 時文字色変更 (`text-blue-300`) を撤去 — 面塗りの濃度で active を表現済みなので文字色との二重表現は冗長
rejected(scrollbar): `scrollbar-gutter: stable` — gutter が常時インセットとして残る挙動を不採用
rejected(scrollbar): `::-webkit-scrollbar` で classic 強制 — scrollbar 用の列を常時予約する点で gutter:stable と効果が同じ
decision(scrollbar): `scrollbar-width: none` + `::-webkit-scrollbar { display:none }` で完全非表示 — macOS native の trackpad / wheel / keyboard でスクロール可能なため scrollbar UI 自体が不要、content がフル幅を保てる
decision(wt-row): `py-1` (4px) で行高をコンパクト維持 — task の `p-2` と差を付け wt は密に、task は読みやすくの非対称構成
constraint(platform): gozd は macOS 26 専用なので Windows / Linux のマウスユーザー向け scrollbar UX を考慮する必要なし
learned(tailwind-v4): `--alpha()` は Tailwind v4 の `@apply` 文脈専用で raw CSS では使えない。raw `<style>` 内で theme 変数 + 半透明を表現するなら `color-mix(in srgb, var(--color-zinc-XXX) N%, transparent)` を使う
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughこのプルリクエストはサイドバーのワークツリーカード実装を整理し、ターミナルカウント表示機能を削除してタスク表示ロジックを簡素化します。terminal モジュールから collectLeafIds エクスポートを削除し、SidebarPane と RepoSection から getTerminalCount 関連のコードを除去。WtCard ではタスクの並び順を従来の状態優先・時刻ベースから task.createdAt 昇順に変更し、関連するソートロジックを廃止。ヘッダハイライト判定を props.active のみに簡潔化し、CSS 制御を data 属性ベースに変更。あわせて TaskRow のレイアウトを flex ベースに更新し、テキスト表示とスタイルを調整します。 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
apps/renderer/src/features/sidebar/features/worktree/WtCard.vue (1)
105-158:⚠️ Potential issue | 🟡 Minor | ⚡ Quick windata 属性ベースのスタイリングに移行
Line 106-107 と Line 113-114 で
data-active属性を使用し、Tailwind のdata-[active=true]:バリアントでスタイル制御しています。Tailwind v4 では boolean data 属性バリアントがサポートされているため、この実装は正しいです。ただし、Line 106 の
data-active="active"は boolean 値を渡すべきです。🔧 data 属性に boolean 値を渡す修正案
Line 106 では
active(boolean) を直接渡していますが、明示的に boolean として扱うことを推奨します:<article - :data-active="active" + :data-active="active || undefined" class="rounded-lg transition-colors data-[active=true]:bg-blue-500/10" >Vue では
falseの場合に属性自体が削除されるため、|| undefinedを追加することで意図が明確になります。ただし、現在の実装でも動作上の問題はありません。🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/renderer/src/features/sidebar/features/worktree/WtCard.vue` around lines 105 - 158, The data-active attributes should be passed as boolean/explicit so Vue doesn't remove them when false; update both occurrences (:data-active="active" on the <article> and :data-active="headerActive" on the header div in WtCard.vue) to explicitly yield undefined when false (e.g. use active || undefined and headerActive || undefined) so the data attribute is present only when truthy and works with Tailwind's data-[active=true] variant.
🧹 Nitpick comments (1)
apps/renderer/src/features/sidebar/features/worktree/TaskRow.vue (1)
108-108: ⚡ Quick winテキストの読みやすさのため
break-wordsを検討してください。
break-allは単語の途中でも強制的に改行するため、タイトルテキストが読みづらくなる可能性があります。break-wordsを使用すると、まず単語境界で改行を試み、必要な場合のみ単語内で改行するため、より自然な表示になります。♻️ 提案する修正
- <span class="line-clamp-2 flex-1 text-sm break-all" :title="title">{{ title }}</span> + <span class="line-clamp-2 flex-1 text-sm break-words" :title="title">{{ title }}</span>🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/renderer/src/features/sidebar/features/worktree/TaskRow.vue` at line 108, Replace the hard break behavior on the title span in TaskRow.vue: the span with class "line-clamp-2 flex-1 text-sm break-all" (the element rendering :title="title" and {{ title }}) should use "break-words" instead of "break-all" so words are preferred break points and only broken when necessary; update that class list accordingly and run a quick visual check for multi-word titles to confirm improved readability.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/renderer/src/features/sidebar/features/worktree/TaskRow.vue`:
- Line 109: The timestamp span uses an extremely small fixed font class
`text-[10px]` which harms accessibility; replace that class with a slightly
larger size such as `text-[11px]` (or a Tailwind semantic size like `text-xs` /
`text-sm` if you prefer consistent design tokens) while keeping the
`tabular-nums` and `opacity-70` classes intact so the `relativeTime` rendering
remains visually subordinate but more readable.
- Line 99: Replace the use of the focus-visible:outline-none utility in the root
element's class string of TaskRow.vue with focus-visible:outline-hidden so that
the custom focus ring remains visually but accessibility in forced-colors mode
is preserved; locate the class containing "focus-visible:ring-2
focus-visible:ring-blue-500 focus-visible:outline-none" and change that token to
"focus-visible:outline-hidden".
---
Outside diff comments:
In `@apps/renderer/src/features/sidebar/features/worktree/WtCard.vue`:
- Around line 105-158: The data-active attributes should be passed as
boolean/explicit so Vue doesn't remove them when false; update both occurrences
(:data-active="active" on the <article> and :data-active="headerActive" on the
header div in WtCard.vue) to explicitly yield undefined when false (e.g. use
active || undefined and headerActive || undefined) so the data attribute is
present only when truthy and works with Tailwind's data-[active=true] variant.
---
Nitpick comments:
In `@apps/renderer/src/features/sidebar/features/worktree/TaskRow.vue`:
- Line 108: Replace the hard break behavior on the title span in TaskRow.vue:
the span with class "line-clamp-2 flex-1 text-sm break-all" (the element
rendering :title="title" and {{ title }}) should use "break-words" instead of
"break-all" so words are preferred break points and only broken when necessary;
update that class list accordingly and run a quick visual check for multi-word
titles to confirm improved readability.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: acd1aa72-93c6-4319-87f8-e4afa7c0985a
📒 Files selected for processing (5)
apps/renderer/src/features/sidebar/SidebarPane.vueapps/renderer/src/features/sidebar/features/repo/RepoSection.vueapps/renderer/src/features/sidebar/features/worktree/TaskRow.vueapps/renderer/src/features/sidebar/features/worktree/WtCard.vueapps/renderer/src/features/terminal/index.ts
💤 Files with no reviewable changes (1)
- apps/renderer/src/features/terminal/index.ts
decision(focus-ring): Tailwind v4 では `outline-none` が outline 完全削除に変わったため、forced-colors mode でフォーカス枠が消える。`outline-hidden` は視覚的に隠しつつ forced-colors 用のアウトラインを維持する v4 専用ユーティリティで、こちらに統一
概要
サイドバーのレイアウトを刷新し、repo / wt / task の視覚階層を整理しました。task の並び順を静的化、scrollbar によるレイアウト変動を撤去、wt と task の親子関係をブロック塗りで表現します。
背景
サイドバーには次の問題がありました。
py-1.5 text-xsに対し wt header がpy-2 text-smで、子要素のほうが視覚的に強いlastActivityAtを sort key にしていたため、Claude が動くたびに行位置が入れ替わり、空間記憶が壊れる (wt や repo は append 順固定なのに task だけ動的、という非対称設計)scrollbar-gutter:stableのガター幅と干渉grid-cols-[auto_1fr_auto_auto]で 4 列目が空でも track gap が予約され、status badge の右端が TaskRow の経過時刻と 8px ズレる変更内容
視覚階層の反転
py-2.5 text-sm/ iconsize-5/lucide--folder-open(展開時) /lucide--folder(折り畳み時) —folder-git-2差分はやめ、collapse 状態を icon で示すpy-1 text-xs/ iconsize-3.5(列幅はsize-5wrapper で統一) — repo よりコンパクトp-2 line-clamp-2 break-all— 2 行表示対応。経過時刻はtext-[10px]task ソートの静的化
task.createdAt昇順 (append 順) のみSTATE_PRIORITY/resolveStateKey/stateKey/baseTimeフィールドを削除lastActivityAtはTaskRowの相対時刻表示用にのみ残す (動的キーをソートで使うのを廃止し、表示用と分離)<doc>ブロックに「append 順 / 状態は icon + 相対時刻で表現」の責務分担を明記親領域ハイライト
<article>(wt ブロック全体) にdata-[active=true]:bg-blue-500/10の薄塗りTaskRowactive にbg-blue-500/30の中濃 capsuletext-blue-300) を撤去 — 面塗りの濃度で active を表現済みなので文字色との二重表現は冗長headerActiveはprops.active単体評価に変更 (旧:props.active && focusedTaskId === undefinedの排他)レイアウト精度の改善
flex-1に変更 (phantom gap 解消で右端コンテンツ x 座標が統一)absolute right-1 top-1/2で配置 — task 行を含む article 全体を基準にすると task 追加で縦中央が下方にずれるgetTerminalCountも剥がす)size-4廃止) で右端を21mと揃えるscrollbar 撤去
scrollbar-width: none+::-webkit-scrollbar { display: none }で完全非表示scrollbar-gutter: stableおよび classic 強制 (::-webkit-scrollbar { width: 10px }) は「scrollbar 列を常時予約」する点で content 幅を犠牲にするため不採用padding / gap の SSOT 化
RepoSectionのp-2に集約SidebarPane外枠flex flex-col(gap なし)RepoSection内flex flex-col(gap なし、wt ヘッダのpy-1で行高制御)gap-2(8px)その他
+ New worktreeボタンを破線ボーダーのゴーストボタン化 + 中央寄せ<dialog>確認ダイアログ内のmt-2/mb-4をflex flex-col gap-4に置換 (margin → gap)useTerminalStoreのcollectLeafIdsexport を削除 (knip 自動修正)確認事項
folder/ 展開時folder-open)+ New worktreeの hover で border / bg / text が変化