Repository navigation
fix(react): match Base UI Tooltip behaviour - #871
Merged
Merged
Conversation
This was referenced Oct 2, 2026
Ernxst
force-pushed
the
tooltip-base-ui
branch
from
October 2, 2026 19:13
8a72d03 to
2ac22bf
Compare
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.
Harness: Codex
Agent: none
Model: gpt-6-astra
Task statements
Port Base UI 1.8.0 Tooltip tests to GPU-IX and record observable differences. (Working-directory and workflow instructions omitted.)
Fix the reported Tooltip differences and land the parity cases with verification. (Working-directory and workflow instructions omitted.)
Changes
Tooltip now matches Base UI's observable trigger, popup and portal behaviour across controlled state, event details, accessibility, detached handles and positioning. A Tooltip Positioner also reports the required Portal composition error, and the viewport exposes and remounts its current container when the active trigger changes.
Nested-trigger behaviour remains unresolved under #859 — Tooltip.Trigger drops nested children when rendering a custom element. The attempted implementation still failed Windows React shard 2/3: focusing a nested Trigger left the outer popup mounted. The nested-trigger implementation and tests are excluded from this PR, and #859 remains open.
Previous-content morphing, transition cleanup and transition-direction behaviour remain out of scope because the native renderer does not expose retained rendered-subtree snapshots or animation-lifecycle events; issue #879 — Tooltip.Viewport drops previous content during animated trigger changes tracks those cases.
Baseline differences
mainTooltip.Positioneris missing.details.cancelanddetails.allowPropagationwere not functions.openemitted another change.aria-hiddenwas absent.handle.open("missing-trigger")did not report a missing trigger.sideOffsetandalignOffsetreported expectedend, receivedstart.flip, preserving the resolvedendplacement.pointerEventswas absent.handle.isOpenfalse after the outgoing Root unmounted.Base UI: <Tooltip.Portal> is missing.The Tooltip parity ledger has 131 applicable cases: 84 passed on
mainand 47 failed. This PR fixes 24 of those failures; the 23 nested-trigger cases tracked by #859 remain unresolved and are excluded. Eight cases do not apply to GPU-IX. Nineteen cases remain out because the native renderer lacks the support they need.The regression coverage also includes the focus-leaves-triggers behaviour from #834, hover close delays, provider handoff and the Tooltip Positioner offset cases. The focus test does not reproduce the consumer's reported Tab sequence; its exact command and output are recorded in the parity table.
Cases that need renderer support
TooltipPositioner.test.tsx#throws a descriptive error when rendered outside <Tooltip.Root>— the native renderer suppresses render-time React errors instead of exposing a thrownrender()error.TooltipRoot.detached-triggers.test.tsx#keeps a default-open root open while a detached trigger migrates after the initial commit— GPU-IX has no server-rendering or hydration support.TooltipRoot.detached-triggers.test.tsx#should switch to a rendered disabled button trigger when trigger hover is enabled— the native test renderer cannot dispatch hover to a disabled button.TooltipRoot.test.tsx#should not open the outer tooltip when hovering over a nested trigger inside a shadow root— the native renderer has no ShadowRoot support.TooltipRoot.test.tsx#handles a composed path that starts with a ShadowRoot— the native renderer has no ShadowRoot orcomposedPathevent support.TooltipRoot.test.tsx#handles a composed path that is empty— the native renderer has no ShadowRoot orcomposedPathevent support.TooltipRoot.test.tsx#should not reopen the outer tooltip via the local reopen path for touch pointers— the native renderer has no pointer-event simulator or pointer-type parameter.TooltipRoot.test.tsx#should allow mouse hover after leaving a touch interaction— the native renderer has no pointer-event simulator or pointer-type parameter.TooltipTrigger.test.tsx#throws a descriptive error when rendered without a root or a handle— the native renderer suppresses render-time React errors instead of exposing a thrownrender()error.TooltipViewport.test.tsx#should create morphing containers during transitions— the native renderer does not expose retained rendered-subtree snapshots or animation-completion events.TooltipViewport.test.tsx#keeps the latest transition active during rapid trigger changes— the native renderer does not expose retained rendered-subtree snapshots or animation-completion events.TooltipViewport.test.tsx#cleans up the transition when a lagging payload remounts the current container— the native renderer does not expose retained rendered-subtree snapshots or animation-completion events.TooltipViewport.test.tsx#should calculate right down direction— the native renderer does not expose the transition lifecycle needed to observe prior and current trigger geometry.TooltipViewport.test.tsx#should calculate left up direction— the native renderer does not expose the transition lifecycle needed to observe prior and current trigger geometry.TooltipViewport.test.tsx#should calculate right (horizontal only) direction— the native renderer does not expose the transition lifecycle needed to observe prior and current trigger geometry.TooltipViewport.test.tsx#should calculate down (vertical only) direction— the native renderer does not expose the transition lifecycle needed to observe prior and current trigger geometry.TooltipViewport.test.tsx#should handle tolerance for small differences— the native renderer does not expose the transition lifecycle needed to observe prior and current trigger geometry.TooltipViewport.test.tsx#should calculate left down direction— the native renderer does not expose the transition lifecycle needed to observe prior and current trigger geometry.TooltipViewport.test.tsx#should calculate right up direction— the native renderer does not expose the transition lifecycle needed to observe prior and current trigger geometry.GitHub's
pull_requestCI run 37066776451 passed on macOS, Linux and Windows for this head. Nested-trigger behaviour tracked by #859 remains unverified: the previous Windows React shard 2/3 run failed its focus test because the outer popup stayed mounted (run 37064016778), so the nested-trigger tests and implementation are excluded from this PR.Closes #845
Closes #846
Closes #847
Closes #848
Closes #849
Closes #851
Closes #852
Closes #853
Closes #856
Closes #857
Closes #862
Closes #885