@toclocoinc/lattice-grid 1.59.0 → 1.61.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.
Files changed (112) hide show
  1. package/README.md +3 -3
  2. package/docs/API.html +1623 -91
  3. package/docs/api-detail.html +270 -5
  4. package/lattice-grid.d.ts +100 -2880
  5. package/lattice-grid.esm.min.js +449 -66
  6. package/lattice-grid.min.cjs +449 -66
  7. package/lattice-grid.min.js +449 -66
  8. package/modules/ai.d.ts +401 -0
  9. package/modules/ai.esm.min.js +43 -6
  10. package/modules/ai.min.cjs +43 -6
  11. package/modules/ai.min.js +43 -6
  12. package/modules/angular.d.ts +31 -0
  13. package/modules/angular.esm.min.js +3 -3
  14. package/modules/angular.min.cjs +3 -3
  15. package/modules/angular.min.js +3 -3
  16. package/modules/chart-alluvial.d.ts +18 -0
  17. package/modules/chart-alluvial.esm.min.js +1 -1
  18. package/modules/chart-arc.d.ts +18 -0
  19. package/modules/chart-arc.esm.min.js +1 -1
  20. package/modules/chart-bubblemap.d.ts +18 -0
  21. package/modules/chart-bubblemap.esm.min.js +1 -1
  22. package/modules/chart-bump.d.ts +12 -0
  23. package/modules/chart-bump.esm.min.js +1 -1
  24. package/modules/chart-calendar.d.ts +12 -0
  25. package/modules/chart-calendar.esm.min.js +1 -1
  26. package/modules/chart-decomposition.d.ts +20 -0
  27. package/modules/chart-decomposition.esm.min.js +1 -1
  28. package/modules/chart-diverging.d.ts +12 -0
  29. package/modules/chart-diverging.esm.min.js +1 -1
  30. package/modules/chart-dumbbell.d.ts +18 -0
  31. package/modules/chart-dumbbell.esm.min.js +1 -1
  32. package/modules/chart-fan.d.ts +18 -0
  33. package/modules/chart-fan.esm.min.js +1 -1
  34. package/modules/chart-hexbin.d.ts +18 -0
  35. package/modules/chart-hexbin.esm.min.js +1 -1
  36. package/modules/chart-hexmap.d.ts +18 -0
  37. package/modules/chart-hexmap.esm.min.js +1 -1
  38. package/modules/chart-icicle.d.ts +12 -0
  39. package/modules/chart-icicle.esm.min.js +1 -1
  40. package/modules/chart-parallel.d.ts +19 -0
  41. package/modules/chart-parallel.esm.min.js +1 -1
  42. package/modules/chart-ridgeline.d.ts +14 -0
  43. package/modules/chart-ridgeline.esm.min.js +1 -1
  44. package/modules/chart-roc.d.ts +20 -0
  45. package/modules/chart-roc.esm.min.js +1 -1
  46. package/modules/chart-slope.d.ts +12 -0
  47. package/modules/chart-slope.esm.min.js +1 -1
  48. package/modules/chart-splom.d.ts +19 -0
  49. package/modules/chart-splom.esm.min.js +1 -1
  50. package/modules/chart-waffle.d.ts +12 -0
  51. package/modules/chart-waffle.esm.min.js +1 -1
  52. package/modules/charts.d.ts +122 -0
  53. package/modules/charts.esm.min.js +35 -8
  54. package/modules/charts.min.cjs +35 -8
  55. package/modules/charts.min.js +35 -8
  56. package/modules/data-router.d.ts +91 -0
  57. package/modules/data-router.esm.min.js +109 -17
  58. package/modules/data-router.min.cjs +109 -17
  59. package/modules/data-router.min.js +109 -17
  60. package/modules/devtools.d.ts +28 -0
  61. package/modules/devtools.esm.min.js +2 -2
  62. package/modules/devtools.min.cjs +2 -2
  63. package/modules/devtools.min.js +2 -2
  64. package/modules/dhtmlx-compat.d.ts +19 -0
  65. package/modules/dhtmlx-compat.esm.min.js +4 -4
  66. package/modules/dhtmlx-compat.min.cjs +4 -4
  67. package/modules/dhtmlx-compat.min.js +4 -4
  68. package/modules/gantt.d.ts +647 -0
  69. package/modules/gantt.esm.min.js +1070 -201
  70. package/modules/gantt.min.cjs +1070 -201
  71. package/modules/gantt.min.js +1070 -201
  72. package/modules/htmx.d.ts +176 -0
  73. package/modules/htmx.esm.min.js +449 -66
  74. package/modules/htmx.min.cjs +449 -66
  75. package/modules/htmx.min.js +449 -66
  76. package/modules/kanban.d.ts +492 -0
  77. package/modules/kanban.esm.min.js +4 -4
  78. package/modules/kanban.min.cjs +4 -4
  79. package/modules/kanban.min.js +4 -4
  80. package/modules/kpi.d.ts +255 -0
  81. package/modules/kpi.esm.min.js +40 -7
  82. package/modules/kpi.min.cjs +40 -7
  83. package/modules/kpi.min.js +40 -7
  84. package/modules/layout.d.ts +332 -0
  85. package/modules/layout.esm.min.js +4 -4
  86. package/modules/layout.min.cjs +4 -4
  87. package/modules/layout.min.js +4 -4
  88. package/modules/mock-socket.d.ts +114 -0
  89. package/modules/mock-socket.esm.min.js +2 -2
  90. package/modules/mock-socket.min.cjs +2 -2
  91. package/modules/mock-socket.min.js +2 -2
  92. package/modules/react.d.ts +25 -0
  93. package/modules/react.esm.min.js +3 -3
  94. package/modules/react.min.cjs +3 -3
  95. package/modules/react.min.js +3 -3
  96. package/modules/svelte.d.ts +26 -0
  97. package/modules/svelte.esm.min.js +3 -3
  98. package/modules/svelte.min.cjs +3 -3
  99. package/modules/svelte.min.js +3 -3
  100. package/modules/tabs.d.ts +133 -0
  101. package/modules/tabs.esm.min.js +11 -4
  102. package/modules/tabs.min.cjs +11 -4
  103. package/modules/tabs.min.js +11 -4
  104. package/modules/vue.d.ts +24 -0
  105. package/modules/vue.esm.min.js +3 -3
  106. package/modules/vue.min.cjs +3 -3
  107. package/modules/vue.min.js +3 -3
  108. package/modules/webcomponent.d.ts +47 -0
  109. package/modules/webcomponent.esm.min.js +449 -66
  110. package/modules/webcomponent.min.cjs +449 -66
  111. package/modules/webcomponent.min.js +449 -66
  112. package/package.json +2 -2
@@ -0,0 +1,647 @@
1
+ /*!
2
+ * Lattice Grid 1.61.0, gantt module type declarations
3
+ * Copyright (c) 2026 TOCLOCO Inc. All rights reserved.
4
+ * https://latticegrid.dev
5
+ */
6
+ /** One of the four dependency link types (finish-to-start, start-to-start, finish-to-finish, start-to-finish). */
7
+ export type GanttLinkType = 'FS' | 'SS' | 'FF' | 'SF';
8
+
9
+ /** A scheduling constraint: pin the start, pin the finish, or schedule as late as possible. */
10
+ export type GanttConstraintType =
11
+ | 'must-start-on' | 'must-finish-on' | 'as-late-as-possible' | 'MSO' | 'MFO' | 'ALAP';
12
+
13
+ /** A working-time calendar: a Monday–Friday preset, or explicit working weekdays and holidays. */
14
+ export type GanttCalendar =
15
+ | 'weekends'
16
+ | { workdays?: number[]; holidays?: Array<string | number | Date> };
17
+
18
+ /**
19
+ * A task in a Gantt plan. Give a `duration` or a `start`+`end` (a day-number,
20
+ * ISO date string or `Date`; one is derived from the other). `milestone: true`
21
+ * (or `duration: 0`) is a zero-duration point. `parent` nests a task under a
22
+ * summary, whose window and progress are DERIVED from its children.
23
+ * `baselineStart`/`baselineEnd` (host-stored) drive planned-vs-actual variance;
24
+ * `constraint` pins or pulls the task; `assignee` and `height` feed the split
25
+ * view's grid panel.
26
+ */
27
+ export interface GanttTask {
28
+ id: string | number;
29
+ name?: string;
30
+ start?: number | string | Date;
31
+ end?: number | string | Date;
32
+ duration?: number;
33
+ percentComplete?: number;
34
+ milestone?: boolean;
35
+ parent?: string | number;
36
+ baselineStart?: number | string | Date;
37
+ baselineEnd?: number | string | Date;
38
+ baseline?: { start?: number | string | Date; end?: number | string | Date };
39
+ constraint?: GanttConstraintType;
40
+ constraintDate?: number | string | Date;
41
+ assignee?: string | string[];
42
+ assignees?: string[];
43
+ owner?: string;
44
+ /**
45
+ * Explicit resource assignments with fractional units (BACKLOG-0000948):
46
+ * `units` is a multiplier where 1 is a full-time booking. Use this when a
47
+ * task books a resource at less (or more) than 100%; a bare `assignee` is
48
+ * `units: 1`.
49
+ */
50
+ assignments?: Array<{ resource?: string; name?: string; id?: string; units?: number }>;
51
+ /**
52
+ * The task's effort, in one of two forms (BACKLOG-0001281/1282).
53
+ *
54
+ * A **number** is the task's TOTAL hours; the workload band divides it
55
+ * between the assignments in proportion to their units and spreads each
56
+ * share evenly over the working days the task spans. (`hours` is accepted
57
+ * as the same field under its other common name.)
58
+ *
59
+ * An **array** is an explicit per-day contour — what a planner types into a
60
+ * workload cell — and states each day's hours itself: the task's total is
61
+ * the sum of the entries, nothing is spread, and the contour is
62
+ * authoritative for the span, so `applyEdit` derives the task's `start` and
63
+ * `duration` from its first and last day. An EMPTY array means "no hours
64
+ * booked", which is how clearing every bucket is expressed without reviving
65
+ * the even spread. A bar move re-times the contour onto the new days
66
+ * unchanged; a resize stretches it across the new span at the same daily
67
+ * levels. `date` is an ISO date, a `Date` or a plan day-number; the module
68
+ * writes ISO dates back.
69
+ */
70
+ work?: number | Array<{ date: number | string | Date; hours: number }>;
71
+ /** Leveling priority: a higher value is delayed last (default 0). */
72
+ priority?: number;
73
+ /** An explicit row height (px) for the split view; applied to both panels. */
74
+ height?: number;
75
+ /**
76
+ * The budgeted cost (BAC) for earned-value analysis (BACKLOG-0000958). When
77
+ * omitted the task's duration is used as the budget, giving schedule-only EVM.
78
+ */
79
+ cost?: number;
80
+ /**
81
+ * The actual cost incurred (ACWP) for earned-value analysis
82
+ * (BACKLOG-0000958). Left out, the task's cost variance/CPI are `null`.
83
+ */
84
+ actualCost?: number;
85
+ }
86
+
87
+ /**
88
+ * Resource capacities for over-allocation detection and leveling
89
+ * (BACKLOG-0000948): either a list of resources with a capacity (max
90
+ * concurrent units, default 1) or a name→capacity map.
91
+ */
92
+ export type GanttResourceSpec =
93
+ | Array<{ id?: string; name?: string; resource?: string; capacity?: number; maxUnits?: number; max?: number; units?: number }>
94
+ | Record<string, number>;
95
+
96
+ /**
97
+ * A typed dependency between two tasks (by id), with optional lag/lead. `type`
98
+ * defaults to `'FS'`; either endpoint may be a leaf or a summary.
99
+ *
100
+ * `type` also accepts the MS Project string shorthand — `'FS+2'`, `'SS-1'`
101
+ * (BACKLOG-0001072). It is normalised to the structured form on the way in, so
102
+ * `gantt.dependencies` always reads back `{ type, lag }` and there is no second
103
+ * internal representation. Giving both a shorthand lag and a conflicting `lag`
104
+ * field warns; the explicit field wins.
105
+ */
106
+ export interface GanttDependency {
107
+ from: string | number;
108
+ to: string | number;
109
+ type?: GanttLinkType | `${GanttLinkType}${'+' | '-'}${number}`;
110
+ lag?: number;
111
+ }
112
+
113
+ /** The computed CPM values for one task (a leaf is scheduled, a summary derived). */
114
+ interface GanttScheduledTask {
115
+ id: string;
116
+ name: string;
117
+ duration: number;
118
+ es: number;
119
+ ef: number;
120
+ ls: number;
121
+ lf: number;
122
+ totalFloat: number;
123
+ critical: boolean;
124
+ percentComplete: number | null;
125
+ parent: string | null;
126
+ isSummary: boolean;
127
+ isMilestone: boolean;
128
+ children: string[];
129
+ /** The planned (baseline) window, present only when the task carries a baseline. */
130
+ baselineStart?: number | null;
131
+ baselineEnd?: number | null;
132
+ /** Variance vs the baseline (actual − planned, day-numbers); a positive value is a slip. */
133
+ startVariance?: number | null;
134
+ finishVariance?: number | null;
135
+ durationVariance?: number | null;
136
+ }
137
+
138
+ /** An unhonourable scheduling constraint, reported rather than obeyed. */
139
+ interface GanttConflict {
140
+ id: string;
141
+ type: string;
142
+ at: number | null;
143
+ earliestFeasible: number;
144
+ }
145
+
146
+ /** A CPM schedule result: per-task dates/float and the critical path, or an error. */
147
+ interface GanttSchedule {
148
+ ok: boolean;
149
+ error?: { code: string; message: string; cycle?: string[] };
150
+ tasks?: Map<string, GanttScheduledTask>;
151
+ order?: string[];
152
+ critical?: string[];
153
+ criticalPaths?: string[][];
154
+ projectStart?: number;
155
+ projectFinish?: number;
156
+ projectDuration?: number;
157
+ /** Constraints a predecessor made infeasible (empty when all are satisfied). */
158
+ conflicts?: GanttConflict[];
159
+ /** Whether a working-time calendar was applied. */
160
+ calendar?: boolean;
161
+ /** The resource over-allocations for this schedule (BACKLOG-0000948). */
162
+ overAllocations?: GanttOverAllocation[];
163
+ /** The full resource-load report for this schedule (BACKLOG-0000948). */
164
+ resourceLoad?: GanttResourceLoad;
165
+ }
166
+
167
+ /** One contiguous load segment for a resource: how many units are booked over a span. */
168
+ interface GanttResourceSegment {
169
+ start: number;
170
+ end: number;
171
+ load: number;
172
+ taskIds: string[];
173
+ }
174
+
175
+ /** A resource booked beyond its capacity across concurrent tasks (BACKLOG-0000948). */
176
+ interface GanttOverAllocation {
177
+ resource: string;
178
+ capacity: number;
179
+ start: number;
180
+ end: number;
181
+ load: number;
182
+ taskIds: string[];
183
+ }
184
+
185
+ /** The per-resource load and the over-allocations across a schedule (BACKLOG-0000948). */
186
+ interface GanttResourceLoad {
187
+ ok: boolean;
188
+ resources: Array<{ resource: string; capacity: number; peak: number; segments: GanttResourceSegment[] }>;
189
+ overAllocations: GanttOverAllocation[];
190
+ byResource: Map<string, { capacity: number; peak: number; segments: GanttResourceSegment[] }>;
191
+ }
192
+
193
+ /** The result of resource leveling: the shifted tasks and what moved (BACKLOG-0000948). */
194
+ interface GanttLevelResult {
195
+ ok: boolean;
196
+ resolved?: boolean;
197
+ tasks?: GanttTask[];
198
+ schedule?: GanttSchedule;
199
+ moves?: Array<{ id: string; from: number; to: number; delay: number }>;
200
+ remaining?: GanttOverAllocation[];
201
+ error?: { code: string; message: string };
202
+ }
203
+
204
+ /** A placement violation flagged by `findViolations`. */
205
+ interface GanttViolation {
206
+ id: string;
207
+ placedStart: number;
208
+ earliestStart: number;
209
+ by: number;
210
+ }
211
+
212
+ /** The four link types, in documented order. */
213
+ export const LINK_TYPES: readonly GanttLinkType[];
214
+
215
+ /** Error codes the scheduler reports (rather than throwing) on bad input. */
216
+ export const SCHEDULE_ERROR: Record<string, string>;
217
+
218
+ /**
219
+ * Compute the CPM schedule for a set of tasks and dependencies: forward and
220
+ * backward passes over the leaf tasks honouring FS/SS/FF/SF + lag, slack/float
221
+ * and the zero-float critical path, with summaries derived from their children,
222
+ * milestones scheduled as points, and dependency cycles refused (never looped).
223
+ */
224
+ export function computeSchedule(tasks: GanttTask[], deps?: GanttDependency[], options?: { projectStart?: number | string | Date; deadline?: number | string | Date; calendar?: GanttCalendar | null }): GanttSchedule;
225
+
226
+ /** The tasks placed earlier than their earliest feasible start (manual validation). */
227
+ export function findViolations(tasks: GanttTask[], schedule: GanttSchedule): GanttViolation[];
228
+
229
+ /** Format an engine day-number as an ISO calendar date (`YYYY-MM-DD`, UTC). */
230
+ export function toISODate(day: number): string | null;
231
+
232
+ /** Earned-value metrics for one task or the whole project (BACKLOG-0000958). */
233
+ interface GanttEarnedValueRow {
234
+ id: string;
235
+ name: string;
236
+ isSummary: boolean;
237
+ isMilestone: boolean;
238
+ percentComplete: number | null;
239
+ /** Whether a baseline (not the fallback scheduled window) drove PV. */
240
+ hasBaseline: boolean;
241
+ /** Whether any actual cost fed AC (else AC/CV/CPI are null). */
242
+ hasActualCost: boolean;
243
+ /** Budget at completion (the task's cost, or its duration when no cost). */
244
+ bac: number;
245
+ /** Planned Value (BCWS): budgeted cost of the work scheduled by the status date. */
246
+ pv: number;
247
+ /** Earned Value (BCWP): budgeted cost of the work performed (BAC × %complete). */
248
+ ev: number;
249
+ /** Actual Cost (ACWP): what the work performed actually cost, or null. */
250
+ ac: number | null;
251
+ /** Schedule Variance (EV − PV); positive is ahead of schedule. */
252
+ sv: number;
253
+ /** Cost Variance (EV − AC); positive is under budget; null without AC. */
254
+ cv: number | null;
255
+ /** Schedule Performance Index (EV / PV); null when PV is zero. */
256
+ spi: number | null;
257
+ /** Cost Performance Index (EV / AC); null without AC or when AC is zero. */
258
+ cpi: number | null;
259
+ }
260
+
261
+ /** The earned-value result at a status date (BACKLOG-0000958). */
262
+ interface GanttEarnedValue {
263
+ ok: boolean;
264
+ error?: { code: string; message: string };
265
+ /** The status date the metrics were evaluated at (day-number). */
266
+ statusDate?: number;
267
+ /** Every task keyed by id (leaf, summary and derived). */
268
+ byTask?: Map<string, GanttEarnedValueRow>;
269
+ /** The same rows in schedule order. */
270
+ rows?: GanttEarnedValueRow[];
271
+ /** The project total, rolled up as money sums of the leaves. */
272
+ project?: GanttEarnedValueRow;
273
+ }
274
+
275
+ /**
276
+ * Compute earned-value management (EVM) metrics for a scheduled plan at a
277
+ * status date (BACKLOG-0000958): PV/BCWS from the baseline, EV/BCWP from
278
+ * %complete, AC/ACWP from the per-task `actualCost`, and the derived SV/CV and
279
+ * SPI/CPI — per leaf, rolled up to summaries and the project. The math is
280
+ * implemented locally in the module (no core-compute dependency).
281
+ */
282
+ export function computeEarnedValue(
283
+ tasks: GanttTask[],
284
+ schedule: GanttSchedule,
285
+ options?: { statusDate?: number | string | Date; costField?: string; actualCostField?: string },
286
+ ): GanttEarnedValue;
287
+
288
+ /** A headless Gantt controller: holds the model, recomputes on edits, emits changes. */
289
+ interface Gantt {
290
+ readonly tasks: GanttTask[];
291
+ readonly dependencies: GanttDependency[];
292
+ readonly schedule: GanttSchedule | null;
293
+ readonly critical: string[];
294
+ /** Constraints the latest schedule could not honour (empty when all are satisfied). */
295
+ readonly conflicts: GanttConflict[];
296
+ readonly autoSchedule: boolean;
297
+ readonly grid: unknown;
298
+ /** The over-allocations from the latest schedule (BACKLOG-0000948). */
299
+ readonly overAllocations: GanttOverAllocation[];
300
+ /** The latest resource-load report, or null before a successful schedule (BACKLOG-0000948). */
301
+ readonly resourceLoad: GanttResourceLoad | null;
302
+ setTasks(tasks: GanttTask[]): GanttSchedule;
303
+ setDependencies(deps: GanttDependency[]): GanttSchedule;
304
+ /**
305
+ * Apply one task edit and recompute — the single gated choke point every
306
+ * drag, keypress, table cell and workload cell commits through.
307
+ *
308
+ * A `work` ARRAY is the task's per-day contour (BACKLOG-0001282). Given
309
+ * without an explicit `start`/`end`/`duration` it SETS the span: the task
310
+ * starts on the contour's first day and runs through its last, so booking
311
+ * hours beyond the bar extends it and clearing an edge bucket pulls it
312
+ * back. Conversely, a `start` or `duration` in the patch re-times an
313
+ * existing contour rather than discarding it — a move keeps its shape, a
314
+ * resize stretches it across the new span at the same daily levels.
315
+ */
316
+ 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;
317
+ compute(): GanttSchedule;
318
+ findViolations(): GanttViolation[];
319
+ /**
320
+ * Compute the resource load and over-allocations on demand (BACKLOG-0000948),
321
+ * optionally overriding the capacities for this call.
322
+ */
323
+ resources(loadOpts?: { resources?: GanttResourceSpec; defaultCapacity?: number }): GanttResourceLoad;
324
+ /**
325
+ * Resolve resource over-allocation by shifting tasks later — resource
326
+ * leveling (BACKLOG-0000948). Honours the CPM dependencies and the
327
+ * working-time calendar. Mutates the model unless `{ dryRun: true }`; with
328
+ * `{ writeBack: true }` and a bound grid the moved tasks are pushed through
329
+ * the grid's edit surface.
330
+ */
331
+ level(levelOpts?: {
332
+ dryRun?: boolean;
333
+ writeBack?: boolean;
334
+ priorityField?: string;
335
+ maxIterations?: number;
336
+ resources?: GanttResourceSpec;
337
+ defaultCapacity?: number;
338
+ }): GanttLevelResult;
339
+ /** Export the scheduled tasks as CSV; `{ dates: true }` writes ISO dates. */
340
+ toCSV(csvOpts?: { dates?: boolean }): string;
341
+ /**
342
+ * Export the current plan as Microsoft Project (MSPDI) XML (BACKLOG-0000950):
343
+ * tasks, dependencies, constraints, baseline, resources and assignments, plus
344
+ * the working-time calendar, serialised with the computed schedule.
345
+ */
346
+ toMSPDI(xmlOpts?: { hoursPerDay?: number; projectName?: string }): string;
347
+ /**
348
+ * The live consumer surface, mirroring `grid.rows.apply`, so a Data Router
349
+ * can drive the Gantt like any other view. Keyed by the controller's rowKey.
350
+ */
351
+ readonly rows: {
352
+ apply(change: { add?: GanttTask[]; update?: GanttTask[]; remove?: Array<string | GanttTask> }): {
353
+ added: GanttTask[]; updated: GanttTask[]; removed: string[];
354
+ };
355
+ };
356
+ on(event: 'schedule' | 'error', fn: (payload: unknown) => void): () => void;
357
+ off(event: 'schedule' | 'error', fn: (payload: unknown) => void): void;
358
+ /**
359
+ * Render the plan into a container as an SVG timeline (bars, dependency
360
+ * arrows, critical-path highlight, today line, non-working shading,
361
+ * milestones, progress). The view redraws when the schedule recomputes.
362
+ */
363
+ mount(container: unknown, options?: {
364
+ /**
365
+ * The plot width. `'container'` (the default) measures the element it was
366
+ * mounted into and keeps following it, so a plan in a tab, drawer,
367
+ * accordion or split pane fits without the host writing a
368
+ * `ResizeObserver` (BACKLOG-0001079); a container with no box yet holds a
369
+ * 720px fallback rather than drawing at zero. A number is honoured
370
+ * exactly and installs no observer. Ignored under `zoom`, which warns.
371
+ */
372
+ width?: number | 'container';
373
+ rowHeight?: number;
374
+ labelWidth?: number;
375
+ rowLabels?: boolean;
376
+ showArrows?: boolean;
377
+ showCritical?: boolean;
378
+ showProgress?: boolean;
379
+ dateAxis?: boolean;
380
+ /**
381
+ * The today line, as a plan day-number or a calendar date. A date is
382
+ * converted into plan space through `projectEpoch` (BACKLOG-0001079), so
383
+ * "put the line on the real today" is expressible for a relative plan.
384
+ */
385
+ today?: number | string | Date;
386
+ /**
387
+ * The calendar date plan day 0 stands for (BACKLOG-0001079).
388
+ *
389
+ * Display-only: axis ticks, bar labels, tooltips, screen-reader text and
390
+ * the built-in `'weekends'` shading move with it; the schedule, `getState`
391
+ * and the CSV/MSPDI exports do not. Without it, the engine's contract makes
392
+ * day 0 the Unix epoch, which is why a plan written as day offsets renders
393
+ * as January 1970. A host-supplied `nonWorking` function still receives raw
394
+ * plan days.
395
+ */
396
+ projectEpoch?: number | string | Date | null;
397
+ nonWorking?: 'weekends' | ((day: number) => boolean);
398
+ label?: 'name' | 'percent' | 'dates' | 'none' | ((task: GanttScheduledTask) => string);
399
+ /** Whether bars can be dragged to move/resize (default true). */
400
+ editable?: boolean;
401
+ /** Pixels from a bar's right edge that begin a resize rather than a move. */
402
+ resizeZone?: number;
403
+ /** Time-scale zoom: a level, or raw pixels-per-day. Omit to fit the width. */
404
+ zoom?: 'day' | 'week' | 'month' | 'quarter' | number;
405
+ /** Scroll so the today line is in view after drawing. */
406
+ scrollToToday?: boolean;
407
+ /** Show a hover tooltip (dates/duration/%/slack); default true. */
408
+ tooltip?: boolean;
409
+ /** Group tasks into swimlanes by a task property name or `fn(task)`. */
410
+ groupBy?: string | ((task: GanttTask) => unknown);
411
+ /** Keyboard editing + focusable bars + ARIA announcements (default true). */
412
+ keyboard?: boolean;
413
+ /** Days a keyboard arrow moves/resizes a task (default 1). */
414
+ moveStep?: number;
415
+ }): unknown;
416
+ /**
417
+ * Mount the JOINED split view (BACKLOG-0000938): one continuous, row-aligned
418
+ * surface with a left task-grid panel — by default the Task Name tree with
419
+ * expand/collapse, start, finish, duration, assignee avatars and a circular
420
+ * % ring (BACKLOG-0001285), plus any host columns — and the right timeline,
421
+ * sharing a single vertical scroll so every grid row lines up exactly with
422
+ * its bar row. The timeline scrolls horizontally on its own. Composes the
423
+ * controller's schedule; makes no change to grid core.
424
+ *
425
+ * The plan is editable from BOTH panes (BACKLOG-0001280): every gesture
426
+ * `mount` has — pointer drag to move, drag on the right edge to resize,
427
+ * arrow-key move, Shift+arrow resize, `l` to link, Delete — works on the
428
+ * timeline here, and a `start`/`end`/`duration`/`progress`/`name` column in
429
+ * the left panel is inline-editable on a double-click. Both routes commit
430
+ * through the same `applyEdit` choke point, so `beforeTaskMove`,
431
+ * `beforeTaskResize`, `beforeProgressChange` and `beforeTaskEdit` stay the
432
+ * single veto whichever pane the edit came from.
433
+ *
434
+ * The three switches that govern it carry the same meaning and the same
435
+ * defaults as `mount`'s: `editable` (default true) turns every edit on or
436
+ * off, both panes at once; `keyboard` (default true) turns off the
437
+ * focusable bars, the arrow-key gestures and the ARIA announcements while
438
+ * leaving pointer editing alone; and `resizeZone` (default 6) is how many
439
+ * pixels in from a bar's right edge begin a resize rather than a move.
440
+ * `workload` adds the resource band beneath the plan (BACKLOG-0001281),
441
+ * which is display-only — it reports hours, it does not accept them.
442
+ */
443
+ mountSplit(container: unknown, options?: {
444
+ height?: number;
445
+ rowHeight?: number;
446
+ headerHeight?: number;
447
+ gridWidth?: number;
448
+ indent?: number;
449
+ zoom?: 'day' | 'week' | 'month' | 'quarter' | number;
450
+ today?: number;
451
+ nonWorking?: 'weekends' | ((day: number) => boolean);
452
+ calendar?: GanttCalendar | null;
453
+ showArrows?: boolean;
454
+ showProgress?: boolean;
455
+ showBaseline?: boolean;
456
+ barLabel?: 'name' | 'percent' | 'dates' | 'none' | ((task: GanttScheduledTask) => string);
457
+ /**
458
+ * Surface earned-value metrics in `kind: 'evm'` columns (BACKLOG-0000958).
459
+ * `true` computes EVM at the today line (or the project finish); an object
460
+ * overrides the status date and the cost field names.
461
+ */
462
+ evm?: boolean | { statusDate?: number | string | Date; costField?: string; actualCostField?: string };
463
+ /**
464
+ * Whether the plan can be edited: pointer drags on the timeline and the
465
+ * left panel's inline cell editors (default true). Same meaning and
466
+ * default as `mount`'s.
467
+ */
468
+ editable?: boolean;
469
+ /**
470
+ * Keyboard editing + focusable bars + ARIA announcements on the timeline
471
+ * (default true). Same meaning and default as `mount`'s.
472
+ */
473
+ keyboard?: boolean;
474
+ /**
475
+ * Pixels from a bar's right edge that begin a resize rather than a move
476
+ * (default 6). Same meaning and default as `mount`'s.
477
+ */
478
+ resizeZone?: number;
479
+ /**
480
+ * A `{ t(key, params) }` resolver for the view's own text — the live
481
+ * region's edit announcements. Omit it and a gantt bound to a grid borrows
482
+ * that grid's catalogue; a standalone plan falls back to English.
483
+ */
484
+ messages?: { t: (key: string, params?: Record<string, unknown>) => string };
485
+ /**
486
+ * The left panel's columns. `kind` decides what the cell shows and what a
487
+ * double-click edits: `'name'` the WBS tree (edits the name), `'assignee'`
488
+ * the avatars, `'progress'` the % ring (edits `percentComplete`), `'evm'`
489
+ * an earned-value `metric`, and `'start'`/`'end'`/`'duration'` the
490
+ * scheduled window — an ISO date, an ISO date, and a whole number of days,
491
+ * each of which edits the plan through the same path a bar drag takes
492
+ * (BACKLOG-0001280). A column with no `kind` shows the raw task's `key`
493
+ * and edits it only with `editable: true`.
494
+ */
495
+ columns?: Array<{ key: string; title?: string; width?: number; kind?: 'name' | 'assignee' | 'progress' | 'evm' | 'start' | 'end' | 'duration' | 'number'; metric?: 'bac' | 'pv' | 'ev' | 'ac' | 'sv' | 'cv' | 'spi' | 'cpi'; digits?: number; editable?: boolean; editField?: string; render?: (task: GanttScheduledTask, ctx: { rawTask: GanttTask; depth: number }) => unknown }>;
496
+ /**
497
+ * A resource workload band beneath the split view (BACKLOG-0001281):
498
+ * one row per resource on the left and, on the right, that resource's
499
+ * hours per time bucket — aligned column-for-column with the timeline's
500
+ * scale header, scroll-locked to it horizontally (vertically it scrolls
501
+ * on its own), and redrawn in the same paint as the bars whenever the
502
+ * plan changes. `true` takes the defaults below; an object overrides
503
+ * them; omitted, no band is drawn.
504
+ *
505
+ * **Editing (BACKLOG-0001282).** A resource row expands (a disclosure
506
+ * button, `aria-expanded`) into one sub-row per task it carries. The
507
+ * resource's own cell is the read-only aggregate; a SUB-ROW cell accepts
508
+ * a typed number of hours on a double-click whenever the view's
509
+ * `editable` is on. What is typed is written to that task's `work`
510
+ * contour through the same `applyEdit` choke point (and the same
511
+ * `beforeTaskEdit` veto) a bar drag uses, so the bar, the table row and
512
+ * the band all move in one paint — including the span, which follows the
513
+ * contour: type into a column beyond the bar and the bar grows to reach
514
+ * it. A bucket containing no working day declines the edit and says so.
515
+ *
516
+ * **Where the hours come from.** They are DERIVED from the tasks, never
517
+ * supplied: a task's own `work` (or `hours`) field when it carries a
518
+ * finite one, otherwise `working days × hoursPerDay × units`, divided
519
+ * between the task's assignments in proportion to their units and spread
520
+ * evenly over the working days the task spans. Working days are the days
521
+ * this view already shades — pass the `calendar`/`nonWorking` option the
522
+ * plan is scheduled with. Resources, units and capacities are the gantt's
523
+ * existing vocabulary (`assignee`/`assignees`/`owner`/`assignments` on a
524
+ * task; `resources`/`defaultCapacity` on `createGantt`); a task naming no
525
+ * resource is carried on an "Unassigned" row rather than dropped. An
526
+ * empty bucket is blank, not `0`, and a bucket over
527
+ * `capacity × hoursPerDay × the bucket's working days` is marked with a
528
+ * class and an accessible label.
529
+ */
530
+ workload?: boolean | {
531
+ /** Hours a full-time (`units: 1`) resource works in a working day; default 8. */
532
+ hoursPerDay?: number;
533
+ /** The band's height in pixels, taken from the view's own `height`; default 160. */
534
+ height?: number;
535
+ /** A band row's height in pixels; default 28. */
536
+ rowHeight?: number;
537
+ /** Maximum decimal places in a cell, trailing zeros dropped; default 1. */
538
+ decimals?: number;
539
+ /** Draw the totals row and totals column; default true. */
540
+ totals?: boolean;
541
+ };
542
+ }): unknown;
543
+ /**
544
+ * Capture a baseline (planned) snapshot of the current schedule as HOST data
545
+ * (this does not mutate the tasks). Store it and feed it back as
546
+ * `baselineStart`/`baselineEnd` task fields to get variance and ghost bars.
547
+ */
548
+ captureBaseline(): Array<{ id: string; baselineStart: number; baselineEnd: number; baselineDuration: number }>;
549
+ /**
550
+ * Compute earned-value (EVM) metrics for the current plan at a status date
551
+ * (BACKLOG-0000958): PV/EV/AC and the derived SV/CV/SPI/CPI per task, rolled
552
+ * up to summaries and the project. Budget (BAC) is the task's `cost`, or its
553
+ * duration when no cost is given; AC comes from `actualCost`.
554
+ */
555
+ earnedValue(evmOpts?: { statusDate?: number | string | Date; costField?: string; actualCostField?: string }): GanttEarnedValue;
556
+ /** Detach the mounted view, if any. The host still owns the container. */
557
+ unmount(): void;
558
+ /** The mounted view, or null. */
559
+ readonly view: unknown;
560
+ destroy(): void;
561
+ }
562
+
563
+ /**
564
+ * Create a Gantt controller over a task list and a dependency list. Computes
565
+ * the CPM schedule immediately and again on every `setTasks`/`setDependencies`/
566
+ * `applyEdit`, emitting `schedule` on success and `error` on a cycle or bad
567
+ * input. `grid` is stored for the write-back binding; `autoSchedule` requests
568
+ * dependent cascading.
569
+ */
570
+ export function createGantt(opts?: {
571
+ tasks?: GanttTask[];
572
+ dependencies?: GanttDependency[];
573
+ /** The schedule anchor: a day-number, ISO date string or Date. It only sets the floor a task with no predecessor starts on; it does not change how the schedule is computed. */
574
+ projectStart?: number | string | Date;
575
+ /** A project deadline (a day-number, ISO string or Date); tasks that cannot meet it get negative float. */
576
+ deadline?: number | string | Date;
577
+ /** A working-time calendar: skip weekends/holidays, durations in working days. */
578
+ calendar?: GanttCalendar | null;
579
+ /** Resource capacities for over-allocation detection and leveling (BACKLOG-0000948). */
580
+ resources?: GanttResourceSpec;
581
+ /** The capacity for a resource with none stated (default 1 = one full-time booking). */
582
+ defaultCapacity?: number;
583
+ autoSchedule?: boolean;
584
+ grid?: unknown;
585
+ /** Map task fields to grid column ids to enable drag write-back. */
586
+ columns?: { start?: string; end?: string; duration?: string };
587
+ /** Task identity for the live `rows.apply` surface (a field or fn); default 'id'. */
588
+ rowKey?: string | ((row: GanttTask) => unknown);
589
+ /**
590
+ * The host's own names for the task properties the scheduler reads, so a
591
+ * plan can be fed as it already exists rather than renamed for the Gantt:
592
+ * `{ id: 'taskId', start: 'startDate', name: 'jobName' }`. Each value is a
593
+ * field name or a reader `(row) => value`; anything unmapped reads its
594
+ * canonical name. The vocabulary is `id`, `name`, `start`, `end`,
595
+ * `duration`, `milestone`, `percentComplete`, `parent`, `baselineStart`,
596
+ * `baselineEnd`, `constraint`, `constraintDate`.
597
+ *
598
+ * `rowKey` also reaches the scheduler now: a task with no `id` of its own
599
+ * is identified by whatever `rowKey` names, which it previously was not —
600
+ * such a plan was keyed correctly by `rows.apply` and then refused to
601
+ * schedule.
602
+ *
603
+ * A mapping to a field NAME is two-way: `applyEdit` writes back to that
604
+ * name, so an edit on a mapped plan lands instead of springing back
605
+ * (BACKLOG-0001280). A mapping to a READER FUNCTION has no inverse, so an
606
+ * edit to such a field writes the canonical property and says so once, and
607
+ * `level()` refuses a mapped `start` outright rather than writing where
608
+ * nothing reads. `assignee`, `cost` and `actualCost` belong to the resource
609
+ * and earned-value layers and are not mapped.
610
+ */
611
+ fields?: Record<string, string | ((row: GanttTask) => unknown)>;
612
+ /** Auto-mount into this element at construction. */
613
+ element?: unknown;
614
+ }): Gantt;
615
+ export default createGantt;
616
+
617
+ /** The model {@link importMSPDI} returns and {@link exportMSPDI} takes. */
618
+ interface GanttMSPDIModel {
619
+ tasks: GanttTask[];
620
+ dependencies?: GanttDependency[];
621
+ resources?: GanttResourceSpec;
622
+ projectStart?: number | string | Date;
623
+ calendar?: GanttCalendar | null;
624
+ schedule?: GanttSchedule;
625
+ }
626
+
627
+ /**
628
+ * Import a Microsoft Project (MSPDI) XML document (BACKLOG-0000950) into the
629
+ * module's model: the task tree, typed dependencies with lag, constraints,
630
+ * baseline, %complete, resources with capacity, the resource assignments, and
631
+ * the working-time calendar. The result is ready to pass to {@link createGantt}.
632
+ */
633
+ export function importMSPDI(xml: string, opts?: { hoursPerDay?: number }): {
634
+ ok: boolean;
635
+ error?: string;
636
+ tasks: GanttTask[];
637
+ dependencies: GanttDependency[];
638
+ resources: Array<{ id: string; name: string; capacity: number }>;
639
+ projectStart?: number;
640
+ calendar?: null | { workdays: number[]; holidays: number[] };
641
+ };
642
+
643
+ /**
644
+ * Export a Gantt model to Microsoft Project (MSPDI) XML (BACKLOG-0000950). A
645
+ * scheduled model may be passed so start/finish dates are the computed ones.
646
+ */
647
+ export function exportMSPDI(model: GanttMSPDIModel, opts?: { hoursPerDay?: number; projectName?: string }): string;