reopt designreopt design
DocsExploreToolsPricingBuilder
시작하기
시작하기
Playground
핵심 개념
핵심 개념
Calendar
Calendar 개요
이벤트 편집
반복 일정
타임존
예약 · 가용성
AI 스트리밍
원격 소스
앱 조합
구축·운영
스킬
릴리즈 노트
레퍼런스
Hook 레퍼런스
타입 레퍼런스
Oopt-calendar
reopt designreopt design

AI 시대를 위한 디자인 시스템

  • 문서
  • 가격
  • 릴리즈 노트
  • GitHub
  • 서비스 약관
  • 개인정보처리방침

© 2026 reopt-ai. All rights reserved.

Calendar
  1. 문서
  2. /
  3. Calendar
  4. /
  5. Calendar

Calendar 계층

이벤트·예약·AI 편집을 하나의 store와 엔진으로 다룰 수 있도록 기능/시나리오별로 나눈 문서 모음입니다.

reopt design · 업데이트 2026년 7월 2일

시작하기핵심 개념개요이벤트 편집반복 일정타임존예약 · 가용성AI 스트리밍원격 소스앱 조합스킬릴리즈 노트Hook 레퍼런스타입 레퍼런스
이벤트·예약 캘린더와 AI 편집 흐름 구현자opt-calendar

CalendarSpec 모델, 반복(RRULE)/타임존 엔진, 드래그·리사이즈 상호작용, 예약 라이프사이클, AI 스트리밍 draft, 원격 윈도우 소스를 담당합니다.

Calendar와 빠른 시작CalendarSpec, 단일 변경 경로, 뷰/엔진 아키텍처반복·타임존·예약·AI 스트리밍Hook/Type reference와 원격 소스

Package boundary: @reopt-ai/opt-calendar는 Calendar 컴포넌트, createCalendarStore, 반복/타임존 엔진, 예약·AI·원격 훅을 root export로 제공합니다. 구조 CSS는 @reopt-ai/opt-calendar/styles.css 한 번 import가 필요하고, 런타임 peer는 React/React DOM입니다. Core(spec/patch/stream/ catalog)는 ai·zod를 optional peer로만 둔 zero-runtime-dep 레이어입니다.

이벤트·예약·타임존·드래그·AI 스트리밍을 한 화면에서 실험하려면 Fullscreen Playground를 사용하세요.

Playground 열기

1. 기능별/시나리오별 문서

하나의 엔진으로 범용 이벤트 캘린더, 예약/가용성, AI 편집, 원격 데이터 UX를 구성할 수 있습니다. 아래 문서에서 구현 패턴을 확인하세요.

시작하기

설치, styles.css import, 첫 Calendar 렌더링까지의 빠른 시작

핵심 개념

CalendarSpec 5-맵 모델, 단일 변경 경로(applyPatch), 엔진/뷰 레이어 아키텍처

이벤트 편집

이벤트 CRUD, 팝오버 에디터, 드래그·리사이즈 상호작용과 단일 undo 경로

반복 일정

RRULE 전개, occurrence 모델, this/following/all 인스턴스 단위 편집

타임존

TimeZoneAdapter, wall-clock↔instant 변환, DST 경계에서의 정확성

예약 · 가용성

EventType/AvailabilitySchedule/BookingSlot과 confirm→materialize 라이프사이클

AI 스트리밍

useCalendarSuggestion shadow draft, NDJSON 패치 스트림, 라이브 오버레이

원격 소스

useCalendarRemoteSource 윈도우 fetch/save, id-merge, 낙관적 pending

앱 조합

ShellCalendarAdapter로 opt-shell 제품 프레임 안에 캘린더를 배치하는 경계

스킬

Claude Code 스킬로 opt-calendar 설치·통합을 자동화합니다

릴리즈 노트

opt-calendar 버전별 변경 사항과 하이라이트

Hook 레퍼런스

useCalendar*, useCalendarRender, useCalendarNavigation, remote, suggestion

타입 레퍼런스

CalendarSpec, CalendarEvent, Booking, EventType 등 핵심 타입 정의

2. 시나리오 선택 가이드

시나리오적합한 상황핵심 API
이벤트 캘린더월/주/일/아젠다 뷰에서 이벤트를 만들고 드래그·리사이즈로 편집하는 범용 캘린더
variantviewtimeZoneweekStartsOn
예약 · 가용성가용성 스케줄에서 슬롯을 생성하고 예약을 확정하면 이벤트로 materialize되는 Cal.com형 흐름
variantcatalogtimeZone
AI 편집자연어 지시를 NDJSON 패치 스트림으로 받아 shadow draft로 미리 보고 승인/폐기
suggestioncatalogstore
원격 데이터보이는 윈도우만 fetch하고 편집을 batch save하는 원격 이벤트 소스 연동
remoteSourcestoreonDateChange

3. 아키텍처 모델

opt-calendar는 opt-editor의 AI-first 아키텍처(스키마 기반 스트리밍 + RFC 6902 JSON Patch)를 캘린더 도메인으로 옮긴 구조입니다. 아래 다섯 축이 전체 동작을 지탱합니다.

Single mutation path

드래그, 리사이즈, 팝오버 편집, AI 스트림이 모두 `store.applyPatch(ops)` 한 경로로 흐릅니다. 하나의 undo 히스토리를 공유합니다.

Additive-only CalendarSpec

events/calendars/availability/eventTypes/bookings 5개 flat 맵 + timeZone. 필드는 제거·재사용하지 않아 이전 spec이 새 코드에서 그대로 적용됩니다.

Injectable engine seams

`RecurrenceEngine`(기본 zero-dep)와 `TimeZoneAdapter`(기본 native Intl)는 하드 의존이 아니라 주입 지점입니다. rrule/Temporal로 교체 가능합니다.

Record + materialized event

Booking은 워크플로우 레코드이고, 확정 시 CalendarEvent로 materialize되어 그리드에 렌더됩니다(`booking.eventId ↔ event.bookingId`).

Windowed remote + shadow AI

원격 소스는 보이는 윈도우만 fetch/save하고, AI draft는 shadow store에서 스트리밍되어 승인 전 오버레이로 미리 보입니다.

4. API 매트릭스

Calendar props를 역할별로 묶었습니다. 모든 편집이 통과하는 store와 엔티티 catalog를 먼저 연결한 뒤 뷰 상태·지역화·상호작용을 붙이는 순서가 안전합니다.

Store & 데이터

모든 변경이 통과하는 단일 store 계약과 엔티티 카탈로그를 연결합니다.

  • store

    드래그·리사이즈·AI 스트림·팝오버 편집이 모두 통과하는 단일 변경 경로(createCalendarStore). 하나의 undo 히스토리를 공유합니다.

  • catalog

    엔티티 종류 레지스트리 + AI 프롬프트/jsonSchema. 기본값은 defaultCalendarCatalog.

  • remoteSource

    useCalendarRemoteSource가 반환하는 윈도우 원격 소스. 보이는 범위만 fetch하고 편집을 batch save합니다.

  • suggestion

    useCalendarSuggestion/useCalendarAI의 shadow draft. 승인 전에도 변경분을 pending 오버레이로 렌더합니다.

뷰 상태

활성 뷰와 앵커 날짜를 controlled/uncontrolled 어느 쪽으로도 다룹니다.

  • view

    활성 뷰(month/week/day/agenda). 생략 시 내부 상태로 관리됩니다.

  • onViewChange

    뷰 전환 콜백. controlled 뷰를 구현할 때 사용합니다.

  • date

    앵커 날짜(controlled). 생략 시 내부 상태를 사용합니다.

  • onDateChange

    앵커 날짜 변경 콜백. 원격 소스의 visible window 동기화에 연결합니다.

  • variant

    제품 변형: "events"(기본) 또는 "booking".

지역화 & 시간

표시 타임존, 주 시작일, 로케일, 메시지 오버라이드.

  • timeZone

    표시 타임존(IANA). 뷰 위치 계산·반복 전개·드래그 수식이 이 값을 기준으로 정렬됩니다.

  • weekStartsOn

    주 시작 요일(0=일요일). 기본 0.

  • locale

    라벨/날짜 포매팅에 쓰는 BCP-47 로케일.

  • messages

    UI 문자열 오버라이드(CalendarMessages 부분 집합).

  • timeGrid

    주/일 타임그리드 표시 옵션(TimeGridOptions): 시간 범위(startHour/endHour), 행 높이(hourHeight), 스냅(snapMinutes), 내부 스크롤(maxBodyHeight)과 scroll-to-now.

상호작용 & 접근성

이벤트 활성화 콜백과 캘린더 영역의 접근성 라벨.

  • onEventActivate

    이벤트가 활성화(편집 팝오버 열림)될 때 호출됩니다.

  • ariaLabel

    캘린더 region의 접근성 라벨.

  • className

    루트 className.

5. 기본 사용 코드

tsx
"use client";

import {
  Calendar,
  createCalendarStore,
  createEmptyCalendarSpec,
} from "@reopt-ai/opt-calendar";
import "@reopt-ai/opt-calendar/styles.css";
import { useState } from "react";

export default function BasicCalendar() {
  const [store] = useState(() => {
    const spec = createEmptyCalendarSpec("Asia/Seoul");
    spec.events.standup = {
      id: "standup",
      title: "팀 스탠드업",
      start: "2026-07-06T09:00:00+09:00",
      end: "2026-07-06T09:15:00+09:00",
      rrule: "FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR",
    };
    return createCalendarStore(spec);
  });

  // 모든 편집(드래그/리사이즈/팝오버)이 store.applyPatch 한 경로로 흐릅니다.
  return <Calendar store={store} timeZone="Asia/Seoul" weekStartsOn={1} />;
}

6. 원격 + AI 통합 구성

프로덕션에서는 보이는 윈도우만 원격에서 로드하고, 자연어 지시를 shadow draft로 미리 본 뒤 승인하는 조합을 권장합니다.

tsx
"use client";

import {
  Calendar,
  createCalendarStore,
  createEmptyCalendarSpec,
  defaultCalendarCatalog,
  useCalendarRemoteSource,
  useCalendarSuggestion,
} from "@reopt-ai/opt-calendar";
import "@reopt-ai/opt-calendar/styles.css";
import { useState } from "react";

export function ProductionCalendar() {
  const [store] = useState(() =>
    createCalendarStore(createEmptyCalendarSpec("Asia/Seoul")),
  );

  // 1) 보이는 윈도우만 원격에서 로드하고 편집을 batch save.
  //    Calendar가 뷰/날짜 변경 시 onWindowChanged를 자동 호출한다.
  const remote = useCalendarRemoteSource(store, {
    loadEvents: async ({ window, signal }) => ({
      events: await fetchEvents(window, signal),
    }),
    savePatches: ({ ops, changedEventIds }) => persistOps(ops, changedEventIds),
  });

  // 2) 자연어 지시를 NDJSON 패치 스트림으로 받아 shadow draft로 미리보기
  const ai = useCalendarSuggestion(store);

  return (
    <Calendar
      store={store}
      catalog={defaultCalendarCatalog}
      timeZone="Asia/Seoul"
      remoteSource={remote}
      suggestion={ai.suggestion}
    />
  );
}
Previous핵심 개념CalendarSpec 5-맵 모델, 단일 변경 경로(applyPatch), 엔진/뷰 레이어 아키텍처핵심 개념
핵심 개념 페이지로 이동
Next이벤트 편집이벤트 CRUD, 팝오버 에디터, 드래그·리사이즈 상호작용과 단일 undo 경로Calendar