diff --git a/packages/ui/src/components/chat/PendingChangesBar.tsx b/packages/ui/src/components/chat/PendingChangesBar.tsx index 55c60c8e..5ef7ab55 100644 --- a/packages/ui/src/components/chat/PendingChangesBar.tsx +++ b/packages/ui/src/components/chat/PendingChangesBar.tsx @@ -88,6 +88,8 @@ export const PendingChangesBar: React.FC = React.memo(() => { if (!currentDirectory) return; if (!isGitFile(file)) return; + setIsExpanded(false); + const absolutePath = file.path; // Dedicated mobile root: open the per-file diff inside the mobile Changes surface. @@ -96,7 +98,6 @@ export const PendingChangesBar: React.FC = React.memo(() => { diffPath: file.relativePath, staged: file.hasStagedChanges && !file.hasWorkingChanges, }); - setIsExpanded(false); return; } diff --git a/packages/ui/src/components/layout/ContextPanel.tsx b/packages/ui/src/components/layout/ContextPanel.tsx index c1886424..84c18323 100644 --- a/packages/ui/src/components/layout/ContextPanel.tsx +++ b/packages/ui/src/components/layout/ContextPanel.tsx @@ -2290,21 +2290,7 @@ export const ContextPanel: React.FC = () => { }; }), [effectiveDirectory, t, tabs]); - const activeNonChatContent = activeTab?.mode === 'diff' - ? ( - - ) - : activeTab?.mode === 'context' + const activeNonChatContent = activeTab?.mode === 'context' ? : activeTab?.mode === 'plan' ? @@ -2326,6 +2312,10 @@ export const ContextPanel: React.FC = () => { () => tabs.filter((tab) => tab.mode === 'browser'), [tabs], ); + const diffTabs = React.useMemo( + () => tabs.filter((tab) => tab.mode === 'diff'), + [tabs], + ); const BrowserPane = isElectronBrowserRuntime() ? DesktopBrowserPane : IframeBrowserPane; const hasFileTabs = React.useMemo( () => tabs.some((tab) => tab.mode === 'file'), @@ -2496,7 +2486,27 @@ export const ContextPanel: React.FC = () => { ))} - {activeTab?.mode !== 'chat' && !isFileTabActive && activeTab?.mode !== 'browser' ? activeNonChatContent : null} + {diffTabs.map((tab) => ( +
+ +
+ ))} + {activeTab?.mode !== 'chat' && !isFileTabActive && activeTab?.mode !== 'browser' && activeTab?.mode !== 'diff' ? activeNonChatContent : null} ); diff --git a/packages/ui/src/components/views/DiffView.tsx b/packages/ui/src/components/views/DiffView.tsx index 89dbe2b1..6f9b056f 100644 --- a/packages/ui/src/components/views/DiffView.tsx +++ b/packages/ui/src/components/views/DiffView.tsx @@ -213,100 +213,6 @@ const formatDiffTotals = ( ); }; -const DiffFilePathLabel = React.memo<{ - path: string; - className?: string; -}>(({ path, className }) => { - const lastSlash = path.lastIndexOf('/'); - if (lastSlash === -1) { - return ( - - {path} - - ); - } - - const dir = path.slice(0, lastSlash); - const name = path.slice(lastSlash + 1); - - return ( - - - {dir} - - - / - {name} - - - ); -}); - -interface FileSelectorProps { - changedFiles: FileEntry[]; - selectedFile: string | null; - selectedFileEntry: FileEntry | null; - onSelectFile: (path: string) => void; - className?: string; -} - -const FileSelector = React.memo(({ - changedFiles, - selectedFile, - selectedFileEntry, - onSelectFile, - className, -}) => { - const { t } = useI18n(); - - if (changedFiles.length === 0) return null; - - return ( - - - - - - - {changedFiles.map((file) => ( - -
- - - {formatDiffTotals(file.insertions, file.deletions)} -
-
- ))} -
-
-
- ); -}); - interface ChangeScopeSelectorProps { scope: Extract; workingCount: number; @@ -321,11 +227,12 @@ const ChangeScopeSelector = React.memo(({ onScopeChange, }) => { const { t } = useI18n(); + const [open, setOpen] = React.useState(false); const currentCount = scope === 'staged' ? stagedCount : workingCount; const currentLabel = scope === 'staged' ? t('diffView.scope.staged') : t('diffView.scope.changed'); return ( - + )} - {showOpenInEditorAction && selectedFileEntry && ( - - )} - {selectedFileEntry && currentLayoutForSelectedFile && ( + {currentLayoutForAllFiles && ( )} diff --git a/packages/ui/src/index.css b/packages/ui/src/index.css index 9e41239b..e2652df5 100644 --- a/packages/ui/src/index.css +++ b/packages/ui/src/index.css @@ -857,14 +857,8 @@ html:not(.dark) .chat-scroll { } } -/* Diff toolbar: drop low-priority labels as the context panel narrows. */ -@container diff-toolbar (max-width: 34rem) { - .diff-toolbar__file-stats { - display: none; - } -} - -@container diff-toolbar (max-width: 40rem) { +/* Diff toolbar: drop low-priority labels only when the context panel is genuinely tight. */ +@container diff-toolbar (max-width: 28rem) { .diff-toolbar__scope-count, .diff-toolbar__expand-label { display: none; @@ -875,23 +869,6 @@ html:not(.dark) .chat-scroll { } } -@container diff-toolbar (max-width: 29rem) { - .diff-toolbar__file-label { - display: none; - } - - .diff-toolbar__file-trigger { - flex: 0 0 auto; - gap: 0.375rem; - padding-inline: 0.625rem; - } - - .diff-toolbar__file-trigger-content { - flex: 0 0 auto; - gap: 0; - } -} - /* Status row: collapse optional text when narrow to keep both sides in one line. */ @container status-row (max-width: 30rem) { .status-row__active-todo {