Skip to content

fix(web): clear the profile the menu names, and only that profile

MacroscopeApp / Macroscope - UI Consistency failed Aug 16, 2026 in 3m 26s

UI Consistency: 2 issues found

Two UI consistency findings were posted as inline review comments.

  • apps/web/src/components/ui/menu.tsx (L238-242): the new leading-icon treatment on MenuSubTrigger is scoped with [&>svg:first-of-type], which also matches the trailing chevron when a sub-trigger has no leading icon. The compound selector's specificity (0,2,1) overrides the chevron's ms-auto (0,1,0), so the chevron loses its right alignment on the two existing icon-less sub-triggers (Appearance in PreviewMoreMenu.tsx:127, Turn in DiffPanel.tsx:557). Suggested scoping to :not(:last-child).
  • apps/web/src/components/preview/PreviewView.tsx (L700): the profile Badge in leadingActions is shrink-0 with unbounded width and whitespace-nowrap, while profile names may be up to 48 characters. In the compact inline/floating chrome row this takes width from the only flexible element (the URL InputGroup). Suggested a max-w-* cap plus truncate.

The previously reported destructive-delete-without-confirmation issue in IntegrationsSettings.tsx (removeProfile, L504-516, L567) is still unaddressed at this head, but was already flagged in an earlier run and was not re-posted.

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.

Scope reviewed: changed files under apps/web/src/** (components/ui/menu.tsx, components/RightPanelTabs.tsx, components/preview/PreviewMoreMenu.tsx, components/preview/PreviewChromeRow.tsx, components/preview/PreviewView.tsx, components/settings/IntegrationsSettings.tsx, components/ChatView.tsx, browser/*), with desktop/server/contracts changes used only as context.

Verified as consistent and not flagged:

  • IntegrationsSettings.tsx reuses Button, Badge, DraftInput, Select/SelectTrigger/SelectItem, Tooltip, SettingsRow, SettingResetButton, and the shared ITEM_ROW_INNER_CLASSNAME row geometry; aria-labels are present on the rename input, remove button, and default-profile trigger.
  • PreviewMoreMenu correctly wraps the new heading in MenuGroup so MenuGroupLabel has its required context; item variants and separators match surrounding usage.
  • PreviewChromeRow's new leadingActions slot is a plain ReactNode insertion that does not alter existing nav/URL/trailing geometry.
  • RightPanelTabs keeps the disabled SurfaceMenuItem + DisabledReasonTooltip path for the unavailable-browser case, so the disabled hint and pointer-events-auto behaviour are preserved; the controlled Menu open state is needed because a sub-trigger does not auto-close the root popup.
  • MenuPopup's width-defaulting contract is untouched; the new min-w-40/min-w-44 consumer classes exercise it as intended.

Methodology: read the primitives (menu.tsx, badge.tsx, input.tsx, draft-input.tsx, itemRows.ts) at PR head, enumerated all MenuSubTrigger consumers via git grep to determine which have leading icons, and reasoned about the emitted CSS specificity of the arbitrary-variant selectors against the chevron's own ms-auto/-me-0.5 utilities.


🔍 Agent activity — 1 tool call

💭 Looking at the PR diff, the menu.tsx issue with the sub-trigger icon treatment appears to be fixed — the new class string is there. But I need to check whether the IntegrationsSettings removeProfile function was actually updated to include a confirmation dialog, since the diff seems to cut off mid-word on that part. Looking at the UI files for potential issues, I'm focusing on RightPanelTabs.tsx where the MenuSub component has an onClick handler on the trigger that might not behave as expected for a submenu. I also need to check if SurfaceMenuItem was handling disabled states with tooltips or keyboard shortcuts that could be lost when replaced with MenuSub. Let me examine the other candidates like PreviewMoreMenu.tsx, PreviewView.tsx, and IntegrationsSettings.tsx to see what else might need attention. I'm noticing the CSS selector specificity issue with the menu styling — using :first-of-type on the SVG in the menu versus the simpler [&>svg] selector in MenuItem, and how the ChevronRightIcon's -me-0.5 margin interacts with the broader -mx-0.5 applied to the first SVG child. oses its right-alignment because the parent selector's higher specificity overrides the chevron's ms-auto class. The issue is that when there's no leading icon, the chevron becomes the first SVG child and gets caught by the [&>svg:first-of-type]:-mx-0.5 rule, which breaks the existing icon-less sub-trigger layouts where the chevron should stay pushed right. Now I need to check if there are actually any MenuSubTrigger instances in the codebase that don't have a leading icon. I'm noticing a specificity issue where the arbitrary variant selector for targeting the first SVG child is overriding the ms-auto margin utility on existing icon-less sub-triggers like the DiffPanel "Turn" and PreviewMoreMenu "Appearance" buttons. Let me verify how Tailwind v4 handles this specificity—the arbitrary variant generates a higher specificity rule that applies negative margin-inline to the first SVG, which is causing the regression. The shorthand margin-inline property expands to both margin-inline-start and margin-inline-end, and the cascade resolves per longhand property, so the higher specificity rule wins for margin-inline-start, pushing the chevron left-aligned instead of keeping it right-aligned with ms-auto. The opacity exclusion selector is working correctly since the chevron already has the opacity class, but the positioning issue is real. A better approach would be to scope the icon treatment differently—using :not(:last-child) instead of :first-of-type would avoid matching the chevron since it's always the last SVG child. I need to check the ITEM_ROW_INNER_CLASSNAME constant and see how other settings rows reference item rows, then look at the itemRows.ts file to understand the pattern. I need to verify the Badge component supports the outline variant and check what props DraftInput accepts, particularly nativeInput, size="sm", onCommit, maxLength, and value. The badge looks okay with the outline variant and shrink-0 class, but I'm concerned that a long profile name—up to 48 characters—could push against the URL input field in the chrome row. Let me check how PreviewChromeRow is laid out around that area to see if there's a spacing issue. I'm noticing a potential layout issue where the badge with shrink-0 and whitespace-nowrap could push against the URL input field, especially when profile names reach their 48-character limit in a narrow preview panel. The input container uses flex-1 which defaults to min-width: auto, so the input might still overflow even with the flex property set. The badge should probably have a max-width constraint to truncate longer names and prevent this squeeze. But the more concrete finding is the svg:first-of-type selector regression affecting chevron alignment in icon-less sub-triggers like DiffPanel's "Turn" and PreviewMoreMenu's "Appearance" — that's a clear regression from the changed lines in a shared primitive that impacts existing consumers. I should focus on that as the stronger, verifiable issue rather than the speculative truncation concern. I'm checking the actual components to confirm the regression. The DiffPanel's "Turn" submenu trigger and PreviewMoreMenu's "Appearance" trigger both have only text content with the chevron as the sole SVG child, so the :first-of-type selector matches the chevron and applies -mx-0.5, which overrides ms-auto due to higher specificity. This pushes the chevron left instead of keeping it at the right edge. The fix would be to use :not(:last-child) instead to target only leading SVGs. Writing the full class string... Looking for the SurfaceMenuItem definition. I'm thinking through the MenuSub behavior in RightPanelTabs—the submenu shows all profiles including Default, and clicking the trigger opens the default profile. For accessibility with keyboard navigation, Base UI's SubmenuTrigger handles hover and Enter/ArrowRight to open the submenu, but I need to consider adding onClick to simultaneously open the default browser and close the entire menu. The issue is that pressing Enter on the submenu trigger would normally open the submenu in Base UI, but with onClick attached, it would fire the click handler instead—opening a default browser tab and closing the menu, preventing keyboard users from accessing the submenu itself (though they could use ArrowRight as a workaround). With mouse clicks, Base UI would open the submenu while the handler closes the root menu, creating an interaction inconsistency since no other menu item in the app has a clickable sub-trigger that performs an action. It's a deliberate deviation from standard menu semantics, but the guidelines suggest preserving keyboard behavior where possible. There's also a more concrete accessibility concern: the MenuSubTrigger has aria-haspopup="menu" and aria-expanded attributes, so screen reader users expect submenu semantics, but activation triggers an action instead—a real UX inconsistency. However, since this appears to be an intentional design decision rather than a violation introduced by the changes, I'm hesitant to flag it alongside the other issues I've already raised. Let me verify that useBrowserDefaults is being used safely in RightPanelTabs and check the badge in PreviewView more carefully. The badge displaying the profile name needs layout constraints to prevent it from squeezing the URL input field at narrow widths—adding a max-width and truncation would be the minimal fix since profile names can be up to 48 characters. This is worth documenting since it's a real layout regression risk. I'm narrowing down the findings to the menu.tsx :first-of-type selector regression as the primary issue, with the badge width as a possible secondary one. Before I commit to both, I need to verify whether the chrome row already handles variable-width text elsewhere—the InputGroup has flex-1 applied, and while the input itself constrains its minimum width, I should check if the wrapper properly handles overflow. The badge being shrink-0 with up to 48 characters could squeeze the URL input to zero on narrow panels, which is a real layout risk even if it's an edge case. I'll frame it as a suggestion with max-w and truncate to keep it actionable without over-flagging aesthetic preferences. I'm leaning toward posting both comments since the badge issue is concrete enough to warrant inclusion. Now I'm settling on the two findings to report: the menu.tsx change at line 242 and the PreviewView badge issue at line 700. Both are in scope files. For the menu.tsx suggestion, I'll cover lines 238-242 to show the comment context and the class string that needs the icon alignment treatment. Writing the full class string... I'm refining the Badge component suggestion to add max-width and text truncation without overcomplicating it, keeping the line length reasonable for prettier formatting.

1. modify_pr — Two findings in the changed web UI. The MenuSubTrigger icon treatment added in this revision fixes the alignment of the new Browser sub-trigger, but the selector it uses also matches the trailing chevron on the two existing icon-less sub-triggers and overrides their ms-auto.


Agent Credits: 146 credits