Repository navigation
Flyout: freeze content during the hide animation and animate it by default - #675
Merged
Merged
Conversation
…fault Adds an internal Freeze component that suspends its children without a fallback, so React keeps their last committed DOM while ignoring updates from props, state and context, and reveals the DOM React hides for the suspended tree. Freezing in a transition, which would never commit, gives up after a short timeout instead of blocking it. Flyout content is frozen as soon as it stops being active, so Select, DropdownMenu and Autocomplete no longer need to disable the hide animation. disableHideAnimation is kept as an opt-out. Also fixes issues surfaced by animating these components: - aria-expanded reports the collapsed state as soon as the flyout closes - content that's animating out ignores pointer events - content closed before its open transition started is removed right away, since the cancelled transition never fires transitionend - focus trap is released when the content is removed without animation Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TFwAYqyYv9BQJuc5zDGzgv
size-limit report 📦
|
blvdmitry
marked this pull request as ready for review
October 8, 2026 23:11
…with a sibling Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TFwAYqyYv9BQJuc5zDGzgv
…aria attributes as before Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TFwAYqyYv9BQJuc5zDGzgv
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.
Summary
Brings back the Flyout hide animation for every component built on it, using the Suspense "freeze" technique from A React trick to improve exit animations.
New internal
_private/Freezecomponentfrozen, a sibling<Suspend />suspends the boundary with no fallback. React keeps the DOM from the last commit and stops committing updates from props, state or context.display: none !important. Freeze undoes this in auseInsertionEffect, the earliest point in the same commit, before paint.display: contentswrapper also stops React from blanking top-level text nodes and doesn't overwrite the children's own inlinedisplay.startTransitionwould block that transition forever. If the frozen render doesn't commit within 100ms, Freeze gives up and renders the children normally. Covered by a story that fails without this.Flyout
Flyout.Contentwraps its children in<Freeze frozen={!active}>.activeis now passed through context, so the freeze happens in the same render as the close.disableHideAnimationfromSelect,DropdownMenu(which forced it for every non-hover trigger) andAutocomplete. The prop is still supported and still decides between animated and immediate removal.Fixes for problems that turning the animation on exposed
hiddenstate. Per the CSS transitions spec, the transition is cancelled instead of reversed, sotransitionendnever fires. On hide, Flyout now removes the content right away if it has no running animations. This already affected Popover.hidden, unlessdisableHideAnimationwas set. Select used to set it, so Select avoided this. Covered by a story that fails with the old condition.Related Issue
None
Screenshots / Recordings
Visual change:
Select,DropdownMenuandAutocompletenow animate out. Their content keeps its pre-close state while it animates out.Notes for Reviewers
Internal/Freeze, plus three Flyout tests: content doesn't change while closing, close right after opening, and focus returns with transitions disabled.aria-expandedto turn false, since both now happen after the exit animation.Image › onLoad, which also fails onmainin my sandbox because it loads a remote image. Unit tests, lint and typecheck pass.🤖 Generated with Claude Code
https://claude.ai/code/session_01TFwAYqyYv9BQJuc5zDGzgv