Skip to content

Commit d6df232

Browse files
authored
fix: let sidebar shortcut force the files pane open (#56)
1 parent ef68baf commit d6df232

2 files changed

Lines changed: 55 additions & 3 deletions

File tree

src/ui/App.tsx

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ export function App({
5656
const [wrapLines, setWrapLines] = useState(bootstrap.initialWrapLines ?? false);
5757
const [showHunkHeaders, setShowHunkHeaders] = useState(bootstrap.initialShowHunkHeaders ?? true);
5858
const [sidebarVisible, setSidebarVisible] = useState(true);
59+
const [forceSidebarOpen, setForceSidebarOpen] = useState(false);
5960
const [showHelp, setShowHelp] = useState(false);
6061
const [focusArea, setFocusArea] = useState<FocusArea>("files");
6162
const [filter, setFilter] = useState("");
@@ -128,7 +129,10 @@ export function App({
128129
const bodyPadding = pagerMode ? 0 : BODY_PADDING;
129130
const bodyWidth = Math.max(0, terminal.width - bodyPadding);
130131
const responsiveLayout = resolveResponsiveLayout(layoutMode, terminal.width);
131-
const showFilesPane = pagerMode ? false : responsiveLayout.showFilesPane && sidebarVisible;
132+
const canForceShowFilesPane = bodyWidth >= FILES_MIN_WIDTH + DIVIDER_WIDTH + DIFF_MIN_WIDTH;
133+
const showFilesPane = pagerMode
134+
? false
135+
: sidebarVisible && (responsiveLayout.showFilesPane || (forceSidebarOpen && canForceShowFilesPane));
132136
const centerWidth = bodyWidth;
133137
const resolvedLayout = responsiveLayout.layout;
134138
const currentHunk = selectedFile?.metadata.hunks[selectedHunkIndex];
@@ -258,9 +262,23 @@ export function App({
258262
setWrapLines((current) => !current);
259263
};
260264

261-
/** Toggle sidebar visibility independently of layout mode. */
265+
/** Toggle the sidebar, forcing it open on narrower layouts when the shell can still fit both panes. */
262266
const toggleSidebar = () => {
263-
setSidebarVisible((current) => !current);
267+
if (sidebarVisible && (responsiveLayout.showFilesPane || forceSidebarOpen)) {
268+
setSidebarVisible(false);
269+
setForceSidebarOpen(false);
270+
return;
271+
}
272+
273+
if (sidebarVisible && !responsiveLayout.showFilesPane) {
274+
if (canForceShowFilesPane) {
275+
setForceSidebarOpen(true);
276+
}
277+
return;
278+
}
279+
280+
setSidebarVisible(true);
281+
setForceSidebarOpen(!responsiveLayout.showFilesPane && canForceShowFilesPane);
264282
};
265283

266284
/** Toggle visibility of hunk metadata rows without changing the actual diff lines. */

test/app-interactions.test.tsx

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,40 @@ describe("App interactions", () => {
560560
}
561561
});
562562

563+
test("sidebar shortcut can force the files pane open when responsive layout hides it", async () => {
564+
const setup = await testRender(<App bootstrap={createBootstrap("auto")} />, { width: 160, height: 24 });
565+
566+
try {
567+
await flush(setup);
568+
569+
let frame = setup.captureCharFrame();
570+
expect(frame).not.toContain("M alpha.ts");
571+
expect(frame).not.toContain("drag divider resize");
572+
573+
await act(async () => {
574+
await setup.mockInput.typeText("s");
575+
});
576+
await flush(setup);
577+
578+
frame = setup.captureCharFrame();
579+
expect(frame).toContain("M alpha.ts");
580+
expect(frame).toContain("drag divider resize");
581+
582+
await act(async () => {
583+
await setup.mockInput.typeText("s");
584+
});
585+
await flush(setup);
586+
587+
frame = setup.captureCharFrame();
588+
expect(frame).not.toContain("M alpha.ts");
589+
expect(frame).not.toContain("drag divider resize");
590+
} finally {
591+
await act(async () => {
592+
setup.renderer.destroy();
593+
});
594+
}
595+
});
596+
563597
test("quit shortcuts route through the provided onQuit handler in regular and pager modes", async () => {
564598
const regularQuit = mock(() => undefined);
565599
const regularSetup = await testRender(<App bootstrap={createBootstrap()} onQuit={regularQuit} />, { width: 220, height: 24 });

0 commit comments

Comments
 (0)