The visible layer / @forcecalendar/interfaceOpen playground

The calendar is part of your product.

Looks like you.
Works for them.

Turn your application’s records into a calendar people can use. Web Components, adaptable styling, and month, week, and day views built on the Core engine.

Interface 1.9.1 · Web Components · MIT

aAcme CRM/ Customer calendar
Interactive component
Make it yours

Loading your calendar…

Loading synthetic appointments…Interface 1.9.1
Real component. Synthetic customer appointments.Switch views, change the accent, or create a local event.
Month / Week / DayDrag & resizeKeyboard navigationCSS custom propertiesTyped DOM events

01 / the product experience

Make a calendar
feel at home.

A useful calendar needs more than a grid. Give people the right view, a clear way to create events, and room to work with the schedule.

One month. Every detail.

Scan the month, compare the week, or focus on a day. Overlapping appointments stay visible in the time grid.

view="month" | "week" | "day"

Move the work forward.

Create events with the built-in form. Drag, resize, or select a time range, then handle the resulting events in your app.

<forcecal-event-form>

Make room for the keyboard.

Grid semantics, roving focus, arrow-key navigation, and screen-reader labels support keyboard interaction. Validate the complete experience in your app.

ARIA grids + keyboard navigation

02 / your stack, your choice

A web standard.
A familiar way in.

Use the element directly in the browser, or choose the first-party React and Vue adapters. In server-rendered apps, the adapters register the element on the client.

Run in the browser. Mount the element, then supply a complete snapshot of your records.

These examples use synthetic local data. Connect your application’s data layer to load and save real records.

calendar.js
import '@forcecalendar/interface';

const calendar = document.createElement('forcecal-main');
calendar.setAttribute('view', 'week');
calendar.setAttribute('date', '2026-10-05T12:00:00');
calendar.setAttribute('height', '600px');
document.body.append(calendar);

calendar.setEvents([{
  id: 'review', title: 'Customer review',
  start: '2026-10-05T09:00:00Z',
  end: '2026-10-05T10:00:00Z',
}]);

calendar.addEventListener('calendar-event-updated', e => {
  console.log('Updated locally:', e.detail.event);
  // Your app validates and persists the change.
});
Building in Salesforce?

Start with the Lightning integration, packaged resources, and Apex data access.

Salesforce guide

03 / a clear data contract

Your records in.
Your events out.

The component owns the interaction. Your application owns persistence, permissions, and booking rules. Connect them through properties, methods, and DOM events.

Data insetEvents(rows)

Reconcile a complete snapshot. Each record needs an id. Missing records are removed unless removeMissing is false.

Load resultcalendar-events-set

Receive the added, updated, removed, and unchanged sets. Snapshot loads do not fire per-event mutation notifications.

Visible datescalendar-range-change

Receive start, end, view, and date after initial attachment and when the visible window changes. Use it to request your records.

Edits outcalendar-event-add / -update / -remove

Listen for changes from the UI or imperative API. Your application validates and persists them through its authorized data layer.

Fetch the right window.

getVisibleRange() returns browser-local dates with an inclusive end, regardless of the timezone attribute. Translate that window for your backend’s query semantics.

Set editing deliberately.

The readonly attribute or readOnly property disables built-in user edits. Host APIs remain writable; enforce authorization on the server.

Know the edit scope.

Dragging or resizing a recurring occurrence updates the whole series. Per-occurrence editing is not available in the current UI.

04 / bring your design system

Your colors.
Your type.
Your calendar.

CSS custom properties put the component’s visual language in your hands. Define them in a stylesheet on the host element so they survive rerenders.

Explore the component documentation
your-calendar.css
forcecal-main {
  --fc-primary-color: #7564d7;
  --fc-primary-hover: #6050b9;
  --fc-primary-light: #eeeafb;
  --fc-background: #ffffff;
  --fc-background-alt: #f7f6fb;
  --fc-text-color: #252235;
  --fc-text-secondary: #686174;
  --fc-border-color: #e5e1ee;
  --fc-font-family: 'Inter', system-ui, sans-serif;
  --fc-border-radius: 6px;
}

/* Or use the built-in Salesforce preset:
   <forcecal-main theme="slds"></forcecal-main> */

From component to capability

Give your product
a place for time.

Keep the element’s state when temporarily detaching it. Call destroy() when you’re finished with it permanently to release its engine and listeners.

Inspect the source