[리액트를 다루는 기술] todoList와 items를 svg와 & 활용하여 scss 다루기

쿼카쿼카·2022년 9월 7일
0

App.js

import React, { useState } from 'react';
import TodoInsert from './components/TodoInsert';
import TodoList from './components/TodoList';
import TodoTemplate from './components/TodoTemplate';

function App() {
  const [todos, setTodos] = useState([
    {
      id: 1,
      text: '리액트의 기초 알아보기',
      checked: true,
    },
    {
      id: 2,
      text: '컴포넌트 스타일링 해보기',
      checked: true,
    },
    {
      id: 3,
      text: '일정 관리 앱 만들기',
      checked: false,
    },
  ]);
  return (
    <>
      <TodoTemplate>
        <TodoInsert />
        <TodoList todos={todos} />
      </TodoTemplate>
    </>
  );
}

export default App;

TodoList.js

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

function TodoList({todos}) {
  return (
    <div className='TodoList'>
      {todos.map(todo => (
        <TodoListItem todo={todo} key={todo.id} />
      ))}
    </div>
  )
}

export default TodoList;

TodoList.scss

.TodoList {
  min-height: 320px;
  max-height: 513px;
  overflow-y: auto;
}

TodoListItem.js

import {
  MdCheckBoxOutlineBlank,
  MdRemoveCircleOutline,
  MdCheckBox
} from 'react-icons/md';
import cn from 'classnames'; // npm i classnames
import './TodoListItem.scss';

function TodoListItem({todo}) {
  const {text, checked} = todo;
  return (
    <div className='TodoListItem'>
      <div className={cn('checkbox', {checked})}>
        {checked ? <MdCheckBox /> : <MdCheckBoxOutlineBlank />}
        <div className='text'>{text}</div>
      </div>
      <div className="remove">
        <MdRemoveCircleOutline />
      </div>
    </div>
  )
}

export default TodoListItem

TodoListItems.scss

.TodoListItem {
  padding: 1rem;
  display: flex;
  align-items: center; // 세로 중앙 정렬
  &:nth-child(even) {
    // 짝수 순서만 배경색 변경
    background: #f8f9fa;
  }


  .checkbox {
    cursor: pointer;
    flex: 1; // 차지할 수 있는 영역 모두 차지
    display: flex;
    align-items: center; // 세로 중앙 정렬
    svg {
      //아이콘
      font-size: 1.5rem;
    }

    .text {
      margin-left: 0.5rem;
      flex: 1; // 차지할 수 있는 영역 모두 차지
    }

    // 체크되었을 때 보여 줄 스타일
    &.checked {
      svg {
        color: #22b7cf;
      }
      .text {
        color: #adb5bd;
        text-decoration: line-through;
      }
    }
  }

  .remove {
    display: flex;
    align-items: center;
    font-size: 1.5rem;
    color: #ff6b6b;
    cursor: pointer;
    &:hover {
      color: #ff8787;
    }
  }

  // 첫 엘리먼트 제외하고 뒤 따라오는 엘리먼트들에만 테두리 넣어줌
  & + & {
    border-top: 1px solid #dee2e6;
  }
}

TodoList

  • min-height와 max-height로 최소 최대 높이 지정
  • overflow-y: auto로 513px 넘어가면 스크롤바 생성

TodoListItem

  • flex의 align-items: center로 중앙 정렬
  • &:nth-child()의 매개변수로 원하는 숫자나 식을 넣으면 해당 값에만 css 적용
  • flex: 1로 남은 공간 전체 차지
  • 아이콘들은 svg의 font-size로 크기 설정
  • & + &는 첫 엘리먼트 제외하고, 뒤따라오는 같은 엘리먼트들에게만 효과 넣어줌
  • {text, checked}를 이용해 비구조 할당
  • cn을 이용해 classname 동적 생성
  • 삼항연산자 활용하여 체크박스 변경

classnames

  • npm i classnames로 설치 후 cn으로 줄여서 받음
  • cn('checkbox', {checked})에서 true인 값만 적용됨
    • ex) cn('a', 1, 0, null, 'b', 'c', 3) = 'a 1 b c 3'
  • npm 링크(https://www.npmjs.com/package/classnames)
profile
쿼카에요

0개의 댓글