@toclocoinc/lattice-grid 1.67.0 → 1.68.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.
Files changed (163) hide show
  1. package/README.md +1 -1
  2. package/angular/package.json +1 -1
  3. package/docs/API.html +5334 -3788
  4. package/docs/api-detail.html +40 -5
  5. package/lattice-grid.d.ts +3368 -2
  6. package/lattice-grid.esm.min.js +32 -10
  7. package/lattice-grid.min.cjs +32 -10
  8. package/lattice-grid.min.js +32 -10
  9. package/modules/ai.d.ts +64 -1
  10. package/modules/ai.esm.min.js +3 -3
  11. package/modules/ai.min.cjs +3 -3
  12. package/modules/ai.min.js +3 -3
  13. package/modules/angular.d.ts +1 -1
  14. package/modules/angular.esm.min.js +3 -3
  15. package/modules/angular.min.cjs +3 -3
  16. package/modules/angular.min.js +3 -3
  17. package/modules/chart-alluvial.d.ts +1 -1
  18. package/modules/chart-alluvial.esm.min.js +1 -1
  19. package/modules/chart-alluvial.min.cjs +1 -1
  20. package/modules/chart-alluvial.min.js +1 -1
  21. package/modules/chart-arc.d.ts +1 -1
  22. package/modules/chart-arc.esm.min.js +1 -1
  23. package/modules/chart-arc.min.cjs +1 -1
  24. package/modules/chart-arc.min.js +1 -1
  25. package/modules/chart-bubblemap.d.ts +1 -1
  26. package/modules/chart-bubblemap.esm.min.js +1 -1
  27. package/modules/chart-bubblemap.min.cjs +1 -1
  28. package/modules/chart-bubblemap.min.js +1 -1
  29. package/modules/chart-bump.d.ts +1 -1
  30. package/modules/chart-bump.esm.min.js +1 -1
  31. package/modules/chart-bump.min.cjs +1 -1
  32. package/modules/chart-bump.min.js +1 -1
  33. package/modules/chart-calendar.d.ts +1 -1
  34. package/modules/chart-calendar.esm.min.js +1 -1
  35. package/modules/chart-calendar.min.cjs +1 -1
  36. package/modules/chart-calendar.min.js +1 -1
  37. package/modules/chart-decomposition.d.ts +1 -1
  38. package/modules/chart-decomposition.esm.min.js +1 -1
  39. package/modules/chart-decomposition.min.cjs +1 -1
  40. package/modules/chart-decomposition.min.js +1 -1
  41. package/modules/chart-diverging.d.ts +1 -1
  42. package/modules/chart-diverging.esm.min.js +1 -1
  43. package/modules/chart-diverging.min.cjs +1 -1
  44. package/modules/chart-diverging.min.js +1 -1
  45. package/modules/chart-dumbbell.d.ts +1 -1
  46. package/modules/chart-dumbbell.esm.min.js +1 -1
  47. package/modules/chart-dumbbell.min.cjs +1 -1
  48. package/modules/chart-dumbbell.min.js +1 -1
  49. package/modules/chart-fan.d.ts +1 -1
  50. package/modules/chart-fan.esm.min.js +1 -1
  51. package/modules/chart-fan.min.cjs +1 -1
  52. package/modules/chart-fan.min.js +1 -1
  53. package/modules/chart-hexbin.d.ts +1 -1
  54. package/modules/chart-hexbin.esm.min.js +1 -1
  55. package/modules/chart-hexbin.min.cjs +1 -1
  56. package/modules/chart-hexbin.min.js +1 -1
  57. package/modules/chart-hexmap.d.ts +1 -1
  58. package/modules/chart-hexmap.esm.min.js +1 -1
  59. package/modules/chart-hexmap.min.cjs +1 -1
  60. package/modules/chart-hexmap.min.js +1 -1
  61. package/modules/chart-icicle.d.ts +1 -1
  62. package/modules/chart-icicle.esm.min.js +1 -1
  63. package/modules/chart-icicle.min.cjs +1 -1
  64. package/modules/chart-icicle.min.js +1 -1
  65. package/modules/chart-markermap.d.ts +1 -1
  66. package/modules/chart-markermap.esm.min.js +1 -1
  67. package/modules/chart-markermap.min.cjs +1 -1
  68. package/modules/chart-markermap.min.js +1 -1
  69. package/modules/chart-parallel.d.ts +1 -1
  70. package/modules/chart-parallel.esm.min.js +1 -1
  71. package/modules/chart-parallel.min.cjs +1 -1
  72. package/modules/chart-parallel.min.js +1 -1
  73. package/modules/chart-ridgeline.d.ts +1 -1
  74. package/modules/chart-ridgeline.esm.min.js +1 -1
  75. package/modules/chart-ridgeline.min.cjs +1 -1
  76. package/modules/chart-ridgeline.min.js +1 -1
  77. package/modules/chart-roc.d.ts +1 -1
  78. package/modules/chart-roc.esm.min.js +1 -1
  79. package/modules/chart-roc.min.cjs +1 -1
  80. package/modules/chart-roc.min.js +1 -1
  81. package/modules/chart-slope.d.ts +1 -1
  82. package/modules/chart-slope.esm.min.js +1 -1
  83. package/modules/chart-slope.min.cjs +1 -1
  84. package/modules/chart-slope.min.js +1 -1
  85. package/modules/chart-splom.d.ts +1 -1
  86. package/modules/chart-splom.esm.min.js +1 -1
  87. package/modules/chart-splom.min.cjs +1 -1
  88. package/modules/chart-splom.min.js +1 -1
  89. package/modules/chart-waffle.d.ts +1 -1
  90. package/modules/chart-waffle.esm.min.js +1 -1
  91. package/modules/chart-waffle.min.cjs +1 -1
  92. package/modules/chart-waffle.min.js +1 -1
  93. package/modules/charts.d.ts +16 -1
  94. package/modules/charts.esm.min.js +1391 -1257
  95. package/modules/charts.min.cjs +1391 -1257
  96. package/modules/charts.min.js +1391 -1257
  97. package/modules/data-router.d.ts +227 -1
  98. package/modules/data-router.esm.min.js +204 -8
  99. package/modules/data-router.min.cjs +204 -8
  100. package/modules/data-router.min.js +204 -8
  101. package/modules/devtools.d.ts +1 -1
  102. package/modules/devtools.esm.min.js +1 -1
  103. package/modules/devtools.min.cjs +1 -1
  104. package/modules/devtools.min.js +1 -1
  105. package/modules/dhtmlx-compat.d.ts +1 -1
  106. package/modules/dhtmlx-compat.esm.min.js +3 -3
  107. package/modules/dhtmlx-compat.min.cjs +3 -3
  108. package/modules/dhtmlx-compat.min.js +3 -3
  109. package/modules/gantt.d.ts +302 -1
  110. package/modules/gantt.esm.min.js +32 -7
  111. package/modules/gantt.min.cjs +32 -7
  112. package/modules/gantt.min.js +32 -7
  113. package/modules/geo-europe-nuts.d.ts +1 -1
  114. package/modules/geo-europe-nuts.esm.min.js +1 -1
  115. package/modules/geo-uk.d.ts +1 -1
  116. package/modules/geo-uk.esm.min.js +1 -1
  117. package/modules/geo-us-states.d.ts +1 -1
  118. package/modules/geo-us-states.esm.min.js +1 -1
  119. package/modules/geo-world-110m.d.ts +1 -1
  120. package/modules/geo-world-110m.esm.min.js +1 -1
  121. package/modules/geo-world-50m.d.ts +1 -1
  122. package/modules/geo-world-50m.esm.min.js +1 -1
  123. package/modules/htmx.d.ts +1 -1
  124. package/modules/htmx.esm.min.js +32 -10
  125. package/modules/htmx.min.cjs +32 -10
  126. package/modules/htmx.min.js +32 -10
  127. package/modules/kanban.d.ts +233 -1
  128. package/modules/kanban.esm.min.js +3 -3
  129. package/modules/kanban.min.cjs +3 -3
  130. package/modules/kanban.min.js +3 -3
  131. package/modules/kpi.d.ts +196 -8
  132. package/modules/kpi.esm.min.js +32 -7
  133. package/modules/kpi.min.cjs +32 -7
  134. package/modules/kpi.min.js +32 -7
  135. package/modules/layout.d.ts +117 -1
  136. package/modules/layout.esm.min.js +3 -3
  137. package/modules/layout.min.cjs +3 -3
  138. package/modules/layout.min.js +3 -3
  139. package/modules/mock-socket.d.ts +6 -1
  140. package/modules/mock-socket.esm.min.js +1 -1
  141. package/modules/mock-socket.min.cjs +1 -1
  142. package/modules/mock-socket.min.js +1 -1
  143. package/modules/react.d.ts +14 -1
  144. package/modules/react.esm.min.js +3 -3
  145. package/modules/react.min.cjs +3 -3
  146. package/modules/react.min.js +3 -3
  147. package/modules/svelte.d.ts +1 -1
  148. package/modules/svelte.esm.min.js +3 -3
  149. package/modules/svelte.min.cjs +3 -3
  150. package/modules/svelte.min.js +3 -3
  151. package/modules/tabs.d.ts +30 -1
  152. package/modules/tabs.esm.min.js +13 -14
  153. package/modules/tabs.min.cjs +13 -14
  154. package/modules/tabs.min.js +13 -14
  155. package/modules/vue.d.ts +8 -1
  156. package/modules/vue.esm.min.js +3 -3
  157. package/modules/vue.min.cjs +3 -3
  158. package/modules/vue.min.js +3 -3
  159. package/modules/webcomponent.d.ts +113 -1
  160. package/modules/webcomponent.esm.min.js +32 -10
  161. package/modules/webcomponent.min.cjs +32 -10
  162. package/modules/webcomponent.min.js +32 -10
  163. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Lattice Grid 1.67.0, gantt module type declarations
2
+ * Lattice Grid 1.68.1, gantt module type declarations
3
3
  * Copyright (c) 2026 TOCLOCO Inc. All rights reserved.
4
4
  * https://latticegrid.dev
5
5
  */
@@ -25,21 +25,83 @@ export type GanttCalendar =
25
25
  * view's grid panel.
26
26
  */
27
27
  export interface GanttTask {
28
+ /**
29
+ * The task's identity, used by dependencies, edits and `rows.apply`. Stringified; a
30
+ * duplicate id fails the schedule with `duplicate-id`.
31
+ */
28
32
  id: string | number;
33
+ /** The task's label in the table and on its bar. Defaults to the id. */
29
34
  name?: string;
35
+ /**
36
+ * Where the task is placed — a day-number, an ISO date or a `Date`. It is a floor, not
37
+ * a pin: the forward pass never starts the task earlier, but a predecessor may push it
38
+ * later. Use a `constraint` to pin it.
39
+ */
30
40
  start?: number | string | Date;
41
+ /**
42
+ * The task's finish, in the same forms as `start`. Given with `start` and no
43
+ * `duration`, the duration becomes `end − start`.
44
+ */
31
45
  end?: number | string | Date;
46
+ /**
47
+ * How long the task takes, in working days (the plan's time unit). Negative fails the
48
+ * schedule with `bad-duration`; a leaf with no duration and no start/end pair is an
49
+ * error, while a summary's is ignored because its window comes from its children.
50
+ */
32
51
  duration?: number;
52
+ /**
53
+ * Progress, 0-100, drawn as the filled part of the bar and used as the earned-value
54
+ * multiplier. A summary's is the duration-weighted mean of its descendant leaves;
55
+ * anything unparseable reads as null.
56
+ */
33
57
  percentComplete?: number;
58
+ /**
59
+ * Marks a zero-duration point: the task is scheduled as an instant (start equals
60
+ * finish) and drawn as a diamond. `duration: 0` does the same.
61
+ */
34
62
  milestone?: boolean;
63
+ /**
64
+ * The id of the summary task this one sits under. A summary is never scheduled in its
65
+ * own right — its window, progress and criticality are derived from its children — and
66
+ * a parent chain that loops fails with `parent-cycle`.
67
+ */
35
68
  parent?: string | number;
69
+ /**
70
+ * The planned start the task is measured against, in the same forms as `start`. With a
71
+ * baseline the schedule reports `startVariance` (actual − planned; positive is a slip).
72
+ */
36
73
  baselineStart?: number | string | Date;
74
+ /**
75
+ * The planned finish. With both baseline dates the schedule reports `finishVariance`
76
+ * and `durationVariance` too.
77
+ */
37
78
  baselineEnd?: number | string | Date;
79
+ /** The planned window as one object, read when `baselineStart`/`baselineEnd` are absent. */
38
80
  baseline?: { start?: number | string | Date; end?: number | string | Date };
81
+ /**
82
+ * Pins or pulls the task: must-start-on and must-finish-on place it on
83
+ * `constraintDate`, as-late-as-possible pulls it into its late window, consuming its
84
+ * float. A constraint date earlier than the predecessors allow is reported in
85
+ * `schedule.conflicts` and the feasible date is used instead.
86
+ */
39
87
  constraint?: GanttConstraintType;
88
+ /**
89
+ * The date the constraint pins to — a day-number, ISO date or `Date`. Unused by
90
+ * as-late-as-possible.
91
+ */
40
92
  constraintDate?: number | string | Date;
93
+ /**
94
+ * Who is booked on the task: one name or a list. Each name is a full-time booking
95
+ * (units 1) for resource load, over-allocation and the split view's avatars. Ignored
96
+ * when `assignments` is present.
97
+ */
41
98
  assignee?: string | string[];
99
+ /** An alternative spelling of `assignee`, read when that is absent. */
42
100
  assignees?: string[];
101
+ /**
102
+ * A third spelling of `assignee`, read when neither `assignee` nor `assignees` is
103
+ * present.
104
+ */
43
105
  owner?: string;
44
106
  /**
45
107
  * Explicit resource assignments with fractional units:
@@ -101,55 +163,147 @@ export type GanttResourceSpec =
101
163
  * field warns; the explicit field wins.
102
164
  */
103
165
  export interface GanttDependency {
166
+ /**
167
+ * The predecessor task's id. A link naming a summary is expanded to its descendant
168
+ * leaves before scheduling.
169
+ */
104
170
  from: string | number;
171
+ /** The successor task's id. */
105
172
  to: string | number;
173
+ /**
174
+ * Which ends the link ties together — finish-to-start (the default), start-to-start,
175
+ * finish-to-finish or start-to-finish — optionally with the MS Project lag shorthand,
176
+ * `'FS+2'` or `'SS-1'`. It is normalised on the way in, so `gantt.dependencies` always
177
+ * reads back as `{ type, lag }`.
178
+ */
106
179
  type?: GanttLinkType | `${GanttLinkType}${'+' | '-'}${number}`;
180
+ /**
181
+ * A signed offset on the link in working days; a negative value is a lead. Given
182
+ * alongside a shorthand lag in `type`, this field wins and the mismatch is warned
183
+ * about.
184
+ */
107
185
  lag?: number;
108
186
  }
109
187
 
110
188
  /** The computed CPM values for one task (a leaf is scheduled, a summary derived). */
111
189
  interface GanttScheduledTask {
190
+ /** The task's id, as a string. */
112
191
  id: string;
192
+ /** The task's name, defaulting to its id. */
113
193
  name: string;
194
+ /** The task's length in working days. A summary's is its derived window, `ef − es`. */
114
195
  duration: number;
196
+ /**
197
+ * Early start: the earliest day the task can begin once every predecessor and its own
198
+ * placement floor are honoured.
199
+ */
115
200
  es: number;
201
+ /**
202
+ * Early finish, `es + duration` (mapped back to calendar days when a working-time
203
+ * calendar is in use).
204
+ */
116
205
  ef: number;
206
+ /**
207
+ * Late start: the latest the task can begin without pushing the project finish (or the
208
+ * deadline) out.
209
+ */
117
210
  ls: number;
211
+ /**
212
+ * Late finish, `ls + duration`. A task pinned by a constraint has `lf` equal to its
213
+ * `ef`, so it has no float.
214
+ */
118
215
  lf: number;
216
+ /**
217
+ * Slack in working days, `ls − es`. Zero means critical; a deadline earlier than the
218
+ * natural finish drives it negative, which is the at-risk signal.
219
+ */
119
220
  totalFloat: number;
221
+ /**
222
+ * True when the total float is zero or negative. A summary is critical when any child
223
+ * is; an as-late-as-possible task is always marked critical.
224
+ */
120
225
  critical: boolean;
226
+ /**
227
+ * The task's progress, or null when it states none. A summary's is the
228
+ * duration-weighted mean of its descendant leaves, and null when every one of them is a
229
+ * milestone.
230
+ */
121
231
  percentComplete: number | null;
232
+ /** The id of this task's summary, or null at the top level. */
122
233
  parent: string | null;
234
+ /** True when the task has children, and so was derived from them rather than scheduled. */
123
235
  isSummary: boolean;
236
+ /** True when the task's duration is zero — a point in the plan. */
124
237
  isMilestone: boolean;
238
+ /** A summary's direct children, by id, in input order. Empty for a leaf. */
125
239
  children: string[];
126
240
  /** The planned (baseline) window, present only when the task carries a baseline. */
127
241
  baselineStart?: number | null;
242
+ /** The planned finish day-number, or null when only a baseline start was given. */
128
243
  baselineEnd?: number | null;
129
244
  /** Variance vs the baseline (actual − planned, day-numbers); a positive value is a slip. */
130
245
  startVariance?: number | null;
246
+ /**
247
+ * `ef − baselineEnd` in days; positive means finishing later than planned. Null without
248
+ * a baseline finish.
249
+ */
131
250
  finishVariance?: number | null;
251
+ /**
252
+ * How much longer the task runs than its baseline window, in days. Null unless both
253
+ * baseline dates were given.
254
+ */
132
255
  durationVariance?: number | null;
133
256
  }
134
257
 
135
258
  /** An unhonourable scheduling constraint, reported rather than obeyed. */
136
259
  interface GanttConflict {
260
+ /** The task whose constraint could not be honoured. */
137
261
  id: string;
262
+ /** The constraint that was refused, as its normalised code (`MSO` or `MFO`). */
138
263
  type: string;
264
+ /** The date the constraint asked for, as a day-number, or null when it named none. */
139
265
  at: number | null;
266
+ /**
267
+ * The earliest start the predecessors actually allow — the day the engine used instead.
268
+ * It never places a task before its predecessors.
269
+ */
140
270
  earliestFeasible: number;
141
271
  }
142
272
 
143
273
  /** A CPM schedule result: per-task dates/float and the critical path, or an error. */
144
274
  interface GanttSchedule {
275
+ /**
276
+ * Whether the schedule computed. False leaves every other field absent except `error`,
277
+ * and the controller keeps its previous schedule.
278
+ */
145
279
  ok: boolean;
280
+ /**
281
+ * Why the schedule was refused: a code such as `cycle`, `duplicate-id`, `bad-duration`,
282
+ * `unknown-parent` or `parent-cycle`, a message, and for a cycle the ids that form it.
283
+ */
146
284
  error?: { code: string; message: string; cycle?: string[] };
285
+ /** Every task's computed values, keyed by id — leaves scheduled, summaries derived. */
147
286
  tasks?: Map<string, GanttScheduledTask>;
287
+ /** Every task id in input order, which is the order a table or WBS tree walks. */
148
288
  order?: string[];
289
+ /** The ids of the leaf tasks with no float, in input order. */
149
290
  critical?: string[];
291
+ /**
292
+ * Each zero-float chain through the network as its own list of ids, so a plan with
293
+ * several critical routes shows all of them.
294
+ */
150
295
  criticalPaths?: string[][];
296
+ /**
297
+ * The day the plan is anchored to — the `projectStart` option, or the calendar's first
298
+ * working day when one is set.
299
+ */
151
300
  projectStart?: number;
301
+ /** The latest early finish across every task, as a calendar day-number. */
152
302
  projectFinish?: number;
303
+ /**
304
+ * `projectFinish − projectStart` in days — calendar days when a working-time calendar
305
+ * stretched the plan, not the sum of the durations.
306
+ */
153
307
  projectDuration?: number;
154
308
  /** Constraints a predecessor made infeasible (empty when all are satisfied). */
155
309
  conflicts?: GanttConflict[];
@@ -163,46 +317,105 @@ interface GanttSchedule {
163
317
 
164
318
  /** One contiguous load segment for a resource: how many units are booked over a span. */
165
319
  interface GanttResourceSegment {
320
+ /** The day the segment begins (inclusive), as a calendar day-number. */
166
321
  start: number;
322
+ /**
323
+ * The day the segment ends (exclusive). A task that finishes as another starts does not
324
+ * double-count the boundary.
325
+ */
167
326
  end: number;
327
+ /**
328
+ * The units booked across the whole segment — the sum of the covering tasks' assignment
329
+ * units, where 1 is one full-time booking.
330
+ */
168
331
  load: number;
332
+ /** The tasks active during the segment, which is what makes a heavy stretch explainable. */
169
333
  taskIds: string[];
170
334
  }
171
335
 
172
336
  /** A resource booked beyond its capacity across concurrent tasks. */
173
337
  interface GanttOverAllocation {
338
+ /** The over-booked resource's name. */
174
339
  resource: string;
340
+ /**
341
+ * The resource's capacity in units — from the `resources` option, or `defaultCapacity`
342
+ * (1) when it names none.
343
+ */
175
344
  capacity: number;
345
+ /** The day the over-allocation begins, as a calendar day-number. */
176
346
  start: number;
347
+ /** The day it ends (exclusive). */
177
348
  end: number;
349
+ /**
350
+ * The units booked over that stretch — strictly greater than `capacity`, which is what
351
+ * makes it an over-allocation.
352
+ */
178
353
  load: number;
354
+ /** The tasks competing for the resource over that stretch. */
179
355
  taskIds: string[];
180
356
  }
181
357
 
182
358
  /** The per-resource load and the over-allocations across a schedule. */
183
359
  interface GanttResourceLoad {
360
+ /**
361
+ * Whether the load could be computed. False — with empty lists — when there is no
362
+ * successful schedule to read.
363
+ */
184
364
  ok: boolean;
365
+ /**
366
+ * One entry per resource that anything is booked on, sorted by name, each with its
367
+ * capacity, peak load and load segments. A resource named only in the capacities, with
368
+ * no booking, does not appear.
369
+ */
185
370
  resources: Array<{ resource: string; capacity: number; peak: number; segments: GanttResourceSegment[] }>;
371
+ /**
372
+ * Every stretch where a resource is booked beyond its capacity, earliest first. Empty
373
+ * when the plan fits.
374
+ */
186
375
  overAllocations: GanttOverAllocation[];
376
+ /** The same entries as `resources`, keyed by resource name for a direct lookup. */
187
377
  byResource: Map<string, { capacity: number; peak: number; segments: GanttResourceSegment[] }>;
188
378
  }
189
379
 
190
380
  /** The result of resource leveling: the shifted tasks and what moved. */
191
381
  interface GanttLevelResult {
382
+ /**
383
+ * Whether leveling ran. False only when the plan would not schedule, in which case
384
+ * `error` says why.
385
+ */
192
386
  ok: boolean;
387
+ /**
388
+ * Whether every over-allocation was cleared. False when only pinned tasks were left to
389
+ * move, or the iteration cap was hit — the partial result is still returned.
390
+ */
193
391
  resolved?: boolean;
392
+ /**
393
+ * The tasks with their new starts. These are copies; the controller adopts them unless
394
+ * the call was a dry run.
395
+ */
194
396
  tasks?: GanttTask[];
397
+ /** The schedule computed from the levelled tasks. */
195
398
  schedule?: GanttSchedule;
399
+ /**
400
+ * What actually moved: the task, its start before leveling, its start after, and the
401
+ * delay in days. Unmoved tasks are not listed.
402
+ */
196
403
  moves?: Array<{ id: string; from: number; to: number; delay: number }>;
404
+ /** The over-allocations leveling could not clear. Absent when it resolved everything. */
197
405
  remaining?: GanttOverAllocation[];
406
+ /** Why the plan would not schedule — the same codes `GanttSchedule.error` uses. */
198
407
  error?: { code: string; message: string };
199
408
  }
200
409
 
201
410
  /** A placement violation flagged by `findViolations`. */
202
411
  interface GanttViolation {
412
+ /** The task placed earlier than its predecessors allow. */
203
413
  id: string;
414
+ /** Where the plan puts the task — the `start` on the raw task, as a day-number. */
204
415
  placedStart: number;
416
+ /** The earliest start CPM allows, given the dependencies and the calendar. */
205
417
  earliestStart: number;
418
+ /** How many days early the placement is, `earliestStart − placedStart`. */
206
419
  by: number;
207
420
  }
208
421
 
@@ -228,10 +441,25 @@ export function toISODate(day: number): string | null;
228
441
 
229
442
  /** Earned-value metrics for one task or the whole project. */
230
443
  interface GanttEarnedValueRow {
444
+ /**
445
+ * The task the row is for. Absent on the `project` total, which carries only the
446
+ * money fields and the two `has…` flags.
447
+ */
231
448
  id: string;
449
+ /** The task's name. Absent on the `project` total. */
232
450
  name: string;
451
+ /**
452
+ * True for a summary row, whose figures are the sums of its descendant leaves. Absent
453
+ * on the `project` total.
454
+ */
233
455
  isSummary: boolean;
456
+ /** True for a zero-duration task. Absent on the `project` total. */
234
457
  isMilestone: boolean;
458
+ /**
459
+ * The task's progress, reported exactly as the task states it, or null when it states
460
+ * none — which earns nothing. The earned-value multiplier clamps it to 0-100 first.
461
+ * Absent on the `project` total.
462
+ */
235
463
  percentComplete: number | null;
236
464
  /** Whether a baseline (not the fallback scheduled window) drove PV. */
237
465
  hasBaseline: boolean;
@@ -257,7 +485,12 @@ interface GanttEarnedValueRow {
257
485
 
258
486
  /** The earned-value result at a status date. */
259
487
  interface GanttEarnedValue {
488
+ /**
489
+ * Whether the metrics could be computed. False when there is no successful schedule to
490
+ * measure against.
491
+ */
260
492
  ok: boolean;
493
+ /** Why the metrics were refused — `NO_SCHEDULE` when the plan has not scheduled. */
261
494
  error?: { code: string; message: string };
262
495
  /** The status date the metrics were evaluated at (day-number). */
263
496
  statusDate?: number;
@@ -284,19 +517,46 @@ export function computeEarnedValue(
284
517
 
285
518
  /** A headless Gantt controller: holds the model, recomputes on edits, emits changes. */
286
519
  interface Gantt {
520
+ /**
521
+ * The current tasks, as fresh shallow copies — mutating them changes nothing; call
522
+ * `applyEdit` or `setTasks`.
523
+ */
287
524
  readonly tasks: GanttTask[];
525
+ /**
526
+ * The current links, as fresh copies, always in the normalised `{ from, to, type, lag
527
+ * }` form.
528
+ */
288
529
  readonly dependencies: GanttDependency[];
530
+ /**
531
+ * The latest schedule result. It keeps the last successful one when a recompute fails,
532
+ * so a cycle does not blank the view.
533
+ */
289
534
  readonly schedule: GanttSchedule | null;
535
+ /** The critical task ids from the latest schedule; empty when the last compute failed. */
290
536
  readonly critical: string[];
291
537
  /** Constraints the latest schedule could not honour (empty when all are satisfied). */
292
538
  readonly conflicts: GanttConflict[];
539
+ /**
540
+ * Whether the controller was asked to cascade an edit down the dependency chain rather
541
+ * than only recomputing.
542
+ */
293
543
  readonly autoSchedule: boolean;
544
+ /** The grid this controller is bound to, or null for a standalone plan. */
294
545
  readonly grid: unknown;
295
546
  /** The over-allocations from the latest schedule. */
296
547
  readonly overAllocations: GanttOverAllocation[];
297
548
  /** The latest resource-load report, or null before a successful schedule. */
298
549
  readonly resourceLoad: GanttResourceLoad | null;
550
+ /**
551
+ * Replace the whole task list (copied in) and recompute, returning the new schedule.
552
+ * Ignored with a warning after `destroy()`.
553
+ */
299
554
  setTasks(tasks: GanttTask[]): GanttSchedule;
555
+ /**
556
+ * Replace the link list and recompute. Adding a link is gated on
557
+ * `beforeDependencyCreate`, so this returns undefined on a veto, or a promise when a
558
+ * handler defers; a pure removal or reorder applies straight away.
559
+ */
300
560
  setDependencies(deps: GanttDependency[]): GanttSchedule;
301
561
  /**
302
562
  * Apply one task edit and recompute — the single gated choke point every
@@ -311,7 +571,16 @@ interface Gantt {
311
571
  * resize stretches it across the new span at the same daily levels.
312
572
  */
313
573
  applyEdit(patch: { id: string | number; start?: number; end?: number; duration?: number; percentComplete?: number; work?: number | Array<{ date: number | string | Date; hours: number }> }, editOpts?: { writeBack?: boolean }): GanttSchedule;
574
+ /**
575
+ * Recompute the schedule now and return it. On success it emits `schedule` and
576
+ * refreshes the resource load; on a cycle or bad input it emits `error` and leaves the
577
+ * previous schedule in place.
578
+ */
314
579
  compute(): GanttSchedule;
580
+ /**
581
+ * The tasks placed earlier than CPM allows — the "manual with validation" flag. Empty
582
+ * when every placement is feasible, and when there is no successful schedule.
583
+ */
315
584
  findViolations(): GanttViolation[];
316
585
  /**
317
586
  * Compute the resource load and over-allocations on demand,
@@ -350,7 +619,12 @@ interface Gantt {
350
619
  added: GanttTask[]; updated: GanttTask[]; removed: string[];
351
620
  };
352
621
  };
622
+ /**
623
+ * Subscribe to `schedule` (a recompute succeeded, payload the schedule) or `error`
624
+ * (payload the error). Returns a function that unsubscribes.
625
+ */
353
626
  on(event: 'schedule' | 'error', fn: (payload: unknown) => void): () => void;
627
+ /** Remove a listener registered with `on`. */
354
628
  off(event: 'schedule' | 'error', fn: (payload: unknown) => void): void;
355
629
  /**
356
630
  * Render the plan into a container as an SVG timeline (bars, dependency
@@ -552,6 +826,11 @@ interface Gantt {
552
826
  unmount(): void;
553
827
  /** The mounted view, or null. */
554
828
  readonly view: unknown;
829
+ /**
830
+ * Destroy the mounted view, drop the grid subscriptions and clear the listeners. The
831
+ * controller then refuses further edits with a warning; the host still owns the grid
832
+ * and the container.
833
+ */
555
834
  destroy(): void;
556
835
  }
557
836
 
@@ -615,11 +894,33 @@ export default createGantt;
615
894
 
616
895
  /** The model {@link importMSPDI} returns and {@link exportMSPDI} takes. */
617
896
  interface GanttMSPDIModel {
897
+ /**
898
+ * The plan's tasks, written out with their outline level, summary and milestone flags,
899
+ * constraints, baseline and progress.
900
+ */
618
901
  tasks: GanttTask[];
902
+ /** The typed links, written as predecessor links with their lag on the successor task. */
619
903
  dependencies?: GanttDependency[];
904
+ /**
905
+ * The resource list, written with each resource's capacity as `MaxUnits`. Only the
906
+ * array form is read here: a name-to-capacity map is ignored, and its resources then
907
+ * appear only through the tasks' assignments, at capacity 1.
908
+ */
620
909
  resources?: GanttResourceSpec;
910
+ /**
911
+ * The project's start date. Defaults to the schedule's own start when a schedule is
912
+ * supplied.
913
+ */
621
914
  projectStart?: number | string | Date;
915
+ /**
916
+ * The working-time calendar written as the project's base calendar — a `weekends`
917
+ * preset or explicit workdays and holidays. Null writes no calendar.
918
+ */
622
919
  calendar?: GanttCalendar | null;
920
+ /**
921
+ * A computed schedule, so the written start and finish dates are the scheduled ones.
922
+ * Without it (or with a failed one) the tasks' own placements are used.
923
+ */
623
924
  schedule?: GanttSchedule;
624
925
  }
625
926
 
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Lattice Grid 1.67.0, gantt module
2
+ * Lattice Grid 1.68.1, gantt module
3
3
  * Copyright (c) 2026 TOCLOCO Inc. All rights reserved.
4
4
  * https://latticegrid.dev
5
5
  */
@@ -52,12 +52,12 @@ Object.defineProperty(__exports,"frameBatched",{enumerable:true,get:function(){r
52
52
  Object.defineProperty(__exports,"settleDebounce",{enumerable:true,get:function(){return settleDebounce;}});
53
53
  Object.defineProperty(__exports,"whenIdle",{enumerable:true,get:function(){return whenIdle;}});
54
54
  Object.defineProperty(__exports,"uid",{enumerable:true,get:function(){return uid;}});
55
- const STAMPED_VERSION="1.67.0";
55
+ const STAMPED_VERSION="1.68.1";
56
56
  async function resolveVersion(){
57
57
  if(STAMPED_VERSION!=='0.0.0-source')return STAMPED_VERSION;
58
58
  return STAMPED_VERSION;
59
59
  }
60
- const VERSION="1.67.0";
60
+ const VERSION="1.68.1";
61
61
  const warned=new Set();
62
62
  const WARNED_LIMIT=2000;
63
63
  function rememberWarned(key){
@@ -2406,6 +2406,8 @@ const STEPS=[1,2,2.5,5,10];
2406
2406
  const MINUTE=60000;
2407
2407
  const HOUR=3600000;
2408
2408
  const DAY=86400000;
2409
+ const YEAR=365.25*DAY;
2410
+ const YEAR_COUNTS=[1,2,5,10,20,25,50,100];
2409
2411
  const TIME_STEPS=[
2410
2412
  1,5,10,25,50,100,250,500,
2411
2413
  1000,5000,15000,30000,
@@ -2413,7 +2415,7 @@ MINUTE,5*MINUTE,15*MINUTE,30*MINUTE,
2413
2415
  HOUR,3*HOUR,6*HOUR,12*HOUR,
2414
2416
  DAY,2*DAY,7*DAY,14*DAY,
2415
2417
  30*DAY,90*DAY,180*DAY,
2416
- 365*DAY,2*365*DAY,5*365*DAY,10*365*DAY,100*365*DAY,
2418
+ ...YEAR_COUNTS.map((years)=>years*YEAR),
2417
2419
  ];
2418
2420
  function isNumber(v){
2419
2421
  return typeof v==='number'&&Number.isFinite(v);
@@ -2499,12 +2501,35 @@ out.push(Math.abs(v)<step/1e6?0:Number(v.toPrecision(12)));
2499
2501
  return out;
2500
2502
  }
2501
2503
  function timeStepFor(span,count=5){
2502
- const target=span/Math.max(1,count);
2503
- for(const candidate of TIME_STEPS)if(candidate>=target)return candidate;
2504
- return TIME_STEPS[TIME_STEPS.length-1];
2504
+ const wanted=Math.max(1,count);
2505
+ const target=span/wanted;
2506
+ let picked=TIME_STEPS[TIME_STEPS.length-1];
2507
+ for(const candidate of TIME_STEPS){
2508
+ if(candidate>=target){picked=candidate;break;}
2509
+ }
2510
+ if(picked<YEAR)return picked;
2511
+ let best=picked;
2512
+ let bestDiff=Math.abs(span/picked-wanted);
2513
+ for(const candidate of TIME_STEPS){
2514
+ if(candidate<YEAR)continue;
2515
+ const diff=Math.abs(span/candidate-wanted);
2516
+ if(diff<bestDiff){bestDiff=diff;best=candidate;}
2517
+ }
2518
+ return best;
2519
+ }
2520
+ function calendarYearTicks(domain,years){
2521
+ const minYear=new Date(domain.min).getUTCFullYear();
2522
+ let year=Math.ceil(minYear/years)*years;
2523
+ if(Date.UTC(year,0,1)<domain.min)year+=years;
2524
+ const out=[];
2525
+ for(;Date.UTC(year,0,1)<=domain.max;year+=years){
2526
+ out.push(Date.UTC(year,0,1));
2527
+ }
2528
+ return out;
2505
2529
  }
2506
2530
  function timeTicks(domain,count=5){
2507
2531
  const step=timeStepFor(domain.max-domain.min,count);
2532
+ if(step>=YEAR)return calendarYearTicks(domain,Math.round(step/YEAR));
2508
2533
  const out=[];
2509
2534
  const first=Math.ceil(domain.min/step)*step;
2510
2535
  for(let t=first;t<=domain.max;t+=step)out.push(t);
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Lattice Grid 1.67.0, gantt module
2
+ * Lattice Grid 1.68.1, gantt module
3
3
  * Copyright (c) 2026 TOCLOCO Inc. All rights reserved.
4
4
  * https://latticegrid.dev
5
5
  */
@@ -54,12 +54,12 @@ Object.defineProperty(__exports,"frameBatched",{enumerable:true,get:function(){r
54
54
  Object.defineProperty(__exports,"settleDebounce",{enumerable:true,get:function(){return settleDebounce;}});
55
55
  Object.defineProperty(__exports,"whenIdle",{enumerable:true,get:function(){return whenIdle;}});
56
56
  Object.defineProperty(__exports,"uid",{enumerable:true,get:function(){return uid;}});
57
- const STAMPED_VERSION="1.67.0";
57
+ const STAMPED_VERSION="1.68.1";
58
58
  async function resolveVersion(){
59
59
  if(STAMPED_VERSION!=='0.0.0-source')return STAMPED_VERSION;
60
60
  return STAMPED_VERSION;
61
61
  }
62
- const VERSION="1.67.0";
62
+ const VERSION="1.68.1";
63
63
  const warned=new Set();
64
64
  const WARNED_LIMIT=2000;
65
65
  function rememberWarned(key){
@@ -2408,6 +2408,8 @@ const STEPS=[1,2,2.5,5,10];
2408
2408
  const MINUTE=60000;
2409
2409
  const HOUR=3600000;
2410
2410
  const DAY=86400000;
2411
+ const YEAR=365.25*DAY;
2412
+ const YEAR_COUNTS=[1,2,5,10,20,25,50,100];
2411
2413
  const TIME_STEPS=[
2412
2414
  1,5,10,25,50,100,250,500,
2413
2415
  1000,5000,15000,30000,
@@ -2415,7 +2417,7 @@ MINUTE,5*MINUTE,15*MINUTE,30*MINUTE,
2415
2417
  HOUR,3*HOUR,6*HOUR,12*HOUR,
2416
2418
  DAY,2*DAY,7*DAY,14*DAY,
2417
2419
  30*DAY,90*DAY,180*DAY,
2418
- 365*DAY,2*365*DAY,5*365*DAY,10*365*DAY,100*365*DAY,
2420
+ ...YEAR_COUNTS.map((years)=>years*YEAR),
2419
2421
  ];
2420
2422
  function isNumber(v){
2421
2423
  return typeof v==='number'&&Number.isFinite(v);
@@ -2501,12 +2503,35 @@ out.push(Math.abs(v)<step/1e6?0:Number(v.toPrecision(12)));
2501
2503
  return out;
2502
2504
  }
2503
2505
  function timeStepFor(span,count=5){
2504
- const target=span/Math.max(1,count);
2505
- for(const candidate of TIME_STEPS)if(candidate>=target)return candidate;
2506
- return TIME_STEPS[TIME_STEPS.length-1];
2506
+ const wanted=Math.max(1,count);
2507
+ const target=span/wanted;
2508
+ let picked=TIME_STEPS[TIME_STEPS.length-1];
2509
+ for(const candidate of TIME_STEPS){
2510
+ if(candidate>=target){picked=candidate;break;}
2511
+ }
2512
+ if(picked<YEAR)return picked;
2513
+ let best=picked;
2514
+ let bestDiff=Math.abs(span/picked-wanted);
2515
+ for(const candidate of TIME_STEPS){
2516
+ if(candidate<YEAR)continue;
2517
+ const diff=Math.abs(span/candidate-wanted);
2518
+ if(diff<bestDiff){bestDiff=diff;best=candidate;}
2519
+ }
2520
+ return best;
2521
+ }
2522
+ function calendarYearTicks(domain,years){
2523
+ const minYear=new Date(domain.min).getUTCFullYear();
2524
+ let year=Math.ceil(minYear/years)*years;
2525
+ if(Date.UTC(year,0,1)<domain.min)year+=years;
2526
+ const out=[];
2527
+ for(;Date.UTC(year,0,1)<=domain.max;year+=years){
2528
+ out.push(Date.UTC(year,0,1));
2529
+ }
2530
+ return out;
2507
2531
  }
2508
2532
  function timeTicks(domain,count=5){
2509
2533
  const step=timeStepFor(domain.max-domain.min,count);
2534
+ if(step>=YEAR)return calendarYearTicks(domain,Math.round(step/YEAR));
2510
2535
  const out=[];
2511
2536
  const first=Math.ceil(domain.min/step)*step;
2512
2537
  for(let t=first;t<=domain.max;t+=step)out.push(t);