calendarcn
Calendar

Overview

Install CalendarCN, preview the main examples, and wire the calendar into controlled React state.

CalendarCN installs source into your app. The docs below focus on wiring the calendar into controlled React state so drag, resize, and creation behavior stay explicit and easy to persist.

Preview

Example Variants

Starter surface

A controlled week calendar with local create, move, and resize handlers wired directly into state.

Controlled stateAll core viewsCreate, move, resize

Mar 23 - 29, 2026

Local timezone

Time

Mon

Mar 23

Tue

Mar 24

Wed

Mar 25

Thu

Mar 26

Today

Fri

Mar 27

Sat

Mar 28

Sun

Mar 29

All day

Use arrow keys to move the active time slot. Use left and right arrows to change days. Press Enter or Space to create an event at the active slot.

6 AM

7 AM

8 AM

9 AM

10 AM

11 AM

12 PM

1 PM

2 PM

3 PM

4 PM

5 PM

6 PM

7 PM

8 PM

9 PM

10 PM

Installation

Pull the registry item directly into your app with the shadcn CLI. On your deployed site this resolves to the live ` /r/calendarcn.json ` registry endpoint.

terminal
npx shadcn@latest add https://calendarcn.phantomtechind.com/r/calendarcn.json

Usage

app/schedule/page.tsx
"use client"import * as React from "react"import type {  CalendarCreateOperation,  CalendarEvent,  CalendarEventUpdateOperation,  CalendarMoveOperation,  CalendarResizeOperation,  CalendarView,} from "@/components/calendar"import { CalendarRoot } from "@/components/calendar"import {  applyEventUpdateOperation,  applyMoveOperation,  applyResizeOperation,  createEventFromOperation,  shiftDate,} from "@/components/calendar/utils"export function TeamSchedule() {  const [date, setDate] = React.useState(new Date())  const [events, setEvents] = React.useState<CalendarEvent[]>([])  const [resourceFilter, setResourceFilter] = React.useState(["product"])  const [view, setView] = React.useState<CalendarView>("week")  function handleNavigate(direction: -1 | 1) {    setDate((currentDate) => shiftDate(currentDate, view, direction))  }  function handleCreate(operation: CalendarCreateOperation) {    setEvents((currentEvents) => [      ...currentEvents,      createEventFromOperation(operation, {        title: "New event",      }),    ])  }  function handleMove(operation: CalendarMoveOperation) {    setEvents((currentEvents) => applyMoveOperation(currentEvents, operation))  }  function handleResize(operation: CalendarResizeOperation) {    setEvents((currentEvents) => applyResizeOperation(currentEvents, operation))  }  function handleUpdate(operation: CalendarEventUpdateOperation) {    setEvents((currentEvents) =>      applyEventUpdateOperation(currentEvents, operation)    )  }  return (    <CalendarRoot      date={date}      eventDetails      events={events}      keyboardShortcuts      onDateChange={setDate}      onEventCreate={handleCreate}      onEventMove={handleMove}      onEventResize={handleResize}      onEventUpdate={handleUpdate}      onNavigate={handleNavigate}      onResourceFilterChange={setResourceFilter}      onToday={() => setDate(new Date())}      onViewChange={setView}      resourceFilter={resourceFilter}      secondaryTimeZone="America/New_York"      showSecondaryTimeZone      view={view}    />  )}

Examples

The calendar surface should document more than a single happy path. These versions cover both implementation patterns and the individual views that most teams need to wire up.

Implementation Patterns

Preset configurations that show how the same calendar surface adapts to different product constraints.

Calendar Views

Focused docs for each supported view so users can land directly on the surface they need to implement.

Accessibility

  • Week and day views expose a roving schedule grid. Tab enters the active day once, arrow keys move the active slot, and Enter or Space starts the create flow for that slot.
  • Event cards stay as buttons. Arrow keys move a selected event, Shift + Arrow resizes the end, Alt + Arrow resizes the start, and Shift + F10 opens the event context menu.
  • Confirmation, create, details, and keyboard-shortcuts overlays all use modal dialogs with focus trap, escape handling, overlay dismiss, and focus restore.
  • Month uses grid semantics and agenda uses list semantics so assistive technology gets the same structural cues as the visual layout.
  • Press ? anywhere outside inputs to open the shortcuts dialog when keyboard shortcuts are enabled.

Notes

  • CalendarRoot is fully controlled. Keep date, view, and events in your own state or wire them into your store.
  • The utility helpers in @/components/calendar/utils are the fastest path to local optimistic handlers for move, resize, and create flows.
  • resources, businessHours, and blockedRanges are optional. The same core interaction model works with or without them.
  • Use eventDetails, keyboardShortcuts, resourceFilter, and secondaryTimeZone to productize the base surface without forking the core views.
  • Use eventChangeConfirmation when your app needs to gate schedule changes behind a dialog or persistence check.
  • exportEventsToICS, parseICSText, and parseICSFile live in @/components/calendar/utils for import and export workflows outside the rendered calendar.

On this page