refactor: improve plan mode UX with composer-integrated toggle and guidance text

- Move plan mode toggle from pills row to composer send button area
- Plan toggle sits next to the send button as a mode switch icon
- Send button turns emerald when plan mode is active
- Add mode indicator strip below composer when plan mode is on
- Replace 'Implement this plan' auto-send button with instructional
  guidance text that tells the user to send a follow-up message
- Keep Dismiss button to clear the plan review banner

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
David Kaya
2026-03-26 23:46:04 +01:00
co-authored by Copilot
parent 231be36e6c
commit b670680a7d
2 changed files with 63 additions and 73 deletions
+55 -47
View File
@@ -130,12 +130,6 @@ export function ChatPane({
void onSend(content);
}
function handleImplementPlan() {
if (!pendingPlanReview) return;
onDismissPlanReview?.();
void onSend('Implement the plan.');
}
function handleDismissPlan() {
onDismissPlanReview?.();
}
@@ -399,7 +393,6 @@ export function ChatPane({
<div className="mb-3">
<PlanReviewBanner
onDismiss={handleDismissPlan}
onImplement={handleImplementPlan}
planReview={pendingPlanReview}
/>
</div>
@@ -426,22 +419,6 @@ export function ChatPane({
onUpdate={onUpdateSessionApprovalSettings}
/>
)}
{onSetInteractionMode && (
<button
aria-pressed={isPlanMode}
className={`inline-flex items-center gap-1 rounded-lg border px-2.5 py-1 text-[11px] font-medium transition ${
isPlanMode
? 'border-emerald-500/40 bg-emerald-500/15 text-emerald-300 hover:bg-emerald-500/25'
: 'border-zinc-700 text-zinc-400 hover:border-zinc-600 hover:text-zinc-300'
}`}
disabled={isComposerDisabled}
onClick={() => onSetInteractionMode(isPlanMode ? 'interactive' : 'plan')}
type="button"
>
<ClipboardList className="size-3" />
Plan
</button>
)}
{primaryAgent && (
<div className="ml-auto flex items-center gap-2">
<InlineModelPill
@@ -521,32 +498,63 @@ export function ChatPane({
: 'Message...'
}
>
<button
className={`absolute bottom-2 right-2 flex size-8 items-center justify-center rounded-lg transition ${
isSessionBusy
? 'bg-red-600/80 text-white hover:bg-red-500'
: canSubmitInput
? 'bg-indigo-600 text-white hover:bg-indigo-500'
: 'bg-zinc-800 text-zinc-600'
}`}
disabled={!canSubmitInput && !isSessionBusy}
onClick={() => {
if (isSessionBusy) {
onCancelTurn?.();
} else {
composerRef.current?.submit();
}
}}
type="button"
aria-label={isSessionBusy ? 'Stop generating' : 'Send message'}
>
{isSessionBusy ? (
<Square className="size-3.5" fill="currentColor" />
) : (
<ArrowUp className="size-4" />
<div className="absolute bottom-2 right-2 flex items-center gap-1">
{/* Plan mode toggle */}
{onSetInteractionMode && !isSessionBusy && (
<button
aria-label={isPlanMode ? 'Switch to interactive mode' : 'Switch to plan mode'}
aria-pressed={isPlanMode}
className={`flex size-8 items-center justify-center rounded-lg transition ${
isPlanMode
? 'bg-emerald-600/20 text-emerald-400 hover:bg-emerald-600/30'
: 'text-zinc-500 hover:bg-zinc-800 hover:text-zinc-300'
}`}
disabled={isComposerDisabled}
onClick={() => onSetInteractionMode(isPlanMode ? 'interactive' : 'plan')}
type="button"
>
<ClipboardList className="size-3.5" />
</button>
)}
</button>
{/* Send / Stop button */}
<button
className={`flex size-8 items-center justify-center rounded-lg transition ${
isSessionBusy
? 'bg-red-600/80 text-white hover:bg-red-500'
: canSubmitInput
? isPlanMode
? 'bg-emerald-600 text-white hover:bg-emerald-500'
: 'bg-indigo-600 text-white hover:bg-indigo-500'
: 'bg-zinc-800 text-zinc-600'
}`}
disabled={!canSubmitInput && !isSessionBusy}
onClick={() => {
if (isSessionBusy) {
onCancelTurn?.();
} else {
composerRef.current?.submit();
}
}}
type="button"
aria-label={isSessionBusy ? 'Stop generating' : isPlanMode ? 'Send as plan request' : 'Send message'}
>
{isSessionBusy ? (
<Square className="size-3.5" fill="currentColor" />
) : (
<ArrowUp className="size-4" />
)}
</button>
</div>
</MarkdownComposer>
{isPlanMode && !isSessionBusy && (
<div className="flex items-center gap-1.5 px-3 pb-1.5 pt-0.5">
<div className="size-1.5 rounded-full bg-emerald-500" />
<span className="text-[10px] font-medium text-emerald-400/80">
Plan mode the agent will propose a plan instead of implementing
</span>
</div>
)}
</div>
</div>
</div>