react 에서 달력(react-calendar) 적용하기

coilly·2022년 9월 1일
0

react

목록 보기
1/1

깃헙 : https://github.com/wojtekmaj/react-calendar
적용할때 어려웠던 점이나 코드 적용 방법을 기재 하려고 합니다

state가 있을때 class 문법으로 작성해야하는 기준을 따라
class 문법으로 작성합니다

클릭하면 Date를 출력하고 영문 요일, 1일부터 시작하는 달력 옵션입니다

npm으로 react-calendar, momen를 다운받습니다

$npm i react-calendar 
$npm i moment

/DateDropdown.js

/* eslint-disable react/prop-types */
import React from 'react';
import Calendar from 'react-calendar';
import moment from 'moment';
import './DateDropdown.scss';

export default class DateDropdown extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      date: moment().format('MM / DD / YYYY'),
      isToggleOn: false,
    };
    this.onClickDay = this.onClickDay.bind(this);
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState((prevState) => ({
      isToggleOn: !prevState.isToggleOn,
    }));
  }

  onClickDay(e) {
    this.setState((prevState) => ({
      date: moment(e).format('MM / DD / YYYY'),
      isToggleOn: !prevState.isToggleOn,
    }));
  }

  render() {
    const { date, isToggleOn } = this.state;
    const { dropWidth, disabled } = this.props;
    const iconStyle = {
      backgroundImage: 'url(/assets/images/component/calendar.png)',
      backgroundSize: 'cover',
      backgroundRepeat: 'no-repeat',
    };
    const arrowStyle = {
      backgroundImage: 'url(/assets/images/component/arrow_down.png)',
      backgroundSize: 'cover',
      backgroundRepeat: 'no-repeat',
    };
    return (
      <div>
        {disabled ? (
          <div className="date-dropdown disabled">
            <button
              type="button"
              className="date-dropdown__button"
              style={{ width: dropWidth }}
              onClick={this.handleClick}
            >
              <div style={iconStyle} className="date-dropdown__icon">
                <span className="a11y">달력 아이콘</span>
              </div>
              <span className="date-dropdown__data">{date}</span>
              <div style={arrowStyle} className="date-dropdown__arrow">
                <span className="a11y">아래 화살표 아이콘</span>
              </div>
            </button>
          </div>
        ) : (
          <div className="date-dropdown">
            <button
              type="button"
              className={
                isToggleOn
                  ? 'date-dropdown__button active'
                  : 'date-dropdown__button'
              }
              style={{ width: dropWidth }}
              onClick={this.handleClick}
            >
              <div style={iconStyle} className="date-dropdown__icon">
                <span className="a11y">달력 아이콘</span>
              </div>
              <span className="date-dropdown__data">{date}</span>
              <div style={arrowStyle} className="date-dropdown__arrow">
                <span className="a11y">아래 화살표 아이콘</span>
              </div>
            </button>
            {isToggleOn ? (
              <Calendar
                onClickDay={this.onClickDay}
                calendarType="US"
                locale="en-HU"
                showNeighboringMonth={false}
              />
            ) : null}
          </div>
        )}
      </div>
    );
  }
}

/DateDropdown.scss

.react-calendar {
  position: absolute;
  left: 0;
  width: 415px;
  max-width: 100%;
  padding: 17px 20px;
  background: white;
  border: 1px solid #F4F4F4;
  border-radius: 5px;
  box-shadow: 0px 26px 80px 0px #1212171A;
  box-sizing: border-box;
  z-index: 9;
}

.react-calendar--doubleView {
  width: 700px;
}

.react-calendar__viewContainer {
  margin-right: -20px;
}

.react-calendar--doubleView .react-calendar__viewContainer {
  display: flex;
  margin: -0.5em;
}

.react-calendar--doubleView .react-calendar__viewContainer > * {
  width: 50%;
  margin: 0.5em;
}

.react-calendar,
.react-calendar *,
.react-calendar *:before,
.react-calendar *:after {
  -moz-box-sizing: border-box;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
}

.react-calendar button {
  margin: 0;
  border: 0;
  outline: none;
}

.react-calendar button:enabled:hover {
  cursor: pointer;
}

.react-calendar__navigation {
  display: flex;
  height: 44px;
  margin-bottom: 11px;
  align-items: center;
}

.react-calendar__navigation button {
  width: 24px;
  height: 24px;
  background: none;
  text-align: left;
}

.react-calendar__navigation__label__labelText--from {
  font-size: 18px;
  font-weight: 700;
}

.react-calendar__navigation button:disabled {
  background-color: #f0f0f0;
}

.react-calendar__navigation__prev2-button,
.react-calendar__navigation__next2-button {
  display: none;
}

.react-calendar__navigation__prev-button {
  position: absolute;
  right: 8px;
  font-size: 0;

  &::before {
    display: block;
    width: 10px;
    height: 10px;
    border-top: 2px solid #5F44FF;
    border-right: 2px solid #5F44FF;
    transform: rotate(45deg);
    content: '';
  }
}

.react-calendar__navigation__label {
  flex-grow: 0.9 !important;
}

.react-calendar__navigation__next-button {
  position: absolute;
  right: 31px;
  font-size: 0;

  &::before {
    display: block;
    width: 10px;
    height: 10px;
    border-top: 2px solid #5F44FF;
    border-right: 2px solid #5F44FF;
    transform: rotate(-135deg);
    content: '';
  }
}


.react-calendar__month-view__weekdays {
  text-transform: uppercase;
  font-weight: bold;
  margin-bottom: 6px;
  justify-content: space-between;
}
.react-calendar__month-view__weekdays__weekday {
  flex: none !important;
  width: 32px;
  height: 18px;
  margin-right: 25.5px;
  color: #BBBBBB;
  font-size: 13px;
  line-height: 18px;
  text-align: center;
}
.react-calendar__month-view__weekNumbers .react-calendar__tile {
  display: flex;
  align-items: center;
  justify-content: center;
}
.react-calendar__month-view__days__day {
  height: 40px;
  margin-bottom: 6px !important;
}
.react-calendar__month-view__days__day--neighboringMonth {
  color: #757575;
}

.react-calendar__month-view__days {
  display: flex;
}

.react-calendar__month-view__days .react-calendar__tile {
  flex: none;
  margin-right: 16px;
  max-width: 40px;
}

.react-calendar__year-view .react-calendar__tile,
.react-calendar__decade-view .react-calendar__tile,
.react-calendar__century-view .react-calendar__tile {
  padding: 2em 0.5em;
}
.react-calendar__tile {
  max-width: 100%;
  font-size: 20px;
  background: none;
  text-align: center;
}
.react-calendar__tile:disabled {
  background-color: #f0f0f0;
  border-radius: 5px;
}
.react-calendar__tile:enabled:hover,
.react-calendar__tile:enabled:focus {
  background-color: #e6e6e6;
  border-radius: 5px;
}
.react-calendar__tile--now {
  background: #5F44FF;
  border-radius: 5px;
  color: #ffffff;
}
.react-calendar__tile--now:enabled:hover,
.react-calendar__tile--now:enabled:focus {
  background: #5F44FF;
  border-radius: 5px;
}
.react-calendar__tile--hasActive {
  background: #5F44FF;
}
.react-calendar__tile--hasActive:enabled:hover,
.react-calendar__tile--hasActive:enabled:focus {
  background: #5F44FF;
}
.react-calendar__tile--active {
  background: #5F44FF;
  border-radius: 10px;
  color: white;
}
.react-calendar__tile--active:enabled:hover,
.react-calendar__tile--active:enabled:focus {
  background: #5F44FF;
}
.react-calendar--selectRange .react-calendar__tile--hover {
  background-color: #e6e6e6;
  border-radius: 5px;
}

.date-dropdown {
  position: relative;
 
  &__button {
    position: relative;
    border: 1px solid #DDDDDD;
    border-radius: 5px;
    box-sizing: border-box;
  }

  &__data {
    display: block;
    height: 70px;
    margin-left: 58px;
    font-size: 24px;
    line-height: 70px;
    text-align: left;
  }

  &__icon {
    position: absolute;
    top: 24px;
    left: 20px;
    width: 24px;
    height: 24px;
  }

  &__arrow {
    position: absolute;
    top: 25px;
    right: 17px;
    width: 24px;
    height: 24px;
  }
}

.date-dropdown__button.active {
  border: 2px solid #5F44FF;
}

.date-dropdown.disabled {
  .date-dropdown__button {
    background-color: #F4F4F4;
    color: #888888;
    border: none;
    pointer-events: none;
  }
  .date-dropdown__arrow {
    display: none;
  }
}

예시 코드 -> https://codesandbox.io/s/b0vlgr

profile
오늘도 코드 보는중 (。⌒𖧉⌒)⋆.˚⊹⁺

0개의 댓글