Skip to content

chore: Refine exit motion for global drawer #3529

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 11 commits into
base: main
Choose a base branch
from

Conversation

at-susie
Copy link
Member

@at-susie at-susie commented May 21, 2025

Description

This PR fixes an animation issue for global-drawer.
We would like to have a smooth transition when a drawer is being closed.

Before this change, the style drawer-hidden was added immediately when a close button is clicked, which was one of the two reasons for the unwanted sudden closing behavior. To address this, an additional condition has been added to make sure only after the Transition's component state becomes exited.:
[styles['drawer-hidden']]: !show && state === 'exited'
And I updated relevant styles accordingly.

Additionally, I've added Transition component to the global-tools in the skeleton to ensure only after it gets the panel-hidden style.

Issue-2.mp4

Related links, issue #, if available: n/a

How has this been tested?

Review checklist

The following items are to be evaluated by the author(s) and the reviewer(s).

Correctness

  • Changes include appropriate documentation updates.
  • Changes are backward-compatible if not indicated, see CONTRIBUTING.md.
  • Changes do not include unsupported browser features, see CONTRIBUTING.md.
  • Changes were manually tested for accessibility, see accessibility guidelines.

Security

Testing

  • Changes are covered with new/existing unit tests?
  • Changes are covered with new/existing integration tests?

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@at-susie at-susie marked this pull request as ready for review May 21, 2025 09:11
@at-susie at-susie requested a review from a team as a code owner May 21, 2025 09:11
@at-susie at-susie requested review from avinashbot and georgylobko and removed request for a team and avinashbot May 21, 2025 09:11
Copy link

codecov bot commented May 21, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 96.56%. Comparing base (250c45e) to head (63e8600).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3529      +/-   ##
==========================================
+ Coverage   96.54%   96.56%   +0.01%     
==========================================
  Files         805      805              
  Lines       23446    23449       +3     
  Branches     7750     8106     +356     
==========================================
+ Hits        22637    22644       +7     
+ Misses        802      752      -50     
- Partials        7       53      +46     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@at-susie at-susie requested a review from just-boris May 21, 2025 10:38
@at-susie
Copy link
Member Author

Replaced the 3rd party Transition component with the internal one. This change provides an expected motion behavior that we wanted to achieve with minimum change on the global drawer style.

One note is that the appear props is not available in the internal Transition component. If necessary we can introduce i, but before that I want to discuss if it's necessary.

@@ -75,8 +75,9 @@ function AppLayoutGlobalDrawerImplementation({
(wasExpanded && !isExpanded);

return (
<Transition nodeRef={drawerRef} in={show || isExpanded} appear={show || isExpanded} timeout={0}>
{state => {
<Transition in={show} exit={!show}>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: Removed isExpanded condition because when 'isExpanded' it's always show.

Copy link
Member Author

@at-susie at-susie May 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: The appear props is not available in the internal Transition component. If necessary we can introduce it, but before that I want to discuss if it's necessary.

Copy link
Member

@georgylobko georgylobko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR introduces a closing animation only for global drawers with preserveInactiveContent: true, and only after they’ve been opened at least once. The first open is not animated. However, it also breaks the existing animation for global drawers that don’t use preserveInactiveContent: true. See the video below for reference.

Screen.Recording.2025-05-26.at.15.09.44.mov

@at-susie
Copy link
Member Author

at-susie commented May 26, 2025

This PR introduces a closing animation only for global drawers with preserveInactiveContent: true, and only after they’ve been opened at least once. The first open is not animated. However, it also breaks the existing animation for global drawers that don’t use preserveInactiveContent: true. See the video below for reference.

@georgylobko I've addressed those issues as follows:

  1. "closing animation only for global drawers with preserveInactiveContent: true"

    • Fixed by removing the defaultActive condition from animationDisabled
  2. "only after they've been opened at least once. The first open is not animated"

    • Fixed by using hasOpened state to control Transition's in prop
    • First open is now properly animated with appear={true} and proper state management
  3. "breaks the existing animation for global drawers that don't use preserveInactiveContent: true"

    • Fixed by removing the preserveInactiveContent-related checks
    • global-drawers now have consistent animation behavior regardless of their settings

Note:
I've checked other Transition component instances that use our internal Transition component which are:

  • src/app-layout/visual-refresh/split-panel.tsx (used only for bottom position)
  • src/app-layout/visual-refresh/navigation.tsx
    The changes on the internal Transition component don't create any regression.

@at-susie at-susie requested a review from georgylobko May 26, 2025 16:24
Copy link
Member

@georgylobko georgylobko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed by removing the defaultActive condition from animationDisabled

this code was introduced on purpose and should be there, it makes sure that animation is not applied on initial load in consoles. you cannot just remove existing conditions

Fixed by using hasOpened state to control Transition's in prop

why? you already have a prop show. what is the purpose of this addition?

@at-susie
Copy link
Member Author

@georgylobko Thanks for your feedback!

Fixed by removing the defaultActive condition from animationDisabled

Got it, I've brought it back.

Fixed by using hasOpened state to control Transition's in prop

When a drawer mounts with show=true, the Transition component's initial state is 'entered' (from its useState logic). This skips the animation sequence because it starts in the final state, preventing it from having the first-open motion. This ensures we get:

  • Initial mount: 'exited' state
  • After useEffect: 'enter' -> 'entering' -> 'entered'

Without hasOpened, we'd get:

  • Initial mount: 'entered' state (no animation)
  • Subsequent opens: 'enter' -> 'entering' -> 'entered'

The state is necessary to force the proper animation sequence on first mount, while still respecting the animationDisabled logic.

if (!hasTriggerButton) {
return;
}
<Transition in={hasOpened && show} exit={!show}>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious why this file got completely reformatted? Could you check your linter and turn it back?

setTransitionState('enter');
onStatusChange('enter');
}
appear={true}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This component is used in multiple other places. Did you make sure other components / use cases aren't affected?

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.

3 participants