iris-gantt 1.4.11 → 1.5.1

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
@@ -2,27 +2,36 @@
2
2
 
3
3
  A comprehensive, production-ready Gantt chart component built with React and TypeScript. Easy to install, simple to use, fully customizable, and responsive.
4
4
 
5
- ## 🆕 Version 1.4.10 (Latest)
5
+ ## 🆕 Version 1.5.0 (Latest)
6
6
 
7
7
  ### Bug Fixes
8
+ - **On-Hold correctly renders over completed tasks** — The grey hatched on-hold overlay now correctly sits *above* the task bar in the DOM tree. Previously, the `status-completed` blue background colour overrode it.
9
+ - **On-Hold overlay stays visible on hover** — Raised the CSS `z-index` of `.gantt-on-hold-period` to `101 !important`. The task bar hover state elevates to `z-index: 100`, so the hold pattern will no longer disappear when you mouse over a task.
10
+
8
11
  - **OnHold grey lines now render with project API data** — Fixed a bug where on-hold grey bars were not visible when tasks used API field names (`workGroupName`, `plannedStartDate`, `plannedEndDate`). The normalizer now recognises these aliases, so dates are correctly resolved and the hold period overlap is detected.
9
12
 
13
+ ### Improvements
14
+ - **Prop-driven day/week/month timeline switcher** — You can now expose a calendar view switcher in the toolbar and control the available `day`, `week`, and `month` views through props.
15
+
10
16
  ### New API Field Aliases
17
+
11
18
  The `tasks` prop now accepts the following additional field names used by common project APIs:
12
19
 
13
- | New alias | Maps to |
14
- |---|---|
15
- | `workGroupName` | Task display name |
20
+ | New alias | Maps to |
21
+ | ------------------ | ------------------- |
22
+ | `workGroupName` | Task display name |
16
23
  | `plannedStartDate` | Task bar start date |
17
- | `plannedEndDate` | Task bar end date |
24
+ | `plannedEndDate` | Task bar end date |
18
25
 
19
26
  ## 🔖 Version 1.4.6
20
27
 
21
28
  ### Bug Fixes
29
+
22
30
  - **Baselines now show by default** — Fixed a critical bug where baselines were not rendering because the `config` spread was overriding the default `baselines: true` with `undefined`. Baselines are now always enabled unless you explicitly pass `config={{ baselines: false }}`.
23
31
  - **`on_hold_periods` snake_case prop supported** — The Gantt component now accepts both `onHoldPeriods` (camelCase) and `on_hold_periods` (snake_case) as a top-level prop for project-level on-hold periods. Previously only the camelCase variant was recognized, causing the feature to silently fail for API-style payloads.
24
32
 
25
33
  ### Improvements
34
+
26
35
  - **Project-level OnHold applied to all tasks** — The `onHoldPeriods` / `on_hold_periods` prop now propagates the grey hatched on-hold bar to **all** task rows including `project`-type tasks. Previously, only child/standalone tasks showed the hold bar; now the entire project hierarchy displays it consistently.
27
36
  - **Same-height on-hold bars** — The grey on-hold period bar is now the same height (28px) as the task bar.
28
37
  - **Tasks continue after hold period** — When a project resumes after an on-hold period, all affected tasks continue in sequence after the hold, and remaining days are extended automatically.
@@ -31,6 +40,7 @@ The `tasks` prop now accepts the following additional field names used by common
31
40
  ## 🔖 Version 1.4.2
32
41
 
33
42
  ### Included Changes
43
+
34
44
  - **Per-task tooltip config** — Each task can now carry its own `tooltipConfig` to override global tooltip settings (show/hide fields, labels, accessors, formatters).
35
45
  - **Unified `onTaskDragUpdate` callback** — Single callback for all drag operations: task bar move/resize AND row reorder (grip icon drag-and-drop).
36
46
  - **Row reorder API integration** — `onTaskDragUpdate` now fires with `dragType: 'reorder'` and `reorderMeta` (sequence IDs, stage ID) when tasks are reordered via grip icon.
@@ -51,6 +61,7 @@ The `tasks` prop now accepts the following additional field names used by common
51
61
  ## ✨ Features
52
62
 
53
63
  ### Core Features
64
+
54
65
  - ✅ Interactive task management
55
66
  - ✅ Drag & drop task bars
56
67
  - ✅ Task dependencies with 4 link types (end-to-start, start-to-start, end-to-end, start-to-end)
@@ -61,6 +72,7 @@ The `tasks` prop now accepts the following additional field names used by common
61
72
  - ✅ Light & dark themes
62
73
 
63
74
  ### Advanced Features
75
+
64
76
  - ✅ Auto-scheduling
65
77
  - ✅ Critical path analysis
66
78
  - ✅ **Baselines (always visible, automatically created)**
@@ -69,7 +81,8 @@ The `tasks` prop now accepts the following additional field names used by common
69
81
  - ✅ Filtering & search
70
82
  - ✅ Resource leveling
71
83
  - ✅ **Fully responsive** (desktop, tablet, mobile)
72
- - ✅ **Fully customizable** (all text, buttons, colors, fonts)
84
+ - ✅ **Fully customizable** (all text, buttons, colors, fonts, icons)
85
+ - ✅ **Vertical Marker Lines** (Today & Project Start)
73
86
 
74
87
  ## 📦 Installation
75
88
 
@@ -93,31 +106,31 @@ npm install @fortawesome/react-fontawesome@^3.1.0
93
106
  ## 🚀 Quick Start
94
107
 
95
108
  ```tsx
96
- import { Gantt } from 'iris-gantt'
97
- import 'iris-gantt/gantt.css'
109
+ import { Gantt } from "iris-gantt";
110
+ import "iris-gantt/gantt.css";
98
111
 
99
112
  function MyGantt() {
100
113
  const tasks = [
101
114
  {
102
- id: '1',
103
- text: 'Project Planning',
115
+ id: "1",
116
+ text: "Project Planning",
104
117
  start: new Date(2024, 0, 1),
105
118
  end: new Date(2024, 0, 15),
106
119
  duration: 14,
107
120
  progress: 100,
108
- type: 'project',
121
+ type: "project",
109
122
  },
110
123
  {
111
- id: '2',
112
- text: 'Development',
124
+ id: "2",
125
+ text: "Development",
113
126
  start: new Date(2024, 0, 15),
114
127
  end: new Date(2024, 1, 15),
115
128
  duration: 31,
116
129
  progress: 60,
117
130
  },
118
- ]
131
+ ];
119
132
 
120
- return <Gantt tasks={tasks} />
133
+ return <Gantt tasks={tasks} />;
121
134
  }
122
135
  ```
123
136
 
@@ -133,19 +146,25 @@ function MyGantt() {
133
146
 
134
147
  ```tsx
135
148
  // Main component (named import - recommended)
136
- import { Gantt } from 'iris-gantt'
149
+ import { Gantt } from "iris-gantt";
137
150
 
138
151
  // Main component (default import - also works)
139
- import Gantt from 'iris-gantt'
152
+ import Gantt from "iris-gantt";
140
153
 
141
154
  // Types
142
155
  import type {
143
- Task, Link, GanttConfig, GanttUIConfig, GanttStyleConfig,
144
- TaskTooltipConfig, TaskDragUpdatePayload, TaskReorderMeta,
145
- } from 'iris-gantt'
156
+ Task,
157
+ Link,
158
+ GanttConfig,
159
+ GanttUIConfig,
160
+ GanttStyleConfig,
161
+ TaskTooltipConfig,
162
+ TaskDragUpdatePayload,
163
+ TaskReorderMeta,
164
+ } from "iris-gantt";
146
165
 
147
166
  // CSS (required!)
148
- import 'iris-gantt/gantt.css'
167
+ import "iris-gantt/gantt.css";
149
168
  ```
150
169
 
151
170
  ## 🔧 Basic Configuration
@@ -155,12 +174,112 @@ import 'iris-gantt/gantt.css'
155
174
  tasks={tasks}
156
175
  links={links}
157
176
  config={{
158
- theme: 'light',
177
+ theme: "light",
159
178
  weekends: true,
160
- containerHeight: '100%',
161
- containerMinHeight: '400px',
179
+ containerHeight: "100%",
180
+ containerMinHeight: "400px",
181
+ timelineView: "day",
182
+ timelineViews: ["day", "week", "month"],
183
+ }}
184
+ uiConfig={{
185
+ timelineViewLabels: {
186
+ day: "Days",
187
+ week: "Weeks",
188
+ month: "Months",
189
+ },
190
+ }}
191
+ onTaskUpdate={(task) => console.log("Updated:", task)}
192
+ />
193
+ ```
194
+
195
+ ## View Switcher
196
+
197
+ Use the toolbar switcher to toggle the calendar between day, week, and month views.
198
+
199
+ ```tsx
200
+ <Gantt
201
+ tasks={tasks}
202
+ config={{
203
+ timelineView: "week",
204
+ timelineViews: ["day", "week", "month"],
205
+ timelineViewScales: {
206
+ day: [
207
+ { unit: "month", step: 1, format: "MMM YYYY" },
208
+ { unit: "day", step: 1, format: "D" },
209
+ ],
210
+ week: [
211
+ { unit: "month", step: 1, format: "MMM YYYY" },
212
+ { unit: "week", step: 1, format: "Week W" },
213
+ ],
214
+ month: [
215
+ { unit: "year", step: 1, format: "YYYY" },
216
+ { unit: "month", step: 1, format: "MMM" },
217
+ ],
218
+ },
219
+ }}
220
+ uiConfig={{
221
+ timelineViewLabels: {
222
+ day: "Days",
223
+ week: "Weeks",
224
+ month: "Months",
225
+ },
226
+ }}
227
+ />
228
+ ```
229
+
230
+ ## 📍 Vertical Marker Lines
231
+
232
+ The Gantt chart supports vertical indicator lines for the current date (Today) and the project start date. Both are enabled by default and come with customizable markers and labels.
233
+
234
+ ```tsx
235
+ <Gantt
236
+ tasks={tasks}
237
+ config={{
238
+ // Today Line
239
+ showTodayLine: true,
240
+ todayLineColor: "#ff4d4f",
241
+ todayLineLabel: "Today",
242
+ todayLineStyle: "solid", // 'solid' | 'dashed' | 'dotted'
243
+ todayLineWidth: 1,
244
+ todayLineOpacity: 1,
245
+ showTodayLineMarker: true, // Triangle marker at the top
246
+ todayLineMarkerStyle: "triangle", // 'triangle' | 'arrow' | 'dot'
247
+
248
+ // Project Start Line
249
+ showProjectStartLine: true,
250
+ projectStartDate: new Date(2024, 0, 1), // Optional: defaults to earliest task
251
+ projectStartLineColor: "#40a9ff",
252
+ projectStartLineLabel: "Kick-off",
253
+ projectStartLineStyle: "dashed",
254
+ showProjectStartLineMarker: true,
255
+ }}
256
+ />
257
+ ```
258
+
259
+ ## 🎨 Custom Icons
260
+
261
+ You can replace any UI icon by passing a React component or a string (for font-icon classes) to the `iconConfig` prop. This allows you to match your project's icon library (e.g., Ant Design, Lucide, FontAwesome).
262
+
263
+ ```tsx
264
+ <Gantt
265
+ tasks={tasks}
266
+ iconConfig={{
267
+ // Toolbar
268
+ addTask: <PlusCircleOutlined />, // React node
269
+ zoomIn: "fas fa-search-plus", // Font-icon string
270
+ zoomOut: "fas fa-search-minus",
271
+ exportPDF: <FilePdfOutlined />,
272
+
273
+ // Grid
274
+ gripVertical: <HolderOutlined />,
275
+ chevronRight: <RightOutlined />,
276
+ chevronDown: <DownOutlined />,
277
+
278
+ // Context Menu
279
+ edit: <EditOutlined />,
280
+ delete: <DeleteOutlined />,
281
+ copy: <CopyOutlined />,
162
282
  }}
163
- onTaskUpdate={(task) => console.log('Updated:', task)}
164
283
  />
165
284
  ```
166
285
 
@@ -178,17 +297,18 @@ All task hover fields are configurable via props and can be mapped from API valu
178
297
  showStatus: true,
179
298
  showDependencyRule: true,
180
299
  showProgress: true,
181
- plannedLabel: 'Planned start/end',
182
- actualLabel: 'Actual start/end',
183
- statusLabel: 'Current status',
184
- dependencyRuleLabel: 'Dependency rule',
185
- progressLabel: 'Progress',
186
- ownerLabel: 'Owner',
187
- dateFormat: 'MMM D, YYYY',
300
+ plannedLabel: "Planned start/end",
301
+ actualLabel: "Actual start/end",
302
+ statusLabel: "Current status",
303
+ dependencyRuleLabel: "Dependency rule",
304
+ progressLabel: "Progress",
305
+ ownerLabel: "Owner",
306
+ dateFormat: "MMM D, YYYY",
188
307
  taskNameAccessor: (task) => task.text,
189
308
  statusAccessor: (task) => task.status,
190
309
  progressAccessor: (task) => task.progress,
191
- dependencyRuleAccessor: (task, generatedRules) => task.dependencyRule || generatedRules,
310
+ dependencyRuleAccessor: (task, generatedRules) =>
311
+ task.dependencyRule || generatedRules,
192
312
  }}
193
313
  />
194
314
  ```
@@ -202,9 +322,9 @@ Each task can override the global `taskTooltipConfig` with its own `tooltipConfi
202
322
  tasks={[
203
323
  {
204
324
  id: 1,
205
- text: 'Task with custom tooltip',
206
- start: '2026-01-01',
207
- end: '2026-01-10',
325
+ text: "Task with custom tooltip",
326
+ start: "2026-01-01",
327
+ end: "2026-01-10",
208
328
  duration: 9,
209
329
  progress: 50,
210
330
  tooltipConfig: {
@@ -212,7 +332,8 @@ Each task can override the global `taskTooltipConfig` with its own `tooltipConfi
212
332
  showDependencyRule: false,
213
333
  showProgress: true,
214
334
  showActualDates: true,
215
- plannedStartAccessor: (task) => customDataMap.get(task.id)?.plannedStart,
335
+ plannedStartAccessor: (task) =>
336
+ customDataMap.get(task.id)?.plannedStart,
216
337
  plannedEndAccessor: (task) => customDataMap.get(task.id)?.plannedEnd,
217
338
  actualStartAccessor: (task) => customDataMap.get(task.id)?.actualStart,
218
339
  actualEndAccessor: (task) => customDataMap.get(task.id)?.actualEnd,
@@ -220,9 +341,9 @@ Each task can override the global `taskTooltipConfig` with its own `tooltipConfi
220
341
  },
221
342
  {
222
343
  id: 2,
223
- text: 'Task using global tooltip config',
224
- start: '2026-01-05',
225
- end: '2026-01-15',
344
+ text: "Task using global tooltip config",
345
+ start: "2026-01-05",
346
+ end: "2026-01-15",
226
347
  duration: 10,
227
348
  progress: 30,
228
349
  // No tooltipConfig — uses global taskTooltipConfig
@@ -233,6 +354,7 @@ Each task can override the global `taskTooltipConfig` with its own `tooltipConfi
233
354
  ```
234
355
 
235
356
  API-friendly task aliases accepted in `tasks`:
357
+
236
358
  - Name: `text`, `name`, `title`, `taskName`, `task_name`, `workGroupName`
237
359
  - Drag/resize handles: `ShowHandle` (boolean), `showHandle` (boolean)
238
360
  - OnHold periods: `onHoldPeriods`, `on_hold_periods`, `onHold`, `on_hold`, `onhold`
@@ -248,11 +370,13 @@ API-friendly task aliases accepted in `tasks`:
248
370
  ## ⏸️ OnHold In `tasks` Props
249
371
 
250
372
  You can pass paused periods directly inside each task using either:
373
+
251
374
  - `onHoldPeriods` (camelCase)
252
375
  - `on_hold_periods` (snake_case API style)
253
376
  - `onHold`, `on_hold`, `onhold` (additional API aliases)
254
377
 
255
378
  Each alias accepts either:
379
+
256
380
  - An array of periods: `[{ start, end }, ...]`
257
381
  - A single period object: `{ start, end }`
258
382
 
@@ -263,14 +387,14 @@ Date values can be `Date`, ISO date string, or timestamp number.
263
387
  tasks={[
264
388
  {
265
389
  id: 1,
266
- text: 'Development',
267
- start: '2026-02-01',
268
- end: '2026-02-20',
390
+ text: "Development",
391
+ start: "2026-02-01",
392
+ end: "2026-02-20",
269
393
  duration: 19,
270
394
  progress: 45,
271
395
  on_hold_periods: [
272
- { start: '2026-02-06', end: '2026-02-09' },
273
- { start: '2026-02-12', end: '2026-02-13' },
396
+ { start: "2026-02-06", end: "2026-02-09" },
397
+ { start: "2026-02-12", end: "2026-02-13" },
274
398
  ],
275
399
  },
276
400
  ]}
@@ -286,16 +410,16 @@ Date values can be `Date`, ISO date string, or timestamp number.
286
410
  tasks={tasks}
287
411
  uiConfig={{
288
412
  // Header
289
- headerTitle: 'My Project Gantt',
413
+ headerTitle: "My Project Gantt",
290
414
  showHeader: true,
291
-
415
+
292
416
  // Toolbar Buttons
293
417
  showAddTaskButton: true,
294
418
  showZoomButtons: true,
295
419
  showExportButtons: true,
296
420
  showFilterSearch: true,
297
- addTaskButtonText: 'Add New Task',
298
-
421
+ addTaskButtonText: "Add New Task",
422
+
299
423
  // All labels, placeholders, tooltips are configurable
300
424
  // See USAGE.md for complete list
301
425
  }}
@@ -309,17 +433,17 @@ Date values can be `Date`, ISO date string, or timestamp number.
309
433
  tasks={tasks}
310
434
  styleConfig={{
311
435
  // Colors - Match your brand
312
- primary: '#37a9ef',
313
- success: '#77d257',
314
- warning: '#fcba2e',
315
- danger: '#fe6158',
316
- background: '#ffffff',
317
- fontColor: '#333333',
318
-
436
+ primary: "#37a9ef",
437
+ success: "#77d257",
438
+ warning: "#fcba2e",
439
+ danger: "#fe6158",
440
+ background: "#ffffff",
441
+ fontColor: "#333333",
442
+
319
443
  // Fonts - Use your project fonts
320
- fontFamily: 'Inter, sans-serif',
321
- fontSize: '14px',
322
-
444
+ fontFamily: "Inter, sans-serif",
445
+ fontSize: "14px",
446
+
323
447
  // See USAGE.md for complete list
324
448
  }}
325
449
  />
@@ -332,11 +456,11 @@ Date values can be `Date`, ISO date string, or timestamp number.
332
456
  tasks={tasks}
333
457
  config={{
334
458
  // Responsive container
335
- containerHeight: '100%',
336
- containerMinHeight: '400px',
337
-
459
+ containerHeight: "100%",
460
+ containerMinHeight: "400px",
461
+
338
462
  // Responsive grid width
339
- gridWidth: 'clamp(280px, 30vw, 720px)', // Adapts to viewport
463
+ gridWidth: "clamp(280px, 30vw, 720px)", // Adapts to viewport
340
464
  }}
341
465
  />
342
466
  ```
@@ -350,10 +474,10 @@ Date values can be `Date`, ISO date string, or timestamp number.
350
474
  --wx-gantt-primary: #your-brand-color;
351
475
  --wx-gantt-background: var(--your-bg-color);
352
476
  --wx-gantt-font-color: var(--your-text-color);
353
-
477
+
354
478
  /* Use your project fonts */
355
- --wx-gantt-font-family: 'Your Font', sans-serif;
356
-
479
+ --wx-gantt-font-family: "Your Font", sans-serif;
480
+
357
481
  /* Responsive sizing */
358
482
  --gantt-grid-width: clamp(280px, 30vw, 720px);
359
483
  }
@@ -362,6 +486,7 @@ Date values can be `Date`, ISO date string, or timestamp number.
362
486
  ## 📱 Responsive
363
487
 
364
488
  The component is fully responsive and adapts to:
489
+
365
490
  - ✅ Desktop (1024px+)
366
491
  - ✅ Tablet (768px - 1024px)
367
492
  - ✅ Mobile Landscape (480px - 768px)
@@ -394,12 +519,12 @@ A single callback for **all** drag operations: task bar move/resize AND row reor
394
519
  // task.rawId preserves the original API ID (before string normalization)
395
520
  const taskId = task.rawId ?? task.id;
396
521
 
397
- if (dragType === 'reorder' && reorderMeta) {
522
+ if (dragType === "reorder" && reorderMeta) {
398
523
  // Row reorder — task was dragged to a new position via grip icon
399
524
  await api.reorderTask(taskId, {
400
525
  current_sequence_id: reorderMeta.currentSequenceId,
401
526
  target_sequence_id: reorderMeta.targetSequenceId,
402
- target_stage_id: reorderMeta.targetStageId, // parent task ID or null for root
527
+ target_stage_id: reorderMeta.targetStageId, // parent task ID or null for root
403
528
  });
404
529
  } else {
405
530
  // Task bar drag — move or resize on the timeline
@@ -419,12 +544,12 @@ A single callback for **all** drag operations: task bar move/resize AND row reor
419
544
 
420
545
  **`TaskDragUpdatePayload` fields:**
421
546
 
422
- | Field | Type | Description |
423
- |-------|------|-------------|
424
- | `task` | `Task` | The updated task (after drag/reorder) |
425
- | `previousTask` | `Task` | The task state before the operation |
426
- | `dragType` | `'move' \| 'resize-left' \| 'resize-right' \| 'reorder'` | What kind of drag was performed |
427
- | `reorderMeta` | `TaskReorderMeta \| undefined` | Only present for `'reorder'` — contains `currentSequenceId`, `targetSequenceId`, `targetStageId` |
547
+ | Field | Type | Description |
548
+ | -------------- | -------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
549
+ | `task` | `Task` | The updated task (after drag/reorder) |
550
+ | `previousTask` | `Task` | The task state before the operation |
551
+ | `dragType` | `'move' \| 'resize-left' \| 'resize-right' \| 'reorder'` | What kind of drag was performed |
552
+ | `reorderMeta` | `TaskReorderMeta \| undefined` | Only present for `'reorder'` — contains `currentSequenceId`, `targetSequenceId`, `targetStageId` |
428
553
 
429
554
  ### Other Event Handlers
430
555
 
@@ -456,10 +581,11 @@ A single callback for **all** drag operations: task bar move/resize AND row reor
456
581
  If you get: `Module not found: Error: Package path ./dist/gantt.css is not exported`
457
582
 
458
583
  **Solution:**
584
+
459
585
  ```tsx
460
- import 'iris-gantt/gantt.css'
586
+ import "iris-gantt/gantt.css";
461
587
  // or
462
- import 'iris-gantt/dist/gantt.css'
588
+ import "iris-gantt/dist/gantt.css";
463
589
  ```
464
590
 
465
591
  ### Default Import Error
@@ -467,9 +593,10 @@ import 'iris-gantt/dist/gantt.css'
467
593
  If you get: `export 'default' was not found`
468
594
 
469
595
  **Solution:**
596
+
470
597
  ```tsx
471
598
  // Use named import instead
472
- import { Gantt } from 'iris-gantt'
599
+ import { Gantt } from "iris-gantt";
473
600
  ```
474
601
 
475
602
  ### Runtime Error: recentlyCreatedOwnerStacks
@@ -477,6 +604,7 @@ import { Gantt } from 'iris-gantt'
477
604
  This is a **cached code issue** in your project, not the package.
478
605
 
479
606
  **Solution:**
607
+
480
608
  ```bash
481
609
  # In your project directory
482
610
  rm -rf node_modules package-lock.json .next .cache dist build
@@ -488,69 +616,69 @@ npm start
488
616
  ## 📖 Complete Example
489
617
 
490
618
  ```tsx
491
- import React, { useState } from 'react'
492
- import { Gantt } from 'iris-gantt'
493
- import 'iris-gantt/gantt.css'
494
- import type { Task, Link } from 'iris-gantt'
619
+ import React, { useState } from "react";
620
+ import { Gantt } from "iris-gantt";
621
+ import "iris-gantt/gantt.css";
622
+ import type { Task, Link } from "iris-gantt";
495
623
 
496
624
  function ProjectGantt() {
497
625
  const [tasks, setTasks] = useState<Task[]>([
498
626
  {
499
- id: '1',
500
- text: 'Project Planning',
627
+ id: "1",
628
+ text: "Project Planning",
501
629
  start: new Date(2024, 0, 1),
502
630
  end: new Date(2024, 0, 15),
503
631
  duration: 14,
504
632
  progress: 100,
505
- type: 'project',
633
+ type: "project",
506
634
  },
507
- ])
635
+ ]);
508
636
 
509
637
  const [links, setLinks] = useState<Link[]>([
510
- { id: 'l1', source: '1', target: '2', type: 'e2s' },
511
- ])
638
+ { id: "l1", source: "1", target: "2", type: "e2s" },
639
+ ]);
512
640
 
513
641
  return (
514
- <div style={{ width: '100%', height: '100vh' }}>
642
+ <div style={{ width: "100%", height: "100vh" }}>
515
643
  <Gantt
516
644
  tasks={tasks}
517
645
  links={links}
518
646
  config={{
519
- theme: 'light',
647
+ theme: "light",
520
648
  weekends: true,
521
- containerHeight: '100%',
522
- containerMinHeight: '500px',
523
- gridWidth: 'clamp(300px, 35vw, 800px)',
649
+ containerHeight: "100%",
650
+ containerMinHeight: "500px",
651
+ gridWidth: "clamp(300px, 35vw, 800px)",
524
652
  }}
525
653
  uiConfig={{
526
- headerTitle: 'My Project Timeline',
527
- addTaskButtonText: 'New Task',
654
+ headerTitle: "My Project Timeline",
655
+ addTaskButtonText: "New Task",
528
656
  }}
529
657
  styleConfig={{
530
- primary: '#6366f1',
531
- fontFamily: 'Inter, sans-serif',
658
+ primary: "#6366f1",
659
+ fontFamily: "Inter, sans-serif",
532
660
  }}
533
661
  onTaskUpdate={(task) => {
534
- setTasks(tasks.map(t => t.id === task.id ? task : t))
662
+ setTasks(tasks.map((t) => (t.id === task.id ? task : t)));
535
663
  }}
536
664
  onTaskCreate={(task) => {
537
- setTasks([...tasks, task])
665
+ setTasks([...tasks, task]);
538
666
  }}
539
667
  onTaskDelete={(taskId) => {
540
- setTasks(tasks.filter(t => t.id !== taskId))
668
+ setTasks(tasks.filter((t) => t.id !== taskId));
541
669
  }}
542
670
  onLinkCreate={(link) => {
543
- setLinks([...links, link])
671
+ setLinks([...links, link]);
544
672
  }}
545
673
  onLinkDelete={(linkId) => {
546
- setLinks(links.filter(l => l.id !== linkId))
674
+ setLinks(links.filter((l) => l.id !== linkId));
547
675
  }}
548
676
  />
549
677
  </div>
550
- )
678
+ );
551
679
  }
552
680
 
553
- export default ProjectGantt
681
+ export default ProjectGantt;
554
682
  ```
555
683
 
556
684
  ## 📝 TypeScript Support
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import type { GanttConfig, Baseline, GanttUIConfig, GanttStyleConfig, GanttIconConfig } from './types';
2
+ import type { GanttConfig, Baseline, GanttUIConfig, GanttStyleConfig, GanttIconConfig, TimelineView } from './types';
3
3
  import type { Task, TaskInput, Link, TaskReorderMeta, OnHoldPeriodInput, TaskTooltipConfig, TaskDragUpdatePayload } from './types';
4
4
  import './gantt.css';
5
5
  export interface GanttProps {
@@ -21,6 +21,7 @@ export interface GanttProps {
21
21
  onTaskDelete?: (taskId: string) => void;
22
22
  onLinkCreate?: (link: Link) => void;
23
23
  onLinkDelete?: (linkId: string) => void;
24
+ onTimelineViewChange?: (view: TimelineView) => void;
24
25
  cellWidth?: number;
25
26
  cellHeight?: number;
26
27
  scaleHeight?: number;
@@ -1 +1 @@
1
- {"version":3,"file":"Gantt.d.ts","sourceRoot":"","sources":["../../src/components/Gantt/Gantt.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAQ3D,OAAO,KAAK,EAAE,WAAW,EAA4B,QAAQ,EAAiB,aAAa,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAQhJ,OAAO,KAAK,EAEV,IAAI,EACJ,SAAS,EACT,IAAI,EACJ,eAAe,EACf,iBAAiB,EAEjB,iBAAiB,EACjB,qBAAqB,EAEtB,MAAM,SAAS,CAAC;AACjB,OAAO,aAAa,CAAC;AAErB,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IAC9B,QAAQ,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;IAClC,WAAW,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACxC,UAAU,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;IACtC,iBAAiB,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAC/C,aAAa,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACpC,eAAe,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACtC,MAAM,CAAC,EAAE,iBAAiB,EAAE,GAAG,iBAAiB,CAAC;IACjD,OAAO,CAAC,EAAE,iBAAiB,EAAE,GAAG,iBAAiB,CAAC;IAClD,MAAM,CAAC,EAAE,iBAAiB,EAAE,GAAG,iBAAiB,CAAC;IACjD,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,WAAW,CAAC,EAAE,eAAe,KAAK,IAAI,CAAC;IACnE,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,qBAAqB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5E,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IACpC,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IACpC,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAGxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;CACnC;AA0YD,eAAO,MAAM,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,UAAU,CA0xBtC,CAAC"}
1
+ {"version":3,"file":"Gantt.d.ts","sourceRoot":"","sources":["../../src/components/Gantt/Gantt.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAQ3D,OAAO,KAAK,EAAE,WAAW,EAA4B,QAAQ,EAAiB,aAAa,EAAE,gBAAgB,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAQ9J,OAAO,KAAK,EAEV,IAAI,EACJ,SAAS,EACT,IAAI,EACJ,eAAe,EACf,iBAAiB,EAEjB,iBAAiB,EACjB,qBAAqB,EAEtB,MAAM,SAAS,CAAC;AACjB,OAAO,aAAa,CAAC;AAErB,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IAC9B,QAAQ,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;IAClC,WAAW,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACxC,UAAU,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;IACtC,iBAAiB,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAC/C,aAAa,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACpC,eAAe,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACtC,MAAM,CAAC,EAAE,iBAAiB,EAAE,GAAG,iBAAiB,CAAC;IACjD,OAAO,CAAC,EAAE,iBAAiB,EAAE,GAAG,iBAAiB,CAAC;IAClD,MAAM,CAAC,EAAE,iBAAiB,EAAE,GAAG,iBAAiB,CAAC;IACjD,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,WAAW,CAAC,EAAE,eAAe,KAAK,IAAI,CAAC;IACnE,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,qBAAqB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5E,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IACpC,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IACpC,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,oBAAoB,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;IAGpD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;CACnC;AA6bD,eAAO,MAAM,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,UAAU,CAo2BtC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"Timeline.d.ts","sourceRoot":"","sources":["../../src/components/Gantt/Timeline.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4C,MAAM,OAAO,CAAC;AACjE,OAAO,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAM/G,UAAU,aAAa;IACrB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,KAAK,EAAE;QAAE,KAAK,EAAE,IAAI,CAAC;QAAC,GAAG,EAAE,IAAI,CAAA;KAAE,CAAC;IAClC,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,MAAM,EAAE,WAAW,CAAC;IACpB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,eAAe,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5E,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,YAAY,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,kBAAkB,KAAK,IAAI,CAAC;IACvF,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAClC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;CACvC;AAED,eAAO,MAAM,QAAQ,sFAktBpB,CAAC"}
1
+ {"version":3,"file":"Timeline.d.ts","sourceRoot":"","sources":["../../src/components/Gantt/Timeline.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4C,MAAM,OAAO,CAAC;AACjE,OAAO,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AA4E/G,UAAU,aAAa;IACrB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,KAAK,EAAE;QAAE,KAAK,EAAE,IAAI,CAAC;QAAC,GAAG,EAAE,IAAI,CAAA;KAAE,CAAC;IAClC,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,MAAM,EAAE,WAAW,CAAC;IACpB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,eAAe,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5E,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,YAAY,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,kBAAkB,KAAK,IAAI,CAAC;IACvF,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAClC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;CACvC;AAED,eAAO,MAAM,QAAQ,sFAi1BpB,CAAC"}
@@ -1,9 +1,15 @@
1
1
  import React from 'react';
2
2
  import type { FilterOptions } from './features/filterUtils';
3
- import type { GanttUIConfig, GanttIconConfig, GanttStyleConfig } from './types';
3
+ import type { GanttUIConfig, GanttIconConfig, GanttStyleConfig, TimelineView } from './types';
4
4
  interface ToolbarProps {
5
5
  zoomLevel: number;
6
6
  setZoomLevel: (zoom: number) => void;
7
+ timelineView?: TimelineView;
8
+ timelineViewOptions?: Array<{
9
+ value: TimelineView;
10
+ label: string;
11
+ }>;
12
+ onTimelineViewChange?: (view: TimelineView) => void;
7
13
  onBaselineToggle?: () => void;
8
14
  showBaselines?: boolean;
9
15
  onExport: (type: 'csv' | 'excel' | 'json' | 'pdf') => void;