Calendar | CoUI

Calendar

캘린더 컴포넌트

Calendar#

날짜를 시각적으로 탐색하고 선택할 수 있는 캘린더 컴포넌트입니다.

Live Preview#

사용 시기 (When to Use)#

이 컴포넌트를 사용하세요:

  • 날짜를 시각적으로 탐색하고 선택해야 할 때
  • 범위(체크인/체크아웃) 또는 다중 날짜 선택이 필요할 때

대신 다른 컴포넌트를 사용하세요:

  • DatePicker: 입력 필드와 결합된 날짜 선택 폼 요소일 때
  • Input: 단순 날짜 텍스트 입력만 필요할 때

기본 사용법 (Basic Usage)#

// 단일 선택
CoCalendar.single(
  onChanged: (value) => print('Selected: $value'),
)

// 범위 선택
CoCalendar.range(
  onChanged: (value) => print('Range: $value'),
)

// 다중 선택
CoCalendar.multi(
  onChanged: (value) => print('Multi: $value'),
)
// 단일 선택
CoCalendar.single(
  onChanged: (value) => print('Selected: $value'),
)

// 범위 선택
CoCalendar.range(
  onChanged: (value) => print('Range: $value'),
)

// 다중 선택
CoCalendar.multi(
  onChanged: (value) => print('Multi: $value'),
)

Props / Parameters#

속성타입기본값설명
selectionMode CoreCalendarSelectionMode single 선택 모드
value CoreCalendarValue? null 현재 선택 값
onChanged Function(CoreCalendarValue?)? null 선택 변경 콜백
initialView CoreCalendarView? null 초기 표시 월/년
stateBuilder CoreCalendarDateStateBuilder? null 날짜별 활성/비활성 결정
minDate DateTime? null 최소 선택 가능 날짜
maxDate DateTime? null 최대 선택 가능 날짜
calendarStyle CoreCalendarStyle<Clr>? null 인스턴스별 스타일 (chrome / 슬롯 / 상태 토큰)

스타일 시스템 (Style System)#

CoCalendar 의 모든 chrome / dimensional / 슬롯 / 상태 토큰 override 는 단일 calendarStyle: CoreCalendarStyle<Clr> 슬롯으로 흐릅니다 (Epic #1302). selectionMode / initialView 같은 시맨틱 enum 과 동작 필드는 위젯에 그대로 남고, 스타일 슬롯에는 들어가지 않습니다 (원칙 6 / 7).

구조#

CoreCalendarStyle<Clr> 는 composite Style 입니다 — 하위 컴포넌트의 Style 을 nested 로 보유합니다.

필드타입적용 대상
navButtonStyle CoreButtonStyle<Clr>? prev / next 네비 버튼, 헤더 버튼
dateCellStyle CoreButtonStyle<Clr>? 날짜 / 월 / 연도 셀 버튼 chrome
arrowIconStyle CoreIconStyle<Clr>? prev / next 화살표 아이콘
headerLabelStyle CoreTextStyle<Clr>? 헤더 라벨 ("May 2026")
weekdayLabelStyle CoreTextStyle<Clr>? 요일 라벨 (Sun / Mon …)
selectedColorClr?선택된 셀 배경
todayColorClr?오늘 셀 배경
todayTextColorClr?오늘 셀 텍스트
rangeSelectionColorClr?range 내부 셀 배경
rangeSelectionTextColorClr?range 내부 셀 텍스트

상태 토큰 5 개는 grid 안의 state-coloured 셀이라 단일 sub-component chrome 에 귀속되지 않으므로 nested slot Style 이 아닌 평면(flat) 색 토큰으로 노출합니다.

Resolve chain#

design system default
  → CoreCalendarTheme.style                   // 프로젝트 공통
  → parent component slot override
      (예: CoreDatePickerStyle.calendarStyle)
  → widget.calendarStyle                      // 인스턴스별

CoreCalendarStyle.merge 는 nested slot Style (navButtonStyle 등) 을 재귀적으로 머지하므로 부모 / theme / 인스턴스 단계에서 부분 override 가 가능합니다.

사용 예#

CoCalendar(
  selectionMode: CoreCalendarSelectionMode.single,
  calendarStyle: CoreCalendarStyle<Color>(
    selectedColor: Colors.purple,
    dateCellStyle: CoreButtonStyle(
      labelStyle: CoreTextStyle(fontWeight: 600),
    ),
  ),
  onChanged: (value) => print(value),
)
CoCalendar(
  selectionMode: CoreCalendarSelectionMode.single,
  calendarStyle: CoreCalendarStyle<String>(
    selectedColor: 'var(--coui-primary)',
    rangeSelectionColor: 'var(--coui-secondary)',
  ),
  onChanged: (value) => print(value),
)

변형 (Variants)#

단일 선택 (Single)#

CoCalendar.single(
  onChanged: (value) => print('Selected: $value'),
)

범위 선택 (Range)#

CoCalendar.range(
  onChanged: (value) => print('Range: $value'),
)

범위 모드에서는 듀얼 캘린더 레이아웃이 표시됩니다.

다중 선택 (Multi)#

CoCalendar.multi(
  onChanged: (value) => print('Multi: $value'),
)

표시 전용 (None)#

CoCalendar(
  selectionMode: CoreCalendarSelectionMode.none,
)

동작 스펙 (Behavior)#

선택 모드#

CoreCalendarSelectionMode.none    // 표시 전용
CoreCalendarSelectionMode.single  // 단일 날짜 선택
CoreCalendarSelectionMode.range   // 시작~끝 범위 선택
CoreCalendarSelectionMode.multi   // 다중 날짜 선택
  • Single: 클릭으로 선택, 다시 클릭하면 해제
  • Range: 첫 번째 클릭=시작, 두 번째 클릭=끝. 자동 정렬(start < end)
  • Multi: 클릭할 때마다 선택/해제 토글

CoreCalendarValue#

// 단일 선택
CoreCalendarValue.single(DateTime(2024, 3, 15))

// 범위 선택
CoreCalendarValue.range(DateTime(2024, 3, 10), DateTime(2024, 3, 20))

// 다중 선택
CoreCalendarValue.multi([DateTime(2024, 3, 5), DateTime(2024, 3, 15)])

뷰 전환#

  • CoreCalendarViewType.date: 월별 일 그리드 (6행 × 7열)
  • CoreCalendarViewType.month: 월 선택 (4×3 그리드)
  • CoreCalendarViewType.year: 연도 선택 (4×4 그리드)
  • 헤더의 월/연도를 클릭하면 상위 뷰로 전환

날짜 상태 검증#

CoCalendar.single(
  stateBuilder: (date) {
    if (date.isBefore(DateTime.now())) return CoreCalendarDateState.disabled;
    return CoreCalendarDateState.enabled;
  },
  onChanged: (value) => print(value),
)

크로스 플랫폼 차이점 (Platform Differences)#

항목FlutterWeb
클래스명CoCalendarCoCalendar
값 모델CoreCalendarValueCoreCalendarValue
선택 모드none/single/range/multinone/single/range/multi
뷰 전환date → month → yeardate → month → year
범위 레이아웃듀얼 캘린더듀얼 캘린더
네비게이션 CoButton(variant: .outline) CoButton(variant: .outline)
날짜 셀 CoButton(variant: .ghost/.primary/.secondary) CoButton(variant: .ghost/.primary/.secondary)