Skip to content

Commit d3fb45c

Browse files
authored
Feat : 모달 UI 구현
Feat : 모달 UI 구현
2 parents 3ae5408 + e98c3e7 commit d3fb45c

File tree

16 files changed

+329
-0
lines changed

16 files changed

+329
-0
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import ModalContainer from "./modalComponents/ModalContainer";
2+
import ModalInput from "./modalComponents/ModalInput";
3+
4+
const AddFolderModal = ({ folderName }: { folderName: string }) => {
5+
return (
6+
<ModalContainer title="폴더 추가" buttonText="추가하기">
7+
<ModalInput placeholder="내용 입력" name={folderName} />
8+
</ModalContainer>
9+
);
10+
};
11+
export default AddFolderModal;

components/modal/AddModal.tsx

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import FolderList from "./modalComponents/FolderList";
2+
import ModalContainer from "./modalComponents/ModalContainer";
3+
interface ItemType {
4+
id: number;
5+
title: string;
6+
totalCount: number;
7+
}
8+
const list: ItemType[] = [
9+
{ id: 1, title: "코딩팁", totalCount: 7 },
10+
{ id: 2, title: "채용 사이트", totalCount: 7 },
11+
{ id: 3, title: "유용한 글", totalCount: 7 },
12+
{ id: 4, title: "나만의 장소", totalCount: 7 },
13+
];
14+
15+
const AddModal = ({ list }: { list: ItemType[] }) => {
16+
return (
17+
<ModalContainer
18+
title="폴더에 추가"
19+
subtitle="링크 주소"
20+
buttonText="추가하기"
21+
>
22+
<FolderList list={list} />
23+
</ModalContainer>
24+
);
25+
};
26+
export default AddModal;
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import ModalContainer from "./modalComponents/ModalContainer";
2+
3+
const DeleteFolderModal = ({ folderName }: { folderName: string }) => {
4+
return (
5+
<ModalContainer
6+
title="폴더 삭제"
7+
subtitle={folderName}
8+
buttonText="삭제하기"
9+
buttonColor="negative"
10+
></ModalContainer>
11+
);
12+
};
13+
export default DeleteFolderModal;
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import ModalContainer from "./modalComponents/ModalContainer";
2+
3+
const DeleteLinkModal = ({ link }: { link: string }) => {
4+
return (
5+
<ModalContainer
6+
title="링크 삭제"
7+
subtitle={link}
8+
buttonText="삭제하기"
9+
buttonColor="negative"
10+
></ModalContainer>
11+
);
12+
};
13+
export default DeleteLinkModal;

components/modal/EditModal.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import ModalContainer from "./modalComponents/ModalContainer";
2+
import ModalInput from "./modalComponents/ModalInput";
3+
4+
const EditModal = ({ folderName }: { folderName: string }) => {
5+
return (
6+
<ModalContainer title="폴더 이름 변경" buttonText="변경하기">
7+
<ModalInput placeholder="내용 입력" name={folderName} />
8+
</ModalContainer>
9+
);
10+
};
11+
export default EditModal;

components/modal/SNSModal.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import ModalContainer from "./modalComponents/ModalContainer";
2+
import ModalShare from "./modalComponents/ModalShare";
3+
4+
const SNSModal = ({ folderName }: { folderName: string }) => {
5+
return (
6+
<ModalContainer title="폴더 공유" subtitle={folderName}>
7+
<ModalShare />
8+
</ModalContainer>
9+
);
10+
};
11+
export default SNSModal;
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { cls } from "@/lib/utils";
2+
import { useState } from "react";
3+
import { FaCheck } from "react-icons/fa6";
4+
5+
interface ItemType {
6+
id: number;
7+
title: string;
8+
totalCount: number;
9+
}
10+
const FolderItem = ({ item }: { item: ItemType }) => {
11+
const [selected, setSelected] = useState(false);
12+
13+
const bgColor = selected ? "bg-gray100" : "bg-white";
14+
15+
const { title, totalCount } = item;
16+
17+
const onClickFolder = () => {
18+
setSelected(!selected);
19+
};
20+
return (
21+
<li
22+
className={cls(
23+
bgColor,
24+
"w-full p-2 flex h-10 rounded-lg items-center justify-between"
25+
)}
26+
onClick={onClickFolder}
27+
>
28+
<div className="flex items-center gap-2">
29+
<div
30+
className={cls(
31+
"text-base",
32+
selected ? "text-purple100" : "text-black300"
33+
)}
34+
>
35+
{title}
36+
</div>
37+
<div className="text-gray400 text-sm">{totalCount}개 링크</div>
38+
</div>
39+
{selected && (
40+
<div>
41+
<FaCheck className="text-purple100" />
42+
</div>
43+
)}
44+
</li>
45+
);
46+
};
47+
export default FolderItem;
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import FolderItem from "./FolderItem";
2+
interface ItemType {
3+
id: number;
4+
title: string;
5+
totalCount: number;
6+
}
7+
8+
const list: ItemType[] = [
9+
{ id: 1, title: "코딩팁", totalCount: 7 },
10+
{ id: 2, title: "채용 사이트", totalCount: 7 },
11+
{ id: 3, title: "유용한 글", totalCount: 7 },
12+
{ id: 4, title: "나만의 장소", totalCount: 7 },
13+
];
14+
const FolderList = ({ list }: { list: ItemType[] }) => {
15+
return (
16+
<ul className="mb-6 flex flex-col gap-1 min-w-[280px] w-full">
17+
{list.map((item) => (
18+
<FolderItem key={item.id} item={item} />
19+
))}
20+
</ul>
21+
);
22+
};
23+
24+
export default FolderList;
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { MouseEvent, ReactNode } from "react";
2+
import { IoIosClose } from "react-icons/io";
3+
import Button from "../../Button";
4+
5+
const ModalContainer = ({
6+
title,
7+
subtitle,
8+
children,
9+
buttonText,
10+
buttonColor,
11+
onClick,
12+
}: {
13+
title: string;
14+
subtitle?: string;
15+
children?: ReactNode;
16+
buttonText?: string;
17+
buttonColor?: "positive" | "negative";
18+
onClick?: (e: MouseEvent<HTMLButtonElement>) => void;
19+
}) => {
20+
return (
21+
<div className="z-30 absolute top-0 left-0 flex justify-center items-center bg-black/40 h-screen w-screen">
22+
<div className="z-20 relative w-[360px] py-8 px-10 flex flex-col gap-6 bg-white rounded-[15px] border border-gray300">
23+
{/* 제목 + 부제목 */}
24+
<div className="flex flex-col items-center justify-center gap-2">
25+
<div className="text-center w-[280px] gap-2 text-black300 text-xl leading-6 font-bold">
26+
{title}
27+
</div>
28+
{subtitle && (
29+
<div className="text-sm leading-[22px] font-normal text-gray400">
30+
{subtitle}
31+
</div>
32+
)}
33+
</div>
34+
{/* children -> inpul, sns공유, folder list 등.. */}
35+
<div className="flex justify-center items-center flex-col">
36+
{children && <>{children}</>}
37+
38+
{/* 제출 버튼 */}
39+
{buttonText && (
40+
<Button
41+
type="button"
42+
width="w-full"
43+
height="h-[51px] "
44+
color={buttonColor}
45+
>
46+
{buttonText}
47+
</Button>
48+
)}
49+
</div>
50+
51+
{/* 모달 닫기 버튼 */}
52+
<button
53+
type="button"
54+
onClick={onClick}
55+
className="bg-gray200 absolute top-4 right-4 rounded-full size-6 flex justify-center items-center"
56+
>
57+
<IoIosClose className="text-gray400" strokeWidth={2} />
58+
</button>
59+
</div>
60+
</div>
61+
);
62+
};
63+
export default ModalContainer;
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { cls } from "@/lib/utils";
2+
3+
const ModalInput = ({
4+
placeholder,
5+
name,
6+
}: {
7+
placeholder?: string;
8+
name: string;
9+
}) => {
10+
return (
11+
<input
12+
type="text"
13+
name={name}
14+
id={name}
15+
className={cls(
16+
"w-full rounded-lg border border-gray300 py-[18px] px-[15px] mb-6 text-black300",
17+
"placeholder:text-base placeholder:text-gray400",
18+
"focus:outline-1px focus:outline-purple100"
19+
)}
20+
placeholder={placeholder}
21+
></input>
22+
);
23+
};
24+
25+
export default ModalInput;

0 commit comments

Comments
 (0)