feat: modal enter & exit transitions

This commit is contained in:
Sonny
2023-05-17 02:12:44 +02:00
parent 95c5ca78bc
commit 050c4e2324
4 changed files with 33 additions and 20 deletions

View File

@@ -1,7 +1,8 @@
import { ReactNode } from "react";
import { ReactNode, useId } from "react";
import { createPortal } from "react-dom";
import { GrClose } from "react-icons/gr";
import { motion } from "framer-motion";
import styles from "./modal.module.scss";
interface ModalProps {
@@ -22,12 +23,25 @@ export default function Modal({
noHeader = false,
padding = "1em 1.5em",
}: ModalProps) {
const modalId = useId();
const handleWrapperClick = (event) =>
event.target.classList?.[0] === styles["modal-wrapper"] && close();
return createPortal(
<div className={styles["modal-wrapper"]} onClick={handleWrapperClick}>
<div className={styles["modal-container"]} style={{ padding }}>
<motion.div
className={styles["modal-wrapper"]}
onClick={handleWrapperClick}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0, transition: { duration: 0.1 } }}
>
<motion.div
className={styles["modal-container"]}
style={{ padding }}
initial={{ opacity: 0, y: -15 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -15, transition: { duration: 0.1 } }}
>
{!noHeader && (
<div className={styles["modal-header"]}>
<h3>{title}</h3>
@@ -42,8 +56,8 @@ export default function Modal({
</div>
)}
<div className={styles["modal-body"]}>{children}</div>
</div>
</div>,
</motion.div>
</motion.div>,
document.body
);
}

View File

@@ -1,5 +1,4 @@
@import "styles/colors.scss";
@import "styles/keyframes.scss";
.modal-wrapper {
z-index: 9999;
@@ -13,7 +12,6 @@
display: flex;
align-items: center;
flex-direction: column;
animation: opacityin 0.3s both;
}
.modal-container {
@@ -25,7 +23,6 @@
align-items: center;
justify-content: center;
flex-direction: column;
animation: fadeintop 0.3s both;
box-shadow: 0 0 1em 0px rgba($black, 0.25);
}

View File

@@ -38,8 +38,8 @@ export default function CategoryItem({
transition={{
type: "spring",
stiffness: 260,
damping: 20,
delay: index * 0.025,
damping: 25,
delay: index * 0.02,
duration: 200,
}}
className={className}

View File

@@ -9,7 +9,7 @@ import SearchModal from "components/SearchModal/SearchModal";
import SideMenu from "components/SideMenu/SideMenu";
import * as Keys from "constants/keys";
import { motion } from "framer-motion";
import { AnimatePresence, motion } from "framer-motion";
import { Category, Link, SearchItem } from "types";
import { prisma } from "utils/back";
import { BuildCategory } from "utils/front";
@@ -174,15 +174,17 @@ function Home(props: HomeProps) {
openSearchModal={modal.open}
/>
<Links category={categoryActive} toggleFavorite={toggleFavorite} />
{modal.isShowing && (
<SearchModal
close={modal.close}
categories={categories}
favorites={favorites}
items={itemsSearch}
handleSelectCategory={handleSelectCategory}
/>
)}
<AnimatePresence>
{modal.isShowing && (
<SearchModal
close={modal.close}
categories={categories}
favorites={favorites}
items={itemsSearch}
handleSelectCategory={handleSelectCategory}
/>
)}
</AnimatePresence>
</motion.div>
);
}