# FullCalendar

> A calendar shows events in a month, week, day, or list view. Use it for schedules, bookings, and team plans.

Show events in a calendar.

Source: https://docs.tabler.io/ui/plugins/fullcalendar

---

## Overview

The calendar is built with [FullCalendar](https://fullcalendar.io/). Tabler adds a style layer on top of it, so the calendar matches the rest of the interface: the same borders, the same button style, and event colors from the theme.

You only need an empty element. FullCalendar builds the whole calendar inside it.

```html
<div id="calendar-overview" style="width: 100%;"></div>
```

## Installation

Install FullCalendar with npm:

```shell
npm install fullcalendar
```

Or include the global bundle from a CDN. One file contains all the standard views:

```html
<script src="https://cdn.jsdelivr.net/npm/@tabler/core@1.5.0/dist/libs/fullcalendar/index.global.min.js"></script>
```

The Tabler look comes from the vendors plugin. Include `tabler-vendors.css` next to `tabler.css`:

```html
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@tabler/core@1.5.0/dist/css/tabler-vendors.min.css" />
```

## Usage

### Markup

Add an empty element with an id. Do not put anything inside it, because FullCalendar replaces its content.

```html
<div id="calendar"></div>
```

### Init the calendar

Create the calendar and call `render()`. `initialView` decides which view opens first.

```js
document.addEventListener('DOMContentLoaded', function () {
  const calendarEl = document.getElementById('calendar')

  const calendar = new FullCalendar.Calendar(calendarEl, {
    initialView: 'dayGridMonth',
  })

  calendar.render()
})
```

### Views

The global bundle ships with these views. Set one as `initialView`, or let users switch between them from the toolbar.

| View | Result |
| --- | --- |
| `dayGridMonth` | One month, days in a grid. |
| `timeGridWeek` | One week with hours. |
| `timeGridDay` | One day with hours. |
| `listWeek` | A plain list of events for the week. |
| `multiMonthYear` | A whole year, month by month. |

The example below opens in the week view.

```html
<div id="calendar-week" style="width: 100%;"></div>
```

### Toolbar

Use `headerToolbar` to set what appears in the three toolbar slots. Pass the view names as buttons, so users can switch views.

```js
const calendar = new FullCalendar.Calendar(calendarEl, {
  initialView: 'dayGridMonth',
  headerToolbar: {
    left: 'prev,next today',
    center: 'title',
    right: 'dayGridMonth,timeGridWeek,listWeek',
  },
})
```

The list view is a good second option, because it stays readable on a phone.

```html
<div id="calendar-toolbar" style="width: 100%;"></div>
```

### Events

Pass events as an array. Each event needs a `title` and a `start`. Use real `Date` objects or ISO strings.

```js
const calendar = new FullCalendar.Calendar(calendarEl, {
  initialView: 'dayGridMonth',
  events: [
    { title: 'Monthly Planning', start: '2026-08-03T10:00', end: '2026-08-03T11:30' },
    { title: 'Design Sprint', start: '2026-08-07T09:00', end: '2026-08-07T12:00' },
  ],
})
```

### Event colors

Set the colors per event to group them by type. `backgroundColor` fills the event, `borderColor` draws its border, and `color` sets the dot in the month view. Tabler color variables work here.

```js
{
  title: 'Offsite Retreat',
  start: '2026-08-02T09:00',
  end: '2026-08-04T17:00',
  color: 'var(--tblr-red)',
  backgroundColor: 'var(--tblr-red-lt)',
  borderColor: 'var(--tblr-red-200)',
}
```

### Theming

Tabler sets the FullCalendar variables on `:root`. Override them to change all calendars at once, or set them on one calendar element.

| Variable | Used for |
| --- | --- |
| `--fc-border-color` | Grid lines. |
| `--fc-event-bg-color` | Event background. |
| `--fc-event-border-color` | Event border. |
| `--fc-event-text-color` | Event text. |
| `--fc-daygrid-event-dot-width` | Dot size in the month view. |

## Examples

### Calendar in a card

Put the calendar in a card body. This is the usual layout for a full page calendar.

```html
<div class="card">
  <div class="card-body">
    <div id="calendar-card" style="width: 100%;"></div>
  </div>
</div>
```

## Accessibility

- Give the calendar a heading, for example a card title, so its purpose is clear.
- Offer the `listWeek` view as well. It reads as a normal list, which works better with a screen reader and on small screens.
- Do not use color alone to mark a type of event. Repeat the type in the event title.
- Keep the toolbar buttons visible. They are real buttons, so they work with the keyboard.

<script>{`
document.addEventListener('DOMContentLoaded', function () {
	if (typeof FullCalendar === 'undefined') return;

	const year = new Date().getFullYear();
	const month = new Date().getMonth();
	const at = (day, hour, minute) => new Date(year, month, day, hour, minute);

	const events = [
		{
			title: 'Offsite Retreat',
			start: at(2, 9, 0),
			end: at(4, 17, 0),
			color: 'var(--tblr-red)',
			backgroundColor: 'var(--tblr-red-lt)',
			borderColor: 'var(--tblr-red-200)',
		},
		{ title: 'Monthly Planning', start: at(1, 10, 0), end: at(1, 11, 30) },
		{ title: 'Design Sprint', start: at(7, 9, 0), end: at(7, 12, 0) },
		{ title: 'Dev Team Check-in', start: at(10, 11, 0), end: at(10, 11, 30) },
		{ title: 'Mid-Month Review', start: at(15, 10, 30), end: at(15, 11, 30) },
		{ title: 'Company All-Hands', start: at(25, 15, 0), end: at(25, 16, 0) },
	];

	const calendars = [
		{ id: 'calendar-overview', options: { initialView: 'dayGridMonth', events: events } },
		{ id: 'calendar-week', options: { initialView: 'timeGridWeek', events: events } },
		{
			id: 'calendar-toolbar',
			options: {
				initialView: 'listWeek',
				headerToolbar: { left: 'prev,next today', center: 'title', right: 'dayGridMonth,timeGridWeek,listWeek' },
				events: events,
			},
		},
		{ id: 'calendar-card', options: { initialView: 'dayGridMonth', events: events } },
	];

	calendars.forEach(function (item) {
		const el = document.getElementById(item.id);
		if (!el) return;

		new FullCalendar.Calendar(el, item.options).render();
	});
});
`}</script>
