두 가지 모달을 만들어야 한다.
첫 번째 모달은 버튼을 클릭했을때 닫기와 확인 버튼이 있고 닫기 버튼으로만 모달창을 닫을 수 있어야 한다.
두 번째 모달은 버튼을 클릭했을 때, X 버튼이 있고 X 버튼과 모달창 외부를 눌렀을 대 모달창을 닫을 수 있어야한다.
기본적인 모달에 대한 코드는 아래와 같다.
// Modal.jsx
function Modal({ modalType }) {
const [isOpen, setIsOpen] = useState(false);
const handleClickOpen = (e) => {
setIsOpen((isOpen) => !isOpen);
};
const handleClickClose = () => {
setIsOpen(false);
};
생략
return (
<div>
{modalType === "modal_1" ? (
<div>
<button>Open Modal</button>
{isOpen && (
<>
<StModalBox />
<StModal>
<p>닫기와 확인 버튼 2개가 있고, 외부 영역을 눌러도 모달이 닫히지 않아요.</p>
<button onClick={handleClickClose}>닫기</button>
<button>확인</button>
</StModal>
</>
)}
</div>
) : (
<div>
<button>Open Modal</button>
{isOpen && (
<>
<StModalBox onClick={handleClickClose} />
<StModal>
<p>닫기 버튼 1개가 있고, 외부 영역을 누르면 모달이 닫혀요.</p>
<button onClick={handleClickClose}>X</button>
</StModal>
</>
)}
</div>
)}
</div>
);
}
export default Modal;
두 번째 모달은 모달을 감싸고 있는 <StModalBox>
컴포넌트에 handleClickClose 이벤트 핸들러를 줘서, 해당 영역을 눌렀을 때 모달창이 꺼지게 로직을 작성했다.
모달창을 띄웠을 때, 내용물을 감싸고 있는 모달 박스를 스타일링 해보겠다.
App 컴포넌트가 margin을 가지고 있어서 그냥 모달 박스를 postion: fixed로 설정해주면 아래와 같다.
자세히 보면 왼쪽에 앱 컴포넌트의 마진만큼 간격이 있다.
이 부분을 left: 0으로 해줘도 되고 그 전체 속성을 단축해주는 inset을 사용해도 된다. 나는 inset을 사용했다.
inset: 0;
을 통해 App 컴포넌트의 마진만큼 떨어지지 않고 각 위치마다 (left,right,bottom,top) 0만큼 떨어지게 된다. = 뷰포트에 딱 붙음
const StModal = styled.div`
position: absolute;
left: calc(50% - 250px);
top: calc(50% - 150px);
border-radius: 12px;
box-sizing: border-box;
padding: 24px;
background-color: #ffffff;
width: 500px;
height: 300px;
`;
position: absolute로 position : fixed를 준 상위 컴포넌트를 위치상의 부모요소로 인식하게 하고, left와 top모두 calc함수를 사용해서 절반(50%)에서 내가 가진 width의 절반 만큼 빼줘서 정중앙에 오게 한다.
모달창 스타일링 끝!