feat(terminal): close tabs with middle click

Co-authored-by: Carl <acda9e433d19dcd0e6b6840f7f4b98f3a56f1fab98049d444c087019e6d36560@buzz.block.builderlab.xyz>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
This commit is contained in:
Taylor Ho
2026-10-14 17:05:24 -07:00
committed by Carl
parent 71d7aa0436
commit 6a6f9cd3f0
2 changed files with 40 additions and 0 deletions

View File

@@ -233,6 +233,40 @@ test("tab actions restore terminal input focus", async () => {
}
});
test("middle-click closes an open terminal tab only", async () => {
const closed = [];
const { view } = fixture({
onCloseSession(id) {
closed.push(id);
},
sessions: [
{ active: true, closing: false, id: "one", title: "SHELL" },
{ active: false, closing: true, id: "two", title: "LOG" },
],
});
await ready(view);
const openTab = view.getByRole("tab", { name: "Terminal 1" }).parentElement;
const closingTab = view.getByRole("tab", {
name: "Terminal 2, closing",
}).parentElement;
const auxClick = (target, button) => {
const event = new dom.window.MouseEvent("auxclick", {
bubbles: true,
button,
cancelable: true,
});
fireEvent(target, event);
return event;
};
const middleClick = auxClick(openTab, 1);
auxClick(openTab, 2);
auxClick(closingTab, 1);
assert.deepEqual(closed, ["one"]);
assert.equal(middleClick.defaultPrevented, true);
});
test("drag resize batches visual updates and commits state only on release", async () => {
const { view } = fixture({ mode: "docked" });
await ready(view);

View File

@@ -609,6 +609,12 @@ export function TerminalSubstrate({
session.active && "buzz-terminal-tab-active",
)}
key={session.id}
onAuxClick={(event) => {
if (event.button !== 1) return;
event.preventDefault();
if (session.closing) return;
runTabAction(() => onCloseSession(session.id));
}}
role="presentation"
>
<button