# Headless core and React bindings

The engine without the UI, to build your own calendar.

The engine behind the `<Scheduler>` is published on its own as `calendarkit-pro/core`: no React, no DOM, usable on the server and from any framework. Use it to build a calendar UI of your own, or to drive the calendar's state from outside.

```ts
import { createCalendar, selectTimeGrid } from 'calendarkit-pro/core'

const calendar = createCalendar({ defaultEvents: events, onEventsChange: save })
calendar.subscribe(() => draw(selectTimeGrid(calendar.getState(), { maxColumns: 3 })))

calendar.openSlot(new Date(2026, 9, 15, 14))
calendar.updateDraft({ title: 'Lunch with Lea tomorrow 1pm for 2h' }) // moves the draft
calendar.saveDraft() // creates "Lunch with Lea", then calls onEventsChange
calendar.undo()
```

- `createCalendar` keeps the view, the date, the events (controlled with `events`, or uncontrolled with `defaultEvents`), dialogs and drafts. Moving, resizing, deleting and duplicating call the 1.x callbacks, then `onEventsChange` with the full list; `undo()` reverts the last change.
- `selectTimeGrid`, `selectMonth`, `selectAgenda`, `selectFlowDay` and `selectResources` turn a state into plain data ready to render (overlaps laid out, extra events grouped into "+N").
- `parseEventSentence` reads dates, times, durations and repetition in a title, in English and French.

## React bindings

`calendarkit-pro/react` connects the engine to React (the `<Scheduler>` itself now runs on it):

```tsx
import { useCalendar, useCalendarSelector, getEventProps, CalendarDndContext } from 'calendarkit-pro/react'
import { selectTimeGrid } from 'calendarkit-pro/core'

function MyWeek({ events, onEventsChange }) {
  const calendar = useCalendar({ events, onEventsChange })
  const grid = useCalendarSelector(calendar, (s) => selectTimeGrid(s, { maxColumns: 3 }))
  return (
    <CalendarDndContext calendar={calendar}>
      {grid.columns.map((column) => column.blocks.map((b) => <button key={b.event.id} {...getEventProps(calendar, b.event)}>{b.event.title}</button>))}
    </CalendarDndContext>
  )
}
```

- `useCalendar(options)` creates the store once and keeps it in sync with your props; `useCalendarSelector` re-renders only when the selected slice changes. `CalendarProvider` / `useCalendarContext` share the store without passing it down.
- `getEventProps`, `getSlotProps` and `getResizeHandleProps` return the props of an accessible event button, an empty slot and a resize handle.
- `CalendarDndContext`, `useDraggableEvent`, `useDroppableSlot` and `useActiveDrag` wire dnd-kit to the store (drops call `calendar.move`, dragging is off in `readOnly`).
