프로덕트
모듈 · 진행 중
fullcalendar
월, 주, 일 보기를 기본으로 담고, 일정 종류와 보기를 플러그인으로 더하는 React 캘린더입니다.
0소스 코드에서 any 타입을 쓴 곳 (테스트와 스토리 제외)
- 기간
- 2026.05 ~ 현재
- 소속
- Firstage
- 역할
- 설계와 구현 (1인)
- 쓰임
- 날짜 형식, 화면 문구, 스타일, 기본 컴포넌트를 서로 독립된 채널로 끼워, 한 채널을 바꿔도 나머지는 그대로입니다.
- 핵심 작업과 결과
- 캘린더마다 상태 저장소를 따로 두어, 한 화면에 여러 캘린더를 놓아도 서로 섞이지 않음
- 일정, 캠페인, 예약 같은 도메인을 플러그인 하나로 등록하고, 보기도 직접 만들어 등록
- WAI-ARIA 그리드 키보드 조작과 버튼으로 된 일정, 스토리북에서 axe 접근성 검사
- 겹치는 일정 배치와 현재 시각 표시 같은 계산을 순수 함수 패키지로 분리
- 기술 스택
- React
- TypeScript
- dnd-kit
- Storybook
배경
달력 화면은 제품마다 쓰는 날짜 라이브러리와 번역, 스타일, 기본 컴포넌트가 다르고, 달력에 놓이는 기록도 일정, 캠페인, 예약처럼 제품마다 다릅니다. 이 넷을 따로 끼우고 기록의 종류는 플러그인으로 더할 수 있는 캘린더를 타입을 엄격하게 지키며 직접 만들었습니다.
결정과 구현
- 다섯 패키지로 나눴습니다. 조립(fullcalendar), 플러그인 계약과 레지스트리(registry), 순수 계산(features), 드래그 앤 드롭 어댑터(dnd), 공용 타입과 날짜 도구(shared)입니다. 드래그 앤 드롭은 필요할 때만 더합니다.
- 상태는 캘린더마다 따로 만드는 저장소에 둡니다. 한 페이지에 캘린더를 여러 개 놓아도 상태가 섞이지 않습니다.
- 날짜 형식과 시간대, 화면 문구, 슬롯별 클래스, 기본 컴포넌트를 서로 독립된 네 주입 채널로 받습니다. dayjs를 luxon으로 바꿔도 번역과 스타일, 드래그 앤 드롭은 그대로입니다.
- 일정 종류, 보기, 기능은 모두 레지스트리에 등록하는 플러그인입니다. 월, 주, 일 보기가 기본이고, 사흘 보기 같은 열 보기는
createColumnsView로 만들어 등록합니다. - 칸은 WAI-ARIA 그리드 키보드 모델을 따르고, 일정은 버튼으로 그립니다. 터치 화면의 월 보기는 일정을 요약하는 작은 칸으로 바뀌고, 날짜를 누르면 그날을 엽니다.
any없이exactOptionalPropertyTypes를 켜고, 분기는 빠짐없는 구분 유니언으로 처리합니다.
현재 상태
패키지 스토리북에서 axe 접근성 검사가 CI로 돕니다. 아직 이 캘린더를 쓰는 제품 화면은 없습니다.