App.jsx
import React, { useState } from "react";
import Modal from "./components/Modal/Modal";
export default function App() {
const [showModal, setShowModal] = useState(false);
return (
<div className="app">
<p className="ppp">Sample text</p>
<div className="modal_menu_wrap">
<div className="modal_menu">
<button
onClick={() => {
setShowModal(true);
}}
className="open-btn"
>
Open/Close
</button>
<Modal active={showModal} setShowModal={setShowModal} />
</div>
</div>
</div>
);
}
index.css
.open-btn {
padding: 10px 15px;
border: none;
background-color: black;
color: aliceblue;
cursor: pointer;
}
.open-btn:hover {
scale: 1.05;
}
.modal_menu_wrap {
display: flex;
justify-content: center;
border: 1px solid rgb(255, 0, 0) !important;
}
.modal_menu {
width: 100%;
max-width: 200px;
border: 1px solid rgb(255, 0, 0) !important;
}
Modal.jsx
import styles from "./modal.module.css";
import React, { useEffect, useState } from "react";
export default function Modal({ active, setShowModal }) {
const [showContent, setShowContent] = useState(false);
const closeModal = () => {
setShowContent(false);
setTimeout(() => {
setShowModal(false);
}, 500);
};
useEffect(() => {
if (active) {
setShowContent(true);
}
}, [active]);
if (!active) return null;
return (
<div
className={
showContent ? `${styles.modal} ${styles.showModal}` : `${styles.modal}`
}
>
<p className="ppp"></p>
<div onClick={closeModal} className={styles.closeBtn}>
<span>×</span>
</div>
</div>
);
}
modal.module.css
.modal {
position: absolute;
width: 100%;
max-width: 200px;
height: 300px;
background-color: azure;
border-radius: 10px;
z-index: 2;
opacity: 0.5;
border: 1px solid rgb(255, 0, 0) !important;
transform: translateY(-100vh);
transition: all 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
.showModal {
opacity: 1;
transform: translateY(0);
z-index: 2;
}
.closeBtn {
position: absolute;
top: 10px;
right: 20px;
cursor: pointer;
z-index: 9;
border: 1px solid rgb(255, 0, 0) !important;
}
.closeBtn span {
display: block;
font-size: 2rem;
font-weight: bold;
transition: transform 0.2s ease;
}
.closeBtn span:hover {
transform: scale(1.2);
}
It is necessary that the element appears and disappears when you click on the Open / Close button, as well as if you click outside the element field. I gave the button a value onClick={() => {setShowModal( !showModal);}}
, but in this case, the animation disappears. It is necessary that the element completely disappears from the dom. There should not be a button with a cross.
Demo – https://codesandbox.io/s/serverless-dust-8vj86d?file=/src/index.css
2
Answers
A better method is to add the animation to a class.
Then set the component’s styling to the state in the last frame of the animation. And as simple as that when you add the className to the component the animations happen and return to the last state by removing the className at the end of the animation. so you may edit
Simply edited 2 files
First
made the open/close button to toggle the state by setting the new value to the inverse of the old value !showModal
in the file ` App.js`
Then
I removed the line
if (!active) return null;
which is a bad approach using react! no offense but this might affect your application performance.
And added after that a check if it is active so it removes the class
active && showContent
which means if active is == true then do the code on the right side of the operator
in the file
Modal.jsx
the final code would be :
App.jsx
Modal.jsx