Jelly Diary

[🐾 Jelly Diary] React + Typescript 캘린더 FullCalendar 라이브러리 사용 방법

밍띠이 2024. 4. 16. 20:46
반응형

 

리액트와 타입스크립트 환경에서 캘린더를 구현할 때

 

FullCalendar 라이브러리를 이용하여 개발하게 되었다.

https://fullcalendar.io/

 

FullCalendar - JavaScript Event Calendar

Open Source... With over 10 years of open source and over 120 contributors, FullCalendar will always have a free and open source core. Learn more

fullcalendar.io

기본적인 컴포넌트 구성을 파악하고 적용해 보고자 한다.

 

기본 제공 템플릿의 UI다

나는 Monthly 페이지만 필요했기 때문에 필요 없는 상단 버튼들은 삭제하여 주는 등 커스텀 하여 사용 할 예정이다.

우선 템플릿에서 제공하는 기본 코드와 여러 설정 값들을 정리해 보았다.

export default class DemoApp extends React.Component<{}, DemoAppState> {

  state: DemoAppState = {
    weekendsVisible: true,
    currentEvents: []
  }

  render() {
    return (
      <div className='demo-app'>
        {this.renderSidebar()}
        <div className='demo-app-main'>
          <FullCalendar
            plugins={[dayGridPlugin, timeGridPlugin, interactionPlugin]} // 사용할 플러그인
            headerToolbar={{ // 헤더에 넣을 버튼들 (왼쪽, 가운데, 오른쪽 배치 가능)
              left: 'prev,next today', // 이전달, 다음달, 오늘달
              center: 'title', // 오늘 날짜
              right: 'dayGridMonth,timeGridWeek,timeGridDay' // 월별,주별,일별 뷰
            }}
            initialView='dayGridMonth' // 첫 화면 뷰어 설정
            editable={true} // 수정 가능 여부
            selectable={true} // 선택 가능 여부
            selectMirror={true} // TimeGrid 뷰에서 자리 표시자 여부
            dayMaxEvents={true} // 한 셀에 최대 이벤트(more) 표시 여부
            weekends={this.state.weekendsVisible} // 주말 표시 여부
            initialEvents={INITIAL_EVENTS} // 초기값
            select={this.handleDateSelect} // 선택 시 기능 추가
            eventContent={renderEventContent} // 이벤트 컨텐츠 랜더링 설정
            eventClick={this.handleEventClick} // 이벤트 클릭 기능 설정
            eventsSet={this.handleEvents} // 이벤트가 초기화/추가/변경/제거된 후에 호출되는 기능
            /* 데이터 베이스 업뎃 함수
            eventAdd={function(){}} // 이벤트 추가
            eventChange={function(){}} // 이벤트 수정
            eventRemove={function(){}} // 이벤트 삭제
            */
          />
        </div>
      </div>
    )
  }

 

1. 설치

npm install --save \
  @fullcalendar/core \
  @fullcalendar/daygrid

 

우선 캘린더 코어 라이브러리와 추가적인 라이브러리를 프로젝트에 다운받아야 한다.

이후에는 간단하게 사용가능하다

 

2. 헤더 변경

<FullCalendar
            plugins={[dayGridPlugin, interactionPlugin]}
            headerToolbar={{
              left: "prev",
              center: "title",
              right: "next",
            }}
            ...
 />

 

이전달(prev), 월 이름(title), 다음달(next) 이동 버튼을 배치해 준다.

 

3. FullCalendar 이벤트 추가

달력 일자를 클릭하여 이벤트를 추가할 수 있다.

프롬프트로 입력 받아 일정을 추가할 수 있다.

  // ...
  			editable={true}
            select={this.handleDateSelect}
// ...
>


  handleDateSelect = (selectInfo: DateSelectArg) => {
    let title = prompt("✏️ 일정 제목을 작성해주세요.");
    let calendarApi = selectInfo.view.calendar;

    calendarApi.unselect(); 

    if (title) {
      calendarApi.addEvent({
        id: createEventId(),
        title,
        start: selectInfo.startStr,
        end: selectInfo.endStr,
        allDay: selectInfo.allDay,
      });
    }
  };

 

4. FullCalendar 이벤트 삭제

이벤트를 클릭하면 삭제가 가능하게 할 수 있다.

            eventClick={this.handleEventClick}
>
  handleEventClick = (clickInfo: EventClickArg) => {
    if (confirm(`🗑️ 정말 일지를 삭제할까요? '${clickInfo.event.title}'`)) {
      clickInfo.event.remove();
    }
  };

 

5. FullCalendar 이벤트 수정

드래그앤 드롭으로 이벤트 일자 수정이 가능하다.

            editable={false}



  handleEvents = (events: EventApi[]) => {
    this.setState({
      currentEvents: events,
    });
  };

 

6. FullCalendar 한글 설정

캘린더는 다국어 지원을 하기 때문에 한글로 설정이 가능하다.

locales={allLocales}
locale="kr"

 

한국어로 설정 시 영어 버전과는 다르게 숫자 뒤에 '일' 표시가 붙는다

이를 제거하기위해 아래와 같은 코드를 추가하였다.

          dayCellContent={(info) => {
            return info.date.getDate();
          }}

 

셀 모양을 다시 랜더링 해주어 원하는 숫자 값만 가지고 올 수 있었다.

 

7. FullCalendar 랜더링 커스텀

기획단계에서 계획한 표현 방법은 날씨, 제목, 작성자를 포함하여야 했기 때문에

랜더링을 커스텀 해줄 필요가 있었다.

          eventContent={renderEventContent}
.../>

function renderEventContent(eventInfo: EventContentArg) {
  return (
  	<>
      {eventInfo.event.extendedProps.weather === "sunny" ? (
        <b>
          <BiSun />
        </b>
      ) : (
        <b>
          <BiCloud />
        </b>
      )}
      <a>{eventInfo.event.title}</a>
      </>
  );
}

 

8. FullCalendar 커스텀 버튼 추가

headerToolbar={{
            left: "",
            center: "prev,title,next",
            right: "myCustomButton",
          }}
          customButtons={{
            myCustomButton: {
              text: "+",
              click: () => {
                setEvents([
                  ...events,
                  {
                    title: "event",
                    date: new Date().toISOString().substr(0, 10),
                    color: "#ffffff",
                  },
                ]);
              },
            },
          }}

 

9. FullCalendar 스타일 오버라이딩

 

등으로 활용 가능하다.

필요한 기능이 있다면 더 추가해 보면 좋 을 것 같다.

반응형