Angular Scheduler Recurrence

Recurrence

RFC 5545 RRULE recurrence with windowed, DST-safe expansion, exception dates, and per-occurrence editing.

Events repeat through the rrule property — a raw RFC 5545 RRULE string. Any rule the standard allows is valid in the data model; the built-in editing UI exposes daily/weekly/monthly presets.

Aug 10 – 16, 2026
10 Mon
11 Tue
12 Wed
13 Thu
14 Fri
15 Sat
16 Sun
07:00
08:00
09:00
10:00
11:00
12:00
13:00
14:00
15:00
16:00
17:00
18:00
07:30 AM – 08:15 AM
Yoga
09:00 AM – 09:15 AM
Daily standup
09:00 AM – 09:15 AM
Daily standup
07:30 AM – 08:15 AM
Yoga
09:00 AM – 09:15 AM
Daily standup
11:00 AM – 12:00 PM
Backlog grooming
09:00 AM – 09:15 AM
Daily standup
07:30 AM – 08:15 AM
Yoga
09:00 AM – 09:15 AM
Daily standup
07:30 AM – 08:15 AM
Yoga
ts
import { Component } from '@angular/core'
import { SchedulerComponent } from '@coreui/angular-scheduler'

const pad = (n: number) => String(n).padStart(2, '0')
const day = (offset: number) => {
  const date = new Date()
  date.setDate(date.getDate() - ((date.getDay() + 6) % 7) + offset)
  return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`
}

@Component({
  selector: 'docs-scheduler-recurrence-example',
  imports: [SchedulerComponent],
  template: `
    <c-scheduler [dayStartHour]="7" [dayEndHour]="19" [events]="events" />
  `
})
export class SchedulerRecurrenceExample {
  readonly events = [
    {
 id: 'standup', title: 'Daily standup', start: `${day(0)}T09:00`, end: `${day(0)}T09:15`, rrule: 'FREQ=DAILY;COUNT=5'
},
    {
 id: 'yoga', title: 'Yoga', start: `${day(0)}T07:30`, end: `${day(0)}T08:15`, rrule: 'FREQ=DAILY;INTERVAL=2', color: '#2eb85c'
},
    {
 id: 'grooming', title: 'Backlog grooming', start: `${day(2)}T11:00`, end: `${day(2)}T12:00`, rrule: 'FREQ=WEEKLY', exdates: [`${day(9)}T11:00`]
}
  ]
}

How expansion works

Occurrences are computed only for the visible range — never “the whole series ahead” — and each occurrence keeps the series’ wall-clock time across DST transitions in the scheduler’s time zone. An occurrence that would land on a nonexistent time (the spring-forward gap) shifts forward with the gap; durations stay real elapsed time.

exdates lists wall-clock exception dates excluded from the series.

Editing occurrences

Clicking any event opens the edit dialog — title, start, end, color, and a repeat preset. For recurring events the dialog adds an Applies to scope that governs how the edit lands:

ScopeEffect of a move/resize/delete
occurrence (default)The occurrence detaches: the series gains an exdate, the change becomes a standalone event.
futureThe series ends just before this occurrence; the remainder becomes a new series at the edited time. COUNT rules are dropped on split.
allThe whole series shifts by the edit’s delta.

The initial scope comes from the recurringEditScope input. With the occurrence scope, repeat changes are not carried onto the detached copy — switch the scope to future or all to change the rule itself.