---
name: calendar
category: data
summary: "Month/week/day calendar with events and drag-to-move"
subpath: "@42/core/calendar"
deepDoc: docs/llm/calendar.md
---

Month/week/day calendar with events, keyboard date navigation and drag-to-move.

```html
<div data-c42-calendar>
  <div data-c42-calendar-header>
    <button data-c42-calendar-prev aria-label="Previous">‹</button>
    <button data-c42-calendar-today>Today</button>
    <button data-c42-calendar-next aria-label="Next">›</button>
    <span data-c42-calendar-title></span>
    <button data-c42-calendar-view="month">Month</button>
    <button data-c42-calendar-view="week">Week</button>
    <button data-c42-calendar-view="day">Day</button>
  </div>
  <div data-c42-calendar-grid></div>
</div>
```

```ts
import { Calendar } from '@42/core/calendar';
const cal = new Calendar(root, {
  view: 'month',
  events: [{ id: 'e1', title: 'Standup', start: new Date(2026, 5, 16, 9, 0) }],
});
cal.on('calendar:select', (e) => console.log(e.detail.dateKey));
```

The controller renders day cells into `[data-c42-calendar-grid]` (role=grid),
marking `data-today`/`data-selected`/`data-focused`/`data-outside`. Events render
as `[data-c42-calendar-event]` inside their day, with `--c42-calendar-event-start/-end`
fractions for week/day positioning.

Keyboard (grid focused): arrows move the focused day (Up/Down by week), Home/End to week edges, PageUp/PageDown change period, Enter selects. Drag an event to another day to move it.
Options: `defaultDate`, `view` (month), `weekStartsOn` (0), `events`, `locale`
Methods: `setView(v)`, `navigate(dir)`, `goToToday()`, `goToDate(d)`, `selectDate(d)`, `addEvent(e)`, `removeEvent(id)`, `moveEvent(id, day)`, `getEvents()`, `currentView`, `currentDate`, `selectedDate`
Events: `calendar:select` → `{ date, dateKey }`, `calendar:viewchange` → `{ view }`, `calendar:navigate` → `{ date, view }`, `calendar:eventclick` → `{ id, event }`, `calendar:eventmove` → `{ id, event, start, end }`
