Skip to content

chore: migrated from react-transition-group to framer-motion #339

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

Conversation

mgDentist
Copy link

@mgDentist mgDentist commented Apr 28, 2025

PR Type

Enhancement


Description

  • Migrated all UI transitions from react-transition-group to framer-motion

    • Updated animation logic in multiple React components
    • Replaced transition code with framer-motion's motion and AnimatePresence
  • Removed react-transition-group and its types from dependencies

  • Added framer-motion as a new dependency

  • Minor CSS class renaming for consistency


Changes walkthrough 📝

Relevant files
Dependencies
2 files
package.json
Replace react-transition-group with framer-motion in dependencies
+2/-3     
pnpm-lock.yaml
Update lockfile for framer-motion and dependency changes 
+42/-10 
Enhancement
5 files
DiveTransition.tsx
Refactor dive transition to use framer-motion                       
+21/-31 
HotbarRenderApp.tsx
Use framer-motion for item name fade animation                     
+20/-21 
MainMenuRenderApp.tsx
Switch main menu transition to framer-motion                         
+45/-34 
Notification.tsx
Refactor notification slide animation to framer-motion     
+20/-38 
Title.tsx
Use framer-motion for title and action bar fade transitions
+39/-71 
Formatting
1 files
Title.css
Rename .action-bar to .message-action-bar for clarity       
+1/-1     

Need help?
  • Type /help how to ... in the comments thread for any questions about Qodo Merge usage.
  • Check out the documentation for more information.
  • Summary by CodeRabbit

    • New Features
      • Improved animation smoothness and consistency across various components by switching to a new animation library.
    • Refactor
      • Updated multiple UI components to use a declarative animation approach for transitions and visibility.
      • Renamed the action bar CSS class for clearer styling.
      • Added conditional animation behavior for error states in transition components.
    • Chores
      • Updated dependencies: replaced the previous animation library with a new one and removed related type definitions.

    Copy link

    codesandbox bot commented Apr 28, 2025

    Review or Edit in CodeSandbox

    Open the branch in Web EditorVS CodeInsiders

    Open Preview

    Copy link

    coderabbitai bot commented Apr 28, 2025

    Walkthrough

    This update migrates the animation and transition logic in several React components from react-transition-group to framer-motion. The change involves updating the dependencies in package.json, removing both the animation library and its type definitions, and adding framer-motion instead. In the source files, all usages of Transition are replaced with motion and AnimatePresence components from framer-motion, with animation states now declared using props like initial, animate, and exit. Additionally, a CSS class is renamed to reflect updated naming conventions. A new optional isError prop is introduced in DiveTransition to conditionally disable exit opacity animation, and it is passed accordingly in AppStatusProvider.

    Changes

    File(s) Change Summary
    package.json Removed react-transition-group and its type definitions; added framer-motion to dependencies.
    src/react/DiveTransition.tsx
    src/react/HotbarRenderApp.tsx
    src/react/MainMenuRenderApp.tsx
    src/react/Notification.tsx
    src/react/Title.tsx
    Replaced react-transition-group's Transition with framer-motion's motion and AnimatePresence for animations. Updated animation logic to declarative props. Added isError prop to DiveTransition.
    src/react/AppStatusProvider.tsx Passed new isError prop to DiveTransition wrapping AppStatus.
    src/react/Title.css Renamed CSS class .action-bar to .message-action-bar.

    Sequence Diagram(s)

    Loading
    sequenceDiagram
        participant UI as User Interface
        participant FM as framer-motion
        participant Component as React Component
    
        UI->>Component: Trigger show/hide event
        Component->>FM: Render with AnimatePresence/motion.div
        FM-->>Component: Animate (initial → animate → exit)
        Component-->>UI: Rendered with animated transition
    

    Poem

    In the garden of code where transitions bloom,
    Framer Motion hops in, banishing gloom.
    Old transitions retire, new ones take flight,
    Animations now smooth, lively, and light.
    A bunny applauds with a jubilant cheer—
    "Our UI is dancing, springtime is here!"
    🐇✨


    📜 Recent review details

    Configuration used: CodeRabbit UI
    Review profile: CHILL
    Plan: Pro

    📥 Commits

    Reviewing files that changed from the base of the PR and between 918ed3b and 28ef7b3.

    📒 Files selected for processing (2)
    • src/react/AppStatusProvider.tsx (1 hunks)
    • src/react/DiveTransition.tsx (3 hunks)
    🚧 Files skipped from review as they are similar to previous changes (1)
    • src/react/DiveTransition.tsx
    ⏰ Context from checks skipped due to timeout of 90000ms (1)
    • GitHub Check: build-and-deploy
    🔇 Additional comments (2)
    src/react/AppStatusProvider.tsx (2)

    169-169: Successfully updated DiveTransition with isError prop

    The isError prop has been correctly added to the DiveTransition component, aligning with the migration from react-transition-group to framer-motion. This prop will appropriately disable exit opacity animation when in an error state.


    172-172: Clear comment explaining conditional logic

    The comment clarification effectively explains why the back button is displayed when status is empty. This helps maintain code readability during the animation library migration.

    ✨ Finishing Touches
    • 📝 Generate Docstrings

    Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

    ❤️ Share
    🪧 Tips

    Chat

    There are 3 ways to chat with CodeRabbit:

    • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
      • I pushed a fix in commit <commit_id>, please review it.
      • Generate unit testing code for this file.
      • Open a follow-up GitHub issue for this discussion.
    • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
      • @coderabbitai generate unit testing code for this file.
      • @coderabbitai modularize this function.
    • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
      • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
      • @coderabbitai read src/utils.ts and generate unit testing code.
      • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
      • @coderabbitai help me debug CodeRabbit configuration file.

    Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

    CodeRabbit Commands (Invoked using PR comments)

    • @coderabbitai pause to pause the reviews on a PR.
    • @coderabbitai resume to resume the paused reviews.
    • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
    • @coderabbitai full review to do a full review from scratch and review all the files again.
    • @coderabbitai summary to regenerate the summary of the PR.
    • @coderabbitai generate docstrings to generate docstrings for this PR.
    • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
    • @coderabbitai resolve resolve all the CodeRabbit review comments.
    • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
    • @coderabbitai help to get help.

    Other keywords and placeholders

    • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
    • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
    • Add @coderabbitai anywhere in the PR title to generate the title automatically.

    CodeRabbit Configuration File (.coderabbit.yaml)

    • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
    • Please see the configuration documentation for more information.
    • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

    Documentation and Community

    • Visit our Documentation for detailed information on how to use CodeRabbit.
    • Join our Discord Community to get help, request features, and share feedback.
    • Follow us on X/Twitter for updates and announcements.

    PR Reviewer Guide 🔍

    Here are some key observations to aid the review process:

    ⏱️ Estimated effort to review: 2 🔵🔵⚪⚪⚪
    🧪 No relevant tests
    🔒 No security concerns identified
    ⚡ Recommended focus areas for review

    CSS Class Mismatch

    The CSS class name was changed from 'action-bar' to 'message-action-bar' in Title.css, but the component renders with this class. Verify that all references to this class are updated consistently.

    <div className='message-action-bar'>
      <MessageFormattedString message={actionBar} />
    
    Pointer Events

    The pointer events property was changed from empty string to 'auto' which might behave differently. Confirm this change is intentional and doesn't affect interaction behavior.

    pointerEvents: action ? 'auto' : 'none',
    zIndex: 1200,
    

    Copy link

    qodo-merge-pro-for-open-source bot commented Apr 28, 2025

    PR Code Suggestions ✨

    Explore these optional code suggestions:

    CategorySuggestion                                                                                                                                    Impact
    General
    Verify CSS class name change

    The CSS class name was changed from 'action-bar' to 'message-action-bar' in the
    Title.css file, but the corresponding JSX element in Title.tsx is using the new
    class name. Ensure this change is intentional and that the CSS styles are
    properly applied.

    src/react/Title.tsx [73]

    +<div className='message-action-bar'>
     
    -
    • Apply this suggestion
    Suggestion importance[1-10]: 3

    __

    Why: The suggestion correctly identifies the renaming of the CSS class from action-bar to message-action-bar in both Title.css and Title.tsx. It asks the user to verify this change, which is already consistently applied in the PR. The impact is low as it only confirms an existing, correct modification.

    Low
    • Update

    Copy link

    @coderabbitai coderabbitai bot left a comment

    Choose a reason for hiding this comment

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

    Actionable comments posted: 0

    🧹 Nitpick comments (2)
    src/react/Title.tsx (1)

    29-38: Consider removing unused mounted state.

    The mounted state doesn't appear to be used for rendering anymore since AnimatePresence now handles the mounting/unmounting of components. Consider removing this state and the associated useEffect to simplify the code.

    -  const [mounted, setMounted] = useState(false)
    
    -  useEffect(() => {
    -    if (!mounted && (openTitle || openActionBar)) {
    -      setMounted(true)
    -    }
    -  }, [openTitle, openActionBar])
    src/react/DiveTransition.tsx (1)

    8-26: Consider simplifying mounting logic.

    There's redundancy between the manual mounting state management and AnimatePresence. Since AnimatePresence now handles the mounting/unmounting of components based on the open prop, you could potentially simplify this code.

    Consider one of these approaches:

    1. If you need the delayed unmounting behavior:
    - const [mounted, setMounted] = useState(false)
    + const [shouldRender, setShouldRender] = useState(false)
    
      useEffect(() => {
    -   if (!mounted && open) {
    -     setMounted(true)
    +   if (open) {
    +     setShouldRender(true)
        }
        let timeout
    -   if (mounted && !open) {
    +   if (!open && shouldRender) {
          timeout = setTimeout(() => {
    -       setMounted(false)
    +       setShouldRender(false)
          }, durationInMs)
        }
        return () => {
          if (timeout) clearTimeout(timeout)
        }
      }, [open])
    
    - if (!mounted) return null
    + return (
    +   shouldRender ? (
    +     <AnimatePresence>
    1. Or completely rely on AnimatePresence:
    - const [mounted, setMounted] = useState(false)
    - 
    - useEffect(() => {
    -   if (!mounted && open) {
    -     setMounted(true)
    -   }
    -   let timeout
    -   if (mounted && !open) {
    -     timeout = setTimeout(() => {
    -       setMounted(false)
    -     }, durationInMs)
    -   }
    -   return () => {
    -     if (timeout) clearTimeout(timeout)
    -   }
    - }, [open])
    - 
    - if (!mounted) return null
    
      return (
        <AnimatePresence>
          {open && (
    📜 Review details

    Configuration used: CodeRabbit UI
    Review profile: CHILL
    Plan: Pro

    📥 Commits

    Reviewing files that changed from the base of the PR and between 5caca68 and 3a4fb43.

    ⛔ Files ignored due to path filters (1)
    • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
    📒 Files selected for processing (7)
    • package.json (2 hunks)
    • src/react/DiveTransition.tsx (3 hunks)
    • src/react/HotbarRenderApp.tsx (3 hunks)
    • src/react/MainMenuRenderApp.tsx (2 hunks)
    • src/react/Notification.tsx (3 hunks)
    • src/react/Title.css (1 hunks)
    • src/react/Title.tsx (3 hunks)
    🧰 Additional context used
    🧬 Code Graph Analysis (2)
    src/react/Title.tsx (1)
    src/react/TitleProvider.tsx (1)
    • title (33-157)
    src/react/MainMenuRenderApp.tsx (3)
    src/globalState.ts (2)
    • showModal (42-47)
    • openOptionsMenu (91-93)
    src/utils.ts (1)
    • openGithub (162-164)
    src/browserfs.ts (2)
    • openWorldDirectory (301-345)
    • openFilePicker (632-672)
    ⏰ Context from checks skipped due to timeout of 90000ms (1)
    • GitHub Check: build-and-deploy
    🔇 Additional comments (19)
    src/react/Title.css (1)

    35-35: Class name updated to follow new naming convention.

    The class name has been changed from .action-bar to .message-action-bar, which better describes its purpose and aligns with the changes in the corresponding TSX files that now use framer-motion for animations.

    package.json (1)

    80-80: Added framer-motion dependency.

    The addition of framer-motion (v12.9.2) is appropriate for the migration from react-transition-group. This is a modern animation library with a more declarative API.

    Note: I can see that react-transition-group and @types/react-transition-group dependencies have been removed (not visible in the diff), which is the correct approach to avoid keeping unused dependencies.

    src/react/HotbarRenderApp.tsx (3)

    2-2: Imported framer-motion components.

    Correctly importing the required components from framer-motion for the animation migration.


    20-20: Duration format changed to seconds.

    The animation duration has been changed from milliseconds (300) to seconds (0.3) to align with framer-motion's API, which uses seconds instead of milliseconds.


    54-71: Successfully migrated to framer-motion animation API.

    The component has been refactored to use framer-motion's more declarative animation API. This implementation:

    • Uses AnimatePresence to handle the mounting/unmounting animations
    • Replaces manual state handling with declarative initial, animate, and exit props
    • Properly maintains the same animation duration and behavior

    The code is now more readable and follows modern React animation patterns.

    src/react/MainMenuRenderApp.tsx (2)

    2-2: Imported framer-motion components.

    Correctly importing the required components from framer-motion for the animation migration.


    120-163: Successfully migrated to framer-motion animation API.

    The component has been refactored to use framer-motion's declarative animation API:

    • Uses AnimatePresence to properly handle mount/unmount animations
    • Implements motion.div with appropriate animation props
    • Maintains the conditional rendering logic while adding proper exit animations
    • Includes an optimization to disable animations when appropriate (line 128)
    • Adds easing configuration (ease: 'easeInOut') for smoother transitions

    This implementation is cleaner and more maintainable than the previous react-transition-group approach.

    src/react/Title.tsx (5)

    2-2: Library import correctly replaced.

    The import of motion and AnimatePresence from framer-motion aligns with the PR's objective to migrate from react-transition-group.


    31-32: Animation durations correctly defined in seconds.

    The default durations are now properly defined in seconds (0.5s and 1s) as expected by framer-motion, rather than milliseconds used by react-transition-group.


    42-61: Title animation implementation looks good.

    The implementation correctly uses AnimatePresence with conditional rendering and appropriate motion.div properties. The conversion from milliseconds to seconds in the transition timing is properly handled.


    62-78: Action bar animation implementation looks good.

    Similar to the title animation, the action bar implementation correctly uses AnimatePresence with proper motion properties and timing conversions.


    73-73: CSS class name updated for consistency.

    The class name has been updated from 'action-bar' to 'message-action-bar' to reflect updated styling conventions.

    src/react/Notification.tsx (4)

    1-1: Library import correctly replaced.

    The import of motion and AnimatePresence from framer-motion aligns with the PR's objective to migrate from react-transition-group.


    4-4: Animation duration properly defined in seconds.

    The duration is now correctly defined as 0.2 seconds instead of milliseconds, as required by framer-motion.


    12-59: Notification animation implementation looks good.

    The implementation correctly uses AnimatePresence with conditional rendering based on the open prop. The animation transitions (sliding in from bottom, sliding out to top) are well-defined with appropriate opacity and y-axis translations.


    34-34: Pointer events logic improved.

    The pointer events style now explicitly uses 'auto' when an action is provided and 'none' otherwise, which is clearer than the previous implementation that used an empty string fallback.

    src/react/DiveTransition.tsx (3)

    2-2: Library import correctly replaced.

    The import of motion and AnimatePresence from framer-motion aligns with the PR's objective to migrate from react-transition-group.


    5-6: Duration properly defined for both animation and timeout.

    The duration is correctly defined in seconds for framer-motion (0.3s) and converted to milliseconds (300ms) for the timeout function, maintaining consistency.


    28-44: Dive transition animation implementation looks good.

    The implementation correctly uses AnimatePresence with conditional rendering and appropriate motion.div properties, animating both opacity and z-axis translation.

    @zardoy
    Copy link
    Owner

    zardoy commented Apr 28, 2025

    /deploy

    Copy link

    Deployed to Vercel Preview: https://prismarine-3ee4v7yp5-zaro.vercel.app
    Playground
    Storybook

    @zardoy
    Copy link
    Owner

    zardoy commented Apr 29, 2025

    /deploy

    Copy link

    Deployed to Vercel Preview: https://prismarine-dgx9ya5tq-zaro.vercel.app
    Playground
    Storybook

    @zardoy
    Copy link
    Owner

    zardoy commented Apr 30, 2025

    /deploy

    Copy link

    Deployed to Vercel Preview: https://prismarine-hnnk89lk2-zaro.vercel.app
    Playground
    Storybook

    @zardoy zardoy merged commit 0d9cb06 into zardoy:next Apr 30, 2025
    3 checks passed
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Projects
    None yet
    Development

    Successfully merging this pull request may close these issues.

    3 participants