Data model
Resources and events
Section titled “Resources and events”interface Resource { id: string; name: string; role?: string; // shown under the name by the default header events: SchedulerEvent[];}
interface SchedulerEvent { id: string; title: string; startDate: Date; endDate: Date; // exclusive color?: string; // any CSS color description?: string;}By default an event lives in the events array of its resource. Moving an event to another row means taking it out of one array and putting it in another, which onEventDrop tells you to do.
Or as one flat list
Section titled “Or as one flat list”If your data is a table of bookings, pass it as events and name the resource on each event instead. Then resources only needs id and name:
const people = [ { id: "ann", name: "Ann" }, { id: "bob", name: "Bob" },];const events = [ { id: "1", title: "Standup", resourceId: "ann", startDate, endDate }, { id: "2", title: "Kickoff", resourceIds: ["ann", "bob"], startDate, endDate }, // drawn in both rows];
<ResourceScheduler resources={people} events={events} />Both styles work together: flat events are added to whatever a resource holds in its own events. Events that name an unknown resource are not drawn. The handlers are unchanged and still give you fromResourceId and toResourceId, so a move is a setEvents(...) that changes the resourceId. For an event in resourceIds, swap fromResourceId for toResourceId in the list. Conflict rules see flat events too.
Event is still exported as a deprecated alias of SchedulerEvent. Prefer the new name: Event shadows the DOM global.
End times are exclusive
Section titled “End times are exclusive”An event from 9:00 to 10:00 occupies 9:00 up to, but not including, 10:00. Another event starting at 10:00 does not overlap it. For all-day events, end at midnight of the next day: Monday to Wednesday inclusive is start = Mon 00:00, end = Thu 00:00, and the default card shows “All day”.
You own the state
Section titled “You own the state”The scheduler does not copy resources. It reads the prop on every render, and when the user does something it calls a handler:
| Handler | When |
|---|---|
onEventCreate(event, resourceId) |
A click or drag on empty slots, if you did not provide onSlotSelect |
onSlotSelect({ resourceId, start, end }) |
The same gesture, handing you the range so you open your own dialog |
onEventDrop(event, fromId, toId, start, end) |
An event was moved |
onEventResize(event, resourceId, start, end) |
An event edge was dragged |
onEventClick(event, resource) |
An event was clicked |
Update your state in those and pass the new resources back. If you load data from a server, do the request in the handler and update state when it succeeds.
Only the events inside the visible range are drawn, so passing a whole year of events is fine for a week view.