> ## Documentation Index
> Fetch the complete documentation index at: https://super-calendar.afonsojramos.me/llms.txt
> Use this file to discover all available pages before exploring further.

# Recurring events

> Expand recurrence rules into concrete occurrences.

Give an event a `recurrence` rule and `Calendar` expands it into concrete
occurrences automatically: over the visible range in the `month`, `week`, `day`,
`3days`, and `custom` modes, and over a rolling three-month window in `schedule`
(the agenda has no bounded viewport of its own). Non-recurring events pass through
untouched, so you can mix both freely.

```tsx theme={null}
import { Calendar } from "@super-calendar/native";

const events = [
  { title: "Standup", start, end, recurrence: { freq: "weekly", weekdays: [1, 2, 3, 4, 5] } },
];

<Calendar mode="week" date={date} events={events} onChangeDate={setDate} />;
```

When you want the occurrences yourself (to save, export to iCal, or list them over
a window of your own), expand them with `expandRecurringEvents` and pass the
result as `events`:

```tsx theme={null}
import { Calendar, expandRecurringEvents } from "@super-calendar/native";

const events = [
  // Every weekday standup, 20 occurrences:
  {
    title: "Standup",
    start,
    end,
    recurrence: { freq: "weekly", weekdays: [1, 2, 3, 4, 5], count: 20 },
  },
];

const visible = expandRecurringEvents(events, rangeStart, rangeEnd);

<Calendar /* ... */ events={visible} />;
```

Rules support:

* `freq` — `"daily"`, `"weekly"`, `"monthly"`, or `"yearly"`.
* `interval` — every N periods (e.g. every 2 weeks).
* `count` — stop after N occurrences.
* `until` — stop on or before a date.
* `weekdays` — which days, for `weekly` rules (0 = Sunday).
* `nthWeekday` — for `monthly`/`yearly`, repeat on the Nth weekday instead of the
  day-of-month, e.g. `{ week: 3, weekday: 1 }` (the 3rd Monday) or `{ week: -1,
  weekday: 5 }` (the last Friday).
* `monthDays` — for `monthly`, the day(s) of the month to repeat on, e.g. `[1, 15]`
  (the 1st and 15th) or `[-1]` (the last day; negatives count from the month's end).
  Days a month lacks (the 31st in February) are skipped.
* `months` — for `yearly`, the month(s) to repeat in (1 = January … 12 = December),
  keeping the start date's day-of-month, e.g. `[3, 9]` (every March and September).
* `exdates` — dates to skip (exceptions). A date at local midnight skips every
  occurrence on that calendar day; a date with a time skips only the occurrence
  starting at that exact instant, so two same-day occurrences can be cancelled
  independently.
* `rdates` — extra one-off dates added to the set, even ones the rule wouldn't
  produce.

Each occurrence keeps the original duration and fields; non-recurring events pass
through unchanged. These rules map to and from iCal
`RRULE`/`BYMONTHDAY`/`BYMONTH`/`EXDATE`/`RDATE` — see [iCalendar](/guides/ical).

<Tip>
  Compute the range from the visible window. `onChangeDateRange` gives you the `[start, end]` of
  what's on screen each time the user pages — a good trigger to re-expand (and to fetch from a
  server).
</Tip>

Expansion fast-forwards to the range you ask for, so a long-lived rule (a daily
event started years ago) stays cheap to query far in the future. A single
`expandRecurringEvents` call emits at most 5000 occurrences within the range;
pass a `count`/`until`, or query a tighter window, if you need more.
