# React FullCalendar

React FullCalendar in AdminKit PRO: FullCalendar 7 with month, week and day views, drag and drop events and Bootstrap buttons, in light and dark mode.

> This component is only available in **AdminKit PRO**. [Learn more](/pricing/#react).

Use `FullCalendar` to show meetings, deadlines and time off in a month, week or day view. With `editable` on, people can drag an event to another day or resize it. The calendar follows light and dark mode, and its toolbar uses Bootstrap's `btn btn-primary` buttons.

`FullCalendar` is a React component around [FullCalendar](https://fullcalendar.io/) 7 (`@fullcalendar/react` 7.1.3), set up for [AdminKit for React](/react/). It comes with the day grid, time grid and interaction plugins of FullCalendar. It uses FullCalendar's classic theme.

FullCalendar is a large library, so the component loads it and its plugins with `React.lazy`. Vite keeps them out of the main bundle, and the browser only fetches them on the first page that shows a calendar. Until then, a skeleton about the size of the month view (aspect ratio 1.25) keeps the card at its height. FullCalendar's stylesheets are part of `app.scss`.

## Example

The props are FullCalendar's options. The demo events below fill the current month view, so the example always has something to show.

```html
<div id="fullcalendar-example"></div>

<script type="module" src="/preview/pro/js/fullcalendar.js"></script>
<script>
var today = new Date();
var first = new Date(today.getFullYear(), today.getMonth(), 1);
// day(2, 1, "10:00:00"): the Monday of the third row of the month view at 10 am
var day = function (week, weekday, time) {
  var value = new Date(first.getFullYear(), first.getMonth(), 1 - first.getDay() + week * 7 + weekday);
  var text = [
    value.getFullYear(),
    String(value.getMonth() + 1).padStart(2, "0"),
    String(value.getDate()).padStart(2, "0")
  ].join("-");
  return time ? text + "T" + time : text;
};

new FullCalendar.Calendar(document.getElementById("fullcalendar-example"), {
  plugins: FullCalendar.plugins,
  initialView: "dayGridMonth",
  todayHint: "Today",
  headerToolbar: {
    left: "prev,next today",
    center: "title",
    right: "dayGridMonth,timeGridWeek,timeGridDay"
  },
  editable: true,
  eventDisplay: "block",
  eventClass: "calendar-event",
  events: [
    { title: "Sprint planning", start: day(0, 1, "10:00:00"), end: day(0, 1, "11:30:00"), className: "calendar-event-primary" },
    { title: "Q4 roadmap due", start: day(1, 4), className: "calendar-event-danger" },
    { title: "Web Summit, Lisbon", start: day(2, 2), end: day(2, 5), className: "calendar-event-success" },
    { title: "Fiona Green out", start: day(3, 4), className: "calendar-event-warning" }
  ]
}).render();
</script>
```
```tsx code
import { useState } from "react";
import { type EventInput, FullCalendar } from "@/components/plugins/fullcalendar";

const today = new Date();
const first = new Date(today.getFullYear(), today.getMonth(), 1);

// day(2, 1, "10:00:00"): the Monday of the third row of the month view at 10 am
const day = (week: number, weekday: number, time?: string) => {
  const value = new Date(
    first.getFullYear(),
    first.getMonth(),
    1 - first.getDay() + week * 7 + weekday
  );
  const text = [
    value.getFullYear(),
    String(value.getMonth() + 1).padStart(2, "0"),
    String(value.getDate()).padStart(2, "0"),
  ].join("-");
  return time ? `${text}T${time}` : text;
};

export function TeamCalendar() {
  const [events] = useState<EventInput[]>(() => [
    { title: "Sprint planning", start: day(0, 1, "10:00:00"), end: day(0, 1, "11:30:00"), className: "calendar-event-primary" },
    { title: "Q4 roadmap due", start: day(1, 4), className: "calendar-event-danger" },
    { title: "Web Summit, Lisbon", start: day(2, 2), end: day(2, 5), className: "calendar-event-success" },
    { title: "Fiona Green out", start: day(3, 4), className: "calendar-event-warning" },
  ]);

  return (
    <FullCalendar
      initialView="dayGridMonth"
      todayHint="Today"
      headerToolbar={{
        left: "prev,next today",
        center: "title",
        right: "dayGridMonth,timeGridWeek,timeGridDay",
      }}
      editable
      eventDisplay="block"
      eventClass="calendar-event"
      events={events}
    />
  );
}
```

Keep `events` in state, as the demo does, or outside the component. That way FullCalendar gets the same array on every render.

## Props

`FullCalendarProps` is FullCalendar's `CalendarOptions` plus a `ref`. See [FullCalendar's options](https://fullcalendar.io/docs) for the full list. The component is in `src/components/plugins/fullcalendar.tsx`.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `initialView` | `string` | | `"dayGridMonth"`, `"timeGridWeek"`, `"timeGridDay"`, ... |
| `events` | `EventInput[]` | | The events: `title`, `start`, `end`, `className`, ... |
| `editable` | `boolean` | | Events can be dragged and resized |
| `headerToolbar` | `object` | | The buttons and title of the toolbar |
| `plugins` | `PluginInput[]` | | Plugins to add to the built-in ones; keep it a stable array |
| `ref` | `Ref<CalendarRef>` | | `ref.current.getApi()` returns FullCalendar's Calendar API |

You don't pass the built-in plugins yourself. They are the day grid, the time grid, the interaction plugin and a Bootstrap theme on top of the classic theme. The interaction plugin handles dragging, resizing and clicking dates. The module also exports the `CalendarOptions`, `CalendarRef` and `EventInput` types.

## Event colors

Colors help people tell meetings from deadlines at a glance. Give an event the class `calendar-event`, through `eventClass` as above, and a category class: `calendar-event-primary`, `-success`, `-warning`, `-danger` or `-info`. The event becomes a tinted chip with a colored left edge, in light and dark mode. For a legend, `calendar-swatch` with the same category class draws a small square of that color:

```tsx
<ul className="list-inline small text-body-secondary mb-0" aria-label="Event categories">
  <li className="list-inline-item me-3">
    <span className="calendar-swatch calendar-event-primary me-1" />
    Meetings
  </li>
  <li className="list-inline-item me-0">
    <span className="calendar-swatch calendar-event-danger me-1" />
    Deadlines
  </li>
</ul>
```

The [calendar demo](https://react-demo.adminkit.io/calendar) also shades the weekends: it returns `calendar-weekend` from `dayCellClass` and `dayLaneClass`. It marks today's date by returning `calendar-today-number` from `dayCellTopInnerClass`. To change the colors of the theme, edit the `--fc-classic-*` custom properties in `src/scss/5-vendor/_fullcalendar.scss`.

## Calendar API

To control the calendar from your own code, such as switching views from your own buttons, use FullCalendar's Calendar API. A `ref` gives it to you through `getApi()`:

```tsx
import { useRef } from "react";
import {
  type CalendarRef,
  type EventInput,
  FullCalendar,
} from "@/components/plugins/fullcalendar";

export function WeekCalendar({ events }: { events: EventInput[] }) {
  const calendar = useRef<CalendarRef>(null);

  return (
    <>
      <button
        type="button"
        className="btn btn-light mb-3"
        onClick={() => calendar.current?.getApi().changeView("timeGridWeek")}
      >
        Week
      </button>
      <FullCalendar ref={calendar} initialView="dayGridMonth" events={events} />
    </>
  );
}
```

## Accessibility

- `todayHint="Today"` gives the today button an accessible name that matches its text.
- Don't let color be an event's only label. Keep the category in the title or a legend, and give the legend an `aria-label`, as above.
- The toolbar buttons are Bootstrap buttons, focusable and usable with the keyboard.

## Related

- [Next.js FullCalendar](/nextjs/docs/plugins/calendar/): the same component in AdminKit for Next.js
- [Bootstrap 5 FullCalendar](/bootstrap/docs/plugins/calendar/): the same plugin in the HTML version
- [Date picker](/react/docs/forms/date-picker/): Vanilla Calendar Pro, for picking a date in a form
- [Dark mode](/react/docs/customization/dark-mode/): the color modes the calendar follows
- [Calendar demo](https://react-demo.adminkit.io/calendar)

---

Canonical HTML page: https://adminkit.io/react/docs/plugins/calendar/

Site overview for agents: https://adminkit.io/llms.txt (expanded: https://adminkit.io/llms-full.txt) · Documentation: https://adminkit.io/bootstrap/docs/ · Questions: support@adminkit.io
