Skip to content

DHTMLX/react-scheduler-xstate-starter

Repository files navigation

DHTMLX React Scheduler with XState State Machines

A demo of DHTMLX React Scheduler integrated with XState for client-side state management. All event mutations flow through an XState state machine, with undo/redo via history snapshots, view/date state, and event coloring via templates.event_class. Built with React, TypeScript, and Vite.

What is DHTMLX React Scheduler with XState Starter

This demo shows how to use XState — a library for modeling application logic as finite state machines — as the state layer for DHTMLX React Scheduler. All calendar events live inside an XState machine defined in machine.ts. Every mutation (create, update, delete) is an explicit, typed event dispatched to the machine via Scheduler's data.save callback, and every state transition is a named action.

One feature unique to this starter among the Scheduler demos is event coloring: events in the seed data carry a classname property, and the Scheduler's templates.event_class function reads that property to apply CSS classes per event. This is a practical pattern for rendering events with different visual categories (e.g., meeting, deadline, reminder) without custom Scheduler themes.

When to Use

  • Use this demo when your Scheduler integration has complex conditional state logic that is difficult to express as plain store mutations.
  • Use this when you need formal guarantees that certain invalid states are impossible by construction, enforced by the machine's transition model.
  • Use this as a reference for combining XState history snapshots with Scheduler's data.save callback for undo/redo.
  • Use this when you want a working example of per-event CSS class assignment via templates.event_class.

Quick Start

git clone https://github.com/DHTMLX/react-scheduler-xstate-starter
cd react-scheduler-xstate-starter
npm install
npm run dev

Open http://localhost:5173 in your browser.

Requirements: Node.js 18+, npm.

How to Try

  • Switch between Day, Week, and Month views.
  • Click-drag on an empty slot to create a new event — it dispatches a CREATE event to the machine.
  • Drag an existing event to a new time — dispatches an UPDATE event.
  • Delete an event — dispatches a DELETE event.
  • Click Undo and Redo in the toolbar to step through machine history.
  • Notice that events in the seed data appear in different colors — these are driven by classname on each event and templates.event_class in the Scheduler config.

Architecture

src/
├── components/
│   └── Scheduler.tsx     # Scheduler mount, templates (event_class), data.save → machine bridge
├── machine.ts            # XState machine: states, events, history, reducers
├── seed/
│   └── data.ts           # Seed events with classname, default view and date
└── App.tsx

The machine (machine.ts) owns all state: events, current view, active date, and undo/redo history. Scheduler.tsx subscribes to machine state and passes events, view, and date as props to the Scheduler. When Scheduler fires data.save(...) after a user mutation, Scheduler.tsx dispatches the corresponding typed machine event. The machine transitions, records a history snapshot, and React re-renders.

Key Patterns

  • data.save to machine event bridge — Scheduler's data.save(entity, action, data, id) callback is the single entry point for all mutations. Scheduler.tsx maps each action type (add, update, delete) to a named XState event, dispatching it to the machine. This makes every possible Scheduler mutation visible and traceable in the machine definition.
  • Machine history snapshots for undo/redo — undo/redo is implemented by recording machine context snapshots on every mutation transition. Dispatching UNDO or REDO events restores the corresponding snapshot, replaying state without custom history stack logic outside the machine.
  • Event coloring via templates.event_class — each seed event carries a classname field (e.g. "event-type-a"). The Scheduler's templates.event_class function returns that value, and CSS rules in index.css apply the visual style. This is the correct DHTMLX Scheduler pattern for category-based event coloring.
  • View and date as machine context — active view and current date live inside machine context alongside event data. The toolbar dispatches SET_VIEW and SET_DATE events to navigate; these transitions are intentionally excluded from undo history.
  • Impossible states by construction — the machine's explicit state and transition definitions structurally prevent conflicting concurrent states (such as processing two mutations simultaneously) without defensive runtime guards.

Features

Feature Details
Event CRUD Create, update, and delete events via machine events dispatched from data.save
Drag-and-drop Event rescheduling and resize dispatched as UPDATE machine events
Views Day, week, and month
Custom toolbar View switcher, Prev/Next/Today navigation, undo/redo
Undo/redo Machine history snapshot-based, covers event mutations only
Event coloring Per-event CSS classes via classname field and templates.event_class
Explicit state model Named states and typed transitions in machine.ts
TypeScript Full type coverage for machine events, context, and event data
Vite Fast dev server and production build

Production Notes

This demo is a starter, not a production-ready application. For production use:

  • Add persistence — events are in-memory only; page refresh resets to seed data. Add a machine service or onTransition handler that syncs context to an API or database after each mutation.
  • Extend the machine for your workflow — the demo machine covers CRUD and undo/redo. For real scheduling apps, consider adding states for loading, saving, conflict detection, and optimistic updates. XState's statechart model handles this growth well.
  • Add XState DevTools — XState has a dedicated inspector (Stately DevTools) for visualizing and stepping through machine states. Recommended for any non-trivial machine.
  • Expand event coloring — the demo uses static classname values in seed data. In a real app, derive classname from event properties (type, owner, priority) and define the corresponding CSS in a shared stylesheet.
  • Scheduler license — DHTMLX React Scheduler requires a valid commercial license for production use (see License section below).

Related Resources

License

The source code in this repository is released under the MIT License.

Commercial License Required for proprietary or commercial applications. Includes access to PRO features, dedicated technical support, and long-term maintenance. Learn more →

Try before you buy A free evaluation of DHTMLX React Gantt is available — no credit card required. Start your evaluation →

Releases

Packages

Contributors

Languages