TimelineKit

Features

iCalendar Import/Export

Import and export calendar data in the iCalendar (.ics) format following the RFC 5545 standard. This enables interoperability with Google Calendar, Outlook, Apple Calendar, and other calendar applications.

Export

// Export as .ics file (Blob)
const icsBlob = calendar.exportToIcs();

// Export as text string
const icsText = calendar.exportToIcsText();

// Download
const url = URL.createObjectURL(icsBlob);
const a = document.createElement('a');
a.href = url;
a.download = 'calendar.ics';
a.click();

Import

// Import from .ics text
const result = calendar.importFromIcs(icsText);

// result: {
//   calendar: Calendar,          — the imported calendar
//   items: CalendarItem[],       — imported items
//   warnings: string[],          — parse warnings (unsupported properties, etc.)
//   skippedCount: number,        — items that could not be parsed
// }

console.log('Imported', result.items.length, 'items');
if (result.warnings.length > 0) {
  console.warn('Warnings:', result.warnings);
}

Time Zones

The timeZone property stores an IANA time zone identifier (e.g. 'Europe/Prague', 'America/New_York') as metadata on calendars and items. The default value is null.

Where Time Zone Can Be Set

Time zone can be set at three levels:

  • Calendar — default time zone for all items in the calendar.
  • CalendarItem — time zone of a specific event, overrides the calendar-level value.
  • RecurrenceException overrides — time zone override for a single occurrence of a recurring event.
// Set time zone on a calendar
const cal = calendar.data.getCalendarById('c1');
cal.timeZone = 'Europe/Prague';

// Set time zone on an item
const item = calendar.data.getItemById('i1');
item.timeZone = 'America/New_York';

// Override time zone for a single occurrence
item.recurrenceExceptions.push({
  originalStartTime: new Date('2027-01-20T09:00:00'),
  isCancelled: false,
  overrides: { timeZone: 'Asia/Tokyo' },
});

How Time Zone Is Resolved

When the component renders a CalendarEntry (a visible occurrence), the time zone is resolved in this order:

  1. Recurrence exception override timeZone (if present)
  2. CalendarItem timeZone
  3. null (no time zone)

Display Behavior

All times (startTime, endTime) are stored and displayed as JavaScript Date objects in the browser's local time. The timeZone property does not automatically convert times — it serves as metadata indicating which time zone the event was originally created in. If your application needs to convert times between time zones, perform the conversion at the application level (e.g. using Intl.DateTimeFormat or a library like date-fns-tz) before passing data to the component.

iCalendar Export & Time Zones

When exporting to iCalendar (.ics), all date/time values are written in UTC (with the Z suffix). If an item has a timeZone set, it is preserved as a custom X-TIMELINEKIT-TIMEZONE property for round-trip compatibility.

// Exported .ics output example:
// DTSTART:20270106T080000Z        ← always UTC
// DTEND:20270106T083000Z
// X-TIMELINEKIT-TIMEZONE:America/New_York

iCalendar Import & Time Zones

When importing from iCalendar, the time zone is read in the following order of preference:

  1. TZID parameter from DTSTART (RFC 5545 standard)
  2. X-TIMELINEKIT-TIMEZONE custom property (TimelineKit round-trip)
  3. null if neither is present

UTC times (ending with Z) are parsed correctly. Non-UTC times are interpreted as the browser's local time. The TZID value is stored on CalendarItem.timeZone for metadata purposes but is not used for time conversion.

// Importing an .ics with TZID:
// DTSTART;TZID=America/New_York:20270106T090000
// → item.timeZone === 'America/New_York'
// → item.startTime is 09:00 in browser local time

// Importing an .ics with UTC time + round-trip metadata:
// DTSTART:20270106T140000Z
// X-TIMELINEKIT-TIMEZONE:America/New_York
// → item.timeZone === 'America/New_York'
// → item.startTime is 14:00 UTC converted to browser local time

Export

Export the calendar view as an image, PDF, CSV, or Excel file. See also the Export guide for detailed options.

// Export as PNG image
const imageBlob = await calendar.exportToImage();

// Export as PDF (requires jspdf)
const pdfBlob = await calendar.exportToPdf();

// Export as CSV
const csv = calendar.exportToCsv();

// Export as Excel (requires exceljs)
const excelBlob = await calendar.exportToExcel();

Serialization

Save and load the complete calendar state as JSON. Includes calendars, items (with recurrence rules and exceptions), current date, and view mode.

// Save state
const json = calendar.save();
localStorage.setItem('calendar-state', json);

// Load state
const saved = localStorage.getItem('calendar-state');
calendar.load(saved);

JSON Structure

{
  "calendars": [
    { "id": "c1", "name": "Work", "color": 0, "isVisible": true, "isDefault": true }
  ],
  "items": [
    {
      "id": "i1", "calendarId": "c1", "title": "Standup", "type": "meeting",
      "startTime": "2027-01-06T09:00:00", "endTime": "2027-01-06T09:15:00",
      "recurrenceRule": {
        "frequency": "weekly",
        "byDay": [{ "day": "mo" }, { "day": "tu" }, { "day": "we" }, { "day": "th" }, { "day": "fr" }]
      },
      "recurrenceExceptions": [
        { "originalStartTime": "2027-01-20T09:00:00", "isCancelled": true }
      ]
    }
  ],
  "currentDate": "2027-01-06",
  "viewMode": "week"
}