fix: prevent animateOnMount from overriding running close animations #2529
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.
Motivation
The BottomSheetModal component has a critical issue when
bottomSheetRef.current?.present()andbottomSheetRef.current?.close()are called programmatically throughuseEffecthooks triggered by state changes, causing the modal to remain open instead of closing properly.Problem:
When
openchanges rapidly (e.g., in Storybook controls or programmatic state changes), theuseEffectcallsbottomSheetRef.current?.present()andbottomSheetRef.current?.close()in quick succession. TheanimateOnMountcall from the present action overrides thehandleForceCloseanimation from the close action, causing the modal to stay open and become frozen - unable to be closed afterward.Example:
Root Cause:
In the
evaluatePositionfunction, when!isAnimatedOnMount.valueis true (which happens when the modal is being presented), the code immediately callsanimateToPositionwithout checking if there's already a running animation that should be respected. This allows mount animations to override ongoing close animations, especially problematic when React's state batching and effect scheduling cause rapid successive calls.Expected vs Actual Behavior:
open = true→bottomSheetRef.current?.present()→open = false→bottomSheetRef.current?.close()→ Modal closes properlyopen = true→bottomSheetRef.current?.present()→open = false→bottomSheetRef.current?.close()→open = true(rapid) →bottomSheetRef.current?.present()→ Modal stays open and becomes frozenTechnical Details:
The issue occurs in
BottomSheet.tsxlines 965-985 where the mount animation logic doesn't respect running animations. The fix adds a check foranimationStatus === ANIMATION_STATUS.RUNNINGbefore handling mount animations, ensuring that force close operations are not interrupted by subsequent present calls triggered by React's state update timing.Impact:
This affects programmatic usage of BottomSheetModal where state-driven present/dismiss calls are common, such as in Storybook controls, form workflows, conditional rendering, or user interaction handlers. The fix ensures consistent and predictable modal behavior regardless of React's state update timing and prevents the modal from becoming permanently frozen.