@code-rhapsodie/react-scheduler 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,4 @@
1
+ import { CSSProperties } from "react";
1
2
  import { LocaleType } from "@/context/LocaleProvider/types";
2
3
  import { ColorType } from "@/styles";
3
4
  export declare const allZoomLevel: readonly [0, 1, 2];
@@ -100,6 +101,14 @@ export type SchedulerProjectData = {
100
101
  * Background color of the tile, given in rgb color model. If not given, default color (rgb(114, 141,226 )) is set. Optional
101
102
  */
102
103
  bgColor?: string;
104
+ /**
105
+ * Whether the tile can be dragged when onTileMove is provided. Defaults to true. Optional
106
+ */
107
+ draggable?: boolean;
108
+ /**
109
+ * Additional inline styles applied to the tile (e.g. backgroundImage). Optional
110
+ */
111
+ style?: CSSProperties;
103
112
  };
104
113
  export type Day = {
105
114
  hour: number;
@@ -169,4 +178,55 @@ export type TooltipData = {
169
178
  resourceIndex: number;
170
179
  disposition: OccupancyData;
171
180
  };
181
+ export type CellClickData = {
182
+ /**
183
+ * Id of the resource (row) the clicked cell belongs to
184
+ */
185
+ resourceId: string;
186
+ /**
187
+ * Date represented by the clicked cell
188
+ */
189
+ date: Date;
190
+ };
191
+ export type CellRangeSelectData = {
192
+ /**
193
+ * Id of the resource (row) the selected range belongs to
194
+ */
195
+ resourceId: string;
196
+ /**
197
+ * First date of the selected range
198
+ */
199
+ startDate: Date;
200
+ /**
201
+ * Last date of the selected range
202
+ */
203
+ endDate: Date;
204
+ };
205
+ export type SelectedRange = {
206
+ resourceId: string;
207
+ startDate: Date;
208
+ endDate: Date;
209
+ };
210
+ export type TileMoveData = {
211
+ /**
212
+ * Id of the moved tile's underlying item
213
+ */
214
+ id: string;
215
+ /**
216
+ * Id of the resource (row) the tile was dragged from
217
+ */
218
+ previousResourceId: string;
219
+ /**
220
+ * Id of the resource (row) the tile was dropped onto
221
+ */
222
+ resourceId: string;
223
+ /**
224
+ * New start date, shifted by the same amount the tile was dragged by
225
+ */
226
+ startDate: Date;
227
+ /**
228
+ * New end date, keeping the tile's original duration
229
+ */
230
+ endDate: Date;
231
+ };
172
232
  export {};
@@ -0,0 +1,27 @@
1
+ import { Coords, Day } from "@/types/global";
2
+ export type GridCell = {
3
+ date: Date;
4
+ resourceIndex: number;
5
+ };
6
+ /**
7
+ * Resolves the date and resource row under a given point inside the grid canvas,
8
+ * from the same column/row geometry the grid itself is drawn with.
9
+ */
10
+ export declare const resolveGridCell: (startDate: Day, cursorPosition: Coords, rowsPerPerson: number[], zoom: number) => GridCell;
11
+ export type CellRect = {
12
+ x: number;
13
+ y: number;
14
+ width: number;
15
+ height: number;
16
+ };
17
+ /**
18
+ * The inverse of resolveGridCell: the pixel rect of a given resource row's cell on a
19
+ * given date, on the top (first) sub-row of that resource.
20
+ */
21
+ export declare const getCellRect: (startDate: Day, rowsPerPerson: number[], resourceIndex: number, date: Date, zoom: number) => CellRect | null;
22
+ /**
23
+ * The pixel rect spanning every cell between rangeStart and rangeEnd (inclusive), on a
24
+ * single resource row. The two dates may be given in either order (e.g. when a selection
25
+ * is dragged leftwards from its anchor).
26
+ */
27
+ export declare const getCellRangeRect: (startDate: Day, rowsPerPerson: number[], resourceIndex: number, rangeStart: Date, rangeEnd: Date, zoom: number) => CellRect | null;
@@ -0,0 +1,3 @@
1
+ import dayjs from "dayjs";
2
+ export declare const getCellWidth: (zoom: number) => number;
3
+ export declare const getCellTimeUnit: (zoom: number) => dayjs.ManipulateType;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-rhapsodie/react-scheduler",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "repository": {
package/readme.md CHANGED
@@ -155,15 +155,19 @@ const mockedSchedulerData: SchedulerData = [
155
155
 
156
156
  ##### Scheduler Component Props
157
157
 
158
- | Property Name | Type | Arguments | Description |
159
- | ----------------- | ---------- | --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
160
- | isLoading | `boolean` | - | shows loading indicators on scheduler |
161
- | onRangeChange | `function` | updated `startDate` and `endDate` | runs whenever user reaches end of currently rendered canvas |
162
- | onTileClick | `function` | clicked resource data | detects resource click |
163
- | onItemClick | `function` | clicked left column item data | detects item click on left column |
164
- | onFilterData | `function` | - | callback firing when filter button was clicked |
165
- | onClearFilterData | `function` | - | callback firing when clear filters button was clicked (clearing button is visible **only** when filterButtonState is set to `>0`) |
166
- | config | `Config` | - | object with scheduler config properties |
158
+ | Property Name | Type | Arguments | Description |
159
+ | ----------------- | ------------------------- | --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
160
+ | isLoading | `boolean` | - | shows loading indicators on scheduler |
161
+ | onRangeChange | `function` | updated `startDate` and `endDate` | runs whenever user reaches end of currently rendered canvas |
162
+ | onTileClick | `function` | clicked resource data | detects resource click |
163
+ | onItemClick | `function` | clicked left column item data | detects item click on left column |
164
+ | onFilterData | `function` | - | callback firing when filter button was clicked |
165
+ | onClearFilterData | `function` | - | callback firing when clear filters button was clicked (clearing button is visible **only** when filterButtonState is set to `>0`) |
166
+ | onCellClick | `function` | `CellClickData` | fired when clicking an empty cell (a resource row on a given date, with no tile) without dragging to another date |
167
+ | onCellRangeSelect | `function` | `CellRangeSelectData` | fired when dragging across several cells of the same resource row, from mouse down to mouse up |
168
+ | onTileMove | `function` | `TileMoveData` | fired when a tile is dragged and dropped onto a new cell. Providing it enables tile drag & drop |
169
+ | selectedCell | `SelectedRange` or `null` | - | cell or range of cells to highlight on the grid, e.g. the last selection made via `onCellClick` / `onCellRangeSelect` |
170
+ | config | `Config` | - | object with scheduler config properties |
167
171
 
168
172
  ##### Scheduler Config Object
169
173
 
@@ -276,16 +280,115 @@ data that is accessible as argument of `onItemClick` callback
276
280
 
277
281
  item that will be visible on the grid as tile and that will be accessible as argument of `onTileClick` event
278
282
 
279
- | Property Name | Type | Description |
280
- | ------------- | ------------------- | ------------------------------------------------------------------------------------------------------- |
281
- | id | `string` | unique resource id |
282
- | title | `string` | resource title that will be displayed on resource tile |
283
- | subtitle | `string (optional)` | resource subtitle that will be displayed on resource tile |
284
- | description | `string (optional)` | resource description that will be displayed on resource tile |
285
- | startDate | `Date` | date for calculating start position for resource |
286
- | endDate | `Date` | date for calculating end position for resource |
287
- | occupancy | `number` | number of seconds resource takes up for given row that will be visible on resource tooltip when hovered |
288
- | bgColor | `string (optional)` | tile color |
283
+ | Property Name | Type | Description |
284
+ | ------------- | -------------------------- | ------------------------------------------------------------------------------------------------------- |
285
+ | id | `string` | unique resource id |
286
+ | title | `string` | resource title that will be displayed on resource tile |
287
+ | subtitle | `string (optional)` | resource subtitle that will be displayed on resource tile |
288
+ | description | `string (optional)` | resource description that will be displayed on resource tile |
289
+ | startDate | `Date` | date for calculating start position for resource |
290
+ | endDate | `Date` | date for calculating end position for resource |
291
+ | occupancy | `number` | number of seconds resource takes up for given row that will be visible on resource tooltip when hovered |
292
+ | bgColor | `string (optional)` | tile color |
293
+ | draggable | `boolean (optional)` | whether the tile can be dragged when `onTileMove` is provided. Defaults to `true` |
294
+ | style | `CSSProperties (optional)` | additional inline styles applied to the tile (e.g. `backgroundImage`), overriding the default ones |
295
+
296
+ ### Cell selection and drag & drop
297
+
298
+ The scheduler supports selecting empty cells and rescheduling tiles by dragging them. These interactions are opt-in: they are only enabled when the matching callbacks are provided.
299
+
300
+ - **Cell click / range selection**: pressing the mouse on the grid and releasing it on the same cell fires `onCellClick`; dragging across several cells of the same resource row fires `onCellRangeSelect` (the range can be dragged in either direction, `startDate` is always the earliest date). While dragging, the selected range is highlighted.
301
+ - **Highlighting a selection**: the scheduler does not keep the selection itself. Pass it back through the `selectedCell` prop to keep it highlighted (set it to `null` to clear it).
302
+ - **Tile drag & drop**: when `onTileMove` is provided, every tile becomes draggable (unless its `draggable` property is set to `false`). While dragging, a ghost preview shows where the tile will land. On drop, `onTileMove` receives the new resource and dates: the tile keeps its original duration and the point where it was grabbed is preserved. The scheduler does not update its data by itself, so update your `data` in the callback.
303
+
304
+ ```tsx
305
+ import {
306
+ Scheduler,
307
+ SchedulerData,
308
+ CellClickData,
309
+ CellRangeSelectData,
310
+ SelectedRange,
311
+ TileMoveData
312
+ } from "@code-rhapsodie/react-scheduler";
313
+
314
+ export default function Component() {
315
+ const [data, setData] = useState<SchedulerData>(mockedSchedulerData);
316
+ const [selectedCell, setSelectedCell] = useState<SelectedRange | null>(null);
317
+
318
+ const handleCellClick = ({ resourceId, date }: CellClickData) =>
319
+ setSelectedCell({ resourceId, startDate: date, endDate: date });
320
+
321
+ const handleCellRangeSelect = (range: CellRangeSelectData) => setSelectedCell(range);
322
+
323
+ const handleTileMove = ({
324
+ id,
325
+ previousResourceId,
326
+ resourceId,
327
+ startDate,
328
+ endDate
329
+ }: TileMoveData) =>
330
+ setData((rows) => {
331
+ const tile = rows
332
+ .find((row) => row.id === previousResourceId)
333
+ ?.data.find((item) => item.id === id);
334
+ if (!tile) return rows;
335
+
336
+ return rows.map((row) => {
337
+ const items = row.data.filter((item) => item.id !== id);
338
+ return row.id === resourceId
339
+ ? { ...row, data: [...items, { ...tile, startDate, endDate }] }
340
+ : { ...row, data: items };
341
+ });
342
+ });
343
+
344
+ return (
345
+ <Scheduler
346
+ data={data}
347
+ onCellClick={handleCellClick}
348
+ onCellRangeSelect={handleCellRangeSelect}
349
+ onTileMove={handleTileMove}
350
+ selectedCell={selectedCell}
351
+ />
352
+ );
353
+ }
354
+ ```
355
+
356
+ ##### Cell Click Data
357
+
358
+ argument of `onCellClick` callback
359
+
360
+ | Property Name | Type | Description |
361
+ | ------------- | -------- | -------------------------------------------- |
362
+ | resourceId | `string` | id of the resource (row) the cell belongs to |
363
+ | date | `Date` | date represented by the clicked cell |
364
+
365
+ ##### Cell Range Select Data
366
+
367
+ argument of `onCellRangeSelect` callback, same shape as the `SelectedRange` accepted by the `selectedCell` prop
368
+
369
+ | Property Name | Type | Description |
370
+ | ------------- | -------- | --------------------------------------------- |
371
+ | resourceId | `string` | id of the resource (row) the range belongs to |
372
+ | startDate | `Date` | first date of the selected range |
373
+ | endDate | `Date` | last date of the selected range |
374
+
375
+ ##### Tile Move Data
376
+
377
+ argument of `onTileMove` callback
378
+
379
+ | Property Name | Type | Description |
380
+ | ------------------ | -------- | ------------------------------------------------------------- |
381
+ | id | `string` | id of the moved resource item |
382
+ | previousResourceId | `string` | id of the resource (row) the tile was dragged from |
383
+ | resourceId | `string` | id of the resource (row) the tile was dropped onto |
384
+ | startDate | `Date` | new start date, shifted by the amount the tile was dragged by |
385
+ | endDate | `Date` | new end date, keeping the tile's original duration |
386
+
387
+ All these types (`CellClickData`, `CellRangeSelectData`, `SelectedRange`, `TileMoveData`) are exported from the package.
388
+
389
+ ### Navigation transitions
390
+
391
+ Moving to the previous or next period with the top bar buttons now plays a short slide animation on the grid, in the direction of the navigation.
289
392
 
290
393
  ### Troubleshooting
291
394