반응형
포트폴리오 사이트를 react로 구현하던 중 모달 기능이 필요하여 라이브러리를 사용하지 않고 만들었다.
// Modal.jsx
import React from 'react';
export default function Modal({ open, close, title, children }) {
if (!open) return null;
return (
<div
className={`fixed inset-0 z-50 flex items-center justify-center bg-gray-500 bg-opacity-50 ${
open ? 'animate-fadeIn' : 'animate-fadeOut'
}`}
>
<div
className={`bg-white rounded-lg shadow-lg w-11/12 max-w-md p-6 relative transform transition-transform duration-300 ${
open ? 'scale-100' : 'scale-90'
}`}
>
<header className='flex justify-between items-center mb-4'>
<h2 className='text-2xl font-semibold'>{title}</h2>
<button
className='text-gray-500 hover:text-gray-700 text-xl'
onClick={close}
>
×
</button>
</header>
<main>{children}</main>
</div>
</div>
);
}
모달의 기본적인 틀만 만들어 준 후 나머지는 모달을 사용하는 페이지에서 설정해주도록 한다.
이 때 애니메이션의 fadeIn, fadeOut을 사용하기 위해 tailwind.config.js의 설정이 필요하다
// tailwind.config.js
module.exports = {
content: ['./src/**/*.{js,jsx,ts,tsx}'], // 프로젝트 파일 경로
theme: {
extend: {
keyframes: {
fadeIn: {
from: { opacity: '0' },
to: { opacity: '1' },
},
fadeOut: {
from: { opacity: '1' },
to: { opacity: '0' },
},
},
animation: {
fadeIn: 'fadeIn 0.3s ease-in-out',
fadeOut: 'fadeOut 0.3s ease-in-out',
},
},
},
plugins: [],
};
tailwind.config.js를 설정해주고 시작하도록 하자.
export default function Projects() {
const [openModalId, setOpenModalId] = useState(null);
const openModal = (id) => {
setOpenModalId(id);
};
const closeModal = () => {
setOpenModalId(null);
};
// 배경 스크롤 방지
useEffect(() => {
if (openModalId !== null) {
document.body.style.overflow = 'hidden'; // 스크롤 비활성화
} else {
document.body.style.overflow = ''; // 스크롤 복원
}
return () => {
document.body.style.overflow = ''; // 컴포넌트 언마운트 시 초기화
};
}, [openModalId]);
const currentProject = projects.find((project) => project.id === openModalId);
return (
// ... project 영역 구현
// 모달 렌더링
{currentProject && (
<Modal
open={currentProject}
close={closeModal}
title={currentProject.title}
>
{currentProject.description}
</Modal>
)}
)
}
각각의 카드를 만들고 project의 id에 해당하는 모달이 열릴 수 있도록 구현했다.
반응형
'Today I Learn > React' 카테고리의 다른 글
[React/TypeScript]트리구조 데이터를 기반으로 트리뷰를 렌더링하는 UI 구현하기 2depth메뉴 구현하기 (0) | 2025.03.07 |
---|---|
[Next.js] next js에서 google analytics 사용하기 (React-gtm-module) (0) | 2023.10.05 |
검색어 하이라이트 (0) | 2023.08.09 |
[Next.js] 뒤로가기 시 스크롤 위치 유지하기(scrollRestoration) (0) | 2023.03.31 |
[React/TypeScript]특정 영역 프린트 기능 구현 (0) | 2023.03.10 |