Struggling to add animation to modal in ReactJS

I'm currently in the process of developing my custom modal implementation. Everything is working smoothly so far, but I am facing challenges when it comes to animating it.

Here is my Modal component:

 import React from 'react'
import Slider from './Slider'
import {IoIosCloseCircleOutline} from "react-icons/io"
import styled from "styled-components";



export default function Modal(props) {

    const Modal = styled.div `
    transform: translateX(${({animateSlideInRight}) => (animateSlideInRight ? "0" : "100vw")});
    transition: transform 1s;
    width: 1000px;
    height: 650px;
    z-index: 100;
    position: fixed;
    background: white;
    transition: all 1.1s ease-out;
    box-shadow: 
      -2rem 2rem 2rem rgba(black, 0.2);
    visibility: visible;
    display: flex;
    border-bottom-right-radius: 100px;
    `

    const closeModal = () => {
        props.setShow(false)
    }

    const data = props.data
    if (!props.show) {
        return null
    }
    return (
        <div className="modalWrapper">  
            <Modal className="modal" id="modal" animateSlideInRight = {props.show}>
                <div className="modalHeaderWrapper">
                <IoIosCloseCircleOutline className="modalCloseCross" onClick={closeModal}/>
                    <img src={data[0].logo} alt="logo" />
                    <h2>{data[0].title}</h2>
                </div>
                <div className="modalRightFlex">
                    <Slider 
                        images={[data[0].image1Carrousel, data[0].image2Carrousel, data[0].image3Carrousel]}
                    />
                    <div className="modalRightDescription">
                        <h1>Description</h1>
                        <p>{data[0].description}</p>
                        <h1>Technologies</h1>
                        <div className="modalTechnologiesWrapper">
                            {data[0].technologiesUsed.map((image) => {
                                return <img src={image}/>
                            })}
                        </div>
                    </div>
                </div>
            </Modal>
        </div>
    )
}

In my modal implementation, I use a styledComponent to determine whether to perform translation on the X-axis based on the show state. The state handling happens at the ancestor level since the modal is triggered by clicking on a separate card component.

The current CSS styling for the modal is defined within the styled div itself.

Things I've attempted:

1. Attempted using a regular div and utilizing CSS keyframes for animations - while sliding in works correctly, the closing animation does not behave as expected.

2. Tried setting an animate state and dynamically assigning classNames based on this state. Initially effective upon closing, but then encountered flickering issues.

If anyone can identify the issue here, I would greatly appreciate it. Thank you.

Edit: Sandbox link: https://codesandbox.io/s/trusting-shape-vxujw

Answer №1

Ensure that Modal is defined in the outer scope of the component where it is rendered to prevent the animation from being interrupted by redefinition during subsequent renders.

When resetting an animation, use none instead of specifying a specific length.

Additionally, there may be CSS issues such as z-index and position that could affect the visibility of your modal animation. If your primary concern is with the animation problem, eliminate any extraneous factors.

Check out this functional example:

const Animation = styled.div`
  transform: ${({ animate }) => (animate ? "none" : "translateX(500px)")};
  transition: transform 1s;
`;

function Modal(props) {
  return <Animation animate={props.show}>hello</Animation>;
}

function Component() {
  const [show, toggle] = useReducer((p) => !p, false);
  return (
    <>
      <Modal show={show} />
      <button onClick={toggle}>show</button>
    </>
  );
}

Avoid returning null when you want to disable animation as it will discard the closing animation effect.

// Do not include this code snippet
if (!props.show) {
  return null;
}

https://codesandbox.io/s/react-template-forked-5hgox?fontsize=14&hidenavigation=1&theme=dark

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Creating a Timeless Banner with the Magic of `background:url()`

I have a banner placed within a div tag that displays my banner image. I am trying to create a fading effect when transitioning to the next image, but I am struggling to achieve this. I attempted to use jQuery fadeIn(), however, it did not work as expected ...

Unlimited Scrolling in Angular 2: A Complete Guide

For my current project, I am utilizing angular2-infinite-scroll. My concept is to load 6 items on the initial page load and then add an additional 6 items each time the user scrolls to the bottom of the page. However, I have encountered an issue where the ...

Utilizing .env Variables in NestJS Main App Module for Establishing Database Connection

I recently embarked on my first NestJS project, where I initially had a hardcoded database connection string in app.module.ts that worked perfectly fine. However, our project requirements called for fetching the database configuration values from environm ...

Is it possible to incorporate untrusted data into a URL while working with React?

After exploring information on how JSX in React automatically escapes values, I came across a post discussing that over-reliance on React for escaping is not always secure. My concern arises from wanting to insert an image with a URL that may include poten ...

Issue with decompressing the identical data using zlib (Z_BUF_ERROR)

Below is the Python code snippet I am working with: import zlib raw = bytes.fromhex("789C34C9410AC2301005D0BBFC752289A88BB94A53CAD8061B48D3329D2A1A7277DDB87BF02A14548E9C0DF63FD60DE49DC104AA98238BDE23EB908A467972065DFCF9FAFB4185C708EAD0053C58E38BDF769 ...

TABULAOTR, The complete table calculation is failing to be retrieved

Apologies for any language mistakes, as I am Russian :)I am using Tabulator but facing an issue where the table footer is not being printed. I am also unable to retrieve data from the footer. The footer simply doesn't show up and I'm unsure of wh ...

Eliminate the Tailwind class name from the component displayed in Storybook

As I work on developing a mobile sidebar component that should remain hidden on desktop devices, I have encountered an issue. The component is designed for mobile-only use and has been given the className md:hidden. Currently, as I add all my components t ...

Issue with Vue mounting causing component to not receive updated values

Below is the Vue main file I'm working with: export default { name: 'app', components: { FormSelector, }, data () { return { headerInfo: { issue: '', mode ...

What is the best method to invoke an authenticated HTTP trigger Google Cloud Function from a Next.js (with Typescript) application?

After setting up a Google Cloud Platform account, I created a basic Python "Cloud Function" that outputs simple text. This function is accessible via HTTP and can only be authenticated by a specific "Service Account" that I generated for this purpose. To e ...

Retrieve a specified child object within its parent object using a string identifier

I have a situation where I need to create a JavaScript function that can extract a child object from a parent object based on a specific string identifier. Here is an example of what I'm looking for: function findChild(parent, name) { return par ...

Analyzing and inserting elements into an array of objects

The following code aims to: 1) iterate through the two arrays, 2) if an item exists in both arrays, add its value to the value of the matching item in the first array, 3) if the item is found in arr2 but not in arr1, add the item to arr1. The code funct ...

How to use jQuery to dynamically assign a class to an li element

I'm attempting to use jQuery to add the 'block' class to specific li elements, but for some reason the class isn't being applied. The goal of the program is to display time slots and disable certain ones if they are blocked. Here's ...

Make a deep clone in JavaScript while also altering the parent node's type and name

I am looking for guidance on how to clone a Node and then convert its nodeName, ensuring that the attributes are copied along with the children deeply. I want to achieve something similar to switching an existing span element to a div while retaining all i ...

AngularJS does not allow empty spaces in textarea inputs

I am working on a form that includes a textarea element for users to input descriptions, however it does not allow any empty spaces. Users can only input alphanumeric and numeric characters, but no spaces. <textarea class="form-control" rows="4" maxl ...

Traversing through each element using Array method

I need to create a redux function that will add a specified number n to the fourth element of an array every time a button is clicked. However, if the element is either L or M, I do not want the addition to occur. For example, starting with this initial a ...

After removing an element from an array in Vue.js, how can we adjust its class to reflect the change?

Apologies for my lack of proficiency in English. I am eager to find a solution to resolve these issues. I am working on a todolist and encountering an issue where the class ('centerLine') continues to affect the next element after deleting an a ...

Ways to add empty space in HTML that cannot be duplicated

Is there a simple method to add empty spaces in a line without them being copied when selected by the viewer? I am looking for an easy way to achieve this. Any suggestions? ...

Rendering React App before data is loaded from Firestore.orLoading React App

I am facing an issue where the data from Firestore is not loading in time to be displayed in the gantt-chart. Despite calling setState within componentDidMount, the data remains empty. I'm unsure why this is happening. Any insights? import React, { C ...

Storing JavaScript variables in a database: A step-by-step guide

For the past few days, I've been working with CakePHP and trying to save a javascript variable into a MySQL database using AJAX (jQuery). Here's the code I've been using: <!-- document javascripts --> <script type="text/javas ...

What is the best way to ensure that an anchor in a scrolling list adjusts its width based on its children's content?

Check out the setup I have here: http://jsfiddle.net/9F6CF/ In this scenario, there is a list containing anchors within each list item. The UL element has a specific width and an overflow set to auto, causing text in the anchors to scroll horizontally if ...