Simple Todo UI

Todo UI


Simple Todo UI


UI 개발순서


[1] UI 컴포넌트 구성하기
[2] JSX로 HTML 구조 만들기
[3] Sass로 style 꾸미기(Sass 중 Scss 문법 사용)


[1] UI 컴포넌트 구성하기


[1-1] Todo List 전체를 나타내는 TodoTemplate 컴포넌트(전체화면)

  • 화면을 가운데 정렬
  • 크게 앱의 타이틀(Todo List)과 콘텐츠(Insert와 TodoList)로 나눔

[1-2] 새로운 Todo를 입력하고 추가할 수 있는 TodoInsert 컴포넌트

[1-3] TodoList 컴포넌트와 TodoListItem 컴포넌트

  • Todo의 item들을 나열하는 TodoList 컴포넌트
  • 각 Todo에 대한 정보를 보여주는 TodoListItem 컴포넌트

[1-4] 각 Todo에 대한 정보를 보여주는 TodoListItem 컴포넌트


[1-1] TodoTemplate 컴포넌트


[1] JSX

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// TodoTemplate.js

import React from 'react';
import './TodoTemplate.scss';

const TodoTemplate = ({ children }) => {
return (
<div className="TodoTemplate">
<div className="app-title">Todo List</div>
<div className="content">{children}</div>
</div>
);
};

export default TodoTemplate;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// App.js

import React from 'react';
import TodoTemplate from './components/TodoTemplate';
import TodoInsert from './components/TodoInsert';
import TodoList from './components/TodoList';

function App() {
return (
<TodoTemplate>
<TodoInsert />
<TodoList />
</TodoTemplate>
);
}

export default App;


[2] Scss

Styles

  • Todo 전체화면을 가운데 정렬
  • 앱 타이틀 글자를 가운데 정렬

[2-1] Todo 전체화면을 가운데 정렬

Todo 전체화면은 TodoTemplate 컴포넌트이고, 이는 “div” 형태이므로 블록요소이다. 블록요소를 가운데 정렬하기 위해서는 width를 설정하고, margin-left와 margin-right를 auto로 설정해야한다.

1
2
3
4
5
6
7
8
9
.TodoTemplate {
background-color: orchid;
width: 512px;
margin-left: auto;
margin-right: auto;
margin-top: 6rem; // 기본 font-size 16px를 기준 -> 16px * 6
border-radius: 4px;
overflow: hidden;
}

[2-2] 앱 타이틀 글자를 가운데 정렬

글자를 가운데 정렬하기 위해 flex를 이용하여 상하/좌우 가운데 정렬한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.TodoTemplate {
...

.app-title {
background: #22b8cf;
color: white;
height: 4rem;
font-size: 1.5rem;
display: flex;
align-items: center; // 상하 정렬
justify-content: center; // 좌우 정렬
}
.content {
background: white;
}
}


[1-2] TodoInsert 컴포넌트


[1] JSX

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// TodoInsert.js

import React from 'react';
import { MdAdd } from 'react-icons/md';
import './TodoInsert.scss';

const TodoInsert = () => {
return (
<form className="TodoInsert">
<input placeholder="Enter Todo" />
<button type="submit">
<MdAdd />
</button>
</form>
);
};

export default TodoInsert;


[2] Scss

Styles

  • 각 요소의 기본 스타일 초기화
  • input 태그의 placeholder 추가
  • button을 제외한 모든 영역을 input이 차지
  • button안의 ‘+’ 모양 수직정렬
  • button 마우스 hover 시 배경색상 변경
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// TodoInsert.scss

.TodoInsert {
display: flex;
background: #495057;
input {
// 기본 스타일 초기화
background: none;
outline: none;
border: none;
padding: 0.5rem;
font-size: 1.125rem;
line-height: 1.5;
color: white;
&::placeholder { // input 태그의 placeholder 추가
color: #dee2e6;
}
flex: 1; // button을 제외한 모든 영역을 input이 차지
}
button {
background: none;
outline: none;
border: none;
background: #868e96;
color: white;
padding-left: 1rem;
padding-right: 1rem;
font-size: 1.5rem;
display: flex;
align-items: center; // button안의 '+' 모양 수직정렬
cursor: pointer;
transition: 0.1s background ease-in;
&:hover { // button 마우스 hover 시 배경색상 변경
background: #adb5bd;
}
}
}


[1-3] TodoList & TodoListItem 컴포넌트


[1] JSX

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// TodoList.js

import React from 'react';
import TodoListItem from './TodoListItem';
import './TodoList.scss';

const TodoList = () => {
return (
<div className="TodoList">
<TodoListItem />
<TodoListItem />
<TodoListItem />
<TodoListItem />
</div>
);
};

export default TodoList;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// TodoListItem.js

import React from 'react';
import {
MdCheckBoxOutlineBlank,
MdCheckBox,
MdRemoveCircleOutline,
} from 'react-icons/md';
import './TodoListItem.scss';

const TodoListItem = () => {
return (
<div className="TodoListItem">
<div className="checkbox">
<MdCheckBoxOutlineBlank />
<div className="text">Todo</div>
</div>
<div className="remove">
<MdRemoveCircleOutline />
</div>
</div>
);
};

export default TodoListItem;


[2] Scss

Styles

  • TodoListItem에 있는 모든 요소는 수직 정렬
  • 짝수/홀수 Todo들의 배경색 다름
  • checkbox가 체크되었을 때, svg(아이콘)와 text 색상 바뀜
  • remove 이미지 수직정렬 및 hover 시 색상 바뀜
  • 두 item 사이에 border 색상 진하게 추가
1
2
3
4
5
6
7
// TodoList.scss

.TodoList {
min-height: 320px;
max-height: 513px;
overflow-y: auto;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
// TodoListItem.scss

.TodoListItem {
padding: 1rem;
display: flex;
align-items: center; // TodoListItem에 있는 모든 요소는 수직 정렬
&:nth-child(even) { // 짝수/홀수 Todo들의 배경색 다름
background: #f8f9fa;
}
.checkbox {
cursor: pointer;
flex: 1;
display: flex;
align-items: center;
svg {
font-size: 1.5rem;
}
.text {
margin-left: 1.5rem;
flex: 1;
}
&.checked { // checkbox가 체크되었을 때, svg와 text 색상 바뀜
svg {
color: #22b8cf;
}
.text {
color: #adb5bd;
text-decoration: line-through;
}
}
}
.remove {
display: flex;
align-items: center; // 수직정렬
font-size: 1.5rem;
color: #ff6b6b;
cursor: pointer;
&:hover { // hover 시 색상바뀜
color: #ff8787;
}
}
& + & { // 두 item 사이에 border 색상 진하게 추가
border-top: 1px solid #dee2e6;
}
}