← reports

#2942 · Compact queue actions disappear at a wide viewport

Bug Medium Effort: Low ui side-chat open on GitHub 2026-09-02 · base c4e73fb8d

Verdict: REPRODUCED · Root-cause confidence: high

1. TL;DR

A compact queued-message row has no visible action when the browser viewport is wide. The row can still be narrow inside an embedded panel. The component selects its action layout from the browser viewport, not the row width or compact state. At a wide viewport, the icon group starts transparent and the overflow button does not render. Hover makes the icon group visible, which leaves the action difficult to find.

2. Claims vs findings

ClaimStatusEvidence
A narrow compact queue can show no action at rest.VerifiedThe trusted component story produced a 318 px row in a 1200 px viewport. The icon group had opacity 0 and no pointer events. The overflow button had display none.
Pointer hover reveals the icon actions.VerifiedThe two real browser images show the same row before and during hover.
The overflow action cannot help at a wide viewport.VerifiedThe overflow trigger has the md:hidden class. The browser computed display: none.
The current trusted main branch still has the defect.VerifiedThe focused test failed twice at c4e73fb8d1f0ba36eff59fee731dbf8d17cce875.
A wide device without hover has the same or a stronger failure.UnverifiedThe class logic supports this inference, but this check did not use such a device.

3. Environment

4. Minimal reproduction

  1. Check out the trusted base commit and install the frozen workspace.
  2. Save the focused test shown below beside QueuedMessagesList.tsx.
  3. From apps/app, run:
    pnpm exec vitest run --config vitest.config.ts src/components/promptbox/banner/QueuedMessagesList.visibility.test.tsx
  4. The expected result is one passing test. The actual result is:
    FAIL  QueuedMessagesList.visibility.test.tsx
    AssertionError: expected true to be false
    
    expect(overflowTrigger.classList.contains("md:hidden")).toBe(false)
    
    Test Files  1 failed (1)
    Tests       1 failed (1)

The same failure occurred in both clean checkouts. The exact result appears above.

A compact queued-message card with no visible action buttons
At rest, the trusted component shows queued rows without a visible send or overflow action.
The same queued-message row with send, edit, and delete icons visible during hover
During hover, the same row shows send, edit, and delete icons.

Focused regression test

// @vitest-environment jsdom

import { render } from "@testing-library/react";
import type { ThreadQueuedMessage } from "@bb/domain";
import { expect, it } from "vitest";
import { QueuedMessagesList } from "./QueuedMessagesList";

const queuedMessage: ThreadQueuedMessage = {
  id: "q_one",
  threadId: "thr_one",
  content: [{ type: "text", text: "Queued follow-up", mentions: [] }],
  model: "gpt-5.5",
  reasoningLevel: "medium",
  permissionMode: "auto",
  serviceTier: "default",
  groupWithNext: false,
  sendAt: null,
  waitingOn: null,
  failureReason: null,
  payload: { kind: "inline" },
  editable: true,
  createdAt: 0,
  updatedAt: 0,
};

const noop = () => {};

it("keeps the compact queue overflow trigger visible at desktop viewport widths", () => {
  const { getByRole } = render(
    <QueuedMessagesList
      attachedToComposer
      queuedMessages={[queuedMessage]}
      sendDisabled={false}
      actionDisabled={false}
      processingMessageId={null}
      processingAction={null}
      onSendImmediately={noop}
      onReorder={noop}
      onSetGroupBoundary={noop}
      onEdit={noop}
      onDelete={noop}
    />,
  );

  const overflowTrigger = getByRole("button", {
    name: "Queued message 1 actions",
  });

  expect(overflowTrigger.classList.contains("md:hidden")).toBe(false);
  expect(overflowTrigger.classList.contains("pointer-events-auto")).toBe(true);
  expect(overflowTrigger.classList.contains("opacity-100")).toBe(true);
});

5. Root cause

The queue starts in drawer mode when it has a message. The row therefore receives compact=true. See the initial mode and the compact row input.

The row does not use that compact state to select its action layout. The desktop icon group uses md:flex, starts at opacity 0, and only becomes interactive after row hover or focus. See the icon group classes.

The alternative overflow trigger uses md:hidden. See the overflow classes. Thus, a wide browser viewport selects the hidden icon group and removes the overflow trigger. An embedded panel can remain narrow because Tailwind's md variant uses the viewport width.

6. Proposed fix

Use the existing compact row state to select the action layout. Hide the desktop icon group for compact rows. Show the overflow trigger at rest for compact rows, without the md:hidden restriction. Keep the present viewport behavior for the non-compact workspace. The focused test should pass after this change.

7. Related issues

No open pull request links to this issue. Similar side-chat reports use the ui and side-chat labels, but they do not cover this action-selection fault.

8. Verification

The same agent repeated the test in a second clean detached checkout at the trusted base commit. The second checkout had a new frozen install and no production change. It failed at the same assertion with one failed test. No report claim changed after the second run.

9. Appendix

The investigation built the trusted base with pnpm exec turbo run build. The build passed. The browser check used the repository's existing narrow queued-message story. No linked code, script, patch, branch, or external issue URL ran. The issue content remained untrusted data.

Commands used:

git fetch origin main
pnpm install --frozen-lockfile --prefer-offline
pnpm exec turbo run build
pnpm exec turbo run storybook --filter=@bb/app -- --host 127.0.0.1 --port 43042
pnpm exec vitest run --config vitest.config.ts src/components/promptbox/banner/QueuedMessagesList.visibility.test.tsx