diff --git a/src/ui/App.tsx b/src/ui/App.tsx index 1ca2735..eb3e9a8 100644 --- a/src/ui/App.tsx +++ b/src/ui/App.tsx @@ -49,6 +49,7 @@ export function App({ const [showLineNumbers, setShowLineNumbers] = useState(bootstrap.initialShowLineNumbers ?? true); const [wrapLines, setWrapLines] = useState(bootstrap.initialWrapLines ?? false); const [showHunkHeaders, setShowHunkHeaders] = useState(bootstrap.initialShowHunkHeaders ?? true); + const [sidebarVisible, setSidebarVisible] = useState(true); const [showHelp, setShowHelp] = useState(false); const [focusArea, setFocusArea] = useState("files"); const [activeMenuId, setActiveMenuId] = useState(null); @@ -83,7 +84,7 @@ export function App({ const bodyPadding = pagerMode ? 0 : BODY_PADDING; const bodyWidth = Math.max(0, terminal.width - bodyPadding); const responsiveLayout = resolveResponsiveLayout(layoutMode, terminal.width); - const showFilesPane = pagerMode ? false : responsiveLayout.showFilesPane; + const showFilesPane = pagerMode ? false : responsiveLayout.showFilesPane && sidebarVisible; const centerWidth = bodyWidth; const resolvedLayout = responsiveLayout.layout; const currentHunk = selectedFile?.metadata.hunks[selectedHunkIndex]; @@ -247,6 +248,11 @@ export function App({ setWrapLines((current) => !current); }; + /** Toggle sidebar visibility independently of layout mode. */ + const toggleSidebar = () => { + setSidebarVisible((current) => !current); + }; + /** Toggle visibility of hunk metadata rows without changing the actual diff lines. */ const toggleHunkHeaders = () => { setShowHunkHeaders((current) => !current); @@ -354,6 +360,14 @@ export function App({ action: () => setLayoutMode("auto"), }, { kind: "separator" }, + { + kind: "item", + label: "Sidebar", + hint: "s", + checked: sidebarVisible, + action: toggleSidebar, + }, + { kind: "separator" }, { kind: "item", label: "Agent notes", @@ -678,6 +692,12 @@ export function App({ return; } + if (key.name === "s") { + toggleSidebar(); + closeMenu(); + return; + } + if (key.name === "t") { const currentIndex = THEMES.findIndex((theme) => theme.id === activeTheme.id); const nextIndex = (currentIndex + 1) % THEMES.length; diff --git a/src/ui/components/chrome/StatusBar.tsx b/src/ui/components/chrome/StatusBar.tsx index 3c9b000..48561d1 100644 --- a/src/ui/components/chrome/StatusBar.tsx +++ b/src/ui/components/chrome/StatusBar.tsx @@ -25,7 +25,7 @@ export function StatusBar({ if (canResizeDivider) { hintParts.push("drag divider resize"); } - hintParts.push("space/b page", "/ filter", "[ ] hunk nav", "1 2 0 layout", "t theme", "a notes", "l lines", "w wrap", "m meta", "q quit"); + hintParts.push("space/b page", "/ filter", "[ ] hunk nav", "1 2 0 layout", "s sidebar", "t theme", "a notes", "l lines", "w wrap", "m meta", "q quit"); return ( { frame = setup.captureCharFrame(); expect(frame).not.toContain("Split view"); - expect(frame).not.toContain("│"); expect(frame).toContain("1 - export const alpha = 1;"); } finally { await act(async () => { diff --git a/test/app-responsive.test.tsx b/test/app-responsive.test.tsx index 29db33f..ba02072 100644 --- a/test/app-responsive.test.tsx +++ b/test/app-responsive.test.tsx @@ -162,10 +162,10 @@ describe("responsive shell", () => { expect(forcedSplit).toMatch(/▌.*▌/); expect(forcedSplit).not.toContain("drag divider resize"); - expect(forcedStack).not.toContain("Files"); + expect(forcedStack).toContain("M alpha.ts"); expect(forcedStack).not.toContain("Changeset summary"); expect(forcedStack).not.toMatch(/▌.*▌/); - expect(forcedStack).not.toContain("drag divider resize"); + expect(forcedStack).toContain("drag divider resize"); }); test("pager mode stays responsive while hiding app chrome", async () => {