apexgantt 3.10.0 → 3.10.2

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.
package/README.md CHANGED
@@ -97,6 +97,9 @@ The layout can be configured by passing a second argument to `ApexGantt` with th
97
97
  | `criticalBarColor` | `string` | `'#e53935'` | Fill color for task bars on the critical path. |
98
98
  | `criticalArrowColor` | `string` | `'#e53935'` | Stroke color for dependency arrows on the critical path. |
99
99
  | `baseline` | `Partial<BaselineOptions>` | `undefined` | When `enabled: true`, renders a thin baseline bar below each task bar. |
100
+ | `enableSelection` | `boolean` | `false` | Enable row selection (click, Ctrl+Click, Shift+Click, keyboard). |
101
+ | `showCheckboxColumn` | `boolean` | `true` | Show a checkbox column for multi-select. Only applies when `enableSelection` is `true`. |
102
+ | `toolbarItems` | `ToolbarItem[]` | `[]` | Custom controls rendered in the toolbar alongside the built-in zoom and export buttons. See [Custom Toolbar](#custom-toolbar). |
100
103
  | `tooltipId` | `string` | `'apexgantt-tooltip-container'` | HTML `id` for the tooltip container element. |
101
104
  | `tooltipTemplate` | `(task, dateFormat) => string` | built-in | Custom function returning an HTML string for the task tooltip. |
102
105
  | `tooltipBorderColor` | `string` | `'#BCBCBC'` | Border color of the tooltip. |
@@ -173,21 +176,43 @@ tooltipTemplate(task, dateFormat) {
173
176
 
174
177
  ### Expected data format to set as Options.series
175
178
 
176
- Each tasks should be in below format
179
+ Each task should be in the following format:
177
180
 
178
181
  ```js
179
182
  [
180
183
  {
181
- id: 'a', // unique id of the task
182
- startTime: '10-11-2024', // start time of the task
183
- endTime: '11-01-2024', // end time of the task
184
- name: 'task 1', // task name
185
- parentId: 'a', // parent task id
186
- progress: 65, // progress in percentage
184
+ id: 'a', // unique id of the task
185
+ startTime: '10-11-2024', // start time of the task
186
+ endTime: '11-01-2024', // end time of the task
187
+ name: 'task 1', // task name
188
+ parentId: 'a', // parent task id
189
+ progress: 65, // progress in percentage (0–100)
190
+ type: 'task', // 'task' (default) or 'milestone'
191
+ dependency: 'other-id', // simple string (Finish-to-Start) or typed object (see below)
192
+ barBackgroundColor: '#537CFA', // override bar color for this task
193
+ rowBackgroundColor: '#FFFFFF', // override row background for this task
194
+ collapsed: false, // whether child tasks are collapsed
195
+ baseline: { // optional planned dates (requires baseline.enabled: true)
196
+ start: '10-10-2024',
197
+ end: '10-30-2024',
198
+ },
187
199
  },
188
200
  ];
189
201
  ```
190
202
 
203
+ ### Typed dependency
204
+
205
+ The `dependency` field accepts either a plain task ID string (treated as Finish-to-Start with 0 lag) or a typed object for full control:
206
+
207
+ ```js
208
+ {
209
+ id: 'task-2',
210
+ dependency: { taskId: 'task-1', type: 'FS', lag: 2 }, // start 2 days after task-1 finishes
211
+ }
212
+ ```
213
+
214
+ Supported dependency types: `'FS'` (Finish-to-Start, default), `'FF'` (Finish-to-Finish), `'SF'` (Start-to-Finish), `'SS'` (Start-to-Start). `lag` is in days; negative values create lead (overlap).
215
+
191
216
  ### Expected annotation format to set as Options.annotations
192
217
 
193
218
  Each tasks should be in below format
@@ -370,6 +395,45 @@ const gantt = new ApexGantt(document.getElementById('gantt'), {
370
395
 
371
396
  **Supported fields:** `id`, `name`, `startTime`, `endTime`, `progress`, `type`, `parentId`, `dependency`, `barBackgroundColor`, `rowBackgroundColor`, `collapsed`
372
397
 
398
+ ## Theming
399
+
400
+ ApexGantt ships with built-in light and dark themes. Use the `theme` option to select a preset, or supply a full `GanttTheme` object for complete control.
401
+
402
+ ```js
403
+ import ApexGantt, {LightTheme, DarkTheme, getTheme} from 'apexgantt';
404
+
405
+ // Built-in presets via string shorthand
406
+ const gantt = new ApexGantt(element, {series: tasks, theme: 'dark'});
407
+
408
+ // Programmatic preset access
409
+ const dark = getTheme('dark');
410
+
411
+ // Override individual colors based on a preset
412
+ const gantt = new ApexGantt(element, {
413
+ series: tasks,
414
+ theme: {...DarkTheme, barBackgroundColor: '#7C3AED'},
415
+ });
416
+ ```
417
+
418
+ ## Enums and Constants
419
+
420
+ ```js
421
+ import {ViewMode, TaskType, ColumnKey, Orientation} from 'apexgantt';
422
+
423
+ // ViewMode — timeline granularity
424
+ ViewMode.Day | ViewMode.Week | ViewMode.Month | ViewMode.Quarter | ViewMode.Year
425
+
426
+ // TaskType — how a task is rendered
427
+ TaskType.Task // horizontal bar
428
+ TaskType.Milestone // diamond marker
429
+
430
+ // ColumnKey — built-in task-list columns
431
+ ColumnKey.Name | ColumnKey.StartTime | ColumnKey.EndTime | ColumnKey.Duration | ColumnKey.Progress
432
+
433
+ // Orientation — annotation line direction
434
+ Orientation.Horizontal | Orientation.Vertical
435
+ ```
436
+
373
437
  ## 📘 Public API
374
438
 
375
439
  ### 1. `update(options)`
@@ -424,17 +488,17 @@ ganttInstance.updateTask('task-1', {
424
488
 
425
489
  ### 3. `zoomIn()`
426
490
 
427
- Zooms in the gantt based on current view mode. View mode direction for zoom in year -> quarter -> month -> week -> day
491
+ Zooms in the gantt based on current view mode. View mode direction for zoom in: year -> quarter -> month -> week -> day
428
492
 
429
493
  #### Example
430
494
 
431
495
  ```js
432
- ganttInstance.zoomOut();
496
+ ganttInstance.zoomIn();
433
497
  ```
434
498
 
435
499
  ### 4. `zoomOut()`
436
500
 
437
- Zooms out the gantt based on current view mode. View mode direction for zoom in day -> week -> month -> quarter -> year
501
+ Zooms out the gantt based on current view mode. View mode direction for zoom out: day -> week -> month -> quarter -> year
438
502
 
439
503
  #### Example
440
504
 
@@ -442,6 +506,143 @@ Zooms out the gantt based on current view mode. View mode direction for zoom in
442
506
  ganttInstance.zoomOut();
443
507
  ```
444
508
 
509
+ ### 5. `getSelectedTasks()`
510
+
511
+ Returns an array of currently selected `Task` objects. Requires `enableSelection: true`.
512
+
513
+ ```js
514
+ const selected = ganttInstance.getSelectedTasks();
515
+ console.log(selected.map((t) => t.id));
516
+ ```
517
+
518
+ ### 6. `setSelectedTasks(ids)`
519
+
520
+ Programmatically set the selection to the given task IDs. Requires `enableSelection: true`.
521
+
522
+ ```js
523
+ ganttInstance.setSelectedTasks(['task-1', 'task-3']);
524
+ ```
525
+
526
+ ### 7. `clearSelection()`
527
+
528
+ Clear all selected tasks. Requires `enableSelection: true`.
529
+
530
+ ```js
531
+ ganttInstance.clearSelection();
532
+ ```
533
+
534
+ ### 8. `renderToolbar(container)`
535
+
536
+ Render the built-in toolbar into a custom DOM element. Normally called automatically by `render()`. Use this only when you need to mount the toolbar in a custom slot outside the chart.
537
+
538
+ ```js
539
+ const toolbarEl = document.getElementById('my-toolbar');
540
+ ganttInstance.renderToolbar(toolbarEl);
541
+ ```
542
+
543
+ ### 9. `isDestroyed()`
544
+
545
+ Returns `true` after `destroy()` has been called, `false` while the chart is live. Use this guard before calling other methods when you are unsure whether the instance is still active.
546
+
547
+ ```js
548
+ if (!ganttInstance.isDestroyed()) {
549
+ ganttInstance.update({series: newTasks});
550
+ }
551
+ ```
552
+
553
+ ### 10. `destroy()`
554
+
555
+ Destroy the chart instance and free all associated resources. Removes all event listeners, disconnects `ResizeObserver`s, clears the tooltip, and clears the DOM. After calling `destroy()` the instance cannot be reused — create a new `ApexGantt` instead.
556
+
557
+ Always call `destroy()` before removing the host element from the DOM or when cleaning up in frameworks.
558
+
559
+ ```js
560
+ // React cleanup example
561
+ useEffect(() => {
562
+ const gantt = new ApexGantt(ref.current, options);
563
+ gantt.render();
564
+ return () => gantt.destroy();
565
+ }, []);
566
+ ```
567
+
568
+ ## Custom Toolbar
569
+
570
+ Add custom buttons, dropdowns, and separators to the toolbar alongside the built-in zoom and export controls. Pass an array of `ToolbarItem` objects to the `toolbarItems` option.
571
+
572
+ ### Toolbar Button
573
+
574
+ ```js
575
+ import ApexGantt, {GanttEvents} from 'apexgantt';
576
+
577
+ const gantt = new ApexGantt(element, {
578
+ series: tasks,
579
+ enableSelection: true,
580
+ toolbarItems: [
581
+ {
582
+ type: 'button',
583
+ label: 'Export Selected',
584
+ tooltip: 'Export selected tasks to CSV',
585
+ position: 'right', // 'left' inserts before built-in controls
586
+ requiresSelection: true, // auto-disabled when nothing is selected
587
+ showCount: true, // label becomes "Export Selected (3)"
588
+ onClick: ({selectedTasks}) => exportToCsv(selectedTasks),
589
+ },
590
+ ],
591
+ });
592
+ ```
593
+
594
+ ### Toolbar Select
595
+
596
+ ```js
597
+ toolbarItems: [
598
+ {
599
+ type: 'select',
600
+ label: 'Filter',
601
+ placeholder: 'All types…',
602
+ position: 'left',
603
+ options: [
604
+ {value: 'task', text: 'Tasks'},
605
+ {value: 'milestone', text: 'Milestones'},
606
+ ],
607
+ onChange: (value, {selectedTasks}) => console.log(value, selectedTasks),
608
+ },
609
+ ],
610
+ ```
611
+
612
+ ### Toolbar Separator
613
+
614
+ ```js
615
+ toolbarItems: [
616
+ {type: 'separator', position: 'right'},
617
+ {type: 'button', label: 'Save', onClick: () => save()},
618
+ ],
619
+ ```
620
+
621
+ ### ToolbarButton properties
622
+
623
+ | Property | Type | Default | Description |
624
+ | --- | --- | --- | --- |
625
+ | `type` | `'button'` | — | Required discriminator. |
626
+ | `label` | `string` | — | Text label inside the button. |
627
+ | `icon` | `string` | — | SVG string rendered as the button icon. |
628
+ | `tooltip` | `string` | — | Tooltip shown on hover. |
629
+ | `position` | `'left' \| 'right'` | `'right'` | Where to insert relative to built-in controls. |
630
+ | `disabled` | `boolean \| (context) => boolean` | — | Static flag or function evaluated on every selection change. |
631
+ | `requiresSelection` | `boolean` | `false` | Auto-disabled when no tasks are selected. |
632
+ | `showCount` | `boolean` | `false` | Appends the selection count to the label, e.g. `"Export (3)"`. |
633
+ | `onClick` | `(context) => void` | — | Called when the button is clicked. |
634
+
635
+ ### ToolbarSelect properties
636
+
637
+ | Property | Type | Default | Description |
638
+ | --- | --- | --- | --- |
639
+ | `type` | `'select'` | — | Required discriminator. |
640
+ | `label` | `string` | — | Optional label rendered before the `<select>`. |
641
+ | `placeholder` | `string` | — | Placeholder option shown when no value is chosen. |
642
+ | `position` | `'left' \| 'right'` | `'right'` | Where to insert relative to built-in controls. |
643
+ | `options` | `{value, text}[]` | — | Options shown in the dropdown. |
644
+ | `onChange` | `(value, context) => void` | — | Called when the selected value changes. |
645
+
445
646
  ## Events
446
647
 
447
648
  ApexGantt emits CustomEvents on the container element for various user interactions, allowing you to track and respond to changes in real-time.
@@ -450,12 +651,14 @@ ApexGantt emits CustomEvents on the container element for various user interacti
450
651
 
451
652
  | Event | When | Detail |
452
653
  | --- | --- | --- |
453
- | `taskUpdate` | Task is being updated | `{ taskId, updates, updatedTask, timestamp }` |
654
+ | `taskUpdate` | Task is being updated (before completion) | `{ taskId, updates, updatedTask, timestamp }` |
454
655
  | `taskUpdateSuccess` | Update completed successfully | `{ taskId, updatedTask, timestamp }` |
455
656
  | `taskValidationError` | Form validation failed | `{ taskId, errors, timestamp }` |
456
657
  | `taskUpdateError` | Update failed | `{ taskId, error, timestamp }` |
457
- | `taskDragged` | Task bar is dragged | `{ taskId, oldStartTime, oldEndTime, newStartTime, newEndTime, daysMoved, affectedChildTasks, timestamp }` |
458
- | `taskResized` | Task bar is resized | `{ taskId, resizeHandle, oldStartTime, oldEndTime, newStartTime, newEndTime, durationChange, timestamp }` |
658
+ | `taskDragged` | Task bar is dragged to a new position | `{ taskId, oldStartTime, oldEndTime, newStartTime, newEndTime, daysMoved, affectedChildTasks, timestamp }` |
659
+ | `taskResized` | Task bar is resized via its handles | `{ taskId, resizeHandle, oldStartTime, oldEndTime, newStartTime, newEndTime, durationChange, timestamp }` |
660
+ | `selectionChange` | Selected task rows change | `{ selectedTasks, selectedIds, timestamp }` |
661
+ | `dependencyArrowUpdate` | Dependency arrow created, updated, or removed | `{ fromId, toId, type, lag, chartInstanceId, arrowLinkInstanceId }` |
459
662
 
460
663
  ### Events Usage
461
664
 
@@ -509,3 +712,29 @@ function GanttChart({tasks}) {
509
712
  return <div ref={containerRef} />;
510
713
  }
511
714
  ```
715
+
716
+ #### TypeScript — typed events with `GanttEventMap`
717
+
718
+ Use the `GanttEventMap` interface for fully-typed `CustomEvent.detail` access:
719
+
720
+ ```typescript
721
+ import ApexGantt, {GanttEventMap} from 'apexgantt';
722
+
723
+ const container = document.getElementById('gantt') as HTMLElement;
724
+ const chart = new ApexGantt(container, {series: tasks, enableSelection: true});
725
+ chart.render();
726
+
727
+ container.addEventListener('taskDragged', (e: GanttEventMap['taskDragged']) => {
728
+ console.log(e.detail.taskId, e.detail.daysMoved);
729
+ });
730
+
731
+ container.addEventListener('selectionChange', (e: GanttEventMap['selectionChange']) => {
732
+ console.log('selected IDs:', e.detail.selectedIds);
733
+ });
734
+
735
+ container.addEventListener('dependencyArrowUpdate', (e: GanttEventMap['dependencyArrowUpdate']) => {
736
+ const {fromId, toId, type, lag} = e.detail;
737
+ console.log(`${fromId} → ${toId} (${type}, lag: ${lag ?? 0})`);
738
+ });
739
+ ```
740
+
package/apexgantt.d.ts CHANGED
@@ -369,7 +369,7 @@ export declare class DataParser {
369
369
  }
370
370
 
371
371
  /**
372
- * Detail payload for the `dependency-arrow-update` event.
372
+ * Detail payload for the `dependencyArrowUpdate` event.
373
373
  *
374
374
  * Fires when the user creates, updates, or removes a dependency arrow
375
375
  * between two tasks in the interactive dependency editor.
@@ -431,7 +431,7 @@ export declare interface GanttEventMap {
431
431
  /** Fires when the set of selected tasks changes. */
432
432
  selectionChange: CustomEvent<SelectionChangeEventDetail>;
433
433
  /** Fires when a dependency arrow is updated. */
434
- 'dependency-arrow-update': CustomEvent<DependencyArrowUpdateDetail>;
434
+ dependencyArrowUpdate: CustomEvent<DependencyArrowUpdateDetail>;
435
435
  }
436
436
 
437
437
  export declare const GanttEvents: {