# Recurring events

Daily to yearly rules, single occurrences removed, wall-clock times kept across daylight saving.

```tsx
const recurringEvent: CalendarEvent = {
  id: '1',
  title: 'Weekly Standup',
  start: new Date(),
  end: new Date(Date.now() + 3600000),
  recurrence: {
    freq: 'WEEKLY',
    interval: 1,
    count: 10, // or use 'until' for end date
  },
};
```

Occurrences keep their wall-clock time across daylight-saving changes, in the `timezone` prop's zone (or the browser's).

Moving, resizing or editing one occurrence updates the whole series by the same amount (`onEventUpdate` receives the recurring event). To delete a single occurrence, handle `onOccurrenceDelete`:

```tsx
<Scheduler
  events={events}
  onOccurrenceDelete={(occurrence, updatedSeries) => {
    setEvents(events.map(e => (e.id === updatedSeries.id ? updatedSeries : e)));
  }}
/>
```

## Invalid data

Dates may be `Date` objects, ISO strings or timestamps. Events with an invalid date or an end before their start are skipped, with a warning in development. Event ids must be unique (duplicates are rendered but warned about, and break drag & drop).

Treat events as immutable: to change an event, pass a new object (`events.map(e => e.id === id ? { ...e, title } : e)`). Computations are cached per event object, so mutating an event in place may not be reflected.
