showCreateEventModal method

Future<void> showCreateEventModal({
  1. String? title,
  2. DateTime? startDate,
  3. DateTime? endDate,
  4. String? description,
  5. String? location,
  6. bool? isAllDay,
  7. RecurrenceRule? recurrenceRule,
  8. EventAvailability? availability,
})

Opens the OS's native event editor in create mode, completing when it's dismissed.

All parameters are optional pre-fill values; the user can change anything before saving or cancelling. Useful for letting the user review, or to add attendees (which can't be done programmatically).

Needs no calendar permission on Android or iOS 17+ — the system editor saves the event with its own access — so it also works as a fallback when the user has denied access. Because it normally needs nothing, autoPermissions never prompts for this method. On iOS 16 and below the editor runs in-process and does require full access (request it with requestPermissions first); without it this throws DeviceCalendarException with DeviceCalendarError.permissionDenied.

Throws DeviceCalendarException with DeviceCalendarError.operationFailed when a native modal is already showing (one at a time, shared with showEventModal) or there's no Activity/window to present from.

Implementation

Future<void> showCreateEventModal({
  String? title,
  DateTime? startDate,
  DateTime? endDate,
  String? description,
  String? location,
  bool? isAllDay,
  RecurrenceRule? recurrenceRule,
  EventAvailability? availability,
}) async {
  // Validate dates if both are provided
  if (startDate != null && endDate != null && endDate.isBefore(startDate)) {
    throw ArgumentError('End date must be after start date');
  }

  // Normalize dates for all-day events
  final normalizedStart = (isAllDay == true && startDate != null)
      ? _stripTime(startDate)
      : startDate;
  final normalizedEnd =
      (isAllDay == true && endDate != null) ? _stripTime(endDate) : endDate;

  // Deliberately no _ensurePermission: the modal needs no calendar access on
  // Android or iOS 17+, so gating (or auto-prompting) here would block the
  // one path that still works after a denial. iOS 16 and below enforces its
  // full-access requirement natively.
  try {
    await DeviceCalendarPlusPlatform.instance.showCreateEventModal(
      title: title,
      startDate: normalizedStart?.millisecondsSinceEpoch,
      endDate: normalizedEnd?.millisecondsSinceEpoch,
      description: description,
      location: location,
      isAllDay: isAllDay,
      recurrenceRule: recurrenceRule?.toRruleString(),
      availability: availability?.name,
    );
  } on PlatformException catch (e, stackTrace) {
    final convertedException =
        PlatformExceptionConverter.convertPlatformException(e);
    if (convertedException != null) {
      Error.throwWithStackTrace(convertedException, stackTrace);
    }
    rethrow;
  }
}