diff --git a/src/components/Backdrop/index.tsx b/src/components/Backdrop/index.tsx
index cd697593..ed30e8ed 100644
--- a/src/components/Backdrop/index.tsx
+++ b/src/components/Backdrop/index.tsx
@@ -13,7 +13,10 @@ export interface BackdropProps {
onClick: () => void;
}
-/** AnimatePortal 컴포넌트로 감싸서 사용 */
+/**
+ * @desc 1. < AnimatePortal > 컴포넌트와 함께 사용
+ * @desc 2. < AnimatePresence > + 컴포넌트와 함께 사용
+ * */
export default function Backdrop({
isVisible = true,
className = "",
diff --git a/src/components/Modal/index.tsx b/src/components/Modal/index.tsx
index 822058f4..68dddbd8 100644
--- a/src/components/Modal/index.tsx
+++ b/src/components/Modal/index.tsx
@@ -3,7 +3,7 @@ import { Variants } from "framer-motion";
import useScrollLock from "@/hooks/useScrollLock";
import { StrictPropsWithChildren } from "@/types";
-import AnimatePortal from "../Portal/AnimatePortal";
+import Portal from "../Portal";
import ModalActions from "./ModalActions";
import ModalContent from "./ModalContent";
@@ -22,8 +22,9 @@ export interface ModalProps {
onClose: () => void;
}
+/** @desc < AnimatePresence > 컴포넌트로 감싸서 사용해주세요. */
export default function Modal({
- isVisible = false,
+ isVisible = true,
size = "default",
showBackdrop = true,
onClose,
@@ -32,7 +33,7 @@ export default function Modal({
useScrollLock(isVisible);
return (
-
+
{children}
-
+
);
}
diff --git a/src/components/SnackBar/index.tsx b/src/components/SnackBar/index.tsx
index d1b40b31..a72a7ee3 100644
--- a/src/components/SnackBar/index.tsx
+++ b/src/components/SnackBar/index.tsx
@@ -6,8 +6,14 @@ interface SnackBarProps {
text: string;
}
+//TODO: SnackBar animation 변경
const SnackBar = forwardRef(
({ text }: SnackBarProps, ref: React.ForwardedRef) => {
+ // const [isPresent, safeToRemove] = usePresence();
+ // useEffect(() => {
+ // !isPresent && setTimeout(safeToRemove, 2000);
+ // }, [isPresent, safeToRemove]);
+
return {text};
},
);
diff --git a/src/features/auth/components/LoginAlertModal/index.tsx b/src/features/auth/components/LoginAlertModal/index.tsx
index 23755e58..b783dec5 100644
--- a/src/features/auth/components/LoginAlertModal/index.tsx
+++ b/src/features/auth/components/LoginAlertModal/index.tsx
@@ -7,14 +7,10 @@ import useRedirect from "@/hooks/useRedirect";
import { Text } from "./style";
interface LoginAlertModalProps {
- isVisible: boolean;
onClose: () => void;
}
-export default function LoginAlertModal({
- isVisible,
- onClose,
-}: LoginAlertModalProps) {
+export default function LoginAlertModal({ onClose }: LoginAlertModalProps) {
const location = useLocation();
const navigate = useNavigate();
const { setRedirect } = useRedirect();
@@ -29,7 +25,7 @@ export default function LoginAlertModal({
return (
<>
-
+
로그인이 필요해요
diff --git a/src/features/bookmarks/components/BookmarkButton.tsx b/src/features/bookmarks/components/BookmarkButton.tsx
index 21c884fb..233514f0 100644
--- a/src/features/bookmarks/components/BookmarkButton.tsx
+++ b/src/features/bookmarks/components/BookmarkButton.tsx
@@ -1,3 +1,4 @@
+import { AnimatePresence } from "framer-motion";
import { useEffect, useState } from "react";
import Button from "@/components/Button";
@@ -59,10 +60,12 @@ export default function BookmarkButton({ animeId }: BookmarkButtonProps) {
>
{isBookmarked ? "입덕한 애니" : "입덕하기"}
- setIsLoginModalVisible(false)}
- />
+
+
+ {isLoginModalVisible && (
+ setIsLoginModalVisible(false)} />
+ )}
+
>
);
}
diff --git a/src/features/reviews/components/ReviewCard/ReviewMoreButton.tsx b/src/features/reviews/components/ReviewCard/ReviewMoreButton.tsx
index 03da1cc1..b12e128f 100644
--- a/src/features/reviews/components/ReviewCard/ReviewMoreButton.tsx
+++ b/src/features/reviews/components/ReviewCard/ReviewMoreButton.tsx
@@ -1,5 +1,6 @@
import { useTheme } from "@emotion/react";
import { DotsThree } from "@phosphor-icons/react";
+import { AnimatePresence } from "framer-motion";
import { useState } from "react";
import Button from "@/components/Button";
@@ -13,7 +14,7 @@ import ShortReviewModal from "../ReviewRating/ShortReviewModal";
import { MyRating, RatingContainer } from "./ReviewMoreButton.style";
-const USER_MOCK_DATA = { isMine: false };
+const USER_MOCK_DATA = { isMine: true };
const USER_MOCK_REVIEW_DATA = {
score: 7,
content: "유저가 생성한 짧은 리뷰입니다.",
@@ -62,53 +63,59 @@ export default function ReviewMoreButton() {
color="neutral"
onClick={handleDropDownModalToggle}
/>
-
-
- USER_MOCK_DATA.isMine
- ? handleReviewEditClick()
- : handleReviewSpoilerReport()
- }
- >
- {USER_MOCK_DATA.isMine ? "수정하기" : "스포일러 신고"}
-
-
- USER_MOCK_DATA.isMine
- ? handleReviewDeleteClick()
- : handleReviewEtcReport()
- }
- >
- {USER_MOCK_DATA.isMine ? "삭제하기" : "기타 신고"}
-
-
+
+ {isDropDownModalOpen && (
+
+
+ USER_MOCK_DATA.isMine
+ ? handleReviewEditClick()
+ : handleReviewSpoilerReport()
+ }
+ >
+ {USER_MOCK_DATA.isMine ? "수정하기" : "스포일러 신고"}
+
+
+ USER_MOCK_DATA.isMine
+ ? handleReviewDeleteClick()
+ : handleReviewEtcReport()
+ }
+ >
+ {USER_MOCK_DATA.isMine ? "삭제하기" : "기타 신고"}
+
+
+ )}
- setIsReviewModalVisible(false)}
- onReview={() => setIsReviewModalVisible(false)}
- userReviewData={USER_MOCK_REVIEW_DATA}
- >
- 내 별점
-
-
-
-
+ {isReviewModalVisible && (
+ setIsReviewModalVisible(false)}
+ onReview={() => setIsReviewModalVisible(false)}
+ userReviewData={USER_MOCK_REVIEW_DATA}
+ >
+ 내 별점
+
+
+
+
+ )}
+
>
diff --git a/src/features/reviews/components/ReviewRating/ShortReviewModal.tsx b/src/features/reviews/components/ReviewRating/ShortReviewModal.tsx
index 1fb8051d..833ba0eb 100644
--- a/src/features/reviews/components/ReviewRating/ShortReviewModal.tsx
+++ b/src/features/reviews/components/ReviewRating/ShortReviewModal.tsx
@@ -25,14 +25,12 @@ interface MOCK_USER_REVIEW_DATA {
}
interface ShortReviewModalProps {
- isVisible: boolean;
onClose: () => void;
onReview: () => void;
userReviewData?: MOCK_USER_REVIEW_DATA;
}
export default function ShortReviewModal({
- isVisible,
onClose,
onReview,
userReviewData,
@@ -126,7 +124,7 @@ export default function ShortReviewModal({
// };
return (
-
+
한 줄 리뷰 모달
{children}
diff --git a/src/features/reviews/components/ReviewRating/index.tsx b/src/features/reviews/components/ReviewRating/index.tsx
index f08250b5..9a1625c6 100644
--- a/src/features/reviews/components/ReviewRating/index.tsx
+++ b/src/features/reviews/components/ReviewRating/index.tsx
@@ -1,3 +1,4 @@
+import { AnimatePresence } from "framer-motion";
import { useState } from "react";
import Rating from "@/components/Rating";
@@ -42,15 +43,23 @@ export default function ReviewRating({ animeId }: ReviewRatingProps) {
)}
{hasReviewed && "TODO: 사용자 리뷰 렌더링 "}
- setIsReviewModalVisible(false)}
- onReview={() => setIsReviewModalVisible(false)}
- />
- setIsLoginModalVisible(false)}
- />
+
+
+ {isReviewModalVisible && (
+ setIsReviewModalVisible(false)}
+ onReview={() => setIsReviewModalVisible(false)}
+ />
+ )}
+
+ {isLoginModalVisible && (
+ setIsLoginModalVisible(false)}
+ />
+ )}
+
>
);
}
diff --git a/src/features/users/components/DropDownModal/index.tsx b/src/features/users/components/DropDownModal/index.tsx
index 2ff759a0..2c084dc4 100644
--- a/src/features/users/components/DropDownModal/index.tsx
+++ b/src/features/users/components/DropDownModal/index.tsx
@@ -1,23 +1,24 @@
import { Variants } from "framer-motion";
import Button from "@/components/Button";
-import AnimatePortal from "@/components/Portal/AnimatePortal";
+import Portal from "@/components/Portal";
+import useScrollLock from "@/hooks/useScrollLock";
import { StrictPropsWithChildren } from "@/types";
import { ButtonContainer, Backdrop } from "./style";
export interface DropDownModalProps {
- isVisible: boolean;
onDropDownModalToggle: () => void;
}
export default function DropDownModal({
- isVisible,
onDropDownModalToggle,
children,
}: StrictPropsWithChildren) {
+ useScrollLock(true);
+
return (
-
+
{/* 애니메이션 props: variants, animate, exit */}
@@ -32,7 +33,7 @@ export default function DropDownModal({
취소
-
+
);
}
diff --git a/src/features/users/components/ProfileImageSection/ProfileReportModal.tsx b/src/features/users/components/ProfileImageSection/ProfileReportModal.tsx
index a3a1c2a4..e6be35fa 100644
--- a/src/features/users/components/ProfileImageSection/ProfileReportModal.tsx
+++ b/src/features/users/components/ProfileImageSection/ProfileReportModal.tsx
@@ -18,28 +18,26 @@ const OPTION = [
];
interface ProfileReportModalProps {
- isVisible: boolean;
onClose: () => void;
}
export default function ProfileReportModal({
- isVisible,
onClose,
}: ProfileReportModalProps) {
const { snackBarRef, showSnackBar } = useSnackBar();
-
const [selected, setSelected] = useState(OPTION[0].value);
+
const handleSelectChange = (e: React.ChangeEvent) =>
setSelected(e.target.value);
const handleReportSumbit = () => {
onClose();
showSnackBar();
- setSelected(OPTION[0].value);
};
return (
<>
-
+
+ {/* */}
신고하기
diff --git a/src/features/users/components/ProfileImageSection/ProfileSetupButton.tsx b/src/features/users/components/ProfileImageSection/ProfileSetupButton.tsx
index 2f2dd366..9e5083df 100644
--- a/src/features/users/components/ProfileImageSection/ProfileSetupButton.tsx
+++ b/src/features/users/components/ProfileImageSection/ProfileSetupButton.tsx
@@ -1,3 +1,4 @@
+import { AnimatePresence } from "framer-motion";
import { useState } from "react";
import { useNavigate } from "react-router-dom";
@@ -37,34 +38,42 @@ export default function ProfileSetupButton({
-
-
- 프로필 링크 복사
-
-
- isMine ? handleLinkToEditClick() : handleReportClick()
- }
- >
- {isMine ? "프로필 수정" : "신고하기"}
-
-
-
+
+
+ {isDropDownModalOpen && (
+
+
+ 프로필 링크 복사
+
+
+ isMine ? handleLinkToEditClick() : handleReportClick()
+ }
+ >
+ {isMine ? "프로필 수정" : "신고하기"}
+
+
+ )}
+
+ {isReportModalOpen && (
+
+ )}
+
>
);
}
diff --git a/src/features/users/routes/Profile/AboutMe/StatModal.tsx b/src/features/users/routes/Profile/AboutMe/StatModal.tsx
index 547020ea..94bb45bc 100644
--- a/src/features/users/routes/Profile/AboutMe/StatModal.tsx
+++ b/src/features/users/routes/Profile/AboutMe/StatModal.tsx
@@ -11,18 +11,13 @@ interface StatItemProps {
}
interface StatModalProps {
- isVisible: boolean;
items: StatItemProps[];
onClose: () => void;
}
-export default function StatModal({
- isVisible,
- items,
- onClose,
-}: StatModalProps) {
+export default function StatModal({ items, onClose }: StatModalProps) {
return (
-
+
{items.map((item, index) => (
diff --git a/src/features/users/routes/Profile/AboutMe/index.tsx b/src/features/users/routes/Profile/AboutMe/index.tsx
index 33d74510..c178fa64 100644
--- a/src/features/users/routes/Profile/AboutMe/index.tsx
+++ b/src/features/users/routes/Profile/AboutMe/index.tsx
@@ -1,3 +1,4 @@
+import { AnimatePresence } from "framer-motion";
import { useState } from "react";
import Stat from "@/components/Stat";
@@ -53,11 +54,11 @@ export default function AboutMe() {
-
+
+ {isStatModalVisible && (
+
+ )}
+
>
);
}