Skip to content

fix(Tooltip, overlays): hide on close even when the closed render lands late on Server (#608) - #609

Merged
mathewtaylor merged 1 commit into
v4.2.0from
foreman/ml-579
Oct 13, 2026
Merged

mathewtaylor merged 1 commit into
v4.2.0from
foreman/ml-579

Conversation

@mathewtaylor

@mathewtaylor mathewtaylor commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #608.

Cause. overlay.close is dispatched from OnParametersSet, so it reaches the browser ahead of the render that writes data-state="closed". When the portal host is still waiting on the browser to acknowledge its previous batch (for example the open render, just before a quick mouse leave), the closed render is deferred a full round trip. hidePosition read data-state after one frame to tell a reopen from a close, saw "open", and returned without hiding. The inline visibility: visible !important; opacity: 1 !important from the open stayed.

Fix. hidePosition takes an optional reopen check. overlay.close passes its own token check, so only a real reopen (overlay.open takes a new token) cancels the hide. Direct hidePosition callers (IPositioningService.HidePositionAsync) keep the data-state check. No public API change.

Tests. New tests/js/overlay-close.test.mjs runs the real overlay.close and hidePosition:

  • a close that arrives before the closed render hides the overlay (failed before the fix)
  • a reopen during the exit animation, before its own render lands, keeps the overlay visible (also failed before: the old check hid it because data-state still said closed)

Server demo, with 100 ms added each way between the browser and the circuit (Chrome, DelayDuration="0" tooltip on /primitives/tooltip):

  • before: 22 of 30 hover-and-leave rounds left the tooltip on screen, data-state="closed" with the inline visible styles
  • after: 0 of 30
  • Popover reopened during its exit animation: 16 of 16 stayed open and visible
  • with no added delay: tooltip 0 of 10 stuck, Popover reopen 16 of 16

The issue's own repro (6x CPU slowdown, no added delay) did not reproduce locally: 0 of 30. Latency is what triggers it here.

Note. When the close lands before the closed render, the exit animation has not started yet, so the overlay hides without its fade. Before this fix it stuck on screen in that case.

Type of Change

  • Bug fix (non-breaking change that fixes an issue)

Testing Checklist

  • Blazor Server
  • Blazor WebAssembly
  • Blazor Hybrid (MAUI)
  • Keyboard navigation / accessibility
  • Dark mode

…ds late on Server (#608)

overlay.close reaches the browser ahead of the render that writes
data-state="closed", up to a round trip ahead when the portal host is still
waiting on its previous batch. hidePosition read data-state to tell a reopen
from a close, saw "open", and skipped the hide, leaving the overlay on screen.

overlay.close now passes its own token check, so only a real reopen (which
takes a new token) cancels the hide. Direct hidePosition callers keep the
data-state check.
@mathewtaylor
mathewtaylor marked this pull request as ready for review October 13, 2026 01:26
@mathewtaylor
mathewtaylor merged commit 0de906f into v4.2.0 Oct 13, 2026
1 check passed
@mathewtaylor
mathewtaylor deleted the foreman/ml-579 branch October 13, 2026 01:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant