시작하기
패키지 설치, styles.css import, 첫 Calendar 렌더링까지의 빠른 시작 가이드
reopt designUpdated
1. 패키지 설치
@reopt-ai/opt-calendar는 GitHub Packages로 배포됩니다. 먼저 .npmrc를 프로젝트 루트에 생성하세요.
# .npmrc
@reopt-ai:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}패키지를 설치합니다.
npm install @reopt-ai/opt-calendar
# 또는
bun add @reopt-ai/opt-calendarPeer dependencies: react ^19, react-dom ^19가 필요합니다. ai·zod는 AI 스트리밍을 쓸 때만 필요한 optional peer입니다.
2. 스타일 import
시간 그리드의 기하 구조는 디자인 토큰으로 표현할 수 없어 구조 CSS를 별도로 제공합니다. 앱 진입점(또는 캘린더를 렌더하는 파일)에서 한 번 import하세요. 색상은 opt-palette 토큰(var(--opt-*))에서 해석되며, 셸 없이도 하드코딩 폴백으로 렌더됩니다.
import "@reopt-ai/opt-calendar/styles.css";3. 첫 번째 캘린더
캘린더의 모든 상태는 store가 소유합니다. createEmptyCalendarSpec으로 빈 spec을 만들고 이벤트를 넣은 뒤 createCalendarStore로 store를 만들어 Calendar에 전달합니다. 이벤트 시간은 timed면 오프셋 포함 ISO datetime, all-day면 floating ISO date입니다.
"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",
};
spec.events.offsite = {
id: "offsite",
title: "팀 오프사이트",
start: "2026-07-13",
end: "2026-07-15", // all-day는 end가 배타적(마지막 날 다음)
allDay: true,
};
return createCalendarStore(spec);
});
return <Calendar store={store} timeZone="Asia/Seoul" weekStartsOn={1} />;
}4. 편집 — 단일 변경 경로
별도 설정 없이 timed 이벤트는 드래그로 이동하고 아래 핸들로 리사이즈할 수 있으며, 칩을 클릭하면 편집 팝오버가 열립니다. 드래그·리사이즈·팝오버 편집·AI 스트림은 모두 store.applyPatch(ops) 한 경로로 커밋되어 하나의 undo 히스토리를 공유합니다. 직접 편집도 같은 경로를 씁니다.
import { buildAddEventPatch, buildAllDayEvent } from "@reopt-ai/opt-calendar";
// 새 all-day 이벤트를 추가 — 드래그 결과와 동일한 applyPatch 경로
const event = buildAllDayEvent("launch", "출시일", "2026-07-20");
store.applyPatch(buildAddEventPatch(event), { source: "create" });
// undo/redo 는 store가 관리
store.undo();
store.redo();5. AI 편집 미리보기
useCalendarSuggestion은 AI 패치를 라이브 spec이 아닌 shadow draft로 스트리밍합니다. 사용자는 approve()로 한 번에 적용하거나 reject()로 폐기할 수 있고, 그 사이 변경분은 캘린더에 pending 오버레이로 표시됩니다.
const ai = useCalendarSuggestion(store);
// NDJSON 패치 스트림을 shadow draft로 흘려보냄 (라이브 spec은 그대로)
await ai.start(patchStream);
// 승인 시 draft 전체가 하나의 undo 엔트리로 적용됨
ai.approve();
<Calendar store={store} suggestion={ai.suggestion} />;자세한 내용은 AI 스트리밍 문서를 참고하세요.