Skip to content

fix(web): contain project picker popup

MacroscopeApp / Macroscope - UI Consistency failed Aug 29, 2026 in 2m 27s

UI Consistency: 1 issue found

apps/web/src/components/Sidebar.tsx:3589-3592 — The new ComboboxPopup class string fixes popup containment by reaching into the primitive's internal DOM ([&>[data-slot=combobox-popup]]:min-w-0 [&>[data-slot=combobox-popup]]:overflow-hidden) and is now byte-identical to the string already carried by DiffPanel.tsx:620. The behavior being fixed belongs to the primitive: the inner ComboboxPrimitive.Popup is a flex-1 child of the glass wrapper with default min-width: auto, so long content can push any combobox popup past the anchor width. Duplicating the workaround per call site makes the fix depend on ComboboxPopup's internal structure — if the wrapper/child relationship changes, the selector silently stops matching and the overflow bug returns with no type or build error.

Suggested smallest fix: move min-w-0 overflow-hidden onto the inner ComboboxPrimitive.Popup (and the wrapper defaults) in apps/web/src/components/ui/combobox.tsx, leaving only contextual width at the call site (w-(--anchor-width)), and drop the duplicated descendant selectors from DiffPanel.tsx. If clipping should not be the default for every combobox, a named prop/variant on ComboboxPopup is still preferable to repeating the slot selectors. Since the wrapper overflow-hidden interacts with the ScrollArea scroll fade inside ComboboxList, re-check open/filter/scroll behavior in the sidebar and diff scope pickers after the move.

Details

Note

Your check run agent prompt is: .macroscope/check-run-agents/ui-consistency.md
More information about how Check Run Agents work can be found in our Help Center.

Files examined: apps/web/src/components/Sidebar.tsx (changed lines and surrounding project-picker combobox), apps/web/src/components/ui/combobox.tsx (ComboboxPopup, ComboboxItem, ComboboxList), apps/web/src/components/ui/scroll-area.tsx, and the other ComboboxPopup consumers found via grep (DiffPanel.tsx, ChatView.tsx, RightPanelTabs.tsx, ChatComposer.tsx).

Other checks performed and found clean:

  • Tailwind merge ordering: min-w-0 correctly supersedes the primitive's min-w-(--anchor-width) via cn, and w-(--anchor-width) preserves the intended anchored width.
  • No accessibility/interaction regression in the changed line: no focus ring, hit target, keyboard, or aria-* behavior is altered; nested Button in items uses focus-visible:bg-accent rather than an outset ring, so wrapper clipping does not hide focus feedback.
  • No environment-routing, theme-variant, or global-CSS ownership concerns are touched by this diff.

An inline comment covering the finding is already present on the changed line (posted by an earlier run of this check on the same head commit); a duplicate comment produced by this run was minimized as DUPLICATE.


🔍 Agent activity — 11 tool calls

1. browse_code — apps/web/src/components/Sidebar.tsx

2. git_tools — combobox-popup

💭 I want to check combobox.tsx to see how ComboboxPopup is structured — specifically whether className is passed to the positioner or the popup itself.

3. browse_code — apps/web/src/components/ui/combobox.tsx

💭 I notice this same pattern already exists at DiffPanel.tsx line 620, so two call sites are now repeating identical treatment — which per the rule about repeated durable geometry should perhaps be extracted into a named primitive variant instead. Though I'm also weighing whether this is really a container-clipping fix that belongs inside the primitive itself, since the inner popup component lacks the min-width and overflow handling. The className merge should resolve cleanly since tailwind-merge dedupes the conflicting min-width utilities, with min-w-0 taking precedence. What concerns me more is that this class string also includes a descendant selector reaching into the primitive's internal data-slot to override its behavior directly from the call site, which fits the pattern the rule flags about overriding a primitive's core styling rather than extending it properly. Since the pattern is genuinely shared across two call sites and addresses a real gap—the popup lacking min-w-0/overflow-hidden causes long content to overflow the rounded container—this looks like a legitimate case for fixing the primitive rather than a violation. I want to check whether overflow-hidden on the popup would interfere with internal scrolling, so I should look at how ComboboxList handles its own overflow behavior.

4. browse_code — apps/web/src/components/ui/combobox.tsx

5. browse_code — apps/web/src/components/DiffPanel.tsx

💭 I'm checking whether overflow-hidden on the popup could interfere with ScrollArea's internal scrolling, but since ScrollArea manages its own viewport, it should still work fine even within a flex-column parent with overflow constraints. Considering the min-w-0 override, since Tailwind's merge logic treats it and the anchor-width min-w as the same group, min-w-0 takes precedence, so the popup width still matches the anchor since w-(--anchor-width) is set separately. I'm also checking the data-side=none fallback where items force a larger min-width than the anchor, but since the default side is "bottom" here, that edge case shouldn't trigger. Now I'm weighing whether the duplicated four-utility override reaching into the primitive's internals via a data-slot selector counts as a real violation. It's not touching core height, radius, padding, focus ring, or color contracts, so it's more of a moderate finding: the same clipping fix repeated at two call sites, which would be cleaner if built into ComboboxPopup itself rather than reached into from outside. I want to check whether adding overflow-hidden could clip something intentional, like a focus ring, shadow, or nested tooltip/menu rendered inline inside the Sidebar popup — so I'm going to look at lines 3650-3720 to see what's actually nested in there.

6. browse_code — apps/web/src/components/Sidebar.tsx

7. git_tools

💭 This duplication looks like a real finding since DiffPanel's identical string has existed since June, and now this PR repeats it at a second call site. The clipping/min-width contract should really live inside ComboboxPopup itself rather than being re-implemented at each usage site. I want to check whether overflow-hidden on the popup wrapper could break the ScrollArea's fade or scrollbar, but nesting a ScrollArea inside an overflow-hidden container should be fine. The min-w-0 change also seems safe since width is still governed by the anchor-width variable regardless. I'm also verifying the truncation logic actually needs this fix, tracing through where the item's min-w-0 and flex-1 styles come from to see what's actually causing the overflow. The real question is whether min-w-0 propagates correctly through the ComboboxList and ScrollArea chain, since without ComboboxList's overflow-x-hidden, the ScrollArea might allow horizontal scrolling within its clipped box rather than truncating the text via the item's truncate class. I need to trace whether min-w-0 actually flows down from the popup span into that nested structure to confirm truncation will kick in as expected. Given the pattern here — the same override reaching into primitive internals repeated across call sites — I think this is worth flagging as something that should be pushed into ComboboxPopup itself as a durable contract, since call-site descendant selectors targeting the popup's data-slot are exactly the kind of repeated treatment the rules say should become a primitive-level concern rather than an optional aesthetic tweak. Since the fix spans multiple files, I should describe the change rather than provide a diff. Weighing severity, this feels like a legitimate consistency concern rather than a regression, but since the check defaults to failure when a finding exists, I'll report it and mark the state as failure. I also want to double-check a few other details: whether overflow-hidden might clip the ScrollArea's scroll fade mask or the ComboboxInput's focus ring, but the input container's border styling looks fine there. The sidebar Button's focus-visible state also looks correctly handled. I'm confirming the ScrollArea's scrollbar sits within the padding so overflow-hidden won't clip it at the popup edge, which checks out fine. I'm now wondering if there's a shared utility class in index.css for this containment pattern, so I should search for similar "anchor-width" patterns used in other popups. More importantly, I need to check whether min-w-0 is actually required on the ComboboxList/ScrollArea for truncation to work — without runtime verification, I can't be fully sure the fix is effective, so let me look at how ScrollArea is implemented.

8. git_tools — data-slot="scroll-area

💭 I'll flag one inline comment on Sidebar.tsx around line 3591 pointing out that the containment contract is duplicated through internal data-slot descendant selectors, and suggest moving min-w-0 overflow-hidden into ComboboxPopup in combobox.tsx so call sites can simplify to w-(--anchor-width). I'm weighing whether this point is significant enough to include as a blocking issue.

9. modify_pr — One consistency finding on the project picker popup containment fix.

💭 The line numbers seem off—I passed line 591 with start_line 3589, which is inconsistent, yet it reported one comment added. Line 591 in Sidebar.tsx isn't actually in the diff, so I should check the review comments to verify where it actually landed.

10. github_api_read_only — repos/{owner}/{repo}/pulls/{pull_number}/comments

💭 I notice there's already a prior comment properly anchored at the correct line making the same point, while mine landed as a file-level comment due to bad line numbers and just duplicates it. I should minimize my duplicate comment as DUPLICATE since the earlier one covers it.

11. modify_pr — Minimized comment (duplicate)


Agent Credits: 65 credits

Token usage: 18 uncached input · 255,876 cache-read input · 43,425 cache-write input · 8,410 output
Agent Credits may also include non-token charges from external tools such as web research.