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; } }