Skip to content

Commit 0e08354

Browse files
authored
Merge pull request #40 from boostcampwm-2022/feat/#26-S
Feat/#26-S : 생성/참여 모달 UI 구현 & 모달 Open/Close 기능 구현
2 parents 5d6d8f3 + 886bae5 commit 0e08354

File tree

16 files changed

+314
-93
lines changed

16 files changed

+314
-93
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import cx from 'classnames';
2+
import Portal from 'src/components/Portal';
3+
4+
import style from './style.module.scss';
5+
6+
interface SelcetModalProps {
7+
children: JSX.Element;
8+
className?: string;
9+
onClose: () => void;
10+
}
11+
12+
function SelcetModal({ children, className, onClose }: SelcetModalProps) {
13+
const onClickCloseBtn = () => {
14+
onClose();
15+
};
16+
17+
return (
18+
<Portal>
19+
<div
20+
className={style.modal}
21+
role="alertdialog"
22+
aria-modal
23+
aria-labelledby="modal"
24+
>
25+
<div className={cx(style.container, className)}>{children}</div>
26+
<div
27+
className={style.dimmer}
28+
onClick={onClickCloseBtn}
29+
tabIndex={0}
30+
></div>
31+
</div>
32+
</Portal>
33+
);
34+
}
35+
36+
export default SelcetModal;
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
@import 'style/color.scss';
2+
3+
.modal {
4+
z-index: 100;
5+
display: flex;
6+
align-items: center;
7+
justify-content: center;
8+
position: fixed;
9+
top: 0;
10+
bottom: 0;
11+
left: 0;
12+
right: 0;
13+
14+
.container {
15+
display: flex;
16+
flex-direction: column;
17+
align-items: center;
18+
19+
width: fit-content;
20+
height: fit-content;
21+
22+
border-radius: 10px;
23+
background-color: $primary-100;
24+
padding: 20px;
25+
color: $white;
26+
font-size: 14px;
27+
margin: auto;
28+
}
29+
.dimmer {
30+
position: fixed;
31+
top: 0;
32+
bottom: 0;
33+
left: 0;
34+
right: 0;
35+
background-color: $modalBackground;
36+
}
37+
}

client/src/components/WorkspaceList/AddButton.tsx

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,21 @@
1-
import { MdAdd } from "@react-icons/all-files/md/MdAdd";
2-
import React from "react";
1+
import { MdAdd } from '@react-icons/all-files/md/MdAdd';
2+
import React from 'react';
33

4-
import style from "./style.module.scss";
4+
import style from './style.module.scss';
5+
6+
interface AddButtonProps {
7+
onClick: () => void;
8+
}
9+
10+
function AddButton({ onClick }: AddButtonProps) {
11+
const onClickBtn = () => {
12+
onClick();
13+
};
514

6-
function AddButton() {
715
return (
8-
<div className={style.button}>
16+
<button className={style.button} onClick={onClickBtn}>
917
<MdAdd color="white" size={20} />
10-
</div>
18+
</button>
1119
);
1220
}
1321

client/src/components/WorkspaceList/WorkspaceThumbnailItem.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import React from "react";
1+
import { memo } from 'react';
22

3-
import style from "./style.module.scss";
3+
import style from './style.module.scss';
44

55
interface WorkspaceThumbnailItemProps {
66
name: string;
@@ -21,4 +21,4 @@ function WorkspaceThumbnailItem({ name }: WorkspaceThumbnailItemProps) {
2121
);
2222
}
2323

24-
export default WorkspaceThumbnailItem;
24+
export default memo(WorkspaceThumbnailItem);

client/src/components/WorkspaceList/WorkspaceThumbnailList.tsx

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
1-
import React from "react";
2-
3-
import style from "./style.module.scss";
4-
import WorkspaceThumbnailItem from "./WorkspaceThumbnailItem";
1+
import style from './style.module.scss';
2+
import WorkspaceThumbnailItem from './WorkspaceThumbnailItem';
53

64
const workspaces = [
7-
{ id: 1, name: "왭" },
8-
{ id: 2, name: "네이버" },
9-
{ id: 3, name: "카카오" },
10-
{ id: 4, name: "토스" },
5+
{ id: 1, name: '왭' },
6+
{ id: 2, name: '네이버' },
7+
{ id: 3, name: '카카오' },
8+
{ id: 4, name: '토스' },
119
];
1210

1311
function WorkspaceThumbnailList() {
Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
1-
import React from "react";
1+
import { memo } from 'react';
22

3-
import AddButton from "./AddButton";
4-
import style from "./style.module.scss";
5-
import WorkspaceThumbnaliList from "./WorkspaceThumbnailList";
3+
import AddButton from './AddButton';
4+
import style from './style.module.scss';
5+
import WorkspaceThumbnaliList from './WorkspaceThumbnailList';
66

7-
function WorkspaceList() {
7+
interface WorkspaceListProps {
8+
onSelectModalOpen: () => void;
9+
}
10+
11+
function WorkspaceList({ onSelectModalOpen }: WorkspaceListProps) {
812
return (
913
<div className={style.workspace__container}>
1014
<WorkspaceThumbnaliList />
11-
<AddButton />
15+
<AddButton onClick={onSelectModalOpen} />
1216
</div>
1317
);
1418
}
1519

16-
export default WorkspaceList;
20+
export default memo(WorkspaceList);
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import Button from '../common/Button';
2+
import Modal from '../common/Modal';
3+
import style from './style.module.scss';
4+
5+
interface WorkspaceModalProps {
6+
title: string;
7+
text: string;
8+
btnText: string;
9+
inputValue: string;
10+
onChange?: (value: string) => void;
11+
onClose: () => void;
12+
}
13+
14+
function WorkspaceModal({
15+
title,
16+
text,
17+
btnText,
18+
inputValue,
19+
onChange,
20+
onClose,
21+
}: WorkspaceModalProps) {
22+
const onInput = (e: React.ChangeEvent<HTMLInputElement>) => {
23+
if (onChange) onChange(e.target.value);
24+
};
25+
26+
return (
27+
<Modal title={title} onClose={onClose}>
28+
<>
29+
<span className={style.text}>{text}</span>
30+
<input className={style.input} type="text" onChange={onInput} />
31+
<Button text={btnText} isDisable={!inputValue.length} />
32+
</>
33+
</Modal>
34+
);
35+
}
36+
37+
export default WorkspaceModal;
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
@import 'style/color.scss';
2+
3+
.text {
4+
font-size: 14px;
5+
}
6+
.input {
7+
width: calc(100% - 6rem);
8+
border: 1px solid $gray-100;
9+
border-radius: 10px;
10+
padding: 10px;
11+
font-size: 14px;
12+
margin: 15px 0;
13+
}

client/src/components/common/Button/index.tsx

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,31 @@
1-
import cx from "classnames";
1+
import classNames from 'classnames/bind';
22

3-
import style from "./style.module.scss";
3+
import style from './style.module.scss';
4+
5+
const cx = classNames.bind(style);
46

57
interface ButtonProps {
68
text: string;
79
icon?: JSX.Element;
810
className?: string;
11+
isDisable?: boolean;
12+
color?: string;
913
}
1014

11-
function Button({ text, icon, className }: ButtonProps) {
15+
function Button({
16+
text,
17+
icon,
18+
className,
19+
isDisable = false,
20+
color,
21+
}: ButtonProps) {
1222
return (
13-
<div className={cx(style.button, className)}>
23+
<div
24+
className={cx(style.button, className, { disable: isDisable })}
25+
style={{ backgroundColor: color }}
26+
>
1427
{icon}
15-
<button>{text}</button>
28+
<button disabled={isDisable}>{text}</button>
1629
</div>
1730
);
1831
}

client/src/components/common/Button/style.module.scss

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@import "style/color.scss";
1+
@import 'style/color.scss';
22

33
.button {
44
width: fit-content;
@@ -15,3 +15,7 @@
1515
font-weight: 700;
1616
}
1717
}
18+
19+
.disable {
20+
background-color: $gray-300;
21+
}

0 commit comments

Comments
 (0)