백그라운드 클릭시 꺼지는 모달
우선 컨텐츠를 누르면 state를 이용해 모달이 켜지게 해줬다
//모달 온
const ContentsOnClick = () => {
setModal(!modal);
document.body.style.overflow = "hidden";
};
<Contents done={props.item.done} onClick={ContentsOnClick}>
<p>{props.item.title}</p>
<p>{props.item.date}</p>
</Contents>
그리고 컨텐츠 안의 내용을 모달이 켜질때 함께 보여지게 삼항연산자를 이용해 만들었다.
{modal ? (
<>
<ModalBackground
onClick={ModalBackgroundOnClick}
modal={modal}
></ModalBackground>
<Modal modal={modal} done={props.item.done}>
<ModalDiv>
{/* 제목*/}
{edit ? (
<ModalTItleInput
onChange={editTitleOnChange}
defaultValue={props.item.title}
maxLength={30}
/>
) : (
<ModalTitle done={props.item.done}>
{props.item.title}
</ModalTitle>
)}
{/* 완료 버튼*/}
<DoneText>Done</DoneText>
<DoneButton onClick={DoneOnClick}>
<Done done={props.item.done} />
</DoneButton>
</ModalDiv>
{/*내용*/}
{edit ? (
<ModalTextArea
onChange={editTextOnChange}
defaultValue={props.item.text}
maxLength={1000}
/>
) : (
<ModalText>{props.item.text}</ModalText>
)}
<ModalButton>
{/*날짜*/}
<ModalDate>{props.item.date}</ModalDate>
<ModalEdit onClick={EditOnClick}>
{edit ? "취소" : "수정"}
</ModalEdit>
{edit ? (
<ModalDelete onClick={EditComplete}>완료</ModalDelete>
) : (
<ModalDelete onClick={() => DeleteOnClick(props.item.id)}>
삭제
</ModalDelete>
)}
<ModalExit onClick={ModalBackgroundOnClick}>닫기</ModalExit>
</ModalButton>
</Modal>
</>
) : (
""
)}
모달안의 수정을 클릭하면 내용이 들어있는 input, textarea로 바뀌고 버튼도 수정모드로 바뀌게 해줬다.
//수정 onclick
const EditOnClick = () => {
setEdit(!edit);
};
//수정 title
const editTitleOnChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setEditTitle(event.target.value);
};
//수정 text
const editTextOnChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
setEditText(event.target.value);
};
//수정 완료
const EditComplete = () => {
const newData = {
...props.item,
title: editTitle,
text: editText,
};
if (editTitle.trim() === "" || editText.trim() === "") {
alert("제목, 내용을 모두 입력하세요.");
} else {
EditMutation.mutate(newData);
alert("수정이 완료되었습니다.");
setEdit(false);
}
};
맨 위의 ModalBackground를 이용해 모달이 생기면 배경화면을 어둡게 만들어줬다.
추가로 배경 클릭시 모달이 꺼지게, 모달이 켜졌을때 스크롤도 안되게 해줬다,
스크롤이 안되게 할때 바로 스크롤을 없애면 스크롤 부분만큼의 width가 없어져서 배경이 살짝 이동하는 문제가 있었다.
그래서 모달을 킬때 overflow: hidden을 주고 닫을때 overlay로 줬더니 괜찮아졌다.
const ModalBackgroundOnClick = () => {
setModal(!modal);
setEdit(false);
document.body.style.overflow = "overlay";
};
그리고 투두리스트인 만큼 완료버튼이 필요했는데 왼쪽 오른쪽으로 움직이는 클릭 버튼으로 만들었다.
완료 될시 모달과 컨텐츠의 배경이 어두워지고 글에 line-through속성을 주었다.
const Contents = styled.div<{ done: Boolean }>`
margin: 20px auto 0 auto;
width: 100%;
height: 50px;
background-color: ${(props) => (props.done ? "#ededed" : "#fff")};
color: ${(props) => (props.done ? "#ccc" : "#000")};
text-decoration: ${(props) => (props.done ? "line-through" : "")};
border-radius: 10px;
display: flex;
align-items: center;
justify-content: space-between;
box-shadow: 1px 3px 5px 0px #ccc;
transition: 0.5s;
cursor: pointer;
&:hover {
background-color: #ccc;
color: #fff;
}
p {
margin: 0 15px;
}
@media only screen and (max-width: 667px) {
p:first-child {
width: 300px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
`;
백그라운드 클릭시 꺼지는 모달
우선 컨텐츠를 누르면 state를 이용해 모달이 켜지게 해줬다
//모달 온
const ContentsOnClick = () => {
setModal(!modal);
document.body.style.overflow = "hidden";
};
<Contents done={props.item.done} onClick={ContentsOnClick}>
<p>{props.item.title}</p>
<p>{props.item.date}</p>
</Contents>
그리고 컨텐츠 안의 내용을 모달이 켜질때 함께 보여지게 삼항연산자를 이용해 만들었다.
{modal ? (
<>
<ModalBackground
onClick={ModalBackgroundOnClick}
modal={modal}
></ModalBackground>
<Modal modal={modal} done={props.item.done}>
<ModalDiv>
{/* 제목*/}
{edit ? (
<ModalTItleInput
onChange={editTitleOnChange}
defaultValue={props.item.title}
maxLength={30}
/>
) : (
<ModalTitle done={props.item.done}>
{props.item.title}
</ModalTitle>
)}
{/* 완료 버튼*/}
<DoneText>Done</DoneText>
<DoneButton onClick={DoneOnClick}>
<Done done={props.item.done} />
</DoneButton>
</ModalDiv>
{/*내용*/}
{edit ? (
<ModalTextArea
onChange={editTextOnChange}
defaultValue={props.item.text}
maxLength={1000}
/>
) : (
<ModalText>{props.item.text}</ModalText>
)}
<ModalButton>
{/*날짜*/}
<ModalDate>{props.item.date}</ModalDate>
<ModalEdit onClick={EditOnClick}>
{edit ? "취소" : "수정"}
</ModalEdit>
{edit ? (
<ModalDelete onClick={EditComplete}>완료</ModalDelete>
) : (
<ModalDelete onClick={() => DeleteOnClick(props.item.id)}>
삭제
</ModalDelete>
)}
<ModalExit onClick={ModalBackgroundOnClick}>닫기</ModalExit>
</ModalButton>
</Modal>
</>
) : (
""
)}
모달안의 수정을 클릭하면 내용이 들어있는 input, textarea로 바뀌고 버튼도 수정모드로 바뀌게 해줬다.
//수정 onclick
const EditOnClick = () => {
setEdit(!edit);
};
//수정 title
const editTitleOnChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setEditTitle(event.target.value);
};
//수정 text
const editTextOnChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
setEditText(event.target.value);
};
//수정 완료
const EditComplete = () => {
const newData = {
...props.item,
title: editTitle,
text: editText,
};
if (editTitle.trim() === "" || editText.trim() === "") {
alert("제목, 내용을 모두 입력하세요.");
} else {
EditMutation.mutate(newData);
alert("수정이 완료되었습니다.");
setEdit(false);
}
};
맨 위의 ModalBackground를 이용해 모달이 생기면 배경화면을 어둡게 만들어줬다.
추가로 배경 클릭시 모달이 꺼지게, 모달이 켜졌을때 스크롤도 안되게 해줬다,
스크롤이 안되게 할때 바로 스크롤을 없애면 스크롤 부분만큼의 width가 없어져서 배경이 살짝 이동하는 문제가 있었다.
그래서 모달을 킬때 overflow: hidden을 주고 닫을때 overlay로 줬더니 괜찮아졌다.
const ModalBackgroundOnClick = () => {
setModal(!modal);
setEdit(false);
document.body.style.overflow = "overlay";
};
그리고 투두리스트인 만큼 완료버튼이 필요했는데 왼쪽 오른쪽으로 움직이는 클릭 버튼으로 만들었다.
완료 될시 모달과 컨텐츠의 배경이 어두워지고 글에 line-through속성을 주었다.
const Contents = styled.div<{ done: Boolean }>`
margin: 20px auto 0 auto;
width: 100%;
height: 50px;
background-color: ${(props) => (props.done ? "#ededed" : "#fff")};
color: ${(props) => (props.done ? "#ccc" : "#000")};
text-decoration: ${(props) => (props.done ? "line-through" : "")};
border-radius: 10px;
display: flex;
align-items: center;
justify-content: space-between;
box-shadow: 1px 3px 5px 0px #ccc;
transition: 0.5s;
cursor: pointer;
&:hover {
background-color: #ccc;
color: #fff;
}
p {
margin: 0 15px;
}
@media only screen and (max-width: 667px) {
p:first-child {
width: 300px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
`;