# EventCalendar [](https://www.jsdelivr.com/package/npm/@event-calendar/build) [](https://www.npmjs.com/package/@event-calendar/core)
See [demo](https://vkurko.github.io/calendar/) and [changelog](CHANGELOG.md).
Full-sized drag & drop JavaScript event calendar with resource & timeline views:
* Lightweight (35kb [br](https://en.wikipedia.org/wiki/Brotli) compressed)
* Minimal DOM structure (thanks to [CSS Grid](https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Grid_layout))
* Zero-dependency (standalone bundle)
* Used on over 70,000 websites with [Bookly](https://wordpress.org/plugins/bookly-responsive-appointment-booking-tool/)
Inspired by [FullCalendar](https://fullcalendar.io/), it implements similar options.
### Featured sponsors
|
|
|
:heavy_plus_sign: [Get on the list](https://github.com/sponsors/vkurko)
|
## Table of contents
- [Usage](#usage)
- [JavaScript module](#javascript-module)
- [Svelte 5 component](#svelte-5-component)
- [Content snippets](#content-snippets)
- [Standalone bundle](#standalone-bundle)
- [Modifying options after initialization](#modifying-options-after-initialization)
- [Options](#options)
|
- [allDayContent](#alldaycontent)
- [allDaySlot](#alldayslot)
- [buttonText](#buttontext)
- [columnWidth](#columnwidth)
- [customButtons](#custombuttons)
- [customScrollbars](#customscrollbars)
- [date](#date)
- [dateClick](#dateclick)
- [dateIncrement](#dateincrement)
- [datesAboveResources](#datesaboveresources)
- [datesSet](#datesset)
- [dayCellContent](#daycellcontent)
- [dayCellFormat](#daycellformat)
- [dayHeaderAriaLabelFormat](#dayheaderarialabelformat)
- [dayHeaderFormat](#dayheaderformat)
- [dayMaxEvents](#daymaxevents)
- [dayPopoverFormat](#daypopoverformat)
- [displayEventEnd](#displayeventend)
- [dragConstraint](#dragconstraint)
- [dragScroll](#dragscroll)
- [duration](#duration)
- [editable](#editable)
- [events](#events)
- [eventAllUpdated](#eventallupdated)
- [eventBackgroundColor](#eventbackgroundcolor)
- [eventClassNames](#eventclassnames)
- [eventClick](#eventclick)
- [eventColor](#eventcolor)
- [eventContent](#eventcontent)
- [eventDidMount](#eventdidmount)
- [eventDragMinDistance](#eventdragmindistance)
- [eventDragStart](#eventdragstart)
- [eventDragStop](#eventdragstop)
- [eventDrop](#eventdrop)
- [eventDurationEditable](#eventdurationeditable)
|
- [eventFilter](#eventfilter)
- [eventGap](#eventgap)
- [eventLongPressDelay](#eventlongpressdelay)
- [eventMouseEnter](#eventmouseenter)
- [eventMouseLeave](#eventmouseleave)
- [eventOrder](#eventorder)
- [eventOrderStrict](#eventorderstrict)
- [eventResizableFromStart](#eventresizablefromstart)
- [eventResize](#eventresize)
- [eventResizeStart](#eventresizestart)
- [eventResizeStop](#eventresizestop)
- [eventSources](#eventsources)
- [eventStartEditable](#eventstarteditable)
- [eventTextColor](#eventtextcolor)
- [eventTimeFormat](#eventtimeformat)
- [filterEventsWithResources](#filtereventswithresources)
- [filterResourcesWithEvents](#filterresourceswithevents)
- [firstDay](#firstday)
- [flexibleSlotTimeLimits](#flexibleslottimelimits)
- [headerToolbar](#headertoolbar)
- [height](#height)
- [hiddenDays](#hiddendays)
- [highlightedDates](#highlighteddates)
- [icons](#icons)
- [lazyFetching](#lazyfetching)
- [listDayFormat](#listdayformat)
- [listDaySideFormat](#listdaysideformat)
- [loading](#loading)
- [locale](#locale)
- [longPressDelay](#longpressdelay)
- [monthHeaderFormat](#monthheaderformat)
- [moreLinkContent](#morelinkcontent)
- [noEventsClick](#noeventsclick)
- [noEventsContent](#noeventscontent)
- [nowIndicator](#nowindicator)
|
- [pointer](#pointer)
- [refetchResourcesOnNavigate](#refetchresourcesonnavigate)
- [resizeConstraint](#resizeconstraint)
- [resourceExpand](#resourceexpand)
- [resources](#resources)
- [resourceLabelContent](#resourcelabelcontent)
- [resourceLabelDidMount](#resourcelabeldidmount)
- [scrollTime](#scrolltime)
- [select](#select)
- [selectable](#selectable)
- [selectBackgroundColor](#selectbackgroundcolor)
- [selectConstraint](#selectconstraint)
- [selectLongPressDelay](#selectlongpressdelay)
- [selectMinDistance](#selectmindistance)
- [slotDuration](#slotduration)
- [slotEventOverlap](#sloteventoverlap)
- [slotHeight](#slotheight)
- [slotLabelFormat](#slotlabelformat)
- [slotLabelInterval](#slotlabelinterval)
- [slotMaxTime](#slotmaxtime)
- [slotMinTime](#slotmintime)
- [slotWidth](#slotwidth)
- [snapDuration](#snapduration)
- [theme](#theme)
- [timeZone](#timezone)
- [titleFormat](#titleformat)
- [unselect](#unselect)
- [unselectAuto](#unselectauto)
- [unselectCancel](#unselectcancel)
- [validRange](#validrange)
- [view](#view)
- [viewDidMount](#viewdidmount)
- [views](#views)
- [weekNumberContent](#weeknumbercontent)
- [weekNumbers](#weeknumbers)
|
- [Methods](#methods)
|
- [getOption](#getoption-name-)
- [setOption](#setoption-name-value-)
|
- [addEvent](#addevent-event-)
- [getEventById](#geteventbyid-id-)
- [getEvents](#getevents)
- [removeEventById](#removeeventbyid-id-)
- [updateEvent](#updateevent-event-)
|
- [refetchEvents](#refetchevents)
- [refetchResources](#refetchresources)
|
- [dateFromPoint](#datefrompoint-x-y-)
- [getView](#getview)
- [gotoDate](#gotodate-date-)
- [next](#next)
- [prev](#prev)
- [unselect](#unselect-1)
|
- [Content](#content)
- [Event object](#event-object)
- [Parsing event from a plain object](#parsing-event-from-a-plain-object)
- [Duration object](#duration-object)
- [Parsing duration from input values](#parsing-duration-from-input-values)
- [Resource object](#resource-object)
- [Parsing resource from a plain object](#parsing-resource-from-a-plain-object)
- [View object](#view-object)
- [Theming](#theming)
- [Browser support](#browser-support)
## Usage
### JavaScript module
The first step is to install the EventCalendar `core` package:
```bash
npm install --save-dev @event-calendar/core
```
This package provides functions for creating and destroying the calendar, as well as plugins for various views. You must use at least one plugin that provides a view. The following plugins are currently available:
* `DayGrid`
* `List`
* `ResourceTimeline`
* `ResourceTimeGrid`
* `TimeGrid`
* `Interaction` (doesn't provide a view)
Then, in your JavaScript module:
```js
import {createCalendar, destroyCalendar, TimeGrid} from '@event-calendar/core';
// Import CSS if your build tool supports it
import '@event-calendar/core/index.css';
let ec = createCalendar(
// HTML element the calendar will be mounted to
document.getElementById('ec'),
// Array of plugins
[TimeGrid],
// Options object
{
view: 'timeGridWeek',
events: [
// your list of events
]
}
);
// If you later need to destroy the calendar then use
destroyCalendar(ec);
```
### Svelte 5 component
The first step is to install the EventCalendar `core` package:
```bash
npm install --save-dev @event-calendar/core
```
This package provides the `Calendar` component, as well as plugins for various views. You must use at least one plugin that provides a view. The following plugins are currently available:
* `DayGrid`
* `List`
* `ResourceTimeline`
* `ResourceTimeGrid`
* `TimeGrid`
* `Interaction` (doesn't provide a view)
Then in your Svelte 5 component, use the calendar like this:
```html
```
The calendar is destroyed gracefully when the component containing it is destroyed.
#### Content snippets
The options that define content can also be given as Svelte snippets:
* [allDayContent](#alldaycontent)
* [dayCellContent](#daycellcontent)
* [eventContent](#eventcontent)
* [moreLinkContent](#morelinkcontent)
* [noEventsContent](#noeventscontent)
* [resourceLabelContent](#resourcelabelcontent)
* [weekNumberContent](#weeknumbercontent)
A snippet is passed to the `Calendar` component under the name of the option it defines:
```html
{#snippet eventContent({event, timeText})}
{timeText} {event.title}
{/snippet}
```
It can also be passed as a property, which is convenient when the snippet is declared elsewhere:
```html
```
A snippet receives the same argument as the function form of the option and is rendered in the same place.
The `content` property of [customButtons](#custombuttons) is also supported, but since custom buttons have arbitrary names, such a snippet is named `customButton` followed by the name of the button with the first letter capitalized. The button itself does not have to be listed in the `customButtons` option:
```html
{#snippet customButtonMyFilter()}
{/snippet}
```
Unlike a function, a snippet is rendered by Svelte itself. It can contain components, event handlers and transitions, and it is updated reactively when the state it uses changes.
If both a snippet and an option with the same name are given, the snippet takes precedence.
### Standalone bundle
This bundle contains a version of the calendar that includes all plugins and is prepared for use in the browser via the `
```
Note
> Please note that the file paths contain an indication of a specific version of the library. You can remove this indication, then the latest version will be loaded:
> ```html
>
>
> ```
> But it is recommended to always specify the version and explicitly update it if necessary, in order to avoid unpredictable problems when a new version of the library is released.
Then initialize the calendar like this:
```js
let ec = EventCalendar.create(document.getElementById('ec'), {
view: 'timeGridWeek',
events: [
// your list of events
]
});
// If you later need to destroy the calendar then use
EventCalendar.destroy(ec);
```
### Modifying options after initialization
You can modify the calendar options after initialization using the [setOption](#setoption-name-value-) method.
```js
ec.setOption('slotDuration', '01:00');
```
In Svelte, you can simply update the original `options` object.
```html
Change slot duration
```
## Options
### allDayContent
- Type `Content` or `function`
- Default `'all-day'`
Defines the content that is displayed as a title of the `all-day` slot.
This value can be either a [Content](#content) or a function that re