# V7 JavaScript API Migration Guide

<div class='sidebar-layout'>
<div class='sidebar-layout__sidebar sidebar-layout__sidebar--changelog' markdown='1'>

<button type="button" onclick={() => window.scrollTo({top:0,behavior:'smooth'})}>Back to top</button>

## Table of Contents

- [Before You Begin](#before-you-begin)
- Connectors
  - [React](#react)
  - [Vue](#vue)
  - [Angular](#angular)
  - [Vanilla JS](#vanilla-js)
  - [Web Component](#web-component)
- [Toolbar](#toolbar)
- [Events (General)](#events-general)
- [Resources (General)](#resources-general)
- Calendar Views
  - [General](#calendar-views-general)
  - [DayGrid View](#daygrid-view)
  - [Resource DayGrid View](#resource-daygrid-view)
  - [TimeGrid View](#timegrid-view)
  - [Resource TimeGrid View](#resource-timegrid-view)
  - [List View](#list-view)
  - [MultiMonth View](#multimonth-view)
  - [Resource Timeline View](#resource-timeline-view)
  - [Custom Views](#custom-views)
- Plugins
  - [Luxon Plugin](#luxon-plugin)
  - [Moment Plugins](#moment-plugins)
  - [Custom Plugins](#custom-plugins)
- [Custom Theme Class](#custom-theme-class)
- [Locales](#locales)
- [Interactions](#interactions)
- [Misc](#misc)


</div>
<div class='sidebar-layout__main changelog' markdown='1'>

This document will help you migrate from v6 of the API to v7. It centers around JS settings that must be changed. If you've written custom CSS, see the [CSS migration guide](upgrading-from-v6-css.md) instead.


## Before You Begin

### Components in Examples

Many examples show React component pseudo-code with the `<FullCalendar>` element. Please adapt these examples to [Vue](vue.md) or [Angular](angular.md), minding the way FullCalendar treats components and component props for each library.

### clsx

Many migrations in this document show the merging of multiple class-names with the [clsx utility](https://www.npmjs.com/package/clsx). It's especially important for conditional class-names. Installation:

```bash
npm install --save clsx
```

In the JS:

```js
import clsx from 'clsx'

const bool = true
clsx('you', 'can', 'merge', bool && 'okay?') // "you can merge okay?"
```


## React

### React Standard Packages

**Breaking:** dependency changes:

- `@fullcalendar/core` removed as a peer dependency
- `@fullcalendar/daygrid` and many other packages removed and moved to `@fullcalendar/react/*` entrypoints (see `package.json` below)
- `temporal-polyfill` added as a peer dependency

1) So, your `package.json` should be modified:

```diff
{
  "dependencies": {
-   "@fullcalendar/react": "^6.1.20",
+   "@fullcalendar/react": "7.0.0",
-   "@fullcalendar/core": "^6.1.20",
-   "@fullcalendar/interaction": "^6.1.20",
-   "@fullcalendar/daygrid": "^6.1.20",
-   "@fullcalendar/timegrid": "^6.1.20",
-   "@fullcalendar/list": "^6.1.20",
-   "@fullcalendar/multimonth": "^6.1.20",
  }
}
```

2) Then install `temporal-polyfill`:

```bash
npm install --save temporal-polyfill
```

3) In your JS, change your imports:

```diff
  import interactionPlugin
-   from '@fullcalendar/interaction'
+   from '@fullcalendar/react/interaction'
  import dayGridPlugin
-   from '@fullcalendar/daygrid'
+   from '@fullcalendar/react/daygrid'
  import timeGridPlugin
-   from '@fullcalendar/timegrid'
+   from '@fullcalendar/react/timegrid'
  import listPlugin
-   from '@fullcalendar/list'
+   from '@fullcalendar/react/list'
  import multiMonthPlugin
-   from '@fullcalendar/multimonth'
+   from '@fullcalendar/react/multimonth'
```

### React Scheduler Packages

**Breaking:** additional dependency changes for premium (aka "scheduler"):

1) Remove the following packages from your `package.json`:

```diff
{
  "dependencies": {
    "@fullcalendar/react": "7.0.0",
    ...
-   "@fullcalendar/resource": "^6.1.20",
-   "@fullcalendar/adaptive": "^6.1.20",
-   "@fullcalendar/scrollgrid": "^6.1.20",
-   "@fullcalendar/timeline": "^6.1.20",
-   "@fullcalendar/resource-timeline": "^6.1.20",
-   "@fullcalendar/resource-timegrid": "^6.1.20",
-   "@fullcalendar/resource-daygrid": "^6.1.20"
  }
}
```

2) Install the `@fullcalendar/react-scheduler` package:

```bash
npm install --save @fullcalendar/react-scheduler@7
```

3) In your JS, change your imports:

```diff
  import resourcePlugin
-   from '@fullcalendar/resource'
+   from '@fullcalendar/react-scheduler'
  import adaptivePlugin
-   from '@fullcalendar/adaptive'
+   from '@fullcalendar/react-scheduler/adaptive'
  import scrollGridPlugin
-   from '@fullcalendar/scrollgrid'
+   from '@fullcalendar/react-scheduler/scrollgrid'
  import timelinePlugin
-   from '@fullcalendar/timeline'
+   from '@fullcalendar/react-scheduler/timeline'
  import resourceTimelinePlugin
-   from '@fullcalendar/resource-timeline'
+   from '@fullcalendar/react-scheduler/resource-timeline'
  import resourceTimeGridPlugin
-   from '@fullcalendar/resource-timegrid'
+   from '@fullcalendar/react-scheduler/resource-timegrid'
  import resourceDayGridPlugin
-   from '@fullcalendar/resource-daygrid'
+   from '@fullcalendar/react-scheduler/resource-daygrid'
```

**Breaking**: FullCalendar no longer bundles its own CSS. Furthermore, the calendar "theme" has been pulled out from the core, as a plugin. Thus, you must import your own stylesheets. This depends on what theme you choose (see [themes.fullcalendar.io](https://themes.fullcalendar.io)):

```diff
  import FullCalendar from '@fullcalendar/react'
+ import themePlugin from '@fullcalendar/react/themes/classic'
  // import other plugins...

  // stylesheets
+ import '@fullcalendar/react/skeleton.css' // ALWAYS NEED SKELETON
+ import '@fullcalendar/react/themes/classic/theme.css' // YOUR THEME
+ import '@fullcalendar/react/themes/classic/palette.css' // YOUR THEME'S PALETTE

  <FullCalendar
    plugins={[
+     themePlugin,
      // other plugins here...
    ]}
  />
```

### Remix

**Behavior:** The [Remix framework](https://remix.run/) previously required a hack to explicitly define the DOM-placement for styles, but this is no longer needed. In `app/root.tsx`:

```diff
  function Document({
    children,
    title,
  }: {
    children: React.ReactNode;
    title?: string;
  }) {
    return (
      <html lang="en">
        <head>
          {title ? <title>{title}</title> : null}
          <Meta />
-         <style data-fullcalendar />
          <Links />
        </head>
        <body>
          {children}
          <ScrollRestoration />
          <Scripts />
          <LiveReload />
        </body>
      </html>
    );
  }
```


## Vue

### Vue Standard Packages

**Breaking:** dependency changes:

- `@fullcalendar/core` removed as a peer dependency
- `@fullcalendar/daygrid` and many other packages removed and moved to `@fullcalendar/vue3/*` entrypoints (see `package.json` below)
- `temporal-polyfill` added as a peer dependency

1) So, your `package.json` should be modified:

```diff
{
  "dependencies": {
-   "@fullcalendar/vue3": "^6.1.20",
+   "@fullcalendar/vue3": "7.0.0",
-   "@fullcalendar/core": "^6.1.20",
-   "@fullcalendar/interaction": "^6.1.20",
-   "@fullcalendar/daygrid": "^6.1.20",
-   "@fullcalendar/timegrid": "^6.1.20",
-   "@fullcalendar/list": "^6.1.20",
-   "@fullcalendar/multimonth": "^6.1.20"
  }
}
```

2) Then install `temporal-polyfill`:

```bash
npm install --save temporal-polyfill
```

3) In your JS, change your imports:

```diff
  import interactionPlugin
-   from '@fullcalendar/interaction'
+   from '@fullcalendar/vue3/interaction'
  import dayGridPlugin
-   from '@fullcalendar/daygrid'
+   from '@fullcalendar/vue3/daygrid'
  import timeGridPlugin
-   from '@fullcalendar/timegrid'
+   from '@fullcalendar/vue3/timegrid'
  import listPlugin
-   from '@fullcalendar/list'
+   from '@fullcalendar/vue3/list'
  import multiMonthPlugin
-   from '@fullcalendar/multimonth'
+   from '@fullcalendar/vue3/multimonth'
```

### Vue Scheduler Packages

**Breaking:** additional dependency changes for premium (aka "scheduler"):

1) Remove the following packages from your `package.json`:

```diff
{
  "dependencies": {
    "@fullcalendar/vue3": "7.0.0",
    ...
-   "@fullcalendar/resource": "^6.1.20",
-   "@fullcalendar/adaptive": "^6.1.20",
-   "@fullcalendar/scrollgrid": "^6.1.20",
-   "@fullcalendar/timeline": "^6.1.20",
-   "@fullcalendar/resource-timeline": "^6.1.20",
-   "@fullcalendar/resource-timegrid": "^6.1.20",
-   "@fullcalendar/resource-daygrid": "^6.1.20"
  }
}
```

2) Install the `@fullcalendar/vue3-scheduler` package:

```bash
npm install --save @fullcalendar/vue3-scheduler@7
```

3) In your JS, change your imports:

```diff
  import resourcePlugin
-   from '@fullcalendar/resource'
+   from '@fullcalendar/vue3-scheduler'
  import adaptivePlugin
-   from '@fullcalendar/adaptive'
+   from '@fullcalendar/vue3-scheduler/adaptive'
  import scrollGridPlugin
-   from '@fullcalendar/scrollgrid'
+   from '@fullcalendar/vue3-scheduler/scrollgrid'
  import timelinePlugin
-   from '@fullcalendar/timeline'
+   from '@fullcalendar/vue3-scheduler/timeline'
  import resourceTimelinePlugin
-   from '@fullcalendar/resource-timeline'
+   from '@fullcalendar/vue3-scheduler/resource-timeline'
  import resourceTimeGridPlugin
-   from '@fullcalendar/resource-timegrid'
+   from '@fullcalendar/vue3-scheduler/resource-timegrid'
  import resourceDayGridPlugin
-   from '@fullcalendar/resource-daygrid'
+   from '@fullcalendar/vue3-scheduler/resource-daygrid'
```

**Breaking**: FullCalendar no longer bundles its own CSS. Furthermore, the calendar "theme" has been pulled out from the core, as a plugin. Thus, you must import your own stylesheets. This depends on what theme you choose (see [themes.fullcalendar.io](https://themes.fullcalendar.io)):

```diff
  <script setup>
    import FullCalendar from '@fullcalendar/vue3'
+   import themePlugin from '@fullcalendar/vue3/themes/classic'
    // import other plugins...

    // stylesheets
+   import '@fullcalendar/vue3/skeleton.css' // ALWAYS NEED SKELETON
+   import '@fullcalendar/vue3/themes/classic/theme.css' // YOUR THEME
+   import '@fullcalendar/vue3/themes/classic/palette.css' // YOUR THEME'S PALETTE
  </script>

  <template>
    <FullCalendar
      :options="{
        plugins: [
+         themePlugin,
          // other plugins here...
        ],
      }"
    />
  </template>
```


## Angular

### Angular Standard Packages

**Breaking:** dependency changes:

- The `@fullcalendar/core` peer dependency has been renamed `fullcalendar`
- `@fullcalendar/daygrid` and many other packages removed and moved to `@fullcalendar/angular/*` entrypoints (see `package.json` below)
- `temporal-polyfill` added as a peer dependency

1) So, your `package.json` should be modified:

```diff
{
  "dependencies": {
-   "@fullcalendar/angular": "^6.1.20",
+   "@fullcalendar/angular": "7.0.0",
-   "@fullcalendar/core": "^6.1.20",
-   "@fullcalendar/interaction": "^6.1.20",
-   "@fullcalendar/daygrid": "^6.1.20",
-   "@fullcalendar/timegrid": "^6.1.20",
-   "@fullcalendar/list": "^6.1.20",
-   "@fullcalendar/multimonth": "^6.1.20"
  }
}
```

2) Then install the two additional peer dependencies:

```bash
npm install --save fullcalendar@7 temporal-polyfill
```

3) In your JS, change your imports:

```diff
  import interactionPlugin
-   from '@fullcalendar/interaction'
+   from '@fullcalendar/angular/interaction'
  import dayGridPlugin
-   from '@fullcalendar/daygrid'
+   from '@fullcalendar/angular/daygrid'
  import timeGridPlugin
-   from '@fullcalendar/timegrid'
+   from '@fullcalendar/angular/timegrid'
  import listPlugin
-   from '@fullcalendar/list'
+   from '@fullcalendar/angular/list'
  import multiMonthPlugin
-   from '@fullcalendar/multimonth'
+   from '@fullcalendar/angular/multimonth'
```

### Angular Scheduler Packages

**Breaking:** additional dependency changes for premium (aka "scheduler"):

1) Remove the following packages from your `package.json`:

```diff
{
  "dependencies": {
    "@fullcalendar/angular": "7.0.0",
    "fullcalendar": "7.0.0",
    ...
-   "@fullcalendar/resource": "^6.1.20",
-   "@fullcalendar/adaptive": "^6.1.20",
-   "@fullcalendar/scrollgrid": "^6.1.20",
-   "@fullcalendar/timeline": "^6.1.20",
-   "@fullcalendar/resource-timeline": "^6.1.20",
-   "@fullcalendar/resource-timegrid": "^6.1.20",
-   "@fullcalendar/resource-daygrid": "^6.1.20"
  }
}
```

2) Install the `@fullcalendar/angular-scheduler` package:

```bash
npm install --save @fullcalendar/angular-scheduler@7
```

3) In your JS, change your imports:

```diff
  import resourcePlugin
-   from '@fullcalendar/resource'
+   from '@fullcalendar/angular-scheduler'
  import adaptivePlugin
-   from '@fullcalendar/adaptive'
+   from '@fullcalendar/angular-scheduler/adaptive'
  import scrollGridPlugin
-   from '@fullcalendar/scrollgrid'
+   from '@fullcalendar/angular-scheduler/scrollgrid'
  import timelinePlugin
-   from '@fullcalendar/timeline'
+   from '@fullcalendar/angular-scheduler/timeline'
  import resourceTimelinePlugin
-   from '@fullcalendar/resource-timeline'
+   from '@fullcalendar/angular-scheduler/resource-timeline'
  import resourceTimeGridPlugin
-   from '@fullcalendar/resource-timegrid'
+   from '@fullcalendar/angular-scheduler/resource-timegrid'
  import resourceDayGridPlugin
-   from '@fullcalendar/resource-daygrid'
+   from '@fullcalendar/angular-scheduler/resource-daygrid'
```

**Breaking**: FullCalendar no longer bundles its own CSS. Furthermore, the calendar "theme" has been pulled out from the core, as a plugin. Thus, you must import your own stylesheets. This depends on what theme you choose (see [themes.fullcalendar.io](https://themes.fullcalendar.io)):

```diff
  import { FullCalendarModule } from '@fullcalendar/angular';
  import { FullCalendarModule, CalendarOptions } from '@fullcalendar/angular';
+ import themePlugin from '@fullcalendar/angular/themes/classic'; // YOUR THEME
  // import other plugins...

  export class App {
    calendarOptions = signal<CalendarOptions>({
      plugins: [
+       themePlugin,
        // other plugins here...
      ],
    })
```

Add the following stylesheets to your `angular.json`:

```diff
  {
    "projects": {        // ...
      "my-project": {    // ...
        "architect": {   // ...
          "build": {     // ...
            "options": { // ...
              "styles": [
+               "@fullcalendar/angular/skeleton.css", // ALWAYS NEED SKELETON
+               "@fullcalendar/angular/themes/classic/theme.css", // YOUR THEME
+               "@fullcalendar/angular/themes/classic/palette.css", // YOUR THEME'S PALETTE
                "src/styles.css"
              ]
```


## Vanilla JS

### Vanilla JS Standard Packages

**Breaking:** dependency changes:

- Vanilla JS package `@fullcalendar/core` renamed to `fullcalendar`
- `@fullcalendar/daygrid` and many other packages removed and moved to `fullcalendar/*` entrypoints (see `package.json` below)
- `temporal-polyfill` added as a peer dependency

1) So, your `package.json` should be modified:

```diff
{
  "dependencies": {
-   "@fullcalendar/core": "^6.1.20",
-   "@fullcalendar/interaction": "^6.1.20",
-   "@fullcalendar/daygrid": "^6.1.20",
-   "@fullcalendar/timegrid": "^6.1.20",
-   "@fullcalendar/list": "^6.1.20",
-   "@fullcalendar/multimonth": "^6.1.20"
  }
}
```

2) Then install the renamed vanilla JS connector and `temporal-polyfill`:

```bash
npm install --save fullcalendar@7 temporal-polyfill
```

3) In your JS, change your imports:

```diff
  import interactionPlugin
-   from '@fullcalendar/interaction'
+   from 'fullcalendar/interaction' // no @ at the beginning!
  import dayGridPlugin
-   from '@fullcalendar/daygrid'
+   from 'fullcalendar/daygrid' // no @ at the beginning!
  import timeGridPlugin
-   from '@fullcalendar/timegrid'
+   from 'fullcalendar/timegrid' // no @ at the beginning!
  import listPlugin
-   from '@fullcalendar/list'
+   from 'fullcalendar/list' // no @ at the beginning!
  import multiMonthPlugin
-   from '@fullcalendar/multimonth'
+   from 'fullcalendar/multimonth' // no @ at the beginning!
```

### Vanilla JS Scheduler Packages

**Breaking:** additional dependency changes for premium (aka "scheduler"):

1) Remove the following packages from your `package.json`:

```diff
{
  "dependencies": {
    "fullcalendar": "7.0.0",
    ...
-   "@fullcalendar/resource": "^6.1.20",
-   "@fullcalendar/adaptive": "^6.1.20",
-   "@fullcalendar/scrollgrid": "^6.1.20",
-   "@fullcalendar/timeline": "^6.1.20",
-   "@fullcalendar/resource-timeline": "^6.1.20",
-   "@fullcalendar/resource-timegrid": "^6.1.20",
-   "@fullcalendar/resource-daygrid": "^6.1.20"
  }
}
```

2) Install the `fullcalendar-scheduler` package:

```bash
npm install --save fullcalendar-scheduler@7
```

3) In your JS, change your imports:

```diff
  import resourcePlugin
-   from '@fullcalendar/resource'
+   from 'fullcalendar-scheduler'
  import adaptivePlugin
-   from '@fullcalendar/adaptive'
+   from 'fullcalendar-scheduler/adaptive'
  import scrollGridPlugin
-   from '@fullcalendar/scrollgrid'
+   from 'fullcalendar-scheduler/scrollgrid'
  import timelinePlugin
-   from '@fullcalendar/timeline'
+   from 'fullcalendar-scheduler/timeline'
  import resourceTimelinePlugin
-   from '@fullcalendar/resource-timeline'
+   from 'fullcalendar-scheduler/resource-timeline'
  import resourceTimeGridPlugin
-   from '@fullcalendar/resource-timegrid'
+   from 'fullcalendar-scheduler/resource-timegrid'
  import resourceDayGridPlugin
-   from '@fullcalendar/resource-daygrid'
+   from 'fullcalendar-scheduler/resource-daygrid'
```

**Breaking**: FullCalendar no longer bundles its own CSS. Furthermore, the calendar "theme" has been pulled out from the core, as a plugin. Thus, you must import your own stylesheets. This depends on what theme you choose (see [themes.fullcalendar.io](https://themes.fullcalendar.io)):

```diff
- import { Calendar } from '@fullcalendar/core'
+ import { Calendar } from 'fullcalendar'
+ import themePlugin from 'fullcalendar/themes/classic' // YOUR THEME
  // import other plugins...

  // stylesheets
+ import 'fullcalendar/skeleton.css'
+ import 'fullcalendar/themes/classic/theme.css' // YOUR THEME
+ import 'fullcalendar/themes/classic/palette.css' // YOUR THEME'S PALETTE

  const calendarEl = document.getElementById('calendar')
  const calendar = new Calendar(calendarEl, {
    plugins: [
+     themePlugin,
      // other plugins here...
    ],
  })
  calendar.render()
```

### Global Script Tags

**Breaking:** `index.global.js` renamed to `all/global.js` (which contains "all" standard plugins), and additional scripts/stylesheets must be added for the theme:

```diff
  <!-- STANDARD JS -->
- <script src='https://cdn.jsdelivr.net/npm/fullcalendar@6.1.20/index.global.js'></script>
+ <script src='https://cdn.jsdelivr.net/npm/fullcalendar@7.0.0/all/global.js'></script>

  <!-- THEME JS -->
+ <script src='https://cdn.jsdelivr.net/npm/fullcalendar@7.0.0/themes/classic/global.js'></script>

  <!-- STYLESHEETS -->
+ <link href='https://cdn.jsdelivr.net/npm/fullcalendar@7.0.0/skeleton.css' rel='stylesheet' />
+ <link href='https://cdn.jsdelivr.net/npm/fullcalendar@7.0.0/themes/classic/theme.css' rel='stylesheet' />
+ <link href='https://cdn.jsdelivr.net/npm/fullcalendar@7.0.0/themes/classic/palette.css' rel='stylesheet' />
```

**Breaking:** Similar breaking changes for scheduler, but with an additional one: scheduler's JS file *no longer contains the standard plugins*, so both standard and premium `all/global.js` files must be included:

```diff
  <!-- STANDARD + SCHEDULER JS -->
- <script src='https://cdn.jsdelivr.net/npm/fullcalendar-scheduler@6.1.20/index.global.js'></script>
+ <script src='https://cdn.jsdelivr.net/npm/fullcalendar@7.0.0/all/global.js'></script>
+ <script src='https://cdn.jsdelivr.net/npm/fullcalendar-scheduler@7.0.0/all/global.js'></script>

  <!-- THEME JS -->
+ <script src='https://cdn.jsdelivr.net/npm/fullcalendar@7.0.0/themes/classic/global.js'></script>

  <!-- STYLESHEETS -->
+ <link href='https://cdn.jsdelivr.net/npm/fullcalendar@7.0.0/skeleton.css' rel='stylesheet' />
+ <link href='https://cdn.jsdelivr.net/npm/fullcalendar@7.0.0/themes/classic/theme.css' rel='stylesheet' />
+ <link href='https://cdn.jsdelivr.net/npm/fullcalendar@7.0.0/themes/classic/palette.css' rel='stylesheet' />
```


## Web Component

### Web Component Standard Packages

**Breaking:** dependency changes:

- `@fullcalendar/core` removed as a peer dependency
- `@fullcalendar/daygrid` and many other packages removed (see `package.json` below)
- `temporal-polyfill` added as a peer dependency

1) So, your `package.json` should be modified:

```diff
{
  "dependencies": {
-   "@fullcalendar/web-component": "^6.1.20",
+   "@fullcalendar/web-component": "7.0.0",
-   "@fullcalendar/core": "^6.1.20",
-   "@fullcalendar/interaction": "^6.1.20",
-   "@fullcalendar/daygrid": "^6.1.20",
-   "@fullcalendar/timegrid": "^6.1.20",
-   "@fullcalendar/list": "^6.1.20",
-   "@fullcalendar/multimonth": "^6.1.20"
  }
}
```

2) Then install the upgraded web-component connector and `temporal-polyfill`:

```bash
npm install --save @fullcalendar/web-component@7 temporal-polyfill
```

3) In your JS, change your imports:

```diff
  import interactionPlugin
-   from '@fullcalendar/interaction'
+   from '@fullcalendar/web-component/interaction'
  import dayGridPlugin
-   from '@fullcalendar/daygrid'
+   from '@fullcalendar/web-component/daygrid'
  import timeGridPlugin
-   from '@fullcalendar/timegrid'
+   from '@fullcalendar/web-component/timegrid'
  import listPlugin
-   from '@fullcalendar/list'
+   from '@fullcalendar/web-component/list'
  import multiMonthPlugin
-   from '@fullcalendar/multimonth'
+   from '@fullcalendar/web-component/multimonth'
```

### Web Component Scheduler Packages

**Breaking:** additional dependency changes for premium (aka "scheduler"):

1) Remove the following packages from your `package.json`:

```diff
{
  "dependencies": {
    "@fullcalendar/web-component": "7.0.0",
    ...
-   "@fullcalendar/resource": "^6.1.20",
-   "@fullcalendar/adaptive": "^6.1.20",
-   "@fullcalendar/scrollgrid": "^6.1.20",
-   "@fullcalendar/timeline": "^6.1.20",
-   "@fullcalendar/resource-timeline": "^6.1.20",
-   "@fullcalendar/resource-timegrid": "^6.1.20",
-   "@fullcalendar/resource-daygrid": "^6.1.20"
  }
}
```

2) Install the `@fullcalendar/web-component-scheduler` package:

```bash
npm install --save @fullcalendar/web-component-scheduler@7
```

3) In your JS, change your imports:

```diff
  import resourcePlugin
-   from '@fullcalendar/resource'
+   from '@fullcalendar/web-component-scheduler'
  import adaptivePlugin
-   from '@fullcalendar/adaptive'
+   from '@fullcalendar/web-component-scheduler/adaptive'
  import scrollGridPlugin
-   from '@fullcalendar/scrollgrid'
+   from '@fullcalendar/web-component-scheduler/scrollgrid'
  import timelinePlugin
-   from '@fullcalendar/timeline'
+   from '@fullcalendar/web-component-scheduler/timeline'
  import resourceTimelinePlugin
-   from '@fullcalendar/resource-timeline'
+   from '@fullcalendar/web-component-scheduler/resource-timeline'
  import resourceTimeGridPlugin
-   from '@fullcalendar/resource-timegrid'
+   from '@fullcalendar/web-component-scheduler/resource-timegrid'
  import resourceDayGridPlugin
-   from '@fullcalendar/resource-daygrid'
+   from '@fullcalendar/web-component-scheduler/resource-daygrid'
```

**Breaking**: FullCalendar no longer bundles its own CSS. Furthermore, the calendar "theme" has been pulled out from the core, as a plugin. Thus, you must import your own stylesheets. This depends on what theme you choose (see [themes.fullcalendar.io](https://themes.fullcalendar.io)):

```diff
  import '@fullcalendar/web-component/global'
+ import themePlugin from '@fullcalendar/web-component/themes/classic'
  // import other plugins...

  // stylesheets
+ import '@fullcalendar/web-component/skeleton.styles'
+ import '@fullcalendar/web-component/themes/classic/theme.styles'
+ import '@fullcalendar/web-component/themes/classic/palette.css'

  const fullCalendarElement = document.querySelector('full-calendar')
  fullCalendarElement.options = {
    plugins: [
+     themePlugin,
      // other plugins here...
    ]
  }
```

```html
<!-- HTML -->
<full-calendar></full-calendar>
```

### Global Script Tags

**Breaking:** `index.global.js` renamed to `all/global.js` (which contains "all" standard plugins), and additional scripts/stylesheets must be added for the theme:

```diff
  <!-- STANDARD JS -->
- <script src='https://cdn.jsdelivr.net/npm/@fullcalendar/core@6.1.20/index.global.js'></script>
- <script src='https://cdn.jsdelivr.net/npm/@fullcalendar/web-component@6.1.20/index.global.js'></script>
+ <script src='https://cdn.jsdelivr.net/npm/@fullcalendar/web-component@7.0.0/all/global.js'></script>

  <!-- THEME JS -->
+ <script src='https://cdn.jsdelivr.net/npm/@fullcalendar/web-component@7.0.0/themes/classic/global.js'></script>

  <!-- STYLESHEETS -->
+ <script src='https://cdn.jsdelivr.net/npm/@fullcalendar/web-component@7.0.0/skeleton.styles.js'></script>
+ <script src='https://cdn.jsdelivr.net/npm/@fullcalendar/web-component@7.0.0/themes/classic/theme.styles.js'></script>
+ <link href='https://cdn.jsdelivr.net/npm/@fullcalendar/web-component@7.0.0/themes/classic/palette.css' rel='stylesheet' />
```

Please note, `skeleton.styles.js` and `theme.styles.js` are `<script>` tags, and yes they do inject CSS. This is required for the web component's shadow DOM.

**Breaking:** Similar breaking changes for scheduler, but with an additional one: scheduler's JS file *no longer contains the standard plugins*, so both standard and premium `all/global.js` files must be included:

```diff
  <!-- STANDARD + SCHEDULER JS -->
- <script src='https://cdn.jsdelivr.net/npm/@fullcalendar/web-component-scheduler@6.1.20/index.global.js'></script>
+ <script src='https://cdn.jsdelivr.net/npm/@fullcalendar/web-component@7.0.0/all/global.js'></script>
+ <script src='https://cdn.jsdelivr.net/npm/@fullcalendar/web-component-scheduler@7.0.0/all/global.js'></script>

  <!-- THEME JS -->
+ <script src='https://cdn.jsdelivr.net/npm/@fullcalendar/web-component@7.0.0/themes/classic/global.js'></script>

  <!-- STYLESHEETS -->
+ <script src='https://cdn.jsdelivr.net/npm/@fullcalendar/web-component@7.0.0/skeleton.styles.js'></script>
+ <script src='https://cdn.jsdelivr.net/npm/@fullcalendar/web-component@7.0.0/themes/classic/theme.styles.js'></script>
+ <link href='https://cdn.jsdelivr.net/npm/@fullcalendar/web-component@7.0.0/themes/classic/palette.css' rel='stylesheet' />
```


## Toolbar

**Breaking:** `headerToolbar` is now disabled by default. It no longer shows the title and buttons by default. If you have no `headerToolbar` specified and want to restore:

```diff
  <FullCalendar
+   headerToolbar={{
+     start: 'title',
+     end: 'today prev,next',
+   }}
  />
```

**Breaking:** `customButtons` renamed to `buttons` (used for custom *and* standard buttons). `buttonText` removed in favor of `buttons[].text`:

```diff
  <FullCalendar
-   buttonText={{
-     hello: 'Hello Button' // for custom button
-     week: 'Week View Button' // vague week-view reference
-   }}

-   customButtons={{
+   buttons={{
      hello: { // a custom button
+       text: 'Hello'
        click() {
          alert('hello!')
        }
      },
      // view buttons. view names must match exactly now
+     dayGridWeek: { text: 'Week View Button' },
+     timeGridWeek: { text: 'Week View Button' }
    }}
  />
```

**Breaking:** `buttonIcons` removed. Attach a custom class-name and associated glyphicon with `buttons[].iconClass`:

```diff
  <FullCalendar
-   buttonIcons={{
-     next: 'my-button-icon'
-   }}
+   buttons={{
+     next: {
+       iconClass: 'my-button-icon'
+     }
+   }}
  />
```

However, SVGs are now preferred over glyphicons, and can be attached with `buttons[].iconContent` ([more info](buttons.md)).

**Type changes:** each entry of the `buttons` map:

```diff
- import { type CustomButtonInput } from '@fullcalendar/core'
+ import { type ButtonInput } from '@fullcalendar/react' // or angular/vue3/etc
```

**Type changes:** The parameter given to the button callbacks has changed:

```diff
- import { type ButtonContentArg, type ButtonMountArg } from '@fullcalendar/core'
+ import { type ButtonInfo, type MountInfo } from '@fullcalendar/react' // or angular/vue3/etc
+ // use MountInfo<ButtonInfo>
```


## Events (General)

The changes here apply to events in all views.

**Breaking:** All class-name properties have been renamed and only accept simple string:

```diff
  <FullCalendar
    // calendar-wide
-   eventClassNames={['my-event', 'my-util']}
+   eventClass='my-event my-util'

    // event-specific
    events={[
      title: 'My Event',
      start: '2026-02-02',
-     classNames: ['my-event', 'my-util']
+     className: 'my-event my-util'
    ]}

    // by event-source
    eventSources={[
      {
        url: '/my-feed.php',
-       classNames: ['my-event', 'my-util']
+       className: 'my-event my-util'
      }
    ]}

    // by resource
    resources={[
      {
        id: 'a',
-       eventClassNames: ['my-event', 'my-util']
+       eventClass: 'my-event my-util'
      }
    ]}
  />

  // via Event API
  const event = calendarApi.getEventById('a')
- event.classNames // array of strings
+ event.className // string

  // via Resource API
  const resource = calendarApi.getResourceById('b')
- resource.eventClassNames // array of string
+ resource.eventClass // string
```

**Breaking:** `eventClass` (formerly `eventClassNames`), `eventContent`, `eventDidMount`, `eventWillUnmount` *no longer apply to background events*. If you intentially styled ALL types of events using `eventClass`, and want to restore that behavior in v7, do this:

```diff
  <FullCalendar
    eventClass='all-events'
+   backgroundEventClass='all-events'
  />
```

**Breaking:** In v6, event color customization would affect literal parts of the element (border, background, text). In v7, the properties are more semantic and the individual theme can decide what to do with them.

```diff
  <FullCalendar
    // calendar-wide
-   eventBackgroundColor='red' // these can no longer be set separately...
-   eventBorderColor='red'     // ...use eventColor instead...
    eventColor='red'
-   eventTextColor='white'
+   eventContrastColor='white'

    // event-specific
    events={[
      {
        title: 'My Event',
        start: '2026-02-02',
-       backgroundColor: 'red',
-       borderColor: 'red',
        color: 'red',
-       textColor: 'white',
+       contrastColor: 'white',
      }
    ]}

    // by event-source
    eventSources={[
      {
        url: '/my-feed.php',
-       backgroundColor: 'red',
-       borderColor: 'red',
        color: 'red',
-       textColor: 'white',
+       contrastColor: 'white',
      }
    ]}

    // by resource
    resources={[
      {
        id: 'a',
-       eventBackgroundColor: 'red',
-       eventBorderColor: 'red',
        eventColor: 'red',
-       eventTextColor: 'white',
+       eventContrastColor: 'white',
      }
    ]}
  />

  // via Event API
  const event = calendarApi.getEventById('a')
- event.backgroundColor
- event.borderColor
+ event.color
- event.textColor
+ event.contrastColor

  // via Resource API
  const resource = calendarApi.getResourceById('b')
- resource.eventBackgroundColor
- resource.eventBorderColor
+ resource.eventColor
- resource.eventTextColor
+ resource.eventContrastColor
```

If you've customized the classic theme to have events with border colors that are DIFFERENT than their background colors, and want to maintain that look in v7, you'll need to fork the theme.

**Type changes:** The parameter passed to `eventClass` (formerly `eventClassNames`), `eventContent`, `eventDidMount`, and `eventWillUnmount` has changed:

```diff
- import { type EventContentArg, type EventMountArg } from '@fullcalendar/core'
+ import { type EventDisplayInfo, type MountInfo } from '@fullcalendar/react' // or angular/vue3/etc
+ // use MountInfo<EventDisplayInfo>
```

**Breaking:** Event API's `.toPlainObject()` and `.toJSON()` methods have modified signatures and return types:

```diff
  const res = event.toPlainObject({ // or .toJSON()
-   collapseColor: true
  })

- res.classNames // array of strings
+ res.className // string

- res.backgroundColor
- res.borderColor
+ res.color

- res.textColor
+ res.contrastColor
```


## Resources (General)

**Breaking:** The generic `resourceLabel*` settings have been replaced with more UI-specific settings. Class-name settings now use simple strings instead of arrays:

- [Resource Day Header](#resource-day-header) for **Resource DayGrid** and **Resource TimeGrid** views
- [Resource Cell](#resource-cell) for **Resource Timeline** view

**Breaking:** Resource API's `.toPlainObject()` and `.toJSON()` methods have modified signatures and return types:

```diff
  const res = event.toPlainObject({ // or .toJSON()
-   collapseColor: true
  })

- res.eventClassNames // array of strings
+ res.eventClass // string

- res.eventBackgroundColor
- res.eventBorderColor
+ res.eventColor

- res.eventTextColor
+ res.eventContrastColor
```


## Calendar Views (General)

The follow changes apply to all calendar views.


### Root Element

**Breaking:** `viewClassNames` renamed and accepts only a simple string:

```diff
  <FullCalendar
-   viewClassNames={['my-view', 'my-util']}
+   viewClass='my-view my-util'
  />
```

**Types change:** The parameter given to all `view*` callbacks has changed:

```diff
- import { type ViewContentArg, type ViewMountArg } from '@fullcalendar/core'
+ import { type ViewDisplayInfo, type MountInfo } from '@fullcalendar/react' // or angular/vue3/etc
+ // use MountInfo<ViewDisplayInfo>
```

### Nav-Links

**Breaking:** `navLinkClassNames` rename and accepts only a simple string:

```diff
  <FullCalendar
-   navLinkClassNames={['my-nav-link', 'my-util']}
+   navLinkClass='my-nav-link my-util'
  />
```

### More-Links

**Breaking:** `moreLinkClassNames` rename and accepts only a simple string:

```diff
  <FullCalendar
-   moreLinkClassNames={['my-more-link', 'my-util']}
+   moreLinkClass='my-more-link my-util'
  />
```

**Types change:** The parameter given to all `moreLink*` callbacks has changed:

```diff
- import { type MoreLinkContentArg, type MoreLinkMountArg } from '@fullcalendar/core'
+ import { type MoreLinkInfo, type MountInfo } from '@fullcalendar/react' // or angular/vue3/etc
+ // use MountInfo<MoreLinkInfo>
```

### Week Number

**Breaking:** The generic `weekNumber*` settings have been replaced with more UI-specific settings. Class-name settings now use simple strings instead of arrays:

- [Inline Week Number](#inline-week-number) for **DayGrid** view
- [Week Number Header](#week-number-header) for **TimeGrid** view


### All-Day

**Breaking:** The generic `allDay*` settings have been replaced with more UI-specific settings. Class-name settings now use simple strings instead of arrays:

- [All-Day Header](#all-day-header) for **TimeGrid** view
- [All-Day Text on Events](#all-day-text-on-events) for **List** view


### Time Slot Header

Time slots are present in [TimeGrid View](#timegrid-view) and [Timeline View](#timegrid-view). The changes here apply to both views.

**Breaking**: slot "label" settings have been renamed to slot "header". Also, class-names must be simple strings:

```diff
<FullCalendar
- slotLabelClassNames={['my-slot', 'my-util']}
+ slotHeaderClass='my-slot my-util'

- slotLabelContent={(data) => <span>{data.text}</span>}
+ slotHeaderContent={(data) => <span>{data.text}</span>}

- slotLabelDidMount={(data) => { /* handler */ }}
+ slotHeaderDidMount={(data) => { /* handler */ }}

- slotLabelWillUnmount={(data) => { /* handler */ }}
+ slotHeaderWillUnmount={(data) => { /* handler */ }}

- slotLabelInterval='01:00'
+ slotHeaderInterval='01:00'

- slotLabelFormat={{ hour: 'numeric', minute: '2-digit' }}
+ slotHeaderFormat={{ hour: 'numeric', minute: '2-digit' }}
/>
```

**Type changes:**  The parameter given to the callbacks has changed:

```diff
- import { type SlotLabelContentArg, type SlotLabelMountArg } from '@fullcalendar/core'
+ import { type SlotHeaderInfo, type MountInfo } from '@fullcalendar/react' // or angular/vue3/etc
+ // use MountInfo<SlotHeaderInfo>
```

### Time Slot Lane

Time slots are present in [TimeGrid View](#timegrid-view) and [Timeline View](#timegrid-view). The changes here apply to both views.

**Breaking:** the `slotLaneClassNames` setting renamed. Must be a simple string. `slotLaneContent` removed:

```diff
<FullCalendar
- slotLaneClassNames={['my-slot', 'my-util']}
+ slotLaneClass='my-slot my-util'

  // NO REPLACEMENT - lane inner-content can no longer be customized
- slotLaneContent={(data) => <span>...</span>}
/>
```

**Type changes:** The parameter given to the `slotLane*` callbacks has changed:

```diff
- import { type SlotLaneContentArg, type SlotLaneMountArg } from '@fullcalendar/core'
+ import { type SlotLaneInfo, type MountInfo } from '@fullcalendar/react' // or angular/vue3/etc
+ // use MountInfo<SlotLaneInfo>
```


### Now-Indicator

A now-indicator is present in [TimeGrid View](#timegrid-view) and [Timeline View](#timegrid-view). The changes here apply to both views.

**Breaking:** in v6, the `nowIndicator*` settings represented BOTH the "arrow", which appeared in the time axis, and the "line", which appeared over a day. One would differentiate based on `data.isAxis` (now removed). In v7, there are distinct settings for each:

<div class='diff-code-2col' markdown='1'>
<div>

```diff
<FullCalendar
- nowIndicatorClassNames={(data) => (
-   data.isAxis
-     ? ['my-arrow', 'my-util']
-     : ['my-line', 'my-util']
- )}

- nowIndicatorContent={(data) => (
-   data.isAxis
-     ? <span>the axis content</span>
-     : <span>the line content</span>
- )}

- nowIndicatorDidMount={(data) => {
-   if (data.isAxis) {
-     // for axis
-   } else {
-     // for line
-   }
- }}

- nowIndicatorWillUnmount={(data) => {
-   if (data.isAxis) {
-     // for axis
-   } else {
-     // for line
-   }
- }}
/>
```

</div>
<div>

```diff
<FullCalendar

+  nowIndicatorHeaderClass='my-arrow my-util'
+  nowIndicatorLineClass='my-line my-util'


+ nowIndicatorHeaderContent={(data) => (
+   <span>the axis content</span>
+ )}
+ nowIndicatorLineContent={(data) => (
+   <span>the line content</span>
+ )}


+ nowIndicatorHeaderDidMount={(data) => {
+   // for axis
+ }}
+ nowIndicatorLineDidMount={(data) => {
+   // for line
+ }}


+ nowIndicatorHeaderWillUnmount={(data) => {
+   // for axis
+ }}
+ nowIndicatorLineWillUnmount={(data) => {
+   // for line
+ }}
/>
```

</div>
</div>

**Type changes:** The parameter given to the callbacks has also been split in two:

```diff
- import { NowIndicatorContentArg, NowIndicatorMountArg } from '@fullcalendar/core'

// for axis
+ import { NowIndicatorHeaderInfo, MountInfo } from '@fullcalendar/react' // or angular/vue3/etc
+ // use MountInfo<NowIndicatorHeaderInfo>

// for line
+ import { NowIndicatorLineInfo } from '@fullcalendar/react' // or angular/vue3/etc
+ // use MountInfo<NowIndicatorLineInfo>
```


## DayGrid View

Includes changes from:
- [Calendar Views (General)](#calendar-views-general)
- [Events (General)](#events-general)

### Day Header

**Breaking:** `dayHeaderClassNames` renamed and accepts only a simple string. Can no longer do horizontal alignment:

```diff
<FullCalendar
- dayHeaderClassNames={['my-header', 'my-util']}
+ dayHeaderClass='my-header my-util'
+ dayHeaderAlign='start' // horizontal alignment (in LTR, 'start' means left)
/>

/* in CSS */
.my-header {
- text-align: left; /* horizontal alignment */
}
```

The `dayHeader*` settings now apply to the popover header, which is usually desirable. See [Popover CSS migration docs](upgrading-from-v6-css.md#popover).

<strong id='day-header-classic-bold'>Breaking (Classic Theme):</strong> The day-headers are no longer bold by default. To restore:

```diff
<FullCalendar
+ dayHeaderClass='my-day-header'
/>

/* CSS */
+ .my-day-header {
+   font-weight: bold;
+ }
```

**Types change:** The parameter given to all `dayHeader*` callbacks has changed:

```diff
- import { type DayHeaderContentArg, type DayHeaderMountArg } from '@fullcalendar/core'
+ import { type DayHeaderInfo, type MountInfo } from '@fullcalendar/react' // or angular/vue3/etc
+ // use MountInfo<DayHeaderInfo>
```

### Day Cell

**Breaking:** `dayCellClassNames` renamed and accepts only a simple string. `dayCellContent` renamed:

```diff
<FullCalendar
- dayCellClassNames={['my-cell', 'my-util']}
+ dayCellClass='my-cell my-util'

- dayCellContent={(data) => (
+ dayCellTopContent={(data) => (
    <span>In place of day-number</span>
  )}
/>
```

The `dayCell*` settings now apply to the popover body, which is usually desirable. See [Popover CSS migration docs](upgrading-from-v6-css.md#popover).

The `dayCell*` settings previously applied to [TimeGrid Day Lane](#day-lane), but no longer.

**Types change:** The parameter given to all `dayCell*` callbacks has changed:

```diff
- import { type DayCellContentArg, type DayCellMountArg } from '@fullcalendar/core'
+ import { type DayCellInfo, type MountInfo } from '@fullcalendar/react' // or angular/vue3/etc
+ // use MountInfo<DayCellInfo>
```

### Inline Week Number

**Breaking:** Week numbers, as they render in a DayGrid, are now called "inline week numbers" because they rest within the cells, not as a separate column. Thus, they have been renamed. You can configure them as top-level settings, and class-name settings must be simple strings:

```diff
<FullCalendar
- views={{
-   dayGrid: {
-     weekNumberClassNames: ['my-week-number', 'my-util']
-     weekNumberContent: (data) => <span>{data.text}</span>
-     weekNumberDidMount: (data) => { /* handler */ }
-     weekNumberWillUnmount: (data) => { /* handler */ }
-   }
- }}
+ inlineWeekNumberClass='my-week-number my-util'
+ inlineWeekNumberContent={(data) => <span>{data.text}</span>}
+ inlineWeekNumberDidMount={(data) => { /* handler */ }}
+ inlineWeekNumberWillUnmount={(data) => { /* handler */ }}
/>
```

**Type changes:** The parameter given to these callbacks has changed:

```diff
- import { type WeekNumberContentArg, type WeekNumberMountArg } from '@fullcalendar/core'
+ import { type InlineWeekNumberInfo, type MountInfo } from '@fullcalendar/react' // or angular/vue3/etc
+ // use MountInfo<InlineWeekNumberInfo>
```

### Events

<strong id='event-inner-and-dot'>Breaking:</strong> In v6, for list-item events in DayGrid view, the content generated <code>eventContent</code> would clear rendering of the colored dot. In v7, <code>eventContent</code> injects into the "inner" container (aka <code>eventInnerClass</code>) which does not wrap the dot (aka <code>eventBeforeClass</code>). To restore old behavior:

```diff
  <FullCalendar
    eventContent={(info) => <span>Cool {info.event.title}</span>}
    views={{
+     dayGrid: { listItemEventBeforeClass: 'display-none' },
+     timeGrid: { listItemEventBeforeClass: 'display-none' }
    }}
  />

/* in CSS */
+ .display-none { display: none }
```

## Resource DayGrid View

Includes changes from:
- [Calendar Views (General)](#calendar-views-general)
- [Events (General)](#events-general)
- [DayGrid View](#daygrid-view)

### Resource Day Header

**Breaking:** "Resource labels", as they render in DayGrid and TimeGrid, are now called "resource day headers". You can configure them as top-level settings, and class-name settings must be simple strings:

```diff
<FullCalendar
- views={{
-   resourceDayGrid: { // OR resourceTimeGrid
-     resourceLabelClassNames: ['my-header', 'my-util'],
-     resourceLabelContent: (data) => <span>{data.text}</span>,
-     resourceLabelDidMount: (data) => { /* handler */ },
-     resourceLabelWillUnmount: (data) => { /* handler */ },
-   }
- }}
+ resourceDayHeaderClass='my-header my-util'
+ resourceDayHeaderAlign='start' // horizontal alignment (in LTR, 'start' means left)
+ resourceDayHeaderContent={(data) => <span>{data.text}</span>}
+ resourceDayHeaderDidMount={(data) => { /* handler */ }}
+ resourceDayHeaderWillUnmount={(data) => { /* handler */ }}
/>

/* in CSS */
.my-header {
- text-align: left; /* horizontal alignment */
}
```

**Type changes:** The parameter given to these callbacks has changed:

```diff
- import { type ResourceLabelContentArg, type ResourceLabelMountArg } from '@fullcalendar/core'
+ import { type ResourceDayHeaderInfo, type MountInfo } from '@fullcalendar/react' // or angular/vue3/etc
+ // use MountInfo<ResourceDayHeaderInfo>
```


## TimeGrid View

Includes changes from:
- [Calendar Views (General)](#calendar-views-general)
- [Events (General)](#events-general)
- [DayGrid View](#daygrid-view) - for "day headers" and all-day "day cells"

### Week Number Header

**Breaking:** Week numbers, as they render in a TimeGrid, are now called "week number headers" because they're located in the header of the view, above the time axis. They have been renamed and can be configured as top-level settings, and class-name settings must be simple strings:

```diff
<FullCalendar
- views={{
-   timeGrid: {
-     weekNumberClassNames: ['my-week-header', 'my-util']
-     weekNumberContent: (data) => <span>{data.text}</span>
-     weekNumberDidMount: (data) => { /* handler */ }
-     weekNumberWillUnmount: (data) => { /* handler */ }
-   }
- }}
+ weekNumberHeaderClass='my-week-header my-util'
+ weekNumberHeaderContent={(data) => <span>{data.text}</span>}
+ weekNumberHeaderDidMount={(data) => { /* handler */ }}
+ weekNumberHeaderWillUnmount={(data) => { /* handler */ }}
/>
```

**Type changes:** The parameter given to these callbacks has changed:

```diff
- import { type WeekNumberContentArg, type WeekNumberMountArg } from '@fullcalendar/core'
+ import { type WeekNumberHeaderInfo, type MountInfo } from '@fullcalendar/react' // or angular/vue3/etc
+ // use MountInfo<WeekNumberHeaderInfo>
```

### All-Day Header

**Breaking:** The cell labeling the all-day section has been renamed to "all day header". Class-name settings must be simple strings:

```diff
<FullCalendar
- views={{
-   timeGrid: {
-     allDayClassNames: ['my-all-day', 'my-util'],
-     allDayContent: (data) => <span>{data.text}</span>,
-     allDayDidMount: (data) => { /* handler */ },
-     allDayWillUnmount: (data) => { /* handler */ },
-   }
- }}
+ allDayHeaderClass='my-all-day my-util'
+ allDayHeaderContent={(data) => <span>{data.text}</span>}
+ allDayHeaderDidMount={(data) => { /* handler */ }}
+ allDayHeaderWillUnmount={(data) => { /* handler */ }}
/>
```

**Type changes:** The parameter given to these callbacks has changed:

```diff
- import { type AllDayContentArg, type AllDayMountArg } from '@fullcalendar/core'
+ import { type AllDayHeaderInfo, type MountInfo } from '@fullcalendar/react' // or angular/vue3/etc
+ // use MountInfo<AllDayHeaderInfo>
```

### Day Lane

**Breaking:** TimeGrid lane hooks are renamed from `dayCell*` to `dayLane*`, lane class-name settings must be simple strings, and lane content customization is no longer supported.

```diff
<FullCalendar
- dayCellClassNames={['my-lane', 'my-util']}
+ dayLaneClass='my-lane my-util'

  // NO REPLACEMENT - can't customize content in here anymore
- dayCellContent={(data) => <span>...</span>}

- dayCellDidMount={(data) => { /* handler */ }}
+ dayLaneDidMount={(data) => { /* handler */ }}

- dayCellWillUnmount={(data) => { /* handler */ }}
+ dayLaneWillUnmount={(data) => { /* handler */ }}
/>
```

**Type changes:** The parameter given to these callbacks has changed:

```diff
- import { type DayCellContentArg, type DayCellMountArg } from '@fullcalendar/core'
+ import { type DayLaneInfo, type MountInfo } from '@fullcalendar/react' // or angular/vue3/etc
+ // use MountInfo<DayLaneInfo>
```

## Resource TimeGrid View

Includes changes from:
- [Calendar Views (General)](#calendar-views-general)
- [Events (General)](#events-general)
- [TimeGrid View](#timegrid-view)
- [DayGrid View](#daygrid-view) - for "day headers" and all-day "day cells"


## List View

Includes changes from:
- [Calendar Views (General)](#calendar-views-general)
- [Events (General)](#events-general)

### Day Header

**Breaking:** List-view day header hooks moved from `views.list.dayHeader*` to top-level `listDayHeader*` settings, and class-name must be a simple string.

```diff
<FullCalendar
- views={{
-   list: {
-     dayHeaderClassNames: ['my-header', 'my-util'],
-     dayHeaderContent: (data) => <span>{data.text}</span>,
-     dayHeaderDidMount: (data) => { /* handler */ },
-     dayHeaderWillUnmount: (data) => { /* handler */ },
-   }
- }}
+ listDayHeaderClass='my-header my-util'
+ listDayHeaderContent={(data) => <span>{data.text}</span>}
+ listDayHeaderDidMount={(data) => { /* handler */ }}
+ listDayHeaderWillUnmount={(data) => { /* handler */ }}
/>
```

Furthermore, whereas `dayHeaderContent` affected the entire day-header in list-view, [`listDayHeaderContent`](list-day-header-render-hooks.md) is called for each subpart of the header, one for [`listDayFormat`](listDayFormat.md) (`level:0`) and one for [`listDayAltFormat`](listDayAltFormat.md) (`level:1`):

```diff
<FullCalendar
- views={{
-   list: {
-     dayHeaderContent: (data) => (
-       <>
-         <strong>{data.text}</strong>
-         <em>{data.sideText</em>
-       </>
-     )
-   }
- }}
+ listDayHeaderContent={(data) => (
+   data.level === 0 ? (
+     <strong>{data.text}</strong>
+   ) : (
+     <em>{data.text}</em>
+   )
+ )}
/>
```

**Type changes:** The parameter given to these callbacks has changed:

```diff
- import { type DayHeaderContentArg, type DayHeaderMountArg } from '@fullcalendar/core'

// for listDayHeaderClass, listDayHeaderDidMount, listDayHeaderWillUnmount
+ import { type ListDayHeaderInfo, type MountInfo } from '@fullcalendar/react' // or angular/vue3/etc
+ // use MountInfo<ListDayHeaderInfo>

// for listDayHeaderContent, listDayHeaderInnerClass (new)
+ import { type ListDayHeaderInnerInfo } from '@fullcalendar/react' // or angular/vue3/etc
```

### All-Day Text on Events

**Breaking:** In List view, all-day event text is no longer customized via generic `allDay*` hooks. Use list `event*` hooks instead.

```diff
<FullCalendar
- allDayClassNames={['my-all-day-text', 'my-util']}
- allDayContent={(data) => <span>{data.text}</span>}
- allDayDidMount={(data) => { /* handler */ }}
- allDayWillUnmount={(data) => { /* handler */ }}
+ views={{
+   list: {
+     eventTimeClass: 'my-all-day-text my-util',
+     eventContent: (data) => (
+       <>
+         <div className={data.timeClass}><i>{data.timeText}</i></div>
+         <div className={data.titleClass}>{data.titleText}</div>
+       </>
+     ),
+     eventDidMount: (data) => {
+       data.el.querySelector('.my-all-day-text')
+     },
+     eventWillUnmount: (data) => {
+       data.el.querySelector('.my-all-day-text')
+     }
+   }
+ }}
/>
```

### No-Events Screen

**Breaking:** `noEventsClassNames` has been renamed to `noEventsClass`, which accepts only a simple string.

```diff
<FullCalendar
- noEventsClassNames={['my-no-events', 'my-util']}
+ noEventsClass='my-no-events my-util'
/>
```

**Type changes:** The parameter given to these callbacks has changed:

```diff
- import { type NoEventsContentArg, type NoEventsMountArg } from '@fullcalendar/core'
+ import { type NoEventsInfo, type MountInfo } from '@fullcalendar/react' // or angular/vue3/etc
+ // use MountInfo<NoEventsInfo>
```

## MultiMonth View

Includes changes from:
- [Calendar Views (General)](#calendar-views-general)
- [Events (General)](#events-general)
- [DayGrid View](#daygrid-view) - for each month's day headers/cells

**Breaking:** `multiMonthMinWidth` and `multiMonthTitleFormat` are renamed to `singleMonthMinWidth` and `singleMonthTitleFormat`.

```diff
<FullCalendar
- multiMonthMinWidth={200}
+ singleMonthMinWidth={200}

- multiMonthTitleFormat={{ year: 'numeric', month: 'long' }}
+ singleMonthTitleFormat={{ year: 'numeric', month: 'long' }}
/>
```

**Breaking:** `singleMonthMinWidth` (formerly `multiMonthMinWidth`) now INCLUDES padding.

**Type changes:** The parameter given to these callbacks has changed:

```diff
- import { type MultiMonthContentArg, type MultiMonthMountArg } from '@fullcalendar/core'
+ import { type SingleMonthInfo, type MountInfo } from '@fullcalendar/react' // or angular/vue3/etc
+ // use MountInfo<SingleMonthInfo>
```


## Resource Timeline View

Includes changes from:
- [Calendar Views (General)](#calendar-views-general)
- [Events (General)](#events-general)

**Breaking:** `resourceAreaWidth` is renamed to `resourceColumnsWidth`, and `resourceAreaColumns` is renamed to `resourceColumns`, and related `*ClassNames` hooks are now `*Class` string settings.

```diff
  <FullCalendar
-   resourceAreaWidth='25%'
+   resourceColumnsWidth='25%'

-   resourceAreaColumns={[
+   resourceColumns={[
      {
        id: 'resource-a',
        title: 'Resource A',
-       headerClassNames: ['my-header', 'my-util'],
+       headerClass: 'my-header my-util',
-       cellClassNames: ['my-cell', 'my-util'],
+       cellClass: 'my-cell my-util',
      }
    ]}

    // will apply to ALL headers
-   resourceAreaHeaderClassNames={['my-header', 'my-util']}
+   resourceColumnHeaderClass='my-header my-util'
-   resourceAreaHeaderContent={(data) => <span>custom content</span>}
+   resourceColumnHeaderContent={(data) => <span>custom content</span>}
-   resourceAreaHeaderDidMount={() => { /* handler */ }}
+   resourceColumnHeaderDidMount={() => { /* handler */ }}
-   resourceAreaHeaderWillUnmount={() => { /* handler */ }}
+   resourceColumnHeaderWillUnmount={() => { /* handler */ }}
  />
```

**Type changes:** The parameter given to these callbacks has changed:

```diff
- import { type ColHeaderContentArg, type ColHeaderMountArg } from '@fullcalendar/core'
+ import { type ResourceColumnHeaderInfo, type MountInfo } from '@fullcalendar/react' // or angular/vue3/etc
+ // use MountInfo<ResourceColumnHeaderInfo>
```

**Breaking:** In v6, the `resourceGroupLabel*` settings where used to style both row-grouping group headers AS WELL AS column-grouping cells, without any way to distinguish the two from the callbacks themselves. In v7, there are two separate entities for each (`resourceGroupHeader*` and the generic `resourceCell*`). Also, `.groupValue` is killed:

```diff
<FullCalendar
- resourceGroupLabelClassNames={['my-resource-group-header', 'my-resource-group-cell', 'my-util']}
- resourceGroupLabelContent={(data) => (
-   <span>{data.groupValue}</span>
- )}
- resourceGroupLabelDidMount={(data) => { /* handler */ }}
- resourceGroupLabelWillUnmount={(data) => { /* handler */ }}

  // header for grouped rows
+ resourceGroupHeaderClass='my-resource-group-header my-util'
+ resourceGroupHeaderContent={(data) => (
+   <span>{data.fieldValue}</span>
+ )}
+ resourceGroupHeaderDidMount={(data) => { /* handler */ }}
+ resourceGroupHeaderWillUnmount={(data) => { /* handler */ }}

  // grouped cells
+ resourceCellClass={(data) => clsx(
+   !data.resource && // in group?
+     'my-resource-group-cell my-util'
+ )}
+ resourceCellContent={(data) => (
+   <span>{data.fieldValue}</span> // applies to all cells (grouped and non-grouped)
+ )}
+ resourceCellDidMount={(data) => {
+   if (!data.resource) { /* handler for group */ }
+ }}
+ resourceCellWillUnmount={(data) => {
+   if (!data.resource) { /* handler for group */ }
+ }}
/>
```

**Type changes:** The parameter given to these callbacks has changed:

```diff
- import { type ColCellContentArg, type ColCellMountArg } from '@fullcalendar/core'

// header for grouped rows
+ import { type ResourceGroupHeaderInfo, type MountInfo } from '@fullcalendar/react' // or angular/vue3/etc
+ // use MountInfo<ResourceGroupHeaderInfo>

// grouped cells
+ import { type ResourceCellInfo } from '@fullcalendar/react' // or angular/vue3/etc
+ // use MountInfo<ResourceCellInfo>
```

### Resource Cell

**Breaking:** `resourceLabel*` has been replaced by generalized `resourceCell*` hooks. If you only want the title cell, branch on `data.field === 'title'`.

```diff
<FullCalendar
- views={{
-   resourceTimeline: {
-     resourceLabelClassNames: ['my-resource-cell', 'my-util'],
-     resourceLabelContent: (data) => (
-       <span>{data.resource.title}</span>
-     ),
-     resourceLabelDidMount: (data) => { /* handler */ },
-     resourceLabelWillUnmount: (data) => { /* handler */ },
-   }
- }}

+ resourceCellClass={(data) => clsx(
+   (data.field === 'title') && 'my-resource-cell my-util'
+ )}
+ resourceCellContent={(data) => (
+   <span>{data.fieldValue}</span> // applies to all cells
+ )}
+ resourceCellDidMount={(data) => {
+   if (data.field === 'title') { /* handler */ }
+ }}
+ resourceCellWillUnmount={(data) => {
+   if (data.field === 'title') { /* handler */ }
+ }}
/>
```

Note that the `resourceLabel*` props ALSO apply to Resource DayGrid/TimeGrid. See those migrations above.

### Resource Lane

**Breaking:** `resourceLaneClassNames` is renamed to `resourceLaneClass` (simple string only), and `resourceLaneContent` is split into `resourceLaneTopContent` and `resourceLaneBottomContent`.

```diff
<FullCalendar
- resourceLaneClassNames={['my-lane', 'my-util']}
+ resourceLaneClass='my-lane my-util'

- resourceLaneContent={(data) => <span>...</span>}
+ resourceLaneTopContent={(data) => <span>...</span>}
+ // or
+ resourceLaneBottomContent={(data) => <span>...</span>}
/>
```

**Type changes:** The parameter given to these callbacks has changed:

```diff
- import { type ResourceLaneContentArg, type ResourceLaneMountArg } from '@fullcalendar/core'
+ import { type ResourceLaneInfo, type MountInfo } from '@fullcalendar/react' // or angular/vue3/etc
+ // use MountInfo<ResourceLaneInfo>
```

### Group Lane

**Breaking:** `resourceGroupLaneClassNames` is renamed to `resourceGroupLaneClass` (simple string only), and group data now uses `fieldValue` instead of `groupValue`.

```diff
<FullCalendar
- resourceGroupLaneClassNames={['my-group-lane', 'my-util']}
+ resourceGroupLaneClass='my-group-lane my-util'

  resourceGroupContent={(data) => (
-   <span>{data.groupValue}</span>
+   <span>{data.fieldValue}</span>
  )}
/>
```

**Type changes:** The parameter given to these callbacks has changed:

```diff
- import { type ColCellContentArg, type ColCellMountArg } from '@fullcalendar/core'
+ import { type ResourceGroupLaneInfo, type MountInfo } from '@fullcalendar/react' // or angular/vue3/etc
+ // use MountInfo<ResourceGroupLaneInfo>
```


## Custom Views

### Custom View via Settings

**Breaking:** In custom view definitions, `.classNames` (array) is replaced by `.className` (single string).

```diff
  var calendar = new Calendar(calendarEl, {
    views: {
      timeGridFourDay: {
        type: 'timeGrid',
        duration: { days: 4 },

-       classNames: ['my-classname', 'my-util'],
+       className: 'my-classname my-util',
      }
    }
  })
```

**Breaking:** The `buttonText` setting no longer respected. Instead, add to the `buttons` map:

```diff
  var calendar = new Calendar(calendarEl, {
    views: {
      timeGridFourDay: {
        type: 'timeGrid',
        duration: { days: 4 },
-       buttonText: '4 day'
      }
    },
+   buttons: {
+     timeGridFourDay: {
+       text: '4 day'
+     }
+   },
    headerToolbar: {
      center: 'dayGridMonth,timeGridFourDay'
    }
  })
```

### Custom View via JS

**Breaking:** `createPlugin` is no longer required for custom view plugin objects (see [Custom Plugins](#custom-plugins) below).


## Luxon Plugin

**Breaking:** The `@fullcalendar/luxon3` plugin has been removed. Remove it from your `package.json`:

```diff
{
  "dependencies": {
    "@fullcalendar/react": "7.0.0",
-   "@fullcalendar/luxon3": "^6.1.20",
    "luxon": "^3.7.2"
  }
}
```

**Breaking:** Because the `@fullcalendar/luxon3` plugin has been removed, the `toLuxonDateTime` and `toLuxonDuration` utilities are no longer available. You can easily replace with direct calls to Luxon:

```diff
- import { toLuxonDateTime, toLuxonDuration } from '@fullcalendar/luxon3'
+ import { DateTime, Duration } from 'luxon'

  const locale = 'en-US'
  const timeZone = 'America/New_York'

  <FullCalendar
    locale={locale}
    timeZone={timeZone}
    dateClick={(info) => {
-     const dt = toLuxonDateTime(info.date, info.view.calendar)
+     const dt = DateTime.fromJSDate(info.date, { zone: timeZone, locale })
      ...
    }}
    eventDrop={(info) => {
-     const dur = toLuxonDuration(info.delta, info.view.calendar)
+     const dur = Duration.fromObject(info.delta, { locale })
      ...
    }}
  />
```

**Breaking:** The `@fullcalendar/luxon3` plugin has been removed, but it's format-string functionality has been moved to a different plugin:

```
npm install --save @fullcalendar/format-luxon3
```

Then replace usage in your code:

```diff
- import luxonPlugin from '@fullcalendar/luxon3'
+ import luxonFormatPlugin from '@fullcalendar/format-luxon3'

  <FullCalendar
    titleFormat='LLLL d, yyyy' // a format-string
    plugins={[
-     luxonPlugin,
+     luxonFormatPlugin, // for format-strings only
      ...
    ]}
    ...
  />
```


## Moment Plugins

**Breaking:** The two moment plugin have been removed. Remove them from your `package.json`:

```diff
{
  "dependencies": {
    "@fullcalendar/react": "7.0.0",
-   "@fullcalendar/moment": "^6.1.20",
-   "@fullcalendar/moment-timezone": "^6.1.20",
    "moment": "^2.30.1"
  }
}
```

**Breaking:** Because the `@fullcalendar/moment` plugin has been removed, the `toMoment` and `toMomentDuration` utilities are no longer available. You can replace them with direct calls to Moment:

```diff
- import { toMoment, toMomentDuration } from '@fullcalendar/luxon3'
+ import moment from 'moment'

  const locale = 'en-US'
  const timeZone = 'America/New_York'

  <FullCalendar
    locale={locale}
    timeZone={timeZone}
    dateClick={(info) => {
-     const mom = toMoment(info.date, info.view.calendar)
+     let mom: moment.Moment
+     if (timeZone === 'local') {
+       mom = moment(info.date)
+     } else if (timeZone === 'UTC') {
+       mom = moment.utc(info.date)
+     } else {
+       mom = moment.tz(info.date, timeZone)
+     }
      ...
    }}
    eventDrop={(info) => {
-     const dur = toMomentDuration(info.delta, info.view.calendar)
+     const dur = moment.duration(info.delta)
      ...
    }}
  />
```

**Breaking:** The `@fullcalendar/moment` plugin has been removed, but it's format-string functionality has been moved to a different plugin:

```
npm install --save @fullcalendar/format-moment
```

Then replace usage in your code:

```diff
- import momentPlugin from '@fullcalendar/moment'
+ import momentFormatPlugin from '@fullcalendar/format-moment'

  <FullCalendar
    titleFormat: 'MMMM D, YYYY' // a format-string
    plugins={[
-     momentPlugin,
+     momentFormatPlugin, // for format-strings only
      ...
    ]}
    ...
  />
```


## Custom Plugins

**Breaking:** the `createPlugin` function no longer necessary to prepare a plugin. Just pass-in the object.

```diff
- const customViewPlugin = createPlugin({
+ const customViewPlugin = {
    name: 'custom-view',
    views: {
      custom: CustomViewConfig
    }
+ };
- });

  let calendar = new Calendar(calendarEl, {
    plugins: [customViewPlugin],
  });
```

**Type changes:**

```diff
- import { PluginDef, PluginDefInput } from '@fullcalendar/core'
+ import { PluginInput } from '@fullcalendar/react' // or angular/vue3/etc
```


## Custom Theme Class

**Breaking:** V6 had an poorly-documented API for theming that was rarely used by developers. It has been replaced by the miriad of `*Class` and `*Content` settings now available in v7. Here's how to migrate:

<div class='diff-code-2col' markdown='1'>
<div>

```diff
- import {
-   StandardTheme,
-   createPlugin
- } from '@fullcalendar/core'

- class CustomTheme extends StandardTheme {
-   root = 'my-root'

    // toolbar
-   buttonGroup = 'my-button-group'
-   button = 'my-button'
-   buttonActive = 'my-button-selected'

    // popover
-   popover='my-popover'
-   popoverHeader='my-popover-header'
-   popoverContent='my-popover-body'

    // affects multiple elements
-   tableCellShaded = 'my-cell-shaded'
- }

  <FullCalendar
-   plugins={[
-     createPlugin({
-       name: 'custom-theme',
-       themeClasses: {
-         custom: CustomTheme,
-       }
-     })
-   ]}
-   theme='custom'
```

</div>
<div>

```diff
  <FullCalendar

+   className='my-root'

    // toolbar
+   buttonGroupClass='my-button-group'
+   buttonClass={(data) => clsx(
+     'my-button',
+     data.isSelected && 'my-button-selected',
+   )}

    // popover
+   popoverClass='my-popover'
+   dayHeaderClass={(data) => clsx(
+     data.inPopover && 'my-popover-header'
+   )}
+   dayCellClass={(data) => clsx(
+     data.inPopover && 'my-popover-body'
+   )}

    // affects multiple elements
+   allDayDividerClass='my-cell-shaded'
+   listDayHeaderClass='my-cell-shaded'
+   resourceColumnDividerClass='my-cell-shaded'
+   resourceGroupHeaderClass='my-cell-shaded'
+   resourceGroupLaneClass='my-cell-shaded'
  />
```

</div>
</div>

The following members have been removed because class-based glyph icons are now discouraged:

```diff
- CustomTheme.prototype.baseIconClass
- CustomTheme.prototype.iconClasses
- CustomTheme.prototype.rtlIconClasses
- CustomTheme.prototype.iconOverridePrefix
```


## Locales

**Breaking:** The Shape of a locale object has changed:

<div class='diff-code-2col' markdown='1'>
<div>

```diff
  {
    code: 'es',
-   buttonText: {
-     prev: 'Ant',
-     next: 'Sig',
-     today: 'Hoy',
-     year: 'Año',
-     month: 'Mes',
-     week: 'Semana',       // "long" value
-     day: 'Día',
-     list: 'Agenda',
-   },
    weekTextLong: 'Semana', // "long" value
-   weekText: 'Sm',         // "short" value
-   buttonHints: {
-     prev: '$0 antes',
-     next: '$0 siguiente',
-     today: (unitText) => { /* ... */ }
-   },
  }
```

</div>
<div>

```diff
  {
    code: 'es',

+   prevText: 'Ant',
+   nextText: 'Sig',
+   todayText: 'Hoy',
+   yearText: 'Año',
+   monthText: 'Mes',

+   dayText: 'Día',
+   listText: 'Agenda',

    weekTextLong: 'Semana', // "long" value
+   weekTextShort: "Sm",    // "short" value

+   prevHint: '$0 antes',
+   nextHint: '$0 siguiente',
+   todayHint: (unitText) => { /* ... */ }

  }
```

</div>
</div>

Note `weekText` has been renamed to `weekTextShort`.


## Interactions

**Breaking:** removed `fixedMirrorParent` setting. Element dragging "mirror" elements will always be attached to `<body>` now:

```diff
<FullCalendar
- fixedMirrorParent={document.body} // unnecessary now
/>
```

**Type changes:** For all names, the `Arg` postfix replaced with `Info`:

<div class='diff-code-2col' markdown='1'>
<div>

```diff
- import {
-   DateSelectArg,
-   DateUnselectArg,
-   EventClickArg,
-   EventAddArg,
-   EventChangeArg,
-   EventRemoveArg,
- } from '@fullcalendar/core'

- import {
-   DateClickArg,
-   EventDragStartArg,
-   EventDragStopArg,
-   EventDropArg,
-   EventResizeStartArg,
-   EventResizeStopArg,
-   EventResizeDoneArg,
-   EventHoveringArg,
-   DropArg,
-   EventReceiveArg,
-   EventLeaveArg,
- } from '@fullcalendar/interaction'
```

</div>
<div>

```diff
+ import {
+   DateSelectInfo,
+   DateUnselectInfo,
+   EventClickInfo,
+   EventAddInfo,
+   EventChangeInfo,
+   EventRemoveInfo,
+ } from '@fullcalendar/react'
                      // or angular/vue3/etc
+ import {
+   DateClickInfo,
+   EventDragStartInfo,
+   EventDragStopInfo,
+   EventDropInfo,
+   EventResizeStartInfo,
+   EventResizeStopInfo,
+   EventResizeDoneInfo,
+   EventHoveringInfo,
+   DropInfo,
+   EventReceiveInfo,
+   EventLeaveInfo,
+ } from '@fullcalendar/react/interaction'
                      // or angular/vue3/etc
```

</div>
</div>


## Misc

**Type changes:** The argument given to the `datesSet` callback has changed:

```diff
- import { DatesSetArg } from '@fullcalendar/core'
+ import { DatesSetInfo } from '@fullcalendar/react' // or angular/vue3/etc
```

**Type changes:** The `MountArg` generic has been removed. The `DidMountHandler` and `WillUnmountHandler` generic helpers now take a plain info object instead of a fully-resolved mount arg:

```diff
- const onDayCellDidMount: DidMountHandler<MountArg<DayCellInfo>> = ...
+ const onDayCellDidMount: DidMountHandler<DayCellInfo> = ...

- const onDayCellWillUnmount: WillUnmountHandler<MountArg<DayCellInfo>> = ...
+ const onDayCellWillUnmount: WillUnmountHandler<DayCellInfo> = ...
```


<!-- END -->
</div>
</div>
