본문 바로가기

개발공부/REACT

[React] react-calendar 라이브러리로 캘린더 만들기

프로젝트를 진행하다가 캘린더를 구현해야 해서 react-calendar라이브러리로 리액트 앱에 캘린더를 적용해 보았다.


설치

npm install react-calendar

기본 코드 작성

import React, { useState } from 'react';
import Calendar from 'react-calendar';
import 'react-calendar/dist/Calendar.css';

const Calendar = () => {
  const [value, onChange] = useState(new Date());
  
  return (
    <div>
        <Calendar onChange={handleDateChange} value={value}></Calendar>
    </div>
  );
};

 

모듈을 import하고, 기본 css를 불러와줍니다. 

 

현재 클릭한 날짜를 표시하는 방법

<div>
    {moment(value).format("YYYY년 MM월 DD일")} 
</div>

 

moment를 이용하기 위해서는 마찬가지로 모듈을 설치 후 import 해주어야 한다

 

npm install moment
import moment from "moment";

프로젝트 코드에 적용

Calander.jsx

import React, { useState } from "react";
import styled from "styled-components";
import Calendar from "react-calendar";
import "react-calendar/dist/Calendar.css";
import selectArrow from "../assets/SelectArrow.svg";
import moment from "moment";

const CustomCalendar = ({ onChange, value }) => {
  const [nowDate, setNowDate] = useState("날짜");
  const [isOpen, setIsOpen] = useState(false);

  const handleToggleCalendar = () => {
    setIsOpen(!isOpen);
  };

  const handleDateChange = (selectedDate) => {
    onChange(selectedDate);
    setIsOpen(false);
    setNowDate(moment(selectedDate).format("YYYY년 MM월 DD일"));
  };

  return (
    <CalendarContainer>
      <DropdownButton onClick={handleToggleCalendar}>{nowDate}</DropdownButton>
      <CalendarWrapper isOpen={isOpen}>
        <Calendar onChange={handleDateChange} value={value}></Calendar>
      </CalendarWrapper>
    </CalendarContainer>
  );
};

export default CustomCalendar;

export default CustomCalendar;

 

styled-component 부분

const CalendarContainer = styled.div`
  position: relative;
`;

const DropdownButton = styled.button`
  width: 200px;
  height: 48px;
  border: 0.8px solid var(--festie-gray-600, #949494);
  border-radius: 10px;
  padding: 0px 12px;
  color: var(--festie-gray-800, #3a3a3a);
  font-family: SUIT Variable;
  font-size: 16px;
  font-style: normal;
  font-weight: 500;
  line-height: 140%;
  text-align: start;
  appearance: none;
  background-color: white;
  background-image: url(${selectArrow});
  background-repeat: no-repeat;
  background-position: right 12px center;
  background-size: 12px;
`;

const CalendarWrapper = styled.div`
  z-index: 11;
  position: absolute;
  top: 100%;
  left: 0;
  display: ${(props) => (props.isOpen ? "block" : "none")};
`;

 


디자인 수정

css 파일 경로: node_modules\react-calendar\dist\Calendar.css 

디자이너의 디자인 요구사항!

 

react-calendar의 기본 틀에 메인 색상이랑 틀만 조정해보았다.

 

"일" 빼기

"일" 없애기 전
"일" 없앤 후

 

<Calendar
    onChange={handleDateChange}
    value={value}
    formatDay={(locale, date) => moment(date).format("DD")}
></Calendar>

 

앞서 설치한 moment를 이용해 formatDay를 "DD" 형식으로 설정해주면 "일"을 없앨 수 있다.

 

세부 디자인 수정

.react-calendar {
    border-radius: 10px;
    border: 1px solid var(--festie-gray-400, #c8c8c8); // 전체 틀: border, border-radius 조정
  }

  .react-calendar__navigation__label > span {
    // 달력 상단 년/월 글씨 커스텀
    color: var(--festie-gray-800, #3a3a3a);
    font-family: SUIT Variable;
    font-size: 13px;
    font-weight: 500;
    line-height: 140%;
  }
  .react-calendar__month-view__days__day--weekend {
    // 주말 글씨 빨간색 없애기
    color: var(--festie-gray-800, #3a3a3a);
  }
  .react-calendar__tile:enabled:hover,
  .react-calendar__tile:enabled:focus {
    //hover 했을 때 색상 변경
    background: var(--festie-primary-orange, #ff7a00);
  }
  .react-calendar__tile--now {
    // 오늘 날짜 하이라이트 커스텀
    background: white;
    color: var(--festie-gray-800, #3a3a3a);
  }
  .react-calendar__tile--active {
    background: var(--festie-primary-orange, #ff7a00);
    color: white;
  }

 

디자인 수정 결과


💡 Challenge 

 

기본값을 오늘 날짜가 아닌 "날짜"라는 문자열로 표시해야 하는데..

다른 메뉴들처럼 기본값을 넣었지만, Calendar라는 라이브러리에서 가져오는 value값이 기본적으로 오늘 날짜가 들어오게 되어있어서 한참 씨름했는데..

 

const CustomCalendar = ({ onChange, value }) => {
  const [nowDate, setNowDate] = useState("날짜");  // nowDate라는 상태를 만들어서 기본값으로 날짜를 주고
  const [isOpen, setIsOpen] = useState(false);

  const handleToggleCalendar = () => {
    setIsOpen(!isOpen);
  };

  const handleDateChange = (selectedDate) => {
    onChange(selectedDate);
    setIsOpen(false);
    setNowDate(moment(selectedDate).format("YYYY년 MM월 DD일"));  // 날짜가 선택될 때에 NowDate 값을 넣어주도록 수정
  };

  return (
    <CalendarContainer>
      <DropdownButton onClick={handleToggleCalendar}>{nowDate}</DropdownButton>  // 드롭다운에 nowDate를 넣음
      <CalendarWrapper isOpen={isOpen}>
        <Calendar onChange={handleDateChange} value={value}></Calendar>
      </CalendarWrapper>
    </CalendarContainer>
  );
};

export default CustomCalendar;

 

nowDate라는 새로운 상태를 만들어서 기본값으로 날짜를 주고,

날짜가 선택되었을 때 (onClick인 handleDateChange 함수를 실행시켰을 때), 날짜를 바꿔주도록 구현했다!


참고링크 

 

리액트 앱에 달력(react-calendar) 적용하기

react-calendar 라이브러리로 react 앱에 달력을 적용하는 방법

velog.io

 

 

react-calendar custom 장장 7일간의 고군분투기 (초기설정부터 커스텀까지)

react-calendar 공식문서를 얼마나 읽었는지 모른다 👩🏻‍💻 하필 리액트 캘린더 라이브러리는 이름들도 다들 직관적이고 비슷해서 react-calendar range 라고 검색하면 진짜 react-date-range 라이브러리

velog.io

 

 

react-calendar '일' 빼기

react-calendar 커스텀 날짜 뒤에 있는 '일'

velog.io