$ yarn create react-app todo-app
todo-app 생성
$ yarn add sass classnames react-icons
Sass
설치
react-icons
: 예쁜 아이콘
최상위 폴더에 .prettierrc
생성
{
"singleQuote": true,
"semi": true,
"useTabs": false,
"tabWidth": 2,
"trailingComma": "all",
"printWidth": 80
}
fuction App() {return(...)}
아래로 바꾸기
const App = ()=>{
return (
<div>Todo App을 만들자</div>
)
}
<TodoTemplate>Todo App을 만들자</TodoTemplate>
/TodoTemplate.js
import './TodoTemplate.scss'
const TodoTemplate=({children})=>{
return (
<div className='TodoTemplate'>
<div className='app-title'>일정관리</div>
<div className='content'>{children}</div>
</div>
)
}
export default TodoTemplate
.TodoTemplate {
width: 512px;
margin-left: auto;
margin-right: auto;
margin-top: 6rem;
border-radius: 4px;
overflow: hidden;
}
.app-title {
background: #22b8cf;
color: white;
height: 4rem;
font-size: 1.5rem;
display: flex;
align-items: center;
justify-content: center;
}
.content {
background: whitesmoke;
font-weight: 500;
}
import { 아이콘 이름} from 'react-icons/md';
https://react-icons.github.io/react-icons/#/icons/md
<TodoTemplate> <TodoInsert/> </TodoTemplate>
import './TodoInsert.scss'
import {AiFillApple} from 'react-icons/ai'
const TodoInsert= ()=>{
return (
<form className='TodoInsert'>
<input placeholder='할 일을 입력하세요'/>
<button type='submit'>
<AiFillApple/>
</button>
</form>
)
}
export default TodoInsert
.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 {
color: #dee2e6;
}
flex: 1;
}
button {
background: #868e96;
color: white;
padding-left: 1rem;
padding-right: 1rem;
font-size: 1.5rem;
display: flex;
align-items: center;
cursor: pointer;
transition: 0.1s background ease-in;
&:hover {
background: #adb5bd;
}
}
&:hover { }
호버 시 변경
transition
천천히 변경
<TodoTemplate> <TodoInsert/> <TodoList/> </TodoTemplate>
import TodoListItem from './TodoListItem'
import './TodoList.scss'
const Todolist = () =>{
return (
<div className='TodoList'>
<TodoListItem/>
<TodoListItem/>
<TodoListItem/>
</div>
)
}
export default Todolist
.TodoList {
min-height: 320px;
max-height: 513px;
overflow-y: auto;
}
최소 높이, 최대 높이 설정
점점 늘어나다 scroll 생긴다
import {
MdCheckBoxOutlineBlank,
MdRemoveCircleOutline,
} from 'react-icons/md'
import './TodoListItem.scss'
const TodoListItem= ()=>{
return (
<div className='TodoListItem'>
<div className='checkbox'>
<MdCheckBoxOutlineBlank/>
<div className='text'>할일</div>
</div>
<div className='remove'>
<MdRemoveCircleOutline/>
</div>
</div>
)
}
export default TodoListItem
.TodoListItem {
padding: 1rem;
display: flex;
align-items: center;
&:nth-child(even) {
background: #f8f9fa;
}
.checkbox {
cursor: pointer;
flex: 1;
align-items: center;
svg {
font-size: 1.5rem;
}
.text {
margin-left: 0.5rem;
flex: 1;
}
&.checked {
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 {
color: #c81414;
}
}
& + & {
border-top: 1px solid #dee2e6;
}
}
align-items : center
: 세로 중앙 정렬
flex: 1;
차지할 수 있는 모든 영역 차지
.checkbox { &.checked{...} }
: 체크 되었을 때 보여줄 스타일
& + & {border-top: 1px solid #dee2e6;}
:엘리먼트 사이사이에 테두리를 넣어준다.