fix(scraps): Stop tooltip content clicks from triggering ancestors - #121155
Open
TkDodo wants to merge 2 commits into
Open
fix(scraps): Stop tooltip content clicks from triggering ancestors#121155TkDodo wants to merge 2 commits into
TkDodo wants to merge 2 commits into
Conversation
Tooltip content is portaled to the document body, but React events still bubble through the React component tree — so clicking inside a tooltip reaches the interactive ancestor the tooltip is nested in (a Link, tab, menu item, or a Button wrapping an InfoText label) and fires its action. This is easy to hit with a hoverable tooltip whose content is interactive or selectable: e.g. a Button whose label carries an InfoText would finalize on a click aimed at a link inside the tip. Stop the interaction-initiating events at the portaled overlay so tooltip content never triggers the element the tooltip is attached to. Removes the now-redundant manual stopPropagation workaround in Version.
Contributor
Story previewsPreview the stories changed in this PR on the Vercel deployment: Preview deployment: https://sentry-qudlsl0zg.sentry.dev |
Collaborator
Author
|
bugbot run |
Contributor
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 3871a37. Configure here.
TkDodo
marked this pull request as ready for review
August 4, 2026 13:06
natemoo-re
reviewed
Aug 4, 2026
Comment on lines
+108
to
+110
| onClick={stopPropagation} | ||
| onMouseDown={stopPropagation} | ||
| onPointerDown={stopPropagation} |
Member
There was a problem hiding this comment.
as written, these will override existing handlers for those events on overlayProps. we should create a merged function that calls the user-supplied callback after stopPropagation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Tooltip content is portaled to
document.body, but React events still bubble through the React component tree — not the DOM tree. So a click inside a tooltip reaches whatever interactive element the tooltip is nested within and fires its action. Clicking a link inside the tooltip, or pressing a button in it, or even selecting the tooltip text, would trigger the ancestor.This bites whenever an interactive element is an ancestor of the
<Tooltip>(as opposed to being the tooltip's trigger, which is a harmless sibling of the content). Concrete cases:FeatureBadgein a tab header: clicking the badge tooltip navigates the tab.Versiondropped inside a clickable row: clicking the copy button in its tooltip triggers the row.Buttonwhose label carries anInfoText: a click aimed at a link inside the tip fires the button (e.g. finalizing a release).The fix stops the interaction-initiating events (
click,mousedown,pointerdown) at the portaled overlay, so tooltip content can never trigger the element the tooltip is attached to. This covers both event models — react-router<Link>fires onclick, react-aria tabs and menu items fire onpointerdown. Non-triggering events (text selection, keyboard) are left untouched.Versionpreviously worked around this with a manualstopPropagationon its tooltip content; that's now redundant and is removed.before:
tooltip-before.mov
after:
tooltip-after.mov