From 4f913c0089c4b5866ce06cd8ab1856046a066a1c Mon Sep 17 00:00:00 2001 From: Maksim Lakatkou Date: Tue, 28 Apr 2026 23:41:38 +0200 Subject: [PATCH] feat: add dhtmlx-react-scheduler skill --- README.md | 13 ++ dhtmlx-react-scheduler/SKILL.md | 92 ++++++++++++ .../references/advanced-patterns.md | 53 +++++++ .../references/data-and-crud.md | 90 ++++++++++++ .../references/known-failures.md | 70 +++++++++ .../references/react-integration.md | 118 +++++++++++++++ .../references/styling-and-theming.md | 136 ++++++++++++++++++ 7 files changed, 572 insertions(+) create mode 100644 dhtmlx-react-scheduler/SKILL.md create mode 100644 dhtmlx-react-scheduler/references/advanced-patterns.md create mode 100644 dhtmlx-react-scheduler/references/data-and-crud.md create mode 100644 dhtmlx-react-scheduler/references/known-failures.md create mode 100644 dhtmlx-react-scheduler/references/react-integration.md create mode 100644 dhtmlx-react-scheduler/references/styling-and-theming.md diff --git a/README.md b/README.md index b14f343..6b00bc3 100644 --- a/README.md +++ b/README.md @@ -27,11 +27,23 @@ Guides AI agents through building and integrating DHTMLX React Gantt in web appl - Styling, CSS variables, template-based visual customization - Common pitfalls and constraints +### `dhtmlx-react-scheduler` + +Guides AI agents through building and integrating DHTMLX React Scheduler in web applications. Covers: + +- Package installation (trial and commercial) +- CSS setup and layout requirements +- React integration patterns +- Event state, mapping, and persistence +- Scheduler views, resources, lightboxes, and conflict checks +- Styling, CSS variables, template-based visual customization +- Common pitfalls and constraints ## Installation ```bash npx skills add DHTMLX/skills --skill dhtmlx-react-gantt +npx skills add DHTMLX/skills --skill dhtmlx-react-scheduler ``` Or copy manually: @@ -39,6 +51,7 @@ Or copy manually: ```bash git clone https://github.com/DHTMLX/skills cp -r skills/dhtmlx-react-gantt ~/.claude/skills/ +cp -r skills/dhtmlx-react-scheduler ~/.claude/skills/ ``` ## Requirements diff --git a/dhtmlx-react-scheduler/SKILL.md b/dhtmlx-react-scheduler/SKILL.md new file mode 100644 index 0000000..608f219 --- /dev/null +++ b/dhtmlx-react-scheduler/SKILL.md @@ -0,0 +1,92 @@ +--- +name: dhtmlx-react-scheduler +description: > + Builds and integrates DHTMLX React Scheduler into React applications. Covers setup, props, + templates, themes, data.save, data.batchSave, and + React integration patterns for @dhtmlx/trial-react-scheduler and @dhx/react-scheduler. + Applies when working with booking calendars, resource scheduling, event CRUD, timeline/day/week/month + views, lightboxes, or scheduling conflict checks in React apps — regardless of whether + "DHTMLX" is mentioned by name. Provides verified API guidance rather than guessing React Scheduler APIs. +paths: "**/*.tsx,**/*.jsx,**/*.ts,**/*.js,package.json" +allowed-tools: Read Grep +metadata: + tags: dhtmlx, scheduler, booking, calendar, resources, events +--- + +## Source Of Truth + +Use only: +1. The current project's files, structure, and established patterns +2. DHTMLX MCP for React Scheduler API details: https://docs.dhtmlx.com/mcp +3. Official DHTMLX React Scheduler docs as fallback: https://docs.dhtmlx.com/scheduler/integrations/react/ + +Never invent props, hooks, templates, callback signatures, event names, or backend behavior. + +If any React Scheduler API detail is unclear, resolve it through DHTMLX MCP before writing code. + +## Preflight + +Before writing code, identify: +- **package**: `@dhtmlx/trial-react-scheduler` or `@dhx/react-scheduler` — check `package.json`, imports, lockfiles +- **runtime**: React, Next.js (needs `"use client"`), Remix, or other React-based setup +- **ownership model**: React-managed (default) or Scheduler-managed (large datasets, Scheduler-centric app) +- **persistence**: local only, `data.save` (default, single-entity), or `data.batchSave` (bulk sync) + +## Workflow + +1. Confirm the installed DHTMLX React Scheduler package and import path. +2. Decide the data ownership model before implementing features. +3. Read only the reference file needed for the task: + - React integration/setup: [references/react-integration.md](references/react-integration.md) + - CRUD, state, and persistence: [references/data-and-crud.md](references/data-and-crud.md) + - Failure cases and guardrails: [references/known-failures.md](references/known-failures.md) + - Advanced patterns (views, resources, conflicts, undo/redo): [references/advanced-patterns.md](references/advanced-patterns.md) + - Styling, theming, CSS variables, selectors, and template-based visual customization: [references/styling-and-theming.md](references/styling-and-theming.md) +4. Use DHTMLX MCP before relying on advanced or unfamiliar APIs. +5. Implement with documented APIs only. + +## MCP Server + +This skill relies on DHTMLX MCP for API verification. If the `dhtmlx-mcp` tool is not available, ask the user to add it: + +Claude Code: +```bash +claude mcp add --transport http dhtmlx-mcp https://docs.dhtmlx.com/mcp +``` + +Codex: +```bash +codex mcp add dhtmlx-mcp --url https://docs.dhtmlx.com/mcp +``` + +If MCP is not available, use the official docs at https://docs.dhtmlx.com/scheduler/integrations/react/ as fallback. + +## Consult MCP First For + +Consult DHTMLX MCP before using or changing: +- template callbacks you have not already verified +- advanced props such as `batchSave`, `customLightbox`, `modals`, `view`, or `filter` +- timeline configuration details and related callback signatures +- event handler signatures (`on`) when behavior is not fully clear +- theme/skin methods and runtime view-switch behavior via `ref` instance API +- collision/limit/recurring plugin behavior in combined setups + +## Hard Rules + +- The Scheduler container must have explicit height. +- CSS import must match the installed package and be a separate import line. +- Use the app theme as the single source of truth. +- Prefer JavaScript `Date` objects for `start_date` and `end_date` in React-managed mode. +- Normalize date values before persistence. +- Build backend payloads explicitly from normalized event models. +- Do not use undocumented internals when a documented prop or ref API exists. +- Do not mix React-managed props and imperative instance mutations unless synchronization is intentional. + +## Quick Checklist + +- [ ] Correct package identified +- [ ] Matching CSS import used +- [ ] Explicit height provided +- [ ] Data ownership model chosen +- [ ] Dates normalized before persistence +- [ ] Advanced APIs verified with MCP diff --git a/dhtmlx-react-scheduler/references/advanced-patterns.md b/dhtmlx-react-scheduler/references/advanced-patterns.md new file mode 100644 index 0000000..74389f4 --- /dev/null +++ b/dhtmlx-react-scheduler/references/advanced-patterns.md @@ -0,0 +1,53 @@ +# Advanced Patterns + +Use this file when implementing custom views, plugins, advanced filtering, undo/redo, or scheduling safeguards. + +## Contents +- Views And Plugins As Optional Features +- Resource/Section Mapping +- Undo/Redo With State Management +- Conflict And Availability Guards +- Custom Fields And Backend Mapping + +## Views And Plugins As Optional Features + +When configuring non-trivial custom views: +- verify required plugin set and view configuration with MCP +- verify callback signatures and payload shapes with MCP + +## Resource/Section Mapping + +- keep one canonical event field for section/resource assignment (for example `resource_id`) +- ensure section keys and event assignment values use the same ID type/format +- map section labels from persisted data, not hardcoded display-only arrays +- if unassigned events are supported, keep their behavior explicit in UI and persistence +- keep row/section mapping deterministic across reloads and refetches + +Guardrails: +- do not silently remap unknown section IDs +- verify timeline/section configuration details with MCP before implementation + +## Undo/Redo With State Management + +- use refs to access the latest state snapshot inside `data.save` callbacks — do not rely on render-time closures +- if using Redux or another external store for Scheduler history, normalize date values before writing to the store (state must be serializable) +- undo and redo actions must also update persistence — client-only history creates data gaps on reload +- persist history snapshots when rehydration across sessions is required +- save or refetch operations must not wipe the undo/redo history stack +- keep history refs and store state in sync after every mutation + +## Conflict And Availability Guards + +- run conflict/availability checks before persistence when the app requires scheduling rules +- typical checks: overlap on the same assignment field (for example `resource_id`), location scope, and business-hours window +- keep the check path explicit: `candidate event -> checks -> decision -> persist` +- if conflicts need confirmation, require explicit user confirmation before save +- if conflicts are blocked, stop the write and keep UI state consistent with persisted state + +## Custom Fields And Backend Mapping + +- treat custom fields (for example `location_id`, `resource_id`, `service_id`, `status`, `notes`) as app-level schema and keep them explicit in all CRUD paths +- map backend rows to Scheduler events explicitly (including `start_date` / `end_date` conversion) +- map Scheduler write payloads to backend payloads explicitly; do not persist raw callback objects +- keep server-assigned IDs and client temporary IDs synchronized with a deterministic replacement flow +- if the app has scope constraints (for example location-scoped resources/services), validate them before persistence diff --git a/dhtmlx-react-scheduler/references/data-and-crud.md b/dhtmlx-react-scheduler/references/data-and-crud.md new file mode 100644 index 0000000..8cc4399 --- /dev/null +++ b/dhtmlx-react-scheduler/references/data-and-crud.md @@ -0,0 +1,90 @@ +# Data And CRUD + +Use this file when events, state ownership, or persistence are involved. + +## Data Model Essentials + +Prefer JavaScript `Date` objects for event date fields in React-managed mode. + +Minimum event shape: +```ts +interface Event { + id: string | number; + text: string; + start_date: Date; + end_date: Date; +} +``` + +When loading from a backend, map rows explicitly into Scheduler event objects. Do not pass raw DB rows straight through. + +## Choose The Ownership Model First + +For most React apps, use React-managed data: +- keep `events` in React state or a state manager +- pass them into `` +- handle updates with `data.save` or `data.batchSave` + +Use Scheduler-managed data only when: +- datasets are very large +- mass updates are frequent +- React does not need to react to every edit +- the page is primarily Scheduler-centric + +## CRUD Default + +For normal CRUD, prefer `data.save`. + +Pattern: +```tsx + { + // update local state + // sync backend + // return { id } after creates when backend assigns a real ID + }, + }} +/> +``` + +Strict rules: +- update state from the latest current snapshot, not stale closure state +- for `create`, if the backend assigns a real ID, return `{ id: realId }` +- for `update`, persist only normalized values +- for `delete`, remove from local state and persistence layer +- normalize date values before serialization +- if using temporary IDs, replace them deterministically after persistence +- build backend payloads explicitly from normalized event models, not from raw callback objects + +## Date Formatting And Normalization + +Treat `start_date` and `end_date` in persistence callbacks as `Date | string`, and normalize them before backend writes: + +```ts +function toIso(value: Date | string): string { + const date = value instanceof Date ? value : new Date(value); + if (Number.isNaN(date.getTime())) throw new Error("Invalid date"); + return date.toISOString(); +} +``` + +On backend read, map persisted date strings back into `Date` objects before passing to Scheduler. + +## When To Use batchSave + +Use `data.batchSave` when: +- one user action can emit many related changes +- bulk backend sync is more appropriate than single-event persistence +- grouped change handling is required + +Do not switch to `batchSave` casually. Verify exact behavior and payload shape with MCP first. + +## Persistence Guardrails + +- Do not persist raw Scheduler callback objects directly. +- Keep app-level custom fields explicit in mapping (for example `location_id`, `resource_id`, `service_id`). +- Reject or sanitize writes that violate application constraints before hitting the backend. +- Keep create/update/delete paths idempotent and deterministic. +- If the app introduces undo/redo, persistence rules must remain correct after history actions. diff --git a/dhtmlx-react-scheduler/references/known-failures.md b/dhtmlx-react-scheduler/references/known-failures.md new file mode 100644 index 0000000..8d3b148 --- /dev/null +++ b/dhtmlx-react-scheduler/references/known-failures.md @@ -0,0 +1,70 @@ +# Known Failures + +Use this file when debugging incorrect or flaky DHTMLX React Scheduler integrations. + +## 1. Theme Drift + +Problem: +- app shell and Scheduler follow different theme sources + +Fix: +- use one shared app theme source +- apply Scheduler theme/skin from that source +- do not introduce separate Scheduler-only theme state + +## 2. Date Serialization Bugs + +Problem: +- write handlers receive mixed date shapes (`Date` and/or string) +- backend writes become inconsistent or invalid + +Fix: +- treat `start_date` and `end_date` as `Date | string` +- normalize before persistence +- map backend date strings back to `Date` before passing events to Scheduler + +## 3. Stale Callback State + +Problem: +- `data.save` handlers capture old event arrays or old store snapshots + +Fix: +- use refs, functional updates, or current-store snapshots +- do not build persistence logic from stale render-time closures + +## 4. ID Replacement Gaps + +Problem: +- create flow keeps temporary client IDs after backend persistence +- later update/delete targets the wrong event + +Fix: +- make temp-id -> persisted-id replacement deterministic +- synchronize replacement in both local state and Scheduler instance data + +## 5. Mixed Ownership Bugs + +Problem: +- React props and imperative Scheduler instance mutations both modify events without synchronization + +Fix: +- choose ownership model first +- if imperative mutations are required, keep React-managed event props synchronized deliberately + +## 6. Wrong Template Or Handler Signature + +Problem: +- callback wired with wrong parameter order or wrong payload assumptions + +Fix: +- verify exact documented signature with MCP +- do not infer callback arguments from memory + +## 7. Implicit Height Containers + +Problem: +- Scheduler is mounted into a container without real height +- rendering is broken or collapsed + +Fix: +- provide explicit container height diff --git a/dhtmlx-react-scheduler/references/react-integration.md b/dhtmlx-react-scheduler/references/react-integration.md new file mode 100644 index 0000000..93b2c95 --- /dev/null +++ b/dhtmlx-react-scheduler/references/react-integration.md @@ -0,0 +1,118 @@ +# React Integration + +Use this file when setting up or modifying the React wrapper integration. + +## Installation + +Trial: +```bash +npm install @dhtmlx/trial-react-scheduler +``` + +Commercial (requires private registry setup and login): +```bash +npm config set @dhx:registry=https://npm.dhtmlx.com +npm login --registry=https://npm.dhtmlx.com --scope=@dhx +npm install @dhx/react-scheduler +``` +The user must generate credentials in the [Client's Area](https://dhtmlx.com/clients/) and run the registry config and login commands themselves before the package can be installed. See [installation docs](https://docs.dhtmlx.com/scheduler/integrations/react/installation/) for details. + +CSS import must match the installed package and must be a separate import line: + +```ts +import "@dhtmlx/trial-react-scheduler/dist/react-scheduler.css"; +``` + +or + +```ts +import "@dhx/react-scheduler/dist/react-scheduler.css"; +``` + +## Next.js + +In Next.js (App Router), add `"use client"` at the top of the Scheduler component file. Next.js uses Server Components by default, but React Scheduler must render as a Client Component. + +## Height Rule + +The Scheduler container must have explicit height. + +Valid: +```tsx +
+ +
+``` + +## Documented Props + +Use documented props only: + +- `events` +- `view` +- `date` +- `config` +- `templates` +- `xy` +- `data` +- `customLightbox` +- `modals` +- `filter` +- `on` +- `ref` + +## Ref Access + +Use `ref` with `ReactSchedulerRef` when direct instance access is required: + +```tsx +const schedulerRef = useRef(null); +const scheduler = schedulerRef.current?.instance; +``` + +If you mutate data through the instance while also passing `events` as props, keep them synchronized. Otherwise React can overwrite those changes on re-render. + +## Theme Rule + +Use the app theme as the single source of truth. + +Example: +```tsx +useEffect(() => { + const scheduler = schedulerRef.current?.instance; + if (!scheduler) return; + scheduler.setSkin(appTheme === "dark" ? "dark" : "terrace"); +}, [appTheme]); +``` + +Do not introduce separate Scheduler-only theme state if the app already has a global theme source. + +## Config And Templates + +Wrap `config` and `templates` in `useMemo` when they contain functions. + +Typical: +```tsx +const config: SchedulerConfig = useMemo(() => ({ ... }), [deps]); +const templates: SchedulerTemplates = useMemo(() => ({ ... }), [deps]); +``` + +Common documented config areas: +- `config.first_hour` +- `config.last_hour` +- `config.hour_size_px` +- `config.time_step` +- `config.readonly` +- `config.drag_move` +- `config.drag_resize` +- `config.drag_create` +- `config.header` + +Do not guess template callback signatures. Verify with MCP if there is any doubt. + +## Event Handlers + +When wiring `on` callbacks: +- verify exact callback signatures with MCP +- keep handlers side-effect-safe and avoid stale closure state +- route writes through one persistence path (`data.save` or controlled app action), not both at once diff --git a/dhtmlx-react-scheduler/references/styling-and-theming.md b/dhtmlx-react-scheduler/references/styling-and-theming.md new file mode 100644 index 0000000..7f5cbdb --- /dev/null +++ b/dhtmlx-react-scheduler/references/styling-and-theming.md @@ -0,0 +1,136 @@ +# Styling And Theming + +Use this file when theming Scheduler, matching an app design system, or styling events, rows, scales, and dialogs. + +## Contents +- Styling Priority +- Theme Variables First +- Use Config/XY For Layout And Geometry +- Data-Driven Styling +- Rows And Timeline Cells +- Common Selectors And Escape Hatches +- Practical Guardrails + +## Styling Priority + +Use this order by default: +1. CSS variables for global theme alignment +2. templates and config/xy for semantic or data-driven styling +3. direct CSS selectors only for structural exceptions + +## Theme Variables First + +CSS variables are the preferred customization path. + +Define shared variables at `:root` so inheritance works correctly across the component: + +```css +:root { + --dhx-scheduler-font-family: Inter, sans-serif; + --dhx-scheduler-font-size: 14px; + + --dhx-scheduler-container-background: #ffffff; + --dhx-scheduler-container-color: #0f172a; + + --dhx-scheduler-event-background: #2563eb; + --dhx-scheduler-event-color: #ffffff; +} +``` + +Map app design tokens to Scheduler variables instead of inventing Scheduler-only colors. + +## Use Config/XY For Layout And Geometry + +Some visible behavior belongs to Scheduler config/xy, not CSS: +- `config.first_hour` +- `config.last_hour` +- `config.hour_size_px` +- `config.time_step` +- `config.readonly` +- `xy` sizing values + +Do not force these through CSS when a documented config/xy option exists. + +## Data-Driven Styling + +When styling depends on event data, prefer templates. + +Use `event_class` for semantic styling by status/priority/type: + +```ts +const templates = { + event_class: (_start: Date, _end: Date, event: Event) => { + return event.status ? `event-${event.status}` : ""; + }, +}; +``` + +```css +.event-confirmed { + --dhx-scheduler-event-background: #16a34a; +} +``` + +Supported event color shortcut fields: +- `color` +- `textColor` + +Important caveat: +- these fields are event-level visual overrides +- they can conflict with class-based styling expectations in complex themes + +Use event-level color fields only when the app truly stores per-event visual values as data. For reusable semantic styling, `event_class` is usually safer. + +Advanced pattern: +- if colors come from backend-driven entities such as owners, stages, or statuses, generate CSS classes from the loaded dataset and return those classes from `event_class` + +## Rows And Timeline Cells + +Use view-specific row/cell templates: + +Timeline/Units hooks: +- `..._row_class` templates for row-level classes +- `..._cell_class` templates for cell-level classes +- `..._cell_value` templates for cell content/value rendering + +Day/Week hooks: +- `time_slot_class` for slot-level classes +- `time_slot_text` for slot-level content + +Month/Calendar hooks: +- calendar/month templates and documented CSS classes for month/day rendering + +## Common Selectors And Escape Hatches + +Use these when variables or templates are not enough: + +Event elements: +- `.dhx_cal_event` +- `.dhx_cal_header` +- `.dhx_title` +- `.dhx_cal_data` + +Day/Week grid and scale: +- `.dhx_scale_holder` + +Timeline/Units cells: +- `.dhx_matrix_cell` +- `.dhx_matrix_scell` +- `.dhx_matrix_line` + +Month/Calendar elements: +- `.dhx_month_head` +- `.dhx_cal_container .dhx_mini_calendar .dhx_month_head` + +Dialogs and overlays: +- `.dhx_cal_light` + +Prefer scoped selectors under a local wrapper class to avoid global collisions. + +## Practical Guardrails + +- prefer CSS variables for theme-wide restyling before touching selectors +- prefer templates when styling depends on event, slot, or section data +- prefer scoped selectors over global overrides when changing only one view area +- do not force config/xy-controlled behavior through CSS +- keep theme source unified with the app-level theme state