Events topic

Events

This is part of the kalender documentation.

The event model, and how to attach your own data to it. For where tiles are placed on screen, see Layout. For what they look like, see Appearance.

Custom Events

KalenderEvent is not generic. Attach custom data (title, color, description, and so on) by extending KalenderEvent directly.

class Event extends KalenderEvent {
  final String title;
  final String? description;
  final Color? color;

  Event({
    super.id,
    required super.start,
    required super.end,
    required this.title,
    this.description,
    this.color,
    super.interaction,
    super.multiDayRule,
    super.isAllDay,
  });

  // Rebuilds the fields this class adds. The calendar calls this on every drag
  // and resize, then restores id, interaction, multiDayRule and isAllDay
  // itself, so none of those are listed here.
  @override
  Event copyWithData({required DateTime start, required DateTime end}) {
    return Event(
      start: start,
      end: end,
      title: title,
      description: description,
      color: color,
    );
  }

  // A copy method of your own. It is not an override, so it takes whatever
  // parameters suit you. carryOver keeps the copy's identity and rule.
  Event copyWith({DateTime? start, DateTime? end, String? title, String? description, Color? color}) {
    return carryOver(
      Event(
        start: start ?? this.start,
        end: end ?? this.end,
        title: title ?? this.title,
        description: description ?? this.description,
        color: color ?? this.color,
      ),
    );
  }

  // Override == and hashCode so that the calendar can detect when an event's
  // custom fields have changed and update the tile accordingly.
  @override
  bool operator ==(Object other) {
    if (identical(this, other)) return true;
    return super == other &&
        other is Event &&
        other.title == title &&
        other.description == description &&
        other.color == color;
  }

  @override
  int get hashCode => Object.hash(super.hashCode, title, description, color);
}

Note

If you don't override == and hashCode, the calendar cannot detect changes to your custom fields and tiles will not update when those values change (e.g. via eventsController.updateEvent(...)). Always override both whenever you add fields to your KalenderEvent subclass.

The copy contract

The calendar calls withDateTimeRange on every drag and resize. It calls your copyWithData, then restores the id, interaction, multiDayRule and isAllDay that KalenderEvent holds, which is why copyWithData lists only your own fields. Call carryOver from a copy method of your own to get the same. A subclass with no copyWithData is flagged by the analyzer, since it is @mustBeOverridden.

Updating events

Use eventsController.updateEvent() to replace an existing event with an updated copy:

final original = eventsController.byId(someId)! as Event;
final updated = original.copyWith(title: 'Updated Title', color: Colors.red);
eventsController.updateEvent(event: original, updatedEvent: updated);

Because == and hashCode include your custom fields, the calendar will detect the change and rebuild the tile.

layoutEquals

Only override layoutEquals when a custom property changes the size or position of the tile, for example a flag that makes a tile render taller. It is not for content-only changes like color or title. The default implementation compares id, dateTimeRange, interaction, multiDayRule and isAllDay, which is sufficient for most cases.

Accessing custom fields in tile builders

Cast the event to your subclass. A convenience getter keeps the cast to one place:

TileComponents(
  tileBuilder: (context, event, tileRange) {
    final myEvent = event as Event;
    return Container(
      color: myEvent.color ?? Colors.blue,
      child: Text(myEvent.title),
    );
  },
)

Returning your subclass on event creation

Use onEventCreate to intercept the bare KalenderEvent created by a gesture and return a fully typed instance:

Pass this as KalenderView.callbacks:

KalenderCallbacks(
  onEventCreate: (event) => Event(
    start: event.start,
    end: event.end,
    title: 'New Event',
    color: Colors.blue,
  ),
  onEventCreated: (event) => eventsController.addEvent(event),
)

Multi-day and all-day events

A MultiDayRule decides whether an event renders in the multi-day header lane or in the day timeline. The rule is set on the view configuration (see Shared options) and defaults to counting events of 24 hours or longer as multi-day.

An event that is all-day by nature rather than by duration says so directly, and no rule is consulted:

KalenderEvent(start: range.start, end: range.end, isAllDay: true)

This puts it in the header lane whatever its duration, which no MultiDayRule can express for an event lasting an hour. The date range is left alone, so an app wanting midnight to midnight supplies it. isAllDay defaults to false, where the rules below apply as before.

A single event can override the calendar's rule:

KalenderEvent(
  start: range.start,
  end: range.end,
  multiDayRule: const MultiDayRule.calendarDays(),
)

KalenderEvent.multiDayRule is null unless you set it, and null means the calendar's rule applies. You never forward it manually: copyWithData rebuilds only the fields your subclass adds, and KalenderEvent reapplies the rule, the id and the interaction config afterwards. Accept super.multiDayRule in the constructor so an event can be given one.

spansMultipleDays returns whether an event counts as multi-day, applying the same rules the calendar does:

event.spansMultipleDays(location: location, defaultRule: viewConfiguration.multiDayRule)

The event's own multiDayRule takes precedence when set. Otherwise defaultRule applies. Pass the calendar's location so that rules measuring calendar days, such as MultiDayRule.calendarDays, place midnight in the right timezone.

Classes

DefaultEventsController Events
The default EventsController for managing KalenderEvents.
DefaultEventStore Events
The default class for storing KalenderEvents.
EventsController Events
The EventsController is used to manage KalenderEvents.
EventStore Events
A class that maps KalenderEvents to dates.
KalenderEvent Events
Base class for events displayed in the calendar.
MultiDayRule Events
Decides whether an event belongs in the multi-day header lane rather than the day timeline.

Constants

kDefaultMultiDayRule → const MultiDayRule Events
The rule a calendar uses when nothing overrides it: 24 hours or longer.

Typedefs

DateToEventIds = Map<String, Set<String>> Events
Maps calendar dates to sets of event IDs that occur on those dates.
EventIdToEvent = Map<String, KalenderEvent> Events
Maps unique event IDs to their corresponding KalenderEvent instances.
LocationDateIdMap = Map<String, DateToEventIds> Events
Maps timezone location names to their respective date-to-event-ID indexes.
UpdatedEvent = (KalenderEvent, KalenderEvent) Events