React Schedule
4.2KB gzipped
The Schedule component is an event scheduling interface for React applications. It supports day, week, and weekdays views with drag-and-drop event management. Built for appointment systems, team calendars, and resource scheduling.
- Day, week, and weekdays views
- Drag and drop events
- Create, edit, delete events
- Resource/calendar scheduling
- Keyboard navigation
CalendarJS Product Suite
Section titled “CalendarJS Product Suite”CalendarJS is a complete calendar and scheduling solution that includes:
- Calendar - Date picker with range selection (3.18KB)
- Schedule - Event scheduler with drag & drop (this page)
- Timeline - Chronological event display (2.1KB)
Related Components
Section titled “Related Components”Calendar - Date Selection
Section titled “Calendar - Date Selection”Before scheduling events, users often need to select dates. The Calendar component provides:
- Single and range date selection
- Date validation and restrictions
- International date formats
- Keyboard navigation
Perfect for: Date pickers in booking forms, availability selectors, report date ranges
Timeline - Chronological Display
Section titled “Timeline - Chronological Display”For displaying events in a chronological list format instead of a calendar grid, use the Timeline component:
- Event logs and activity feeds
- Project roadmaps and milestones
- Monthly grouped views
- Ascending/descending sort
Perfect for: Activity logs, project timelines, event history, roadmaps
LemonadeJS Timeline - Reactive Framework
Section titled “LemonadeJS Timeline - Reactive Framework”For reactive applications, LemonadeJS Timeline provides:
- Reactive data binding
- Vue, React, Angular integration
- Built on CalendarJS Timeline
Documentation
Section titled “Documentation”Installation
Section titled “Installation”npm install @calendarjs/react react
Settings
Section titled “Settings”| Property | Description |
|---|---|
type?: 'week' | 'day' | 'weekdays' | Schedule view type. Default: 'week'. |
weekly?: boolean | Weekly schedule mode. No date associated to columns, just day of week. Default: false. |
value?: string | Initial date in ISO format (YYYY-MM-DD). |
data?: EventInput[] | Array of event objects to display. Loose input shape — only start is required (see below). |
grid?: number | Grid time interval in minutes. Default: 15. |
snap?: number | Snap step (in minutes) for create/resize gestures. Independent of grid — e.g. grid: 15, snap: 60 keeps 15-minute rows visible but locks event duration to 60-minute increments. Defaults to grid. |
overlap?: boolean | Accept time overlap between events. Default: false. |
validRange?: string[] | Valid time range [startTime, endTime] in HH:MM format. |
readOnlyRange?: string[] | string[][] | Read-only time range. Single: ['08:00', '18:00'] or multiple: [['00:00', '08:00'], ['18:00', '23:59']]. |
Event types — input vs resolved
Section titled “Event types — input vs resolved”The package distinguishes the input shape (what you pass into data, addEvents, updateEvent) from the resolved shape (what callbacks and getData() hand back, with defaults filled in). See the TypeScript guide for full details.
EventInput — loose input shape
Section titled “EventInput — loose input shape”Only start is required; the component fills in defaults (guid, title, color, type) on render. An index signature lets you attach app-specific metadata (class_id, teacher_id, ...) without casts.
| Property | Description |
|---|---|
start: string | Required. Start time in HH:MM format. |
end?: string | End time in HH:MM format. |
title?: string | Event title displayed on the schedule. |
color?: string | Event background color (hex). |
guid?: string | Unique identifier (auto-generated if omitted). |
type?: string | null | Event type/category. |
date?: string | Event date in YYYY-MM-DD format. Used when weekly is false. |
weekday?: number | Day of the week (0-6, Sunday is 0). Used when weekly is true. |
guests?: string | Guests list. |
location?: string | Event location. |
description?: string | Event description. |
readonly?: boolean | Event is read-only (cannot be edited). |
visible?: boolean | Event visibility. |
warning?: boolean | Show warning border on event. |
[key: string]: any | App-specific metadata (no cast required). |
Event — resolved runtime shape
Section titled “Event — resolved runtime shape”Returned by getData() and passed to callbacks. Extends EventInput with guid, title, color, and type always present.
interface Event extends EventInput {
guid: string;
title: string;
color: string;
type: string | null;
}
Events
Section titled “Events”Use the camelCase names in React (e.g. onCreate instead of oncreate). Handlers receive just the data — the Schedule instance is available via the forwarded ref.
| Event | Description |
|---|---|
onBeforeCreate | Before events are created. Return false to cancel. Always called with an array (length ≥ 1).onBeforeCreate?: (events: Event[], e?: MouseEvent) => boolean | void |
onCreate | Called after events are created. Always called with an array (length ≥ 1). The MouseEvent is forwarded for interactive creates.onCreate?: (events: Event[], e?: MouseEvent) => void |
onBeforeInsert | Per-event hook during the drag-to-create gesture. Return a modified event, or false to drop it.onBeforeInsert?: (event: Event) => Event | boolean | void |
onDblClick | Called on double-click of an event.onDblClick?: (event: Event) => void |
onEdition | Triggered when an event is being edited (double click or after creation).onEdition?: (event: Event) => void |
onBeforeChangeEvent | Before a drag/resize change is applied to an event. Return false to cancel.onBeforeChangeEvent?: (state: object) => boolean | void |
onChangeEvent | Called after updateEvent applies changes.onChangeEvent?: (event: Event, oldValue: Partial<Event>, newValue: Partial<Event>) => void |
onDelete | Called for each event deleted via deleteEvents or the Delete key.onDelete?: (event: Event) => void |
onBeforeChange | Fires before updateEvent / deleteEvents / setData. Return false to cancel. state.action identifies the operation.onBeforeChange?: (state: { action: 'updateEvent' | 'deleteEvents' | 'setData', ...rest }) => boolean | void |
onChange | Fires after updateEvent / deleteEvents / setData and after an interactive create.onChange?: () => void |
onError | Fires when an action is rejected (invalid range, conflict, disabled slot, ...).onError?: (message: string) => void |
Methods
Section titled “Methods”Methods are called via the forwarded ref: ref.current.addEvents(...).
| Method | Description |
|---|---|
addEvents(events: EventInput | EventInput[], e?: MouseEvent): Event[] | false | Add one or more events. Accepts the loose EventInput shape — defaults are filled in. |
updateEvent(guidOrEvent: string | Event, newValue: Partial<EventInput>): void | false | Update an event by guid or reference. Returns false if the change is rejected (onBeforeChange, conflict, disabled range). |
deleteEvents(events: Event | Event[] | string | string[]): void | false | Delete one or more events. Returns false if onBeforeChange cancels. |
getData(): Event[] | Get all events data (resolved shape). |
setData(data: EventInput[]): void | false | Replace all events. Accepts the loose EventInput shape. Returns false if onBeforeChange cancels. |
getEvent(guid: string): HTMLElement | null | Get event DOM element by guid. Returns null if not found. |
setRange(range: string[]): void | Set valid time range. |
setReadOnly(range: string[] | string[][]): void | Set read-only time range. |
resetSelection(e?: MouseEvent): void | Reset current selection. |
render(): void | Render the schedule. |
next(): void | Navigate to the next period (day / week depending on type). |
prev(): void | Navigate to the previous period. |
today(): void | Reset value to today's date. |
undo(): void | Undo last change. |
redo(): void | Redo last undone change. |
Properties
Section titled “Properties”Read on the underlying instance via ref.current.
| Property | Description |
|---|---|
type: 'week' | 'day' | 'weekdays' | Current schedule view type. |
weekly: boolean | Weekly schedule mode. |
value: string | Current date value in ISO format. |
data: Event[] | Array of events. |
grid: number | Grid time interval in minutes. |
snap: number | Snap step (in minutes) for create/resize gestures. |
overlap: boolean | Accept time overlap between events. |
validRange?: string[] | Valid time range. |
readOnlyRange?: string[] | string[][] | Read-only time range. |
el: HTMLElement | The root element. |
tbody: HTMLTableSectionElement | The <tbody> element holding all time-row cells. |
headers: Array<{ day: string, weekday: number, value: string, selected: boolean, el: HTMLElement }> | Header row entries (one per visible column). |
pointer: HTMLElement | Element used to render the current-time pointer. |
Examples
Section titled “Examples”Basic Schedule
Section titled “Basic Schedule”import { useState } from 'react';
import { Schedule } from '@calendarjs/react';
export default function App() {
const [events] = useState([
{ guid: 'evt-1', title: 'Team Meeting', date: '2025-12-03', start: '10:00', end: '11:00', color: '#3498db' },
{ guid: 'evt-2', title: 'Project Review', date: '2025-12-04', start: '14:00', end: '15:30', color: '#e74c3c' }
]);
return <Schedule type="week" value="2025-12-01" data={events} style={{ height: '500px' }} />;
}
With Event Handlers
Section titled “With Event Handlers”onCreate is always called with an array (length ≥ 1) — no Array.isArray unwrap needed.
import { useState } from 'react';
import { Schedule } from '@calendarjs/react';
export default function App() {
const [events] = useState([]);
return (
<Schedule
type="week"
value="2025-12-01"
data={events}
style={{ height: '500px' }}
onCreate={(events) => events.forEach((ev) => console.log('Created:', ev.title))}
onChangeEvent={(event) => console.log('Updated:', event.title)}
onDelete={(event) => console.log('Deleted:', event.title)}
/>
);
}
Controlled with React state
Section titled “Controlled with React state”Replace the array reference (don't mutate in place) and the schedule re-renders:
import { useCallback, useState } from 'react';
import { Schedule } from '@calendarjs/react';
export default function App() {
const [events, setEvents] = useState([
{ start: '09:00', end: '10:00', date: '2025-01-15', title: 'Standup' },
]);
// Memoize so the wrapper's prop diff sees a stable reference.
const onCreate = useCallback(
(created) => setEvents((prev) => [...prev, ...created]),
[],
);
const onDelete = useCallback(
(event) => setEvents((prev) => prev.filter((e) => e.guid !== event.guid)),
[],
);
return (
<Schedule
type="week"
value="2025-01-15"
data={events}
onCreate={onCreate}
onDelete={onDelete}
style={{ height: 500 }}
/>
);
}
Imperative with useSchedule
Section titled “Imperative with useSchedule”The hook returns a callback ref plus a reactive instance — null before mount, the live instance after. Useful when you want to drive UI off of "is the schedule ready?".
import { useState } from 'react';
import { Schedule, useSchedule } from '@calendarjs/react';
export default function App() {
const { ref, instance } = useSchedule();
const [events, setEvents] = useState([]);
return (
<>
<button
disabled={!instance}
onClick={() => instance.addEvents([{ start: '09:00', end: '10:00' }])}
>
Add event
</button>
<button disabled={!instance} onClick={() => instance.undo()}>Undo</button>
<Schedule
ref={ref}
type="week"
value="2025-01-15"
data={events}
onCreate={(created) => setEvents((prev) => [...prev, ...created])}
style={{ height: 500 }}
/>
</>
);
}
App metadata on events (TypeScript)
Section titled “App metadata on events (TypeScript)”The EventInput index signature accepts arbitrary keys — no as any:
import { Schedule } from '@calendarjs/react';
import type { Schedule as ScheduleNS } from '@calendarjs/react';
const events: ScheduleNS.EventInput[] = [
{ start: '09:00', end: '10:00', class_id: 42, teacher_id: 7 },
{ start: '10:00', end: '11:00', class_id: 42, teacher_id: 7 },
];
const onCreate = (created: ScheduleNS.Event[]) => {
created.forEach((ev) => console.log(ev.guid, ev.class_id));
};
<Schedule data={events} onCreate={onCreate} />
See TypeScript for the full input-vs-resolved type guide.
Related
Section titled “Related”- Event Management
- Time Configuration
- Weekly Mode
- Hooks —
useScheduleand friends - TypeScript — input vs resolved types, app metadata