Open In App

Animated modal using react, framer-motion & styled-components

Improve
Improve
Like Article
Like
Save
Share
Report

In this article, we are going to learn how to create an animated model using react, framer-motion & styled components.

Prerequisites:

Steps to Create React Application And Installing Module:

Step 1: Now, you will start a new project using create-react-app so open your terminal and type.

npx create-react-app toggle-modal

Step 2: After creating your project folder i.e. toggle-modal, move to it using the following command.

cd toggle-modal

Step 3: Add the npm packages you will need during the project.

npm install framer-motion styled-components
//For yarn
yarn add framer-motion styled-components

Project structure:

Project structure

package.json:

"dependencies": {
"framer-motion": "^10.16.5",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"styled-components": "^6.1.1",
"web-vitals": "^2.1.4",
}

Approach:

  • We are going to create a Modal component with ‘showModal’ prop only to manage its state of visibility and animated using framer-motion AnimatePresence.
  • AnimatePresence allows components to animate out when they’re removed from the React tree and to enable exit animations.
  • To give spring animation to modal container we will use framer-motion spring animation with stiffness = 300.
  • Content of modal is geeksforgeeks image which is also animated using framer-motion motion.div.
  • React useState hook to manage the state of ‘showModal’ i.e. responsible to toggle the modal container.
  • ‘displayModal’ utility function to set the ‘showModal’ value opposite of its last value to toggle modal.
  • Event listener for document body so that on clicking outside or on the modal, ‘showModal’ is set to false and in turn modal is disappeared.
  • ToggleBtn is also animated using framer-motion motion.button.

Example: Below is the implementation of the Animated modal using react, framer-motion and styled-components.

Step 5: Now open your newly created project and write the code in below files:

  • App.js
  • Styles.js

Javascript




//App.js
import React, { useState } from "react";
import { AnimatePresence } from "framer-motion";
import { ToggleBtn, ModalBox, ModalContent, ModalContainer } from "./Styles";
import "./App.css";
 
// Modal component with 'showModal' prop only
// to manage its state of visibility and
// animated using framer-motion
const Modal = ({ showModal }) => {
    return (
        <ModalContainer>
            <AnimatePresence>
                {showModal && (
                    <ModalBox
                        initial={{
                            opacity: 0,
                            y: 60, scale: 0.5
                        }}
                        animate={{
                            opacity: 1,
                            y: 0,
                            scale: 1,
                            // making use of framer-motion spring animation
                            // with stiffness = 300
                            transition: {
                                type: "spring",
                                stiffness: 300
                            }
                        }}
                        exit={{
                            opacity: 0, scale: 0.5,
                            transition: { duration: 0.6 }
                        }}>
                        <ModalContent
                            initial={{ y: -30, opacity: 0 }}
                            animate={{
                                y: 0, opacity: 1,
                            }}>
                            {/* Modal content is geeksforgeeks image */}
                            <img
                                src=
                                alt="geeksforgeeks"
                                style={{ zIndex: "1" }}
                            />
                        </ModalContent>
                    </ModalBox>
                )}
            </AnimatePresence>
        </ModalContainer>
    );
};
 
const App = () => {
    // React useState hook to manage the state of 'showModal'
    // i.e. responsible to toggle the modal container
    const [showModal, setShowModal] = useState(false);
 
    // utility function to set the showModal value
    // opposite of its last value
    // to toggle modal
    const displayModal = () => {
        setShowModal(!showModal);
        document.getElementById("btn").style.visibility = "hidden";
    };
 
    // event listener for document body
    // so that on clicking outside the modal,
    // 'showModal' is set to false.
    document.body.addEventListener("click", () => {
        if (showModal) {
            setShowModal(false);
        }
    });
 
    return (
        <ModalContainer>
            <ToggleBtn
                id="btn"
                initial={{ x: -700 }}
                animate={{
                    x: 0,
                    transition: { duration: 0.1 }
                }}
                // event listener for the toggle button
                // to display modal on click
                onClick={displayModal}>
                Toggle Modal
            </ToggleBtn>
            {/* passing 'showModal' as a prop to Modal component */}
            <Modal showModal={showModal} />
        </ModalContainer>
    );
};
 
export default App;


Javascript




//Styles.js
import styled from "styled-components";
import { motion } from "framer-motion";
 
export const ModalBox = styled(motion.div)`
  position: relative;
  z-index: 2;
  width: 400px;
  height: 200px;
  display: flex;
  justify-content: center;
  align-items: center;
  background: #fff;
`;
 
export const ModalContent = styled(motion.div)`
  padding: 5px;
`;
 
export const ModalContainer = styled.div`
  height: 100vh;
  background: #111;
  display: flex;
  flex-direction: column;
  align-items: center;
`;
 
export const ToggleBtn = styled(motion.button)`
  cursor: pointer;
  font-size: 20px;
  color: #fff;
  padding: 0.5rem 0.8rem;
  margin-top: 3rem;
  background: #3bb75e;
  text-decoration: none;
  border: none;
  border-radius: 50px;
`;


Step to Run Application: Run the application using the following command from the root directory of the project.

npm start

Output: Now open your browser and go to http://localhost:3000/, you will see the following output.



Last Updated : 21 Nov, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads