Skip to content

fix(web): restore branch-range indicator order with per-label tooltips

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

UI Consistency: 1 issue found

1 finding

  • apps/web/src/components/pullRequest/pullRequestPresentation.tsx (L235-243): PullRequestActorLabel now owns a Tooltip, but the reviewers avatar stack in PullRequestSummaryTab.tsx (~L472-491) already wraps this label in its own TooltipTrigger. Hovering an avatar opens both popups at once (outer side="bottom" with Name (@login), new inner side="top" with just the login). Suggested fix: keep the tooltip at truncating call sites, or add an opt-out prop and pass it from the avatar stack, where the login is sr-only.

An inline review comment was posted for this finding.

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.

Checks performed beyond the finding

  • Disabled menu items (PullRequestListFilters.tsx, _chat.pull-requests.tsx): the tooltip now renders onto the MenuRadioItem with data-disabled:pointer-events-auto, matching the existing contract in RightPanelTabs.tsx (SurfaceMenuItem/DisabledReasonTooltip) and ModelListRow.tsx. DOM structure under MenuRadioGroup is preserved because Tooltip root renders no element. Earlier feedback on this point is addressed.
  • Nested trigger composition (ThemeColorPicker.tsx "Tooltip
    dding> PopoverTrigger > button", DraftHeroHeadline.tsx "Tooltip > MenuTrigger"): matches the precedent in preview/PreviewMoreMenu.tsx. Tooltip positioner is z-[140] vs menu/popover z-[130], so tooltips inside popovers/menus remain visible.
  • data-slot takeover: TooltipTrigger's data-slot="tooltip-trigger" replaces the primitive's slot (documented in ProjectScriptsControl.tsx). Verified no newly wrapped Button/Toggle/Badge/MenuTrigger sits under [data-chat-header], [data-panel-layout-controls], [data-workspace-titlebar-controls] (index.css L1348-1377) or inside Group/ToggleGroup/InputGroup, so themed toolbar styling is unaffected.
  • Accessibility: every migrated control keeps an aria-label or visible text; the previously flagged DiffPanel "Remote only" indicator now labels the icon (role="img" + aria-label). Removed title on the ChatView scroll pill and ConnectionStatusDot was redundant with visible text / aria-label.
  • Layout preservation: triggers render onto the same elements that carried the classes (truncate, flex-1, min-w-0), so flex/truncation geometry is unchanged; the PullRequestDetailPanel toolbar keeps PullRequestBaseFreshnessWarning in its original slot between base and head refs, and the freshness/scopes hover popovers are no longer inside a tooltip trigger.
  • Tests/selectors: no getByTitle/[title=] consumers exist; the updated ComposerPreviewAnnotationCards.test.tsx assertions match the new markup.
  • Lint scope: no remaining title on intrinsic elements in apps/web/src/**/*.tsx, so enabling t3code/no-native-title-tooltip as error should not fail lint (note: title passed through shared components such as Button in Sidebar.tsx L3520 still reaches the DOM and is outside the rule's intrinsic-only detection).

🔍 Agent activity — 1 tool call

💭 I'm checking what issues were flagged in the latest PR run and comparing the current head against those findings to see what still needs to be addressed. I need to review the remaining changes for potential issues. Let me check the DiffPanel's TooltipTrigger to see if the span wrapper is rendering correctly with its children, verify whether ChatView lost accessibility when the title attribute was removed, and confirm that ConnectionStatusDot isn't leaving behind unused variables or missing accessible text after removing the tooltip. The ConnectionStatusDot refactoring in the PR was more extensive than the diff initially suggested, though the key change was removing the title attribute since the Tooltip structure was already in place. Looking at DiffPanel, I see TooltipTrigger wraps a span element, which resolves the earlier scoping concern. Now I need to examine the actual tooltip component implementation to understand how it works. I'm reviewing the changes in the head diff to catch any issues, particularly looking at how BrowserDeviceToolbar handles the Button component inside TooltipTrigger—checking whether Base UI's Trigger properly passes children through when using the render prop with a Button element. There's a potential problem with disabled buttons: when disabled={pending || !customValid}, the tooltip won't open because disabled elements don't receive hover events in most browsers. The native title attribute does show on disabled buttons in Chrome and Firefox, but Base UI's Tooltip.Trigger on a disabled button might not behave the same way since disabled form controls don't fire mouse events. This is similar to the MenuRadioItem issue they fixed with data-disabled:pointer-events-auto. I should check how the codebase handles tooltips on disabled buttons elsewhere to see if there's an existing pattern. Now I need to check if there are existing patterns in the codebase where disabled Buttons are wrapped in Tooltips, to see if this is a convention I should follow. I'm noticing that disabled buttons with tooltips are already an established pattern in the codebase, so the migrations for BrowserDeviceToolbar and ThreadPreviewMiniPlayer follow existing convention rather than introducing something new. Though there is a behavioral shift here — native title attributes on disabled buttons do display in browsers, and I'm checking whether Chrome actually shows these tooltips on disabled buttons. Now I need to look at the other changes for actual issues. The ChatView removal of the "Scroll to end" title is worth examining — if there's no aria-label to replace it, that's a loss of accessible labeling. The DiffPanel remote-only check icon looks fine with its role and aria-label. Let me continue checking the ConnectionsSettings PairingLinkListRow. The tooltip z-index sits above the popover, so it could overlay the popover content when both are open — same z-index layering issue I flagged before. I should check if nesting Tooltip around PopoverTrigger or MenuTrigger is an established pattern elsewhere in the repo. Then I'm looking at MenuRadioItem to verify the disabled state pointer-events handling and class merge ordering, since the consumer classes need to apply last. Checking the MenuRadioItem primitive to see if it has the pointer-events-none class when disabled, and making sure the className merge order is correct for consumers. There's a nuance with key placement in PullRequestListFilters where they're setting it both on the MenuRadioItem inside the item variable and on the Tooltip wrapper — when item gets passed as a render prop, the key on the element itself doesn't cause issues, but I need to verify the non-tooltip branch handles the return correctly. Now I'm looking at whether MenuRadioItem accepts a render prop or supports useRender, since TooltipTrigger passes render={item} and needs to merge trigger props like onMouseEnter and data-slot onto the MenuRadioItem element — that means MenuRadioItem has to forward unknown props through to the DOM. The new code aligns with the existing SurfaceMenuItem and DisabledReasonTooltip pattern. There's already a local DisabledReasonTooltip helper in RightPanelTabs, and this pattern is being duplicated across a couple more places like PullRequestListFilters and the chat pull requests module. While the style guide mentions preferring named primitives when geometry or treatment repeats across multiple sites, a short 4-line tooltip pattern is reasonable to duplicate rather than extract into a shared utility. Now I'm checking the rest of the changes for actual regressions. Looking at ConnectionsSettings around line 695, the <p> wraps a <span> trigger for the tooltip — Base UI's Tooltip.Trigger defaults to rendering as a button, but with render={<span />} it becomes a span instead. I need to verify whether the codebase already uses this pattern elsewhere and whether Trigger adds the necessary accessibility role. For PullRequestListFilters, the TooltipTrigger wraps a MenuRadioItem, and since Base UI's render prop merges props onto the element, that should work fine. The potential concern is nesting a Tooltip inside a MenuPopup — the tooltip portal renders outside the menu, so hovering the item should open the tooltip independently. I need to check z-index values: if the menu popup has a higher z-index than the tooltip's z-140, the tooltip could render behind the menu and be hidden. I should also verify the z-index handling for the nested Tooltip and PopoverTrigger in ThemeColorPicker, and check what z-index values are set in popover.tsx, menu.tsx, and combobox. I'm thinking through the z-index layering between tooltips and menus—tooltips at z-140 sit above menus at z-130, which works well for menu items. But with the ThemeColorPicker, where the tooltip is on the PopoverTrigger itself, there's a potential overlap issue: when you click the swatch to open the popover, the tooltip stays visible while hovering, and since the popover anchors to the trigger with positioning like bottom or top, it might actually cover where the tooltip would appear. But this isn't really a regression compared to the native title attribute—that would also show while the popover is open. The tooltip is positioned above the swatch and the popover typically opens below it by default, so the overlap risk is minimal and not worth flagging. The aria-label and title on the button were already the same (Choose ${label} color), so keeping the tooltip is fine. Now I'm checking other files for actual regressions. In ProjectContentSearchDialog, the SearchOptionButton wraps Toggle in a TooltipTrigger, moving the Toggle into the TooltipTrigger's children. The question is whether Toggle accepts the props that TooltipTrigger passes through—Base UI's TooltipTrigger merges props like onMouseEnter and ref into the element, and since Toggle is from Base UI, it should handle those props correctly. ComposerPreviewAnnotationCards uses TooltipTrigger with a span element and inline children, which works fine. DraftHeroHeadline nests a MenuTrigger inside TooltipTrigger's render prop—this is a composed render pattern that Base UI supports. The conditional TooltipPopup rendering (only showing when activeProjectDisplayName exists) is also fine; the tooltip root opens on hover but nothing renders if the condition is false. The Sidebar draft row discard button previously had a title attribute and now has a tooltip; the button itself has pointer-events-none until the row is hovered or focused, so the TooltipTrigger placement is fine. ServerUpdateProgress... I need to verify that those files already have Tooltip imported to avoid any compile errors. I'm noticing that several migrations are displaying truncated paths with tooltips, and there's already a StartTruncatedPath component in the codebase that handles exactly this pattern — so I should check whether these new instances should be using that shared component instead of implementing truncation inline. StartTruncatedPath handles start-truncation for right-to-left text, which is different from the standard end-truncate approach used in newer migrations. Now I'm checking the remaining risky areas where components have children passed directly to triggers versus render props, particularly in ChangedFilesTree where a Tooltip wraps a button trigger with icon and span children. I'm also verifying potential regressions around tooltips in virtualized lists, and confirming that test assertions for tooltip-trigger data-slots are correct. For DiffPanel's remote-only indicator, the lucide CheckIcon properly passes props through to the SVG. I need to check whether tooltips on disabled MenuRadioItems work correctly — Base UI menu items highlight on hover, and the pointer-events-auto override on disabled items should allow tooltip interactions to work as expected, similar to how RightPanelTabs handles this pattern. One more thing to verify: the oxlint rule for title attributes is now set to error globally, so I should check if there are any remaining title attributes on intrinsic elements in apps/web/src that would cause lint failures in CI. I'm checking a couple of intrinsic HTML elements in the codebase that might trigger linting errors. In ConnectionsSettings.tsx, there are title attributes around lines 775 and 880 that could be on elements like <svg> or <img>, which would flag the rule violation. I need to inspect those specific locations to confirm what elements they're attached to, and there's also a title attribute in Sidebar.tsx at line 3520 that needs investigation. I'm noticing that the linting rule in Sidebar.tsx only catches lowercase intrinsic elements with title attributes, so it misses cases where title is passed through wrapper components like Button that forward it directly to the DOM. This means the PR's goal of removing native title tooltips isn't fully achieved since those forwarded attributes still create tooltips, suggesting the rule itself might be incomplete in how it handles component composition. I need to focus on actual behavioral regressions in the changed lines rather than pre-existing inconsistencies. Let me dig into whether Toggle can properly merge props when rendered inside TooltipTrigger, and check what's happening with that ConnectionsSettings change around line 695. I'm working through how Base UI handles the render prop with children—when a TooltipTrigger wraps a Toggle component and passes children, the children get forwarded to the render element automatically, which should work fine for the ProjectContentSearchDialog setup. For ConnectionsSettings, the tooltip on a span inside a paragraph is acceptable since the span wasn't keyboard-accessible anyway. Now checking ThemeColorPicker, ProjectSettingsPanel, and the ThreadPreviewMiniPlayer resize handle—that last one has a button with both pointer handlers for dragging and tooltip trigger handlers, which should merge correctly without the tooltip interfering with the resize interaction. Looking at BrowserDeviceToolbar's disabled button and the PullRequestDetailPanel copy-branch button, those follow the same pattern. The branch button's tooltip now combines what was previously split between the button title and an inner title attribute. Checking DiffPanel, ChangedFilesTree, FilePreviewPanel, and PullRequestListFilters to verify tooltip placement and RadioGroup interactions are correct. The key concern is whether wrapping MenuRadioItems in a Tooltip root (which doesn't render DOM) breaks Base UI's composite item registration. Since Base UI v1 collects items via context rather than DOM order, this should be fine as long as the items still register properly. Looking at the RightPanelTabs precedent, the same pattern of wrapping MenuItem in Tooltip works without issues. The key prop on the item variable is harmless in this context. Now I need to check the remaining components that were modified — ServeUpdateAction, ChangedFilesTree, ComposerPreviewAnnotationCards, and several others — to see if any have similar nesting problems. I'm particularly concerned about PullRequestActorLabel since it might already be wrapped in a TooltipTrigger or button, which could create nested interactive elements, though the Tooltip trigger's span rendering should be safe. The test file for ComposerPreviewAnnotationCards is checking for exactly 2 tooltip triggers in the markup, so if I've added extra tooltips elsewhere in that component's render tree, the test count could break. I need to verify the test expectations still hold. Looking at TargetStat, it builds the tooltip text outside the JSX which is clean. In DraftHeroHeadline, there's a TooltipTrigger wrapping a MenuTrigger inside a Menu — when the menu opens, the tooltip might stay open and overlap the menu popup since the tooltip has higher z-index (140 vs 130), though the positioning (tooltip top, menu bottom) probably prevents actual overlap. Base UI likely closes the tooltip when the trigger is clicked anyway. I should search the codebase to see if there's already a pattern for wrapping MenuTrigger or PopoverTrigger with Tooltip elsewhere, like in ProviderModelPicker or ComposerPrimaryActions. The regex approach isn't finding matches, so I'll try a simpler grep strategy—searching for <MenuTrigger with a few lines of context before it to spot the pattern in files like ChatHeader. Looking at how components nest their triggers, I'm checking that ThemeColorPicker follows the same pattern as the precedent with Tooltip wrapping PopoverTrigger, but DraftHeroHeadline has a slightly different structure where MenuTrigger is rendered inside TooltipTrigger with children passed directly. Now I'm realizing there's a critical styling issue: when TooltipTrigger wraps a Button, it sets data-slot="tooltip-trigger" which overrides the original data-slot="button", and I need to figure out if any CSS selectors depend on that button slot attribute. Let me search the codebase for selectors targeting [data-slot="button"], [data-slot="toggle"], and [data-slot="badge"] to see if any of the newly wrapped components—like the aspect ratio lock button in BrowserDeviceToolbar, the buttons in ThreadPreviewMiniPlayer, the toggle in ProjectContentSearchDialog, the badge in PullRequestDetailPanel, or the MenuTrigger in DraftHeroHeadline—are inside containers that rely on those slot selectors for styling. I'm noticing that the theme rules in index.css target specific button and toggle slots within certain containers, and wrapping those controls in a TooltipTrigger would bypass that styling. I need to identify which of the newly-wrapped controls are actually located in those containers—so far ProjectContentS is one of them. Now I'm checking whether SearchDialog's SearchOptionButton and BrowserDeviceToolbar's Button fall into those same containers. SearchOptionButton is probably not inside the panel or workspace titlebar controls since it's part of a search dialog, and the browser toolbar button is unlikely to be nested under the chat header. Let me verify the data-slot precedence and trace where these container attributes are actually applied in the codebase. The data-slot="tooltip-trigger" attribute takes precedence over the primitive's data-slot when rendering, which means newly-wrapped buttons inside [data-chat-header] and [data-workspace-titlebar-controls] lose their control icon color, background, border, and hover styling since the CSS selectors only target [data-slot="button"], [data-slot="menu-trigger"], or [data-toolbar-control]. I'm checking whether any of these newly wrapped controls are affected by this issue. Looking at the changed files, CompactFilterMenu in _chat.pull-requests.tsx renders MenuRadioItems inside a portal-ed popup, which renders at the body level so descendant selectors don't apply there. For BrowserDeviceToolbar, I need to verify whether it's inside a chat header and whether its buttons use data-toolbar-control attributes, and check the same for ThreadPreviewMiniPlayer buttons in the floating mini player. I'm checking whether the BrowserDeviceToolbar appears in the chat header and whether it's affected by theme CSS. Now I need to trace through which newly-wrapped Buttons and Toggles fall within the chat header or workspace controls, and whether the ChatView changes actually modified anything inside those regions—it looks like the only change there was removing a title element from the scroll-to-end button. For the sidebar, I'm looking at whether there are theme selectors that would apply to the wrapped elements, and checking if any of the newly-wrapped components like the Badge in PullRequestDetailPanel are inside InputGroups or other styled containers. I also need to verify whether the BrowserDeviceToolbar itself is wrapped in a Group component, since that affects how separators and button styling interact. Now I'm checking if the Player buttons are grouped together, and whether the SearchOptionButton Toggles in ProjectContentSearchDialog are inside a ToggleGroup, since those components have specific sibling selectors that could be affected by the wrapping changes. Checking if there are test files that rely on the data-slot attributes or title attributes for the components I'm changing — things like data-slot="button" in ComposerPreviewAnnotationCards.test.tsx or tests selecting elements by the title="Discard draft" attribute that I'm removing. Looking through the remaining accessibility conversions—the tooltip changes in ChangedFilesTree preserve the accessible name while providing the full path via tooltip, DiffPanel remote-only case is resolved, ServerUpdateProgress is fine, and I'm checking PullRequestChecksPopover where the trigger element needs review. The span with flex truncation classes is now rendered by TooltipTrigger, preserving the layout. Moving through FilePreviewPanel, ProjectSettingsPanel, and Sidebar—the draft discard button's pointer-events-none state works with group hover to enable the tooltip on row interaction. ThemeColorPicker and DraftHeroHeadline need verification that the trigger elements are properly positioned within their parent contexts. I need to check whether MenuTrigger losing the data-slot="menu-trigger" attribute now that TooltipTrigger wraps it will break anything. There's a CSS rule targeting [data-chat-header] [data-slot="menu-trigger"] at line 1349 in index.css, but since DraftHeroHeadline is in the hero section rather than the chat header, that shouldn't affect theming. I should search for any other selectors that might depend on the menu-trigger slot attribute. Looking at the data-slot selectors across the codebase — toggle-group and badge attributes are only used in specific places like input-group and toggle components, so there shouldn't be any broken dependencies when these elements are refactored or moved around. Now I need to verify that Badge can work as a render target inside TooltipTrigger, which requires checking if Badge properly forwards refs and spreads props through to its root element. In React 19, refs are passed as regular props to function components, so as long as Badge destructures and spreads its props onto the underlying span element, the composition should work correctly. Badge renders as a <span> by default, and when I use it with TooltipTrigger's render prop, Base UI merges the props onto the Badge element—so I end up with a span that has tooltip trigger attributes instead of button semantics. That's acceptable since it was previously just a span with a title attribute anyway. But I'm realizing Base UI's Tooltip.Trigger normally uses useRenderElement('button', ...), so the rendered tag depends on what the render prop provides—in this case, a span from Badge. The real concern is accessibility: tooltip triggers on non-focusable spans won't respond to keyboard interaction, only hover, which is the same limitation as before with title. More importantly, when title was the only accessible name for an icon-only control, replacing it with a tooltip that only sets aria-describedby when open means screen reader users get no accessible description when the tooltip is closed. I should check the diff to see which elements lost their title without gaining visible text or an aria-label—looks like most cases already have aria-label or visible text, though I need to verify the DiffPanel headRef span and any other edge cases. - ProjectSettingsPanel: aria-label kept ✓ - ThreadPreviewMiniPlayer: aria-labels kept ✓ - PullRequestListFilters route menu items: the reason moved to tooltip only, which was flagged before and fixed with pointer-events-auto, but keyboard navigation is still an issue—disabled menu items aren't focusable in Base UI menus, so keyboard users can't access the reason text. RightPanelTabs follows the same pattern, so it's consistent with the codebase. Now I'm checking whether the aria-pressed and disabled state styling stayed intact—the ProjectContentSearchDialog Toggle kept pressed={props.active} ✓. I also noticed that in ProjectScriptsControl, wrapping a Button in a tooltip removes the data-slot="button" attribute, so I need to verify whether ThreadPreviewMiniPlayer's toolbar has any Group or ButtonGroup styling that depends on [data-slot=button] selectors, since those buttons are in a plain div. I've already searched the repo and found data-slot=button only appears in group.tsx, input-group.tsx, index.css, and tests, so the main concern is Group and chat-header. Let me search the changed files to see if any modified controls are wrapped in a <Group> component. Checking that the changed files don't introduce any theming or data-slot regressions, and verifying the menu-item hunks still compile and respect the MenuPopup width-defaulting contract. I'm also looking at how PullRequestListFilters.tsx handles React keys on elements inside render functions, particularly whether Base UI's cloneElement behavior is compatible with how the MenuRadioItem is being used. I'm noticing a pattern of repeated "disabled reason tooltip" logic across multiple files — RightPanelTabs, PullRequestListFilters, and the chat pull-requests module all implement the same contract of disabled menu item plus reason tooltip plus the data-disabled:pointer-events-auto behavior. While this duplication is borderline, the subtle behavioral requirement makes it easy to get wrong, so extracting a shared helper would be a reasonable suggestion. I'm checking whether re-enabling pointer events on disabled menu items could accidentally allow clicks—but Base UI's disabled prop prevents the change handler from firing, so that's safe. Let me verify the other components follow the same pattern. I'm noticing a potential issue with the resize handle and tooltip interaction — when pointer capture is active during a drag, the tooltip might stay open and follow the trigger element, which could cause positioning problems. The resize handle tooltip isn't really a regression since the native title was there before. Now I need to do a final review of the key component sections—PullRequestListFilters, the sidebar, and the various tab and panel components—to make sure the key props are properly placed on both MenuRadioItem and Tooltip elements, and that the return logic doesn't accidentally drop keys when options are unavailable. Let me spot-check the PullRequestFiltersMenu region around lines 385-425 to verify the item variable and return statements are correct. The disabled-reason pattern is duplicated across multiple files, and since RightPanelTabs already has an unexported DisabledReasonTooltip component, it might be worth extracting this shared logic into a reusable helper to avoid the repetition. However, I need to be careful not to turn this focused PR into a demand for unrelated cleanup—extracting a helper across three files is more of a design suggestion than a regression, and the guidance warns against treating optional aesthetic preferences as blockers. Let me do a final sweep through the remaining files I haven't fully inspected yet: Sidebar, ChangedFilesTree, ComposerPreviewAnnotationCards, FilePreviewPanel, ProjectSettingsPanel, PullRequestSummaryTab, PullRequestCodeTab, ThemeColorPicker, PullRequestChecksPopover, and pullRequestPresentation. I'm particularly concerned about PullRequestActorLabel in pullRequestPresentation—I need to check where it's used and whether it could end up nested inside another Tooltip trigger or inside a button element, which would create problematic nested tooltips or invalid DOM structures. I found a real regression in PullRequestSummaryTab.tsx where child selectors in the className are targeting specific elements within PullRequestActorLabel—an avatar image and span elements—that depend on the component's internal DOM structure. The component was refactored to wrap its content in a Tooltip component, but the DOM structure itself remains the same: a root span with the same two children (avatar and login text). However, there's a critical issue: PullRequestActorLabel is now nested inside another TooltipTrigger from the avatar stack tooltip in PullRequestSummaryTab, which creates nested tooltips that could break the expected behavior. So the visual result is two popups instead of one styled popup plus a delayed native tooltip. The nested tooltip structure is definitely a regression worth noting—two Tooltip components triggering on the same element. Let me examine the full context to see if this is significant enough to flag. I'm seeing a concrete issue here: wrapping PullRequestActorLabel in a nested TooltipTrigger creates a tooltip conflict where hovering over an avatar now triggers two popups simultaneously—the outer one showing "Name (@login)" from the bottom and the inner one showing just the login from the top, both anchored to nearly the same spot. This is a clear regression that needs fixing. The inner tooltip adds no value since the outer one already displays both the name and login. There's also an accessibility concern: the outer trigger has an aria-label, and when the inner tooltip opens, Base UI sets aria-describedby on its trigger, which could interfere with the outer trigger's semantics and hover logic. The simplest solution is to make the login tooltip optional—either add a prop like showTooltip or tooltip={false} to PullRequestActorLabel, or better yet, keep the label as a plain span and let call sites that need truncation handle the tooltip wrapping themselves. There's another place where this causes issues: in PullRequestReviewerPicker around line 166, the label sits inside a button element, so now hovering the button row shows a tooltip with the login that's already visible as text in the row—redundant but not breaking. Looking at other components that migrated from title to Tooltip, I'm checking whether PullRequestActorLabel appears nested inside a TooltipTrigger anywhere else—so far only found in PullRequestSummaryTab around line 481. I should verify whether the nested-trigger case actually causes both tooltips to open simultaneously based on how Base UI's Tooltip.Trigger behaves. Checking other instances across the codebase — PullRequestDetailPanel has a tooltip wrapping a repository span, ConnectionsSettings looks fine, and I need to verify whether the commit headline span in PullRequestCodeTab around line 1009 is nested inside an existing tooltip trigger since there are other triggers nearby at lines 1043 and 1057. I found the concrete issue: the nested tooltip appearing in the reviewers avatar stack because PullRequestActorLabel now has its own tooltip. The outer trigger span with an aria-label and the actor label (which is now a trigger itself) both open on hover, creating two competing popups. The simplest fix would be to add an optional prop to PullRequestActorLabel to disable the tooltip when needed, then pass that flag when using it in the avatar stack context. I'll place an inline comment on the Tooltip wrapper in pullRequestPresentation.tsx (around line 235-243 in the diff) to flag the nested-tooltip issue at the call site where the label gets used with the reviewer avatar stack, and suggest either adding a prop to opt out or keeping the label plain so truncating contexts can manage their own tooltip behavior. I'm pinpointing the exact lines in the pullRequestPresentation.tsx diff where the Tooltip component was added—lines 235 through 243—so I can place my comment at the right location in the code review. Now I'm thinking through the actual issue: this label component has its own tooltip that just repeats the login text, but that text is already visible in most places where the label is used. The one exception is the avatar stack in PullRequestSummaryTab where the login is screen-reader-only. Since the label itself uses truncation with a max-width constraint, a tooltip makes sense for that specific usage, but not universally. The cleanest fix would be to add a prop that lets call sites opt out of the tooltip, then pass tooltip={false} at the avatar-stack call site to avoid the redundant tooltip there. For the check result, this nested-tooltip situation is a regression risk that warrants reporting as a failure. The check defaults to failure when findings exist, so I'll mark this with one finding and set the state to failure. I'm also reconsidering whether the double tooltip actually triggers—mouseenter doesn't bubble, but the browser does dispatch it to each element in the ancestor chain when the pointer enters, so both the outer span and inner label would fire their hover handlers. Base UI's floating-ui likely uses mouseenter for its hover detection, which means both tooltips would activate simultaneously. Now I'll post the review.

1. modify_pr — One finding: PullRequestActorLabel now owns a tooltip, which stacks a second popup on the reviewer avatar stack that already wraps it in its own tooltip trigger. Everything else in this migration (disabled menu items re-enabling pointer events per the RightPanelTabs contract, render={<Button/>}/render={<PopoverTrigger/>} composition, preserved aria-labels, scoped triggers next to the freshness popover and the base-ref combobox) matches existing conventions, and no wrapped control sits under a [data-slot="button"]/[data-slot="toggle"] themed container or a Group, so the trigger's data-slot takeover has no styling fallout here.


Agent Credits: 439 credits