forceCalendar
Core Package

Event Model

The Event class -- creation, validation, timezone support, attendees, reminders, and categories.

Overview

The Event class represents a calendar event with full timezone support, attendee management, reminders, and category tagging. Events are created through Event.normalize() which assigns defaults and generates unique IDs.

import { Event } from '@forcecalendar/core';

const event = new Event({
  title: 'Team Meeting',
  start: new Date('2026-03-01T09:00:00'),
  end: new Date('2026-03-01T10:00:00'),
  timeZone: 'America/New_York',
});

Constructor Properties

PropertyTypeDefaultDescription
idstringAuto-generatedUnique identifier (evt_ + random hex)
titlestring'Untitled Event'Event title
startDatenew Date()Start date/time
endDateStart + 1 hourEnd date/time
allDaybooleanfalseAll-day event flag
descriptionstring''Event description
locationstring''Event location
colorstring'#4285f4'Primary color
backgroundColorstringnullBackground override
borderColorstringnullBorder override
textColorstringnullText color override
recurringbooleanfalseWhether event recurs
recurrenceRulestring|objectnullRRULE string or parsed rule object
recurrencestring|objectnullAlias for recurrenceRule
timeZonestringnullIANA timezone for start time
endTimeZonestringnullIANA timezone for end time (if different)
statusstring'confirmed''confirmed', 'tentative', 'cancelled'
visibilitystring'public''public', 'private', 'confidential'
organizerobjectnull{ email, name }
attendeesArray[]Attendee objects
remindersArray[]Reminder objects
categoriesArray[]Category strings
categorystringnullShorthand for single category (added to categories)
attachmentsArray[]Attachment objects
conferenceDataobjectnullVideo conference data
metadataobject{}Custom key-value metadata

Static Methods

Event.normalize(data)

Normalize raw event data into a complete event object with defaults applied. Generates an id if not present, ensures start and end are Date objects, and applies default values.

const normalized = Event.normalize({
  title: 'Quick Event',
  start: '2026-03-01T09:00:00',
});
// { id: 'evt_a1b2c3...', title: 'Quick Event', start: Date, end: Date, ... }

Event.validate(data)

Validate event data. Returns { valid: boolean, errors: string[] }.

const result = Event.validate({ title: '', start: 'invalid' });
// { valid: false, errors: ['Title is required', 'Invalid start date'] }

Validation checks:

  • Title must be a non-empty string
  • Start must be a valid Date
  • End must be a valid Date
  • End must be after start (unless all-day)
  • Status must be one of the valid values
  • Visibility must be one of the valid values

Event.fromObject(obj)

Create an Event instance from a plain object.

const event = Event.fromObject(savedEventData);

Computed Properties (Getters)

GetterTypeDescription
durationnumberDuration in milliseconds
durationMinutesnumberDuration in minutes
durationHoursnumberDuration in hours (decimal)
isMultiDaybooleanSpans midnight
isCancelledbooleanStatus is 'cancelled'
isTentativebooleanStatus is 'tentative'
isConfirmedbooleanStatus is 'confirmed'
isPrivatebooleanVisibility is 'private'
isPublicbooleanVisibility is 'public'
hasAttendeesbooleanHas at least one attendee
hasRemindersbooleanHas at least one reminder
isMeetingbooleanHas attendees
isVirtualbooleanHas conference data
categorystring|nullPrimary (first) category

Instance Methods

isRecurring()

Returns true if the event has a recurrence rule.

occursOn(date)

Check if the event occurs on a specific date (considering timezone).

event.occursOn(new Date('2026-03-01')); // true

overlaps(otherEvent)

Check if this event's time range overlaps with another event.

const hasConflict = eventA.overlaps(eventB);

contains(datetime)

Check if a specific datetime falls within this event's time range.

clone(updates?)

Create a copy of this event, optionally with modifications.

const copy = event.clone({ title: 'Copy of Meeting' });

toObject()

Serialize to a plain object (for storage or transmission).

const obj = event.toObject();
JSON.stringify(obj);

equals(other)

Deep equality check against another event.

Timezone Methods

getStartInTimezone(timezone)

Get the start time converted to a specific timezone.

const tokyoStart = event.getStartInTimezone('Asia/Tokyo');

getEndInTimezone(timezone)

Get the end time converted to a specific timezone.

updateTimes(start, end, timezone?)

Update start/end times, optionally specifying the source timezone.

Attendee Management

addAttendee(attendee)

event.addAttendee({
  email: 'alice@example.com',
  name: 'Alice',
  status: 'needs-action',  // 'accepted', 'declined', 'tentative', 'needs-action'
  role: 'required',         // 'required', 'optional', 'chair'
});

removeAttendee(email)

event.removeAttendee('alice@example.com');

updateAttendeeResponse(email, status)

event.updateAttendeeResponse('alice@example.com', 'accepted');

getAttendee(email)

Returns the attendee object for the given email, or undefined.

hasAttendee(email)

Returns boolean.

getAttendeesByStatus(status)

const accepted = event.getAttendeesByStatus('accepted');

getAttendeeCounts()

const counts = event.getAttendeeCounts();
// { total: 5, accepted: 3, declined: 1, tentative: 0, 'needs-action': 1 }

Reminder Management

addReminder(reminder)

event.addReminder({
  type: 'email',      // 'email', 'popup', 'sms'
  minutes: 15,        // Minutes before event
});

removeReminder(index)

Remove a reminder by its array index.

getActiveReminders()

Returns reminders that haven't triggered yet.

getReminderTriggerTimes()

Returns an array of Date objects representing when each reminder should fire.

const times = event.getReminderTriggerTimes();
// [Date(2026-03-01T08:45:00), Date(2026-03-01T08:00:00)]

Category Management

addCategory(category)

event.addCategory('important');

removeCategory(category)

event.removeCategory('important');

hasCategory(category)

Returns boolean.

hasAnyCategory(categories)

Returns true if the event has at least one of the given categories.

event.hasAnyCategory(['meeting', 'review']); // true if has either

hasAllCategories(categories)

Returns true if the event has all of the given categories.