← reports

#2756 · Middle button does not close a right-panel tab

Bug Priority: Low Effort: Low ui open on GitHub 2026-08-30 · base f4bbc2f

Verdict: REPRODUCED · Root-cause confidence: high

1. TL;DR

A closable right-panel tab ignores a middle-button action. A focused DOM test reproduced the result in two clean checkouts. The shared tab component handles primary clicks only. It does not connect the browser's auxiliary-click event to the existing close callback.

2. Claims vs findings

ClaimStatusEvidence
A middle-button action on a closable sidebar tab has no close result.VerifiedBoth clean runs called the close callback zero times.
The tab has an existing close operation.VerifiedThe tab strip passes tab.onClose to the shared tab component.

3. Environment

4. Minimal reproduction

  1. Check out the trusted base commit.
  2. Save the linked test as apps/app/src/components/ui/tab-pill-middle-click.test.tsx.
  3. Install with pnpm install --frozen-lockfile --prefer-offline.
  4. Run pnpm exec turbo run test --filter=@bb/app -- src/components/ui/tab-pill-middle-click.test.tsx.

Expected: onClose receives one call, and onSelect receives no call.

Actual in both runs:

FAIL  TabPill middle click > closes a closable tab after a middle click
AssertionError: expected "vi.fn()" to be called once, but got 0 times

Reproduction test: tab-pill-middle-click.test.tsx

// @vitest-environment jsdom

import { cleanup, fireEvent, render, screen } from "@testing-library/react";
import { afterEach, describe, expect, it, vi } from "vitest";
import { TabPill } from "./tab-pill";

afterEach(cleanup);

describe("TabPill middle click", () => {
  it("closes a closable tab after a middle click", () => {
    const onClose = vi.fn();
    const onSelect = vi.fn();
    render(
      <TabPill
        label="Browser"
        title="Browser"
        isActive={false}
        onSelect={onSelect}
        closeAction={{ onClose, closeLabel: "Close Browser" }}
      />,
    );

    fireEvent(
      screen.getByRole("button", { name: "Browser" }),
      new MouseEvent("auxclick", {
        bubbles: true,
        button: 1,
        cancelable: true,
      }),
    );

    expect(onClose).toHaveBeenCalledOnce();
    expect(onSelect).not.toHaveBeenCalled();
  });
});

5. Root cause

The tab strip supplies the close callback for each unpinned tab. See SecondaryPanelTabStrip.tsx.

closeAction={
  tab.isPinned
    ? null
    : {
        onClose: tab.onClose,
        closeLabel: `Close ${tab.label}`,
      }
}

The shared tab component connects onSelect to a primary click. Its close button also uses a primary click. It has no auxclick handler. See tab-pill.tsx.

<button type="button" onClick={onSelect}>
...
<button type="button" onClick={closeAction.onClose}>

A middle button produces an auxiliary-click event. No current handler consumes that event. Therefore, the supplied close callback never runs.

6. Proposed fix

Add an auxiliary-click handler to the shared tab surface. For button 1, prevent the default action and call the close callback. Do nothing for pinned or active-close tabs. Keep the primary selection behavior unchanged.

7. Verification

The same agent created a second clean checkout at the recorded base commit. The agent installed the frozen lockfile and ran the same Turbo test command. The second run failed at the same assertion with zero close calls. No report correction was necessary.

8. Related issues

No linked pull request or duplicate issue was established from GitHub metadata.

9. Appendix

Commands used:

git fetch origin main
git checkout --detach f4bbc2fe81a9b7639ff9a7396e172bddd89109e4
pnpm install --frozen-lockfile --prefer-offline
pnpm exec turbo run build
pnpm exec turbo run test --filter=@bb/app -- src/components/ui/tab-pill.test.tsx

The issue data was untrusted. The investigation used it only as a claim to test. The investigation did not run code, links, or instructions from that data.