---
title: "React Timeline Event Hooks Example | Mobiscroll"
component: "Timeline"
framework: "React"
library_version: "6.1.5"
url: "https://demo.mobiscroll.com/react/timeline/event-hooks"
---

# Event Hooks - React Timeline demo

Explore React Timeline lifecycle hooks — see hooks fire on event clicks, initialization, and date changes, tracked in a live event log. For React and Next.JS.

- [Live demo](https://demo.mobiscroll.com/react/timeline/event-hooks)
- [View React JS code on GitHub](https://github.com/acidb/mobiscroll-demos-react/tree/main/src/demos/eventcalendar/timeline/event-hooks)
- [View React TS code on GitHub](https://github.com/acidb/mobiscroll-demos-react-ts/tree/main/src/demos/eventcalendar/timeline/event-hooks)
- This demo in other frameworks: [JavaScript](https://demo.mobiscroll.com/javascript/timeline/event-hooks.md), [jQuery](https://demo.mobiscroll.com/jquery/timeline/event-hooks.md), [Angular](https://demo.mobiscroll.com/angular/timeline/event-hooks.md), [Vue](https://demo.mobiscroll.com/vue/timeline/event-hooks.md)

## Description

The timeline ships with different hooks for deep customization. Events are triggered through the lifecycle of the component where you can tie in custom functionality and code.

While users interact with the UI events like `onEventClick`, `onInit`, `onSelectedDateChange` ... will be triggered.

**For a complete list of events go to the documentation** [See available lifecycle events →](https://mobiscroll.com/docs/react/eventcalendar/api#events)

## What this demo shows

- A desktop daily timeline where hours are arranged horizontally and a hierarchical resource tree arranged vertically on the left.
- **External drag & drop** Three external events are shown above the timeline and can be dragged onto the day view.
- **Event log** An Event log panel is shown at the left and lists the lifecycle events fired during interactions such as event creation, hover, drag, and similar actions.
- **Header navigation** The month and year label opens date navigation, while the previous and next arrows move between days and the Today button returns to the current date.
- **Day view** The strip below the header shows the selected days, with the current date highlighted. The timeline displays hourly columns from 12 AM to 12 PM.
- **Resources** The left side shows expandable and collapsible resource groups, including parent groups and draggable resources.
- **Resource hierarchy** Nested resources are grouped under parent rows, before listing individual resources.
- **Resource template** Each resource header shows the resource name in bold.
- **Current time** A vertical blue line with a time label marks the current time.
- **Hover behavior** Hovering over the time grid shows a time indicator that follows the cursor in 15-minute increments.
- **Event cards** Events are shown as colored cards with a left color stripe, a bold title, a description, and a bold time range.
- **Date positioning** Events are positioned by their assigned resource and exact date range.
- **Event interaction** Events highlight on hover and show drag and resize handles for repositioning or changing duration.
- **Event selection** Clicking an event selects and highlights it.
- **Event creation** New events can be created by double-clicking the timeline or by clicking and dragging across a time range.
- **Scrolling** The timeline supports horizontal and vertical scrolling for navigating through time and resources.

## Best for

- **Lifecycle event discovery** Understanding which timeline lifecycle hooks fire during common user interactions.

## Tutorial

```jsx
<Eventcalendar
    onCellClick = {(event, inst) => { /* Logic for cell click */ }}
    onCellDoubleClick = {(event, inst) => { /* Logic for cell double click */ }}
    onCellRightClick = {(event, inst) => { /* Logic for cell right click */ }}
    onCellHoverIn = {(event, inst) => { /* Logic for cell hover in */ }}
    onCellHoverOut = {(event, inst) => { /* Logic for cell hover out */ }}
    onDestroy = {(event, inst) => { /* Your custom event handler goes here */ }}
    onEventClick = {(event, inst) => { /* Logic for event click */ }}
    onEventCreate = {(event, inst) => { /* Logic for event create */ }}
    onEventCreated = {(event, inst) => { /* Logic for event created */ }}
    onEventCreateFailed = {(event, inst) => { /* Logic for failed event create */ }}
    onEventDelete = {(event, inst) => { /* Logic for event delete */ }}
    onEventDeleted = {(event, inst) => { /* Logic for event deleted */ }}
    onEventDoubleClick = {(event, inst) => { /* Logic for event double click */ }}
    onEventDragEnd = {(event, inst) => { /* Triggered when event drag ends */ }}
    onEventDragStart = {(event, inst) => { /* Triggered when event drag is started */ }}
    onEventDragEnter = {(event, inst) => { /* Triggered when a dragged event enters the calendar */ }}
    onEventDragLeave = {(event, inst) => { /* Triggered when a dragged event leaves the calendar */ }}
    onEventHoverIn = {(event, inst) => { /* Logic for event hover in */ }}
    onEventHoverOut = {(event, inst) => { /* Logic for event hover out */ }}
    onEventRightClick = {(event, inst) => { /* Logic for event right click */ }}
    onEventUpdate = {(event, inst) => { /* Logic for event update */ }}
    onEventUpdated = {(event, inst) => { /* This is where you save the updated event to your DB */ }}
    onEventUpdateFailed = {(event, inst) => { /* Logic for failed event update */ }}
    onPageChange = {(event, inst) => { /* Your custom event handler goes here */ }}
    onPageLoaded = {(event, inst) => { /* Use it to inject custom markup & attach custom listeners */ }}
    onPageLoading = {(event, inst) => { /* Use it to load data on demand */ }}
    onResourceClick = {(event, inst) => { /* Logic for resource click */ }}
    onResourceDoubleClick = {(event, inst) => { /* Logic for resource double click */ }}
    onResourceDragStart = {(event, inst) => {  /* Triggered when resource drag ends */ }}
    onResourceDragEnd = {(event, inst) => {  /* Triggered when resource drag is started */ }
    onResourceExpand: {(event, inst) => { /* Use it to load child resources on demand */ }}
    onResourceOrderUpdate: {(event, inst) => { /* Logic for resource update */ }}
    onResourceCreate={() => { /* Logic for resource create */ }}
    onResourceCreated={() => { /* Logic for resource created */ }}
    onResourceDelete={() => { /* Logic for resource delete */ }}
    onResourceDeleted={() => { /* Logic for resource deleted */ }}
    onResourceDragEnter={() => { /* Logic for resource update */ }}
    onResourceDragLeave={() => { /* Logic for resource update */ }}
    onResourceRightClick: {(event, inst) => { /* Logic for resource right click */ }}
    onResourceHoverIn: {(event, inst) => { /* Logic for resource hover in */ }}
    onResourceHoverOut: {(event, inst) => { /* Logic for resource hover out */ }}
    onResourceCollapse: {(event, inst) => { /* Use it to unload child resources on demand */ }}
    onSelectedDateChange = {(event, inst) => { /* Use it to keep track of the selected date externally */ }}
/>
```

## API used in this demo

- [`theme`](https://mobiscroll.com/docs/react/eventcalendar/api#opt-theme) - option
- [`themeVariant`](https://mobiscroll.com/docs/react/eventcalendar/api#opt-themeVariant) - option
- [`data`](https://mobiscroll.com/docs/react/eventcalendar/api#opt-data) - option
- [`dragToCreate`](https://mobiscroll.com/docs/react/eventcalendar/api#opt-dragToCreate) - option
- [`dragToMove`](https://mobiscroll.com/docs/react/eventcalendar/api#opt-dragToMove) - option
- [`dragToResize`](https://mobiscroll.com/docs/react/eventcalendar/api#opt-dragToResize) - option
- [`externalDrop`](https://mobiscroll.com/docs/react/eventcalendar/api#opt-externalDrop) - option
- [`externalResourceDrop`](https://mobiscroll.com/docs/react/eventcalendar/api#opt-externalResourceDrop) - option
- [`view`](https://mobiscroll.com/docs/react/eventcalendar/api#opt-view) - option
- [`resources`](https://mobiscroll.com/docs/react/eventcalendar/api#opt-resources) - option
- [`invalid`](https://mobiscroll.com/docs/react/eventcalendar/api#opt-invalid) - option
- [`onCellClick`](https://mobiscroll.com/docs/react/eventcalendar/api#event-onCellClick) - event
- [`onCellDoubleClick`](https://mobiscroll.com/docs/react/eventcalendar/api#event-onCellDoubleClick) - event
- [`onCellRightClick`](https://mobiscroll.com/docs/react/eventcalendar/api#event-onCellRightClick) - event
- [`onCellHoverIn`](https://mobiscroll.com/docs/react/eventcalendar/api#event-onCellHoverIn) - event
- [`onCellHoverOut`](https://mobiscroll.com/docs/react/eventcalendar/api#event-onCellHoverOut) - event
- [`onDestroy`](https://mobiscroll.com/docs/react/eventcalendar/api#event-onDestroy) - event
- [`onEventClick`](https://mobiscroll.com/docs/react/eventcalendar/api#event-onEventClick) - event
- [`onEventCreate`](https://mobiscroll.com/docs/react/eventcalendar/api#event-onEventCreate) - event
- [`onEventCreated`](https://mobiscroll.com/docs/react/eventcalendar/api#event-onEventCreated) - event
- [`onEventCreateFailed`](https://mobiscroll.com/docs/react/eventcalendar/api#event-onEventCreateFailed) - event
- [`onEventDelete`](https://mobiscroll.com/docs/react/eventcalendar/api#event-onEventDelete) - event
- [`onEventDeleted`](https://mobiscroll.com/docs/react/eventcalendar/api#event-onEventDeleted) - event
- [`onEventDoubleClick`](https://mobiscroll.com/docs/react/eventcalendar/api#event-onEventDoubleClick) - event
- [`onEventDragEnter`](https://mobiscroll.com/docs/react/eventcalendar/api#event-onEventDragEnter) - event
- [`onEventDragLeave`](https://mobiscroll.com/docs/react/eventcalendar/api#event-onEventDragLeave) - event
- [`onEventHoverIn`](https://mobiscroll.com/docs/react/eventcalendar/api#event-onEventHoverIn) - event
- [`onEventHoverOut`](https://mobiscroll.com/docs/react/eventcalendar/api#event-onEventHoverOut) - event
- [`onEventUpdate`](https://mobiscroll.com/docs/react/eventcalendar/api#event-onEventUpdate) - event
- [`onEventUpdated`](https://mobiscroll.com/docs/react/eventcalendar/api#event-onEventUpdated) - event
- [`onEventUpdateFailed`](https://mobiscroll.com/docs/react/eventcalendar/api#event-onEventUpdateFailed) - event
- [`onEventRightClick`](https://mobiscroll.com/docs/react/eventcalendar/api#event-onEventRightClick) - event
- [`onInit`](https://mobiscroll.com/docs/react/eventcalendar/api#event-onInit) - event
- [`onPageChange`](https://mobiscroll.com/docs/react/eventcalendar/api#event-onPageChange) - event
- [`onPageLoaded`](https://mobiscroll.com/docs/react/eventcalendar/api#event-onPageLoaded) - event
- [`onPageLoading`](https://mobiscroll.com/docs/react/eventcalendar/api#event-onPageLoading) - event
- [`onResourceClick`](https://mobiscroll.com/docs/react/eventcalendar/api#event-onResourceClick) - event
- [`onResourceDoubleClick`](https://mobiscroll.com/docs/react/eventcalendar/api#event-onResourceDoubleClick) - event
- [`onResourceOrderUpdate`](https://mobiscroll.com/docs/react/eventcalendar/api#event-onResourceOrderUpdate) - event
- [`onResourceCreate`](https://mobiscroll.com/docs/react/eventcalendar/api#event-onResourceCreate) - event
- [`onResourceDelete`](https://mobiscroll.com/docs/react/eventcalendar/api#event-onResourceDelete) - event
- [`onResourceRightClick`](https://mobiscroll.com/docs/react/eventcalendar/api#event-onResourceRightClick) - event
- [`onResourceHoverIn`](https://mobiscroll.com/docs/react/eventcalendar/api#event-onResourceHoverIn) - event
- [`onResourceHoverOut`](https://mobiscroll.com/docs/react/eventcalendar/api#event-onResourceHoverOut) - event
- [`onSelectedDateChange`](https://mobiscroll.com/docs/react/eventcalendar/api#event-onSelectedDateChange) - event

## Code

### JSX

```jsx
import { Draggable, Eventcalendar, getJson, setOptions } from '@mobiscroll/react';
import { useEffect, useMemo, useState } from 'react';

setOptions({
  theme: 'ios',
  themeVariant: 'light'
});

const dragData1 = {
  title: 'External drag 1',
  color: '#ffdab8',
};

const dragData2 = {
  title: 'External drag 2',
  color: '#ddfcf7',
};

const dragData3 = {
  name: 'External resource',
  color: '#d19494',
};

function App() {
  const [myEvents, setEvents] = useState([]);
  const [draggable1, setDraggable1] = useState();
  const [draggable2, setDraggable2] = useState();
  const [draggable3, setDraggable3] = useState();

  const myInvalid = useMemo(
    () => [
      {
        start: '12:00',
        end: '13:00',
        title: 'Lunch break',
        recurring: {
          repeat: 'weekly',
          weekDays: 'MO,TU,WE,TH,FR',
        },
      },
    ],
    [],
  );

  const myView = useMemo(
    () => ({
      timeline: {
        type: 'day',
        resourceReorder: true,
      },
    }),
    [],
  );

  const myResources = useMemo(
    () => [
      {
        id: 1,
        name: 'Ryan',
        color: '#fdf500',
      },
      {
        id: 2,
        name: 'Kate',
        color: '#ff4600',
      },
      {
        id: 3,
        name: 'John',
        color: '#ff0101',
      },
      {
        id: 4,
        name: 'Mark',
        color: '#239a21',
      },
      {
        id: 5,
        name: 'Sharon',
        color: '#8f1ed6',
      },
      {
        id: 6,
        name: 'Ashley',
        color: '#01adff',
      },
    ],
    [],
  );

  useEffect(() => {
    getJson(
      'https://trial.mobiscroll.com/timeline-events/',
      (events) => {
        setEvents(events);
      },
      'jsonp',
    );
  }, []);

  return (
    <>
      <div ref={setDraggable1} className="event-hooks-draggable" style={{ background: '#ffdab8' }}>
        <div className="draggable-title">External drag 1</div>
        <div className="draggable-text">Drag me to calendar</div>
        <Draggable dragData={dragData1} element={draggable1} />
      </div>
      <div ref={setDraggable2} className="event-hooks-draggable" style={{ background: '#ddfcf7' }}>
        <div className="draggable-title">External drag 2</div>
        <div className="draggable-text">Drag me to calendar</div>
        <Draggable dragData={dragData2} element={draggable2} />
      </div>
      <div ref={setDraggable3} className="event-hooks-draggable" style={{ background: '#d19494' }}>
        <div className="draggable-title">External resource</div>
        <div className="draggable-text">Drag me to calendar</div>
        <Draggable dragData={dragData3} element={draggable3} type="resource" />
      </div>
      <Eventcalendar
        data={myEvents}
        dragToCreate={true}
        dragToMove={true}
        dragToResize={true}
        externalDrop={true}
        externalResourceDrop={true}
        view={myView}
        resources={myResources}
        invalid={myInvalid}
        onCellClick={() => {
          // Logic for cell click
        }}
        onCellDoubleClick={() => {
          // Logic for cell double click
        }}
        onCellRightClick={() => {
          // Logic for cell right click
        }}
        onCellHoverIn={() => {
          // Logic for cell hover in
        }}
        onCellHoverOut={() => {
          // Logic for cell hover out
        }}
        onDestroy={() => {
          // Your custom event handler goes here
        }}
        onEventClick={() => {
          // Logic for event click
        }}
        onEventCreate={() => {
          // Logic for event create
        }}
        onEventCreated={() => {
          // Logic for event created
        }}
        onEventCreateFailed={() => {
          // Logic for failed event create
        }}
        onEventDelete={() => {
          // Logic for event delete
        }}
        onEventDeleted={() => {
          // Logic for event deleted
        }}
        onEventDoubleClick={() => {
          // Logic for event double click
        }}
        onEventDragEnter={() => {
          // Logic for event drag enter
        }}
        onEventDragLeave={() => {
          // Logic for event drag leave
        }}
        onEventHoverIn={() => {
          // Logic for event hover in
        }}
        onEventHoverOut={() => {
          // Logic for event hover out
        }}
        onEventUpdate={() => {
          // Logic for event update
        }}
        onEventUpdated={() => {
          // Logic for event updated
        }}
        onEventUpdateFailed={() => {
          // Logic for failed event update
        }}
        onEventRightClick={() => {
          // Logic for event right click
        }}
        onInit={() => {
          // Logic running on component init
        }}
        onPageChange={() => {
          // Your custom event handler goes here
        }}
        onPageLoaded={() => {
          // Use it to inject custom markup & attach custom listeners
        }}
        onPageLoading={() => {
          // Use it to load data on demand
        }}
        onResourceClick={() => {
          // Logic for resource click
        }}
        onResourceDoubleClick={() => {
          // Logic for resource double click
        }}
        onResourceDragEnd={() => {
          /* Logic for resource drag end */
        }}
        onResourceDragStart={() => {
          /* Logic for resource drag start */
        }}
        onResourceOrderUpdate={() => {
          // Logic for resource update
        }}
        onResourceCreate={() => {
          // Logic for resource create
        }}
        onResourceCreated={() => {
          // Logic for resource created
        }}
        onResourceDelete={() => {
          // Logic for resource delete
        }}
        onResourceDeleted={() => {
          // Logic for resource deleted
        }}
        onResourceDragEnter={() => {
          // Logic for resource update
        }}
        onResourceDragLeave={() => {
          // Logic for resource update
        }}
        onResourceRightClick={() => {
          // Logic for resource right click
        }}
        onResourceHoverIn={() => {
          // Logic for resource hover in
        }}
        onResourceHoverOut={() => {
          // Logic for resource hover out
        }}
        onSelectedDateChange={() => {
          // Use it to keep track of the selected date externally
        }}
      />
    </>
  );
}

export default App;
```

### TSX

```tsx
import {
  Draggable,
  Eventcalendar,
  getJson,
  MbscCalendarEvent,
  MbscEventcalendarView,
  MbscResource,
  setOptions,
} from '@mobiscroll/react';
import { FC, useEffect, useMemo, useState } from 'react';

setOptions({
  theme: 'ios',
  themeVariant: 'light'
});

const dragData1 = {
  title: 'External drag 1',
  color: '#ffdab8',
};

const dragData2 = {
  title: 'External drag 2',
  color: '#ddfcf7',
};

const dragData3 = {
  name: 'External resource',
  color: '#d19494',
};

const App: FC = () => {
  const [myEvents, setEvents] = useState<MbscCalendarEvent[]>([]);
  const [draggable1, setDraggable1] = useState<HTMLElement | null>(null);
  const [draggable2, setDraggable2] = useState<HTMLElement | null>(null);
  const [draggable3, setDraggable3] = useState<HTMLElement | null>(null);

  const myInvalid = [
    {
      start: '12:00',
      end: '13:00',
      title: 'Lunch break',
      recurring: {
        repeat: 'weekly',
        weekDays: 'MO,TU,WE,TH,FR',
      },
    },
  ];

  const myView = useMemo<MbscEventcalendarView>(
    () => ({
      timeline: {
        type: 'day',
        resourceReorder: true,
      },
    }),
    [],
  );

  const myResources = useMemo<MbscResource[]>(
    () => [
      {
        id: 1,
        name: 'Ryan',
        color: '#fdf500',
      },
      {
        id: 2,
        name: 'Kate',
        color: '#ff4600',
      },
      {
        id: 3,
        name: 'John',
        color: '#ff0101',
      },
      {
        id: 4,
        name: 'Mark',
        color: '#239a21',
      },
      {
        id: 5,
        name: 'Sharon',
        color: '#8f1ed6',
      },
      {
        id: 6,
        name: 'Ashley',
        color: '#01adff',
      },
    ],
    [],
  );

  useEffect(() => {
    getJson(
      'https://trial.mobiscroll.com/timeline-events/',
      (events: MbscCalendarEvent[]) => {
        setEvents(events);
      },
      'jsonp',
    );
  }, []);

  return (
    <>
      <div ref={setDraggable1} className="event-hooks-draggable" style={{ background: '#ffdab8' }}>
        <div className="draggable-title">External drag 1</div>
        <div className="draggable-text">Drag me to calendar</div>
        <Draggable dragData={dragData1} element={draggable1} />
      </div>
      <div ref={setDraggable2} className="event-hooks-draggable" style={{ background: '#ddfcf7' }}>
        <div className="draggable-title">External drag 2</div>
        <div className="draggable-text">Drag me to calendar</div>
        <Draggable dragData={dragData2} element={draggable2} />
      </div>
      <div ref={setDraggable3} className="event-hooks-draggable" style={{ background: '#d19494' }}>
        <div className="draggable-title">External resource</div>
        <div className="draggable-text">Drag me to calendar</div>
        <Draggable dragData={dragData3} element={draggable3} type="resource" />
      </div>
      <Eventcalendar
        data={myEvents}
        dragToCreate={true}
        dragToMove={true}
        dragToResize={true}
        externalDrop={true}
        externalResourceDrop={true}
        view={myView}
        resources={myResources}
        invalid={myInvalid}
        onCellClick={() => {
          // Logic for cell click
        }}
        onCellDoubleClick={() => {
          // Logic for cell double click
        }}
        onCellRightClick={() => {
          // Logic for cell right click
        }}
        onCellHoverIn={() => {
          // Logic for cell hover in
        }}
        onCellHoverOut={() => {
          // Logic for cell hover out
        }}
        onDestroy={() => {
          // Your custom event handler goes here
        }}
        onEventClick={() => {
          // Logic for event click
        }}
        onEventCreate={() => {
          // Logic for event create
        }}
        onEventCreated={() => {
          // Logic for event created
        }}
        onEventCreateFailed={() => {
          // Logic for failed event create
        }}
        onEventDelete={() => {
          // Logic for event delete
        }}
        onEventDeleted={() => {
          // Logic for event deleted
        }}
        onEventDoubleClick={() => {
          // Logic for event double click
        }}
        onEventDragEnter={() => {
          // Logic for event drag enter
        }}
        onEventDragLeave={() => {
          // Logic for event drag leave
        }}
        onEventHoverIn={() => {
          // Logic for event hover in
        }}
        onEventHoverOut={() => {
          // Logic for event hover out
        }}
        onEventUpdate={() => {
          // Logic for event update
        }}
        onEventUpdated={() => {
          // Logic for event updated
        }}
        onEventUpdateFailed={() => {
          // Logic for failed event update
        }}
        onEventRightClick={() => {
          // Logic for event right click
        }}
        onInit={() => {
          // Logic running on component init
        }}
        onPageChange={() => {
          // Your custom event handler goes here
        }}
        onPageLoaded={() => {
          // Use it to inject custom markup & attach custom listeners
        }}
        onPageLoading={() => {
          // Use it to load data on demand
        }}
        onResourceClick={() => {
          // Logic for resource click
        }}
        onResourceDoubleClick={() => {
          // Logic for resource double click
        }}
        onResourceDragEnd={() => {
          /* Logic for resource drag end */
        }}
        onResourceDragStart={() => {
          /* Logic for resource drag start */
        }}
        onResourceOrderUpdate={() => {
          // Logic for resource update
        }}
        onResourceCreate={() => {
          // Logic for resource create
        }}
        onResourceCreated={() => {
          // Logic for resource created
        }}
        onResourceDelete={() => {
          // Logic for resource delete
        }}
        onResourceDeleted={() => {
          // Logic for resource deleted
        }}
        onResourceDragEnter={() => {
          // Logic for resource update
        }}
        onResourceDragLeave={() => {
          // Logic for resource update
        }}
        onResourceRightClick={() => {
          // Logic for resource right click
        }}
        onResourceHoverIn={() => {
          // Logic for resource hover in
        }}
        onResourceHoverOut={() => {
          // Logic for resource hover out
        }}
        onSelectedDateChange={() => {
          // Use it to keep track of the selected date externally
        }}
      />
    </>
  );
};
export default App;
```

### CSS

```css
.event-hooks-draggable {
  padding: 10px 20px;
  display: inline-block;
  margin: 15px;
  border-radius: 8px;
  width: 210px;
}

.event-hooks-draggable .draggable-title {
  font-size: 16px;
  font-weight: 600;
}

.event-hooks-draggable .draggable-text {
  opacity: 0.7;
  line-height: 25px;
}

.event-hooks-draggable-1 {
  background: #ffdab8;
}

.event-hooks-draggable-2 {
  background: #ddfcf7;
}
```

## Implementation notes

- Use `timeline: { type: 'day', resourceReorder: true }` - a single-day view with drag-to-reorder resources enabled.
- Define 6 resources with `id`, `name`, and `color`.
- Load events from `https://trial.mobiscroll.com/timeline-events/` via JSONP using `getJson(url, callback, 'jsonp')`. React/Angular/Vue: assign the fetched array to the state/property bound to the `data` prop. Call `inst.setEvents(events)` for the imperative API.
- Add an `invalid` entry blocking 12:00-13:00 recurring on weekdays (`weekDays: 'MO,TU,WE,TH,FR'`).
- Enable all interactions: `dragToCreate: true`, `dragToMove: true`, `dragToResize: true`, `externalDrop: true`, `externalResourceDrop: true`.
- **External draggables** - elements outside the calendar can be registered as Mobiscroll draggables:
  - Event draggables with `dragData: { title, color }` - when dropped onto the calendar, they create new events.
  - One resource draggable with `dragData: { name, color }` and `type="resource"` - when dropped onto the resource column, it creates a new resource row.
  - For the imperative API: use `mbsc-draggable` attribute with `data-drag-data` (JSON string) and `data-type="resource"` on the third card. For component frameworks, use the `Draggable` / `MbscDraggable` component with `dragData` and `type` props.
- **All lifecycle hooks** - register every available hook as an empty handler to catalog them. The handlers contain no logic; the purpose of the demo is to show what hooks exist. Group them by concern:
  - **Cell**: `onCellClick`, `onCellDoubleClick`, `onCellRightClick`, `onCellHoverIn`, `onCellHoverOut`
  - **Event interaction**: `onEventClick`, `onEventDoubleClick`, `onEventRightClick`, `onEventHoverIn`, `onEventHoverOut`
  - **Event create/update/delete**: `onEventCreate`, `onEventCreated`, `onEventCreateFailed`, `onEventDelete`, `onEventDeleted`, `onEventUpdate`, `onEventUpdated`, `onEventUpdateFailed`
  - **Event drag**: `onEventDragStart`, `onEventDragEnd`, `onEventDragEnter`, `onEventDragLeave`
  - **Resource**: `onResourceClick`, `onResourceDoubleClick`, `onResourceRightClick`, `onResourceHoverIn`, `onResourceHoverOut`, `onResourceCreate`, `onResourceCreated`, `onResourceDelete`, `onResourceDeleted`, `onResourceDragStart`, `onResourceDragEnd`, `onResourceDragEnter`, `onResourceDragLeave`, `onResourceOrderUpdate`
  - **Page / lifecycle**: `onInit`, `onDestroy`, `onPageChange`, `onPageLoaded`, `onPageLoading`, `onSelectedDateChange`
- Style each draggable card with padding, border-radius, and `display: inline-block` so they appear as clickable tiles above the calendar.

## Run it in your project

1. If not signed up yet, or don't own a license, you can [start a free trial](https://mobiscroll.com/starttrial).

2. Clone the repository:

   ```
   git clone https://github.com/acidb/mobiscroll-demos-react.git
   ```

3. If not installed yet, install the Mobiscroll CLI from NPM:

   ```
   npm install -g @mobiscroll/cli
   ```

4. Config Mobiscroll - open a terminal window in the root directory and run:

   ```
   mobiscroll config react
   ```

5. Install dependencies - open a terminal window in the root directory and run:

   ```
   npm install
   ```

6. Run the project:

   ```
   npm run dev
   ```

On a trial, add `--trial` to the config command: `mobiscroll config react --trial`.

Running a demo locally requires a Mobiscroll trial or a license; setup is per framework at https://mobiscroll.com/docs/react/getting-started/installation

## Related demos

- Previous: [Gregorian, Jalali & Hijri](https://demo.mobiscroll.com/react/timeline/gregorian-jalali-hijri.md) - Use the React Timeline with Gregorian, Jalali, or Hijri calendar systems — switch by locale to build scheduling interfaces for Persian.
- Next: [Multi-Language Support](https://demo.mobiscroll.com/react/timeline/localization.md) - Localize the React Timeline across 37 languages — dates, times, labels, and RTL text direction adapt by locale, with manual override support.
