gantt-renderer 0.1.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.
- package/CHANGELOG.md +5 -0
- package/LICENSE +21 -0
- package/README.md +546 -0
- package/dist/index.d.mts +364 -0
- package/dist/index.mjs +2462 -0
- package/dist/index.mjs.map +1 -0
- package/dist/styles/gantt.css +238 -0
- package/package.json +73 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
//#region src/gantt-chart/validation/schemas.d.ts
|
|
4
|
+
declare const LinkTypeSchema: z.ZodEnum<{
|
|
5
|
+
FS: "FS";
|
|
6
|
+
SS: "SS";
|
|
7
|
+
FF: "FF";
|
|
8
|
+
SF: "SF";
|
|
9
|
+
}>;
|
|
10
|
+
declare const TaskTypeSchema: z.ZodEnum<{
|
|
11
|
+
task: "task";
|
|
12
|
+
project: "project";
|
|
13
|
+
milestone: "milestone";
|
|
14
|
+
}>;
|
|
15
|
+
declare const SpecialDayKindSchema: z.ZodEnum<{
|
|
16
|
+
holiday: "holiday";
|
|
17
|
+
custom: "custom";
|
|
18
|
+
}>;
|
|
19
|
+
declare const SpecialDaySchema: z.ZodObject<{
|
|
20
|
+
date: z.ZodString;
|
|
21
|
+
kind: z.ZodEnum<{
|
|
22
|
+
holiday: "holiday";
|
|
23
|
+
custom: "custom";
|
|
24
|
+
}>;
|
|
25
|
+
label: z.ZodOptional<z.ZodString>;
|
|
26
|
+
className: z.ZodOptional<z.ZodString>;
|
|
27
|
+
}, z.core.$strip>;
|
|
28
|
+
declare const TaskSchema: z.ZodObject<{
|
|
29
|
+
id: z.ZodNumber;
|
|
30
|
+
text: z.ZodString;
|
|
31
|
+
start_date: z.ZodString;
|
|
32
|
+
duration: z.ZodNumber;
|
|
33
|
+
parent: z.ZodOptional<z.ZodNumber>;
|
|
34
|
+
progress: z.ZodDefault<z.ZodNumber>;
|
|
35
|
+
type: z.ZodDefault<z.ZodEnum<{
|
|
36
|
+
task: "task";
|
|
37
|
+
project: "project";
|
|
38
|
+
milestone: "milestone";
|
|
39
|
+
}>>;
|
|
40
|
+
open: z.ZodDefault<z.ZodBoolean>;
|
|
41
|
+
color: z.ZodOptional<z.ZodString>;
|
|
42
|
+
}, z.core.$strip>;
|
|
43
|
+
declare const LinkSchema: z.ZodObject<{
|
|
44
|
+
id: z.ZodNumber;
|
|
45
|
+
source: z.ZodNumber;
|
|
46
|
+
target: z.ZodNumber;
|
|
47
|
+
type: z.ZodDefault<z.ZodEnum<{
|
|
48
|
+
FS: "FS";
|
|
49
|
+
SS: "SS";
|
|
50
|
+
FF: "FF";
|
|
51
|
+
SF: "SF";
|
|
52
|
+
}>>;
|
|
53
|
+
}, z.core.$strip>;
|
|
54
|
+
declare const GanttInputSchema: z.ZodObject<{
|
|
55
|
+
tasks: z.ZodArray<z.ZodObject<{
|
|
56
|
+
id: z.ZodNumber;
|
|
57
|
+
text: z.ZodString;
|
|
58
|
+
start_date: z.ZodString;
|
|
59
|
+
duration: z.ZodNumber;
|
|
60
|
+
parent: z.ZodOptional<z.ZodNumber>;
|
|
61
|
+
progress: z.ZodDefault<z.ZodNumber>;
|
|
62
|
+
type: z.ZodDefault<z.ZodEnum<{
|
|
63
|
+
task: "task";
|
|
64
|
+
project: "project";
|
|
65
|
+
milestone: "milestone";
|
|
66
|
+
}>>;
|
|
67
|
+
open: z.ZodDefault<z.ZodBoolean>;
|
|
68
|
+
color: z.ZodOptional<z.ZodString>;
|
|
69
|
+
}, z.core.$strip>>;
|
|
70
|
+
links: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
71
|
+
id: z.ZodNumber;
|
|
72
|
+
source: z.ZodNumber;
|
|
73
|
+
target: z.ZodNumber;
|
|
74
|
+
type: z.ZodDefault<z.ZodEnum<{
|
|
75
|
+
FS: "FS";
|
|
76
|
+
SS: "SS";
|
|
77
|
+
FF: "FF";
|
|
78
|
+
SF: "SF";
|
|
79
|
+
}>>;
|
|
80
|
+
}, z.core.$strip>>>;
|
|
81
|
+
}, z.core.$strip>;
|
|
82
|
+
type LinkType = z.infer<typeof LinkTypeSchema>;
|
|
83
|
+
type TaskType = z.infer<typeof TaskTypeSchema>;
|
|
84
|
+
type SpecialDayKind = z.infer<typeof SpecialDayKindSchema>;
|
|
85
|
+
type SpecialDay = z.infer<typeof SpecialDaySchema>;
|
|
86
|
+
type Task = z.infer<typeof TaskSchema>;
|
|
87
|
+
type Link = z.infer<typeof LinkSchema>;
|
|
88
|
+
type GanttInput = z.infer<typeof GanttInputSchema>;
|
|
89
|
+
/** Parses raw external data. Throws ZodError on failure. */
|
|
90
|
+
declare function parseGanttInput(raw: unknown): GanttInput;
|
|
91
|
+
/** Returns null instead of throwing. */
|
|
92
|
+
declare function safeParseGanttInput(raw: unknown): GanttInput | null;
|
|
93
|
+
//#endregion
|
|
94
|
+
//#region src/gantt-chart/timeline/scale.d.ts
|
|
95
|
+
type TimeScale = 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'year';
|
|
96
|
+
type ScaleConfig = {
|
|
97
|
+
/** Pixel width of one column unit */columnWidth: number; /** Milliseconds per column unit */
|
|
98
|
+
msPerColumn: number;
|
|
99
|
+
headerFormat: TimeScale;
|
|
100
|
+
};
|
|
101
|
+
declare const SCALE_CONFIGS: Record<TimeScale, ScaleConfig>;
|
|
102
|
+
//#endregion
|
|
103
|
+
//#region src/gantt-chart/domain/tree.d.ts
|
|
104
|
+
type TaskNode = Task & {
|
|
105
|
+
children: TaskNode[]; /** 0 = root */
|
|
106
|
+
depth: number;
|
|
107
|
+
};
|
|
108
|
+
/**
|
|
109
|
+
* Builds a typed tree from a flat task array.
|
|
110
|
+
* Order of tasks[] is irrelevant — parents need not precede children.
|
|
111
|
+
* Throws if any parent reference is unresolvable.
|
|
112
|
+
*/
|
|
113
|
+
declare function buildTaskTree(tasks: Task[]): TaskNode[];
|
|
114
|
+
/**
|
|
115
|
+
* Flattens a tree into a visible row list.
|
|
116
|
+
* A node's children are included only when its id is in expandedIds.
|
|
117
|
+
*/
|
|
118
|
+
declare function flattenTree(roots: TaskNode[], expandedIds: ReadonlySet<number>): TaskNode[];
|
|
119
|
+
/** Returns true when a node has children in the tree. */
|
|
120
|
+
declare function isParent(node: TaskNode): boolean;
|
|
121
|
+
//#endregion
|
|
122
|
+
//#region src/gantt-chart/timeline/pixelMapper.d.ts
|
|
123
|
+
type PixelMapper = {
|
|
124
|
+
/** Date → x pixel offset from viewport start */toX: (date: Date) => number; /** x pixel offset → Date */
|
|
125
|
+
toDate: (x: number) => Date; /** Days → pixel width */
|
|
126
|
+
durationToWidth: (days: number) => number; /** Pixel width → days (float) */
|
|
127
|
+
widthToDuration: (px: number) => number; /** The origin timestamp used for this mapper */
|
|
128
|
+
originMs: number; /** Pixel width of one column unit */
|
|
129
|
+
columnWidth: number;
|
|
130
|
+
};
|
|
131
|
+
/**
|
|
132
|
+
* Creates a stateless pixel mapper for the given scale and viewport start.
|
|
133
|
+
* All conversions are O(1) arithmetic — safe to call in tight loops.
|
|
134
|
+
*/
|
|
135
|
+
declare function createPixelMapper(scale: TimeScale, viewportStart: Date): PixelMapper;
|
|
136
|
+
//#endregion
|
|
137
|
+
//#region src/gantt-chart/timeline/layoutEngine.d.ts
|
|
138
|
+
declare const DENSITY: {
|
|
139
|
+
readonly rowHeight: 44;
|
|
140
|
+
readonly barHeight: 28;
|
|
141
|
+
readonly milestoneSize: 20;
|
|
142
|
+
};
|
|
143
|
+
declare const ROW_HEIGHT: 44;
|
|
144
|
+
declare const BAR_HEIGHT: 28;
|
|
145
|
+
declare const BAR_Y_OFFSET: number;
|
|
146
|
+
declare const MILESTONE_SIZE: 20;
|
|
147
|
+
/** Half-width of a milestone diamond */
|
|
148
|
+
declare const MILESTONE_HALF: number;
|
|
149
|
+
type BarLayout = {
|
|
150
|
+
taskId: number; /** Left edge x in timeline coordinates */
|
|
151
|
+
x: number; /** Top edge y in content coordinates */
|
|
152
|
+
y: number;
|
|
153
|
+
width: number;
|
|
154
|
+
height: number;
|
|
155
|
+
progressWidth: number;
|
|
156
|
+
type: 'task' | 'project' | 'milestone';
|
|
157
|
+
rowIndex: number; /** Center x; identical to x + width/2 or x for milestones */
|
|
158
|
+
centerX: number;
|
|
159
|
+
centerY: number;
|
|
160
|
+
};
|
|
161
|
+
/**
|
|
162
|
+
* Computes pixel-space layout for all visible task rows.
|
|
163
|
+
* Returns a map keyed by task id for O(1) lookup during link routing.
|
|
164
|
+
*/
|
|
165
|
+
declare function computeLayout(rows: TaskNode[], mapper: PixelMapper): Map<number, BarLayout>;
|
|
166
|
+
/**
|
|
167
|
+
* Derives viewport bounds from task data with padding.
|
|
168
|
+
* Returns [start, end] as UTC midnight dates.
|
|
169
|
+
*/
|
|
170
|
+
declare function deriveViewport(tasks: TaskNode[], paddingDays?: number): [Date, Date];
|
|
171
|
+
//#endregion
|
|
172
|
+
//#region src/gantt-chart/locale.d.ts
|
|
173
|
+
type LocaleLabelKey = 'aria_task' | 'aria_milestone' | 'add_subtask_title' | 'column_task_name' | 'column_start_time' | 'column_duration' | 'column_quarter';
|
|
174
|
+
type ChartLocale = {
|
|
175
|
+
code: string;
|
|
176
|
+
labels?: Partial<Record<LocaleLabelKey, string>>;
|
|
177
|
+
weekStartsOn?: 0 | 1 | 6;
|
|
178
|
+
weekNumbering?: 'iso' | 'us' | 'simple';
|
|
179
|
+
weekendDays?: number[];
|
|
180
|
+
};
|
|
181
|
+
declare const EN_US_LABELS: Record<LocaleLabelKey, string>;
|
|
182
|
+
declare const CHART_LOCALE_EN_US: ChartLocale;
|
|
183
|
+
/**
|
|
184
|
+
* Resolves a ChartLocale from either a full ChartLocale object or a BCP 47 string.
|
|
185
|
+
* When given a string, derives weekStartsOn, weekNumbering, and weekendDays from CLDR conventions.
|
|
186
|
+
*/
|
|
187
|
+
declare function resolveChartLocale(raw: ChartLocale | string | undefined): ChartLocale;
|
|
188
|
+
/**
|
|
189
|
+
* Derives the first day of week (0=Sun, 1=Mon, 6=Sat) from a BCP 47 code.
|
|
190
|
+
* Uses Intl.Locale.getWeekInfo() where available (Chromium, Safari 15.4+),
|
|
191
|
+
* with a CLDR-based fallback table for Firefox and older runtimes.
|
|
192
|
+
*/
|
|
193
|
+
declare function deriveWeekStartsOn(code: string): 0 | 1 | 6;
|
|
194
|
+
/**
|
|
195
|
+
* Derives the week numbering scheme from a BCP 47 code.
|
|
196
|
+
* Europe and ISO-aligned regions default to 'iso'; Americas and others to 'us'.
|
|
197
|
+
*/
|
|
198
|
+
declare function deriveWeekNumbering(code: string): 'iso' | 'us' | 'simple';
|
|
199
|
+
/**
|
|
200
|
+
* Derives weekend days (0=Sun … 6=Sat) from a BCP 47 code.
|
|
201
|
+
* Uses Intl.Locale.getWeekInfo() where available, with a CLDR-based fallback table.
|
|
202
|
+
*/
|
|
203
|
+
declare function deriveWeekendDays(code: string): number[];
|
|
204
|
+
/**
|
|
205
|
+
* Formats a week number according to the specified scheme.
|
|
206
|
+
*
|
|
207
|
+
* - `'iso'`: ISO 8601 (week 1 contains the first Thursday; Monday start).
|
|
208
|
+
* - `'us'`: Week 1 contains January 1; Sunday start.
|
|
209
|
+
* - `'simple'`: `Math.ceil(dayOfYear / 7)`.
|
|
210
|
+
*/
|
|
211
|
+
declare function formatWeekNumber(date: Date, scheme: 'iso' | 'us' | 'simple'): number;
|
|
212
|
+
/**
|
|
213
|
+
* Formats a label template by replacing `{0}` with the given argument.
|
|
214
|
+
*/
|
|
215
|
+
declare function formatLabel(template: string, arg: string): string;
|
|
216
|
+
//#endregion
|
|
217
|
+
//#region src/gantt-chart/domain/dependencies.d.ts
|
|
218
|
+
/**
|
|
219
|
+
* Detects circular dependencies in the link graph using DFS tri-colour marking.
|
|
220
|
+
* Throws with a human-readable cycle path on detection.
|
|
221
|
+
* Silent return = no cycles.
|
|
222
|
+
*/
|
|
223
|
+
declare function detectCycles(tasks: Task[], links: Link[]): void;
|
|
224
|
+
/**
|
|
225
|
+
* Returns true when all link source/target ids reference existing tasks.
|
|
226
|
+
* Throws with details on failure.
|
|
227
|
+
*/
|
|
228
|
+
declare function validateLinkRefs(tasks: Task[], links: Link[]): void;
|
|
229
|
+
//#endregion
|
|
230
|
+
//#region src/gantt-chart/domain/dateMath.d.ts
|
|
231
|
+
/** Parses YYYY-MM-DD → UTC midnight Date. Throws on invalid input. */
|
|
232
|
+
declare function parseDate(dateStr: string): Date;
|
|
233
|
+
/** Returns date + n days (exact ms arithmetic). */
|
|
234
|
+
declare function addDays(date: Date, days: number): Date;
|
|
235
|
+
/** Difference in days (float). Positive when b > a. */
|
|
236
|
+
declare function diffDays(a: Date, b: Date): number;
|
|
237
|
+
//#endregion
|
|
238
|
+
//#region src/gantt-chart/rendering/linkRouter.d.ts
|
|
239
|
+
type Point = {
|
|
240
|
+
x: number;
|
|
241
|
+
y: number;
|
|
242
|
+
};
|
|
243
|
+
type RoutedLink = {
|
|
244
|
+
linkId: number;
|
|
245
|
+
sourceTaskId: number;
|
|
246
|
+
targetTaskId: number; /** Ordered vertices of the orthogonal polyline (source → target). */
|
|
247
|
+
points: Point[];
|
|
248
|
+
};
|
|
249
|
+
/**
|
|
250
|
+
* Computes orthogonal routing for all dependency links.
|
|
251
|
+
* Links whose source or target is not in the layout map are skipped silently
|
|
252
|
+
* (e.g. when the row is collapsed).
|
|
253
|
+
*/
|
|
254
|
+
declare function routeLinks(links: Link[], layouts: Map<number, BarLayout>): RoutedLink[];
|
|
255
|
+
//#endregion
|
|
256
|
+
//#region src/gantt-chart/vanilla/dom/gridColumns.d.ts
|
|
257
|
+
type GridColumn = {
|
|
258
|
+
id: string;
|
|
259
|
+
header: string;
|
|
260
|
+
width: string;
|
|
261
|
+
align?: 'left' | 'center' | 'right';
|
|
262
|
+
visible?: boolean;
|
|
263
|
+
field?: keyof Task;
|
|
264
|
+
format?: (value: unknown, task: Task, row: TaskNode, locale: ChartLocale) => string;
|
|
265
|
+
};
|
|
266
|
+
declare const DEFAULT_GRID_COLUMNS: GridColumn[];
|
|
267
|
+
/**
|
|
268
|
+
* Returns a localized default grid column schema.
|
|
269
|
+
* Column headers use locale label overrides with EN_US_LABELS fallback.
|
|
270
|
+
*/
|
|
271
|
+
declare function gridColumnDefaults(locale: ChartLocale): GridColumn[];
|
|
272
|
+
declare function gridTemplateColumns(columns: GridColumn[]): string;
|
|
273
|
+
declare function visibleColumns(columns: GridColumn[]): GridColumn[];
|
|
274
|
+
declare const GRID_COLUMN_FR_MIN_WIDTH = 120;
|
|
275
|
+
declare function gridNaturalWidth(columns: GridColumn[]): number;
|
|
276
|
+
//#endregion
|
|
277
|
+
//#region src/gantt-chart/vanilla/gantt-chart.d.ts
|
|
278
|
+
type OnTaskSelect = (taskId: number | null) => void;
|
|
279
|
+
type OnTaskMove = (payload: {
|
|
280
|
+
id: number;
|
|
281
|
+
startDate: Date;
|
|
282
|
+
}) => void;
|
|
283
|
+
type OnTaskResize = (payload: {
|
|
284
|
+
id: number;
|
|
285
|
+
duration: number;
|
|
286
|
+
}) => void;
|
|
287
|
+
type OnTaskAdd = (payload: {
|
|
288
|
+
parentId: number;
|
|
289
|
+
}) => void;
|
|
290
|
+
type OnTaskDoubleClick = (payload: {
|
|
291
|
+
id: number;
|
|
292
|
+
source: 'grid' | 'bar' | 'milestone';
|
|
293
|
+
}) => void;
|
|
294
|
+
type OnTaskEditIntent = (payload: {
|
|
295
|
+
id: number;
|
|
296
|
+
source: 'grid' | 'bar' | 'milestone';
|
|
297
|
+
trigger: 'double_click';
|
|
298
|
+
task: Task;
|
|
299
|
+
}) => void;
|
|
300
|
+
type OnLinkCreate = (payload: {
|
|
301
|
+
sourceTaskId: number;
|
|
302
|
+
targetTaskId: number;
|
|
303
|
+
type: 'FS';
|
|
304
|
+
}) => void;
|
|
305
|
+
type GanttCallbacks = {
|
|
306
|
+
onSelect?: OnTaskSelect;
|
|
307
|
+
onMove?: OnTaskMove;
|
|
308
|
+
onResize?: OnTaskResize;
|
|
309
|
+
onAdd?: OnTaskAdd;
|
|
310
|
+
onTaskDoubleClick?: OnTaskDoubleClick;
|
|
311
|
+
onTaskEditIntent?: OnTaskEditIntent;
|
|
312
|
+
onLinkCreate?: OnLinkCreate;
|
|
313
|
+
onLeftPaneWidthChange?: (width: number) => void;
|
|
314
|
+
onGridColumnsChange?: (columns: GridColumn[]) => void;
|
|
315
|
+
};
|
|
316
|
+
type ThemeMode = 'light' | 'dark' | 'system';
|
|
317
|
+
type GanttOptions = {
|
|
318
|
+
scale?: TimeScale;
|
|
319
|
+
highlightLinkedDependenciesOnSelect?: boolean;
|
|
320
|
+
linkCreationEnabled?: boolean;
|
|
321
|
+
leftPaneWidth?: number;
|
|
322
|
+
responsiveSplitPane?: boolean;
|
|
323
|
+
mobileBreakpoint?: number;
|
|
324
|
+
mobileLeftPaneMinWidth?: number;
|
|
325
|
+
mobileLeftPaneMaxRatio?: number;
|
|
326
|
+
timelineMinWidth?: number;
|
|
327
|
+
height?: number;
|
|
328
|
+
viewportStart?: Date;
|
|
329
|
+
viewportEnd?: Date;
|
|
330
|
+
locale?: ChartLocale | string;
|
|
331
|
+
showWeekends?: boolean;
|
|
332
|
+
weekendDays?: number[];
|
|
333
|
+
specialDays?: SpecialDay[];
|
|
334
|
+
gridColumns?: GridColumn[];
|
|
335
|
+
theme?: ThemeMode;
|
|
336
|
+
} & GanttCallbacks;
|
|
337
|
+
type GanttInstance = {
|
|
338
|
+
update: (input: GanttInput) => void;
|
|
339
|
+
setScale: (scale: TimeScale) => void;
|
|
340
|
+
select: (id: number | null) => void;
|
|
341
|
+
collapseAll: () => void;
|
|
342
|
+
expandAll: () => void;
|
|
343
|
+
destroy: () => void;
|
|
344
|
+
};
|
|
345
|
+
declare class GanttChart implements GanttInstance {
|
|
346
|
+
#private;
|
|
347
|
+
constructor(container: HTMLElement, input: GanttInput, opts?: GanttOptions);
|
|
348
|
+
update(newInput: GanttInput): void;
|
|
349
|
+
setScale(scale: TimeScale): void;
|
|
350
|
+
select(id: number | null): void;
|
|
351
|
+
collapseAll(): void;
|
|
352
|
+
expandAll(): void;
|
|
353
|
+
destroy(): void;
|
|
354
|
+
}
|
|
355
|
+
//#endregion
|
|
356
|
+
//#region src/gantt-chart/errors.d.ts
|
|
357
|
+
type GanttErrorCode = 'PARENT_REFERENCE' | 'LINK_REFERENCE' | 'DEPENDENCY_CYCLE' | 'INSTANCE_DESTROYED';
|
|
358
|
+
declare class GanttError extends Error {
|
|
359
|
+
readonly code: GanttErrorCode;
|
|
360
|
+
constructor(code: GanttErrorCode, message: string);
|
|
361
|
+
}
|
|
362
|
+
//#endregion
|
|
363
|
+
export { BAR_HEIGHT, BAR_Y_OFFSET, type BarLayout, CHART_LOCALE_EN_US, type ChartLocale, DEFAULT_GRID_COLUMNS, DENSITY, EN_US_LABELS, GRID_COLUMN_FR_MIN_WIDTH, type GanttCallbacks, GanttChart, GanttError, type GanttErrorCode, type GanttInput, GanttInputSchema, type GanttInstance, type GanttOptions, type GridColumn, type Link, LinkSchema, type LinkType, LinkTypeSchema, type LocaleLabelKey, MILESTONE_HALF, MILESTONE_SIZE, type OnLinkCreate, type OnTaskAdd, type OnTaskDoubleClick, type OnTaskEditIntent, type OnTaskMove, type OnTaskResize, type OnTaskSelect, type PixelMapper, type Point, ROW_HEIGHT, type RoutedLink, SCALE_CONFIGS, type ScaleConfig, type SpecialDay, type SpecialDayKind, SpecialDayKindSchema, SpecialDaySchema, type Task, type TaskNode, TaskSchema, type TaskType, TaskTypeSchema, type ThemeMode, type TimeScale, addDays, buildTaskTree, computeLayout, createPixelMapper, deriveViewport, deriveWeekNumbering, deriveWeekStartsOn, deriveWeekendDays, detectCycles, diffDays, flattenTree, formatLabel, formatWeekNumber, gridColumnDefaults, gridNaturalWidth, gridTemplateColumns, isParent, parseDate, parseGanttInput, resolveChartLocale, routeLinks, safeParseGanttInput, validateLinkRefs, visibleColumns };
|
|
364
|
+
//# sourceMappingURL=index.d.mts.map
|