@ninthforge/timeline 0.0.0-stage → 1.0.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +9 -0
- package/README.md +81 -3
- package/dist/index.cjs +2451 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +416 -0
- package/dist/index.d.ts +416 -0
- package/dist/index.js +2404 -0
- package/dist/index.js.map +1 -0
- package/package.json +51 -3
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,416 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Optimistic editing for Ninth Forge components — pure functions, no React.
|
|
5
|
+
*
|
|
6
|
+
* A change is `{ id, …fields, previous, source }`: the new values of some fields of one item,
|
|
7
|
+
* the old values of the same fields, and what caused it. Components define which fields are
|
|
8
|
+
* editable (`keys`), when two values count as the same (`equal`), and what "no value" is for
|
|
9
|
+
* a field when undoing (`blank`). Shared by the Gantt and the Scheduler.
|
|
10
|
+
*/
|
|
11
|
+
/** One edit to one item. `F` is the editable field set; `S` the sources a component uses. */
|
|
12
|
+
type Change<F extends object, S extends string = string> = Partial<F> & {
|
|
13
|
+
id: string;
|
|
14
|
+
/** The same fields before the edit — for undo, and for hosts that diff. */
|
|
15
|
+
previous: Partial<F>;
|
|
16
|
+
source: S;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* One action offered in a component's empty state, e.g. "Load sample data" on a Ninth Forge
|
|
21
|
+
* sample table. The host decides when to offer it and runs it; the component only shows it.
|
|
22
|
+
*/
|
|
23
|
+
interface EmptyAction {
|
|
24
|
+
label: string;
|
|
25
|
+
onClick: () => void;
|
|
26
|
+
/** Running: the button gives way to `status` ("Loading sample data… 120 of 380"). */
|
|
27
|
+
busy?: boolean;
|
|
28
|
+
status?: string;
|
|
29
|
+
/** Shown under the button, e.g. what the action does. */
|
|
30
|
+
hint?: string;
|
|
31
|
+
/** The last attempt failed (the button stays, so the user can retry). */
|
|
32
|
+
error?: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** The host props every Plan component takes for its watermark. */
|
|
36
|
+
interface WatermarkHostProps {
|
|
37
|
+
/**
|
|
38
|
+
* `false` draws no watermark at all (no link, no space). The licence is still checked; the
|
|
39
|
+
* host decides when, e.g. Power BI Desktop for authoring (DECISIONS 2026-10-31). Default true.
|
|
40
|
+
*/
|
|
41
|
+
watermark?: boolean;
|
|
42
|
+
/** `text`: words only, no coloured mark (Power BI certification). Default `mark`. */
|
|
43
|
+
watermarkStyle?: 'mark' | 'text';
|
|
44
|
+
/** The host opens the link itself (Power BI's `launchUrl`): the watermark becomes a button. */
|
|
45
|
+
onWatermarkClick?: () => void;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
interface Tick {
|
|
49
|
+
day: number;
|
|
50
|
+
x: number;
|
|
51
|
+
width: number;
|
|
52
|
+
label: string;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
type RoadmapZoom = 'month' | 'quarter' | 'half';
|
|
56
|
+
interface RoadmapScale {
|
|
57
|
+
zoom: RoadmapZoom;
|
|
58
|
+
fiscalYearStart: number;
|
|
59
|
+
startDay: number;
|
|
60
|
+
/** Exclusive. */
|
|
61
|
+
endDay: number;
|
|
62
|
+
dayWidth: number;
|
|
63
|
+
width: number;
|
|
64
|
+
x(day: number): number;
|
|
65
|
+
dayAt(px: number): number;
|
|
66
|
+
/** Years (or fiscal years) on top. */
|
|
67
|
+
major: Tick[];
|
|
68
|
+
/** Months, quarters or halves below. */
|
|
69
|
+
minor: Tick[];
|
|
70
|
+
/** Quarter zoom only: the months under each quarter (empty at other zooms). */
|
|
71
|
+
months: Tick[];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Host hooks shared by the Plan components (Gantt, Timeline, capacity heatmap) when a host such
|
|
76
|
+
* as a Power BI visual wraps them. Same shapes as `@ninthforge/charts`' hooks. All optional:
|
|
77
|
+
* Power Apps passes none of them.
|
|
78
|
+
*/
|
|
79
|
+
/** Passed with a selection: `multi` is true when Ctrl or Cmd was held (add to the selection). */
|
|
80
|
+
interface SelectInfo {
|
|
81
|
+
multi: boolean;
|
|
82
|
+
}
|
|
83
|
+
/** Where the pointer (or, from the keyboard, the item's anchor) is, in client coordinates. */
|
|
84
|
+
interface PointerInfo extends SelectInfo {
|
|
85
|
+
clientX: number;
|
|
86
|
+
clientY: number;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* "Copy diagnostics": one click copies what support needs to reproduce a problem, and nothing
|
|
91
|
+
* else. Product and control version, licence state (never the key), host, browser, locale, time
|
|
92
|
+
* zone, the mapped property names and the row count. No data values and no personal data: the
|
|
93
|
+
* input types only take names and counts, and every string is trimmed to one short line.
|
|
94
|
+
*
|
|
95
|
+
* Framework-free. The drop-in menu item is `CopyDiagnosticsItem` in `@ninthforge/core/react`.
|
|
96
|
+
*/
|
|
97
|
+
/** Where the control runs. PCF wrappers and Power BI visuals pass it when they know. */
|
|
98
|
+
type DiagnosticsHost = 'model-driven' | 'canvas' | 'canvas (Studio)' | 'custom page' | 'Power BI' | 'code app' | 'web page';
|
|
99
|
+
/**
|
|
100
|
+
* The licence as diagnostics reads it: a `LicenseResult` from `@ninthforge/license` fits. Only
|
|
101
|
+
* `status`, `payload.tier`, `payload.org` and `payload.exp` are read; the key itself never
|
|
102
|
+
* reaches this function, and the tenant ID and key id are left out.
|
|
103
|
+
*/
|
|
104
|
+
interface DiagnosticsLicence {
|
|
105
|
+
status: string;
|
|
106
|
+
payload?: {
|
|
107
|
+
tier?: string;
|
|
108
|
+
org?: string;
|
|
109
|
+
exp?: string;
|
|
110
|
+
} | null;
|
|
111
|
+
}
|
|
112
|
+
interface DiagnosticsInput {
|
|
113
|
+
/** The product, e.g. `Plan`, `Charts`. */
|
|
114
|
+
product: string;
|
|
115
|
+
/** The control, e.g. `Gantt` or `nf_NinthForge.PlanGantt`. */
|
|
116
|
+
control: string;
|
|
117
|
+
/** The control or package version, e.g. `0.4.4`. */
|
|
118
|
+
version: string;
|
|
119
|
+
licence?: DiagnosticsLicence | null;
|
|
120
|
+
/** Overrides detection (Power BI visuals, code apps, or a PCF that knows its host). */
|
|
121
|
+
host?: DiagnosticsHost;
|
|
122
|
+
/**
|
|
123
|
+
* Mapped properties: `{ taskStart: 'nf_start' }` gives `taskStart → nf_start`, and a list
|
|
124
|
+
* gives the names alone. Names only, never values.
|
|
125
|
+
*/
|
|
126
|
+
properties?: Readonly<Record<string, string | null | undefined>> | readonly string[];
|
|
127
|
+
/** Rows the control received. */
|
|
128
|
+
rows?: number;
|
|
129
|
+
/**
|
|
130
|
+
* A few product-specific settings, e.g. `{ 'Save mode': 'direct' }`. Settings only: never
|
|
131
|
+
* record values, user names or e-mail addresses.
|
|
132
|
+
*/
|
|
133
|
+
extra?: Readonly<Record<string, string | number | boolean | null | undefined>>;
|
|
134
|
+
now?: Date;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* What a host adds to a component's own diagnostics (the component fills product, version,
|
|
138
|
+
* licence and its row count): a PCF passes its control name, mapped properties and settings.
|
|
139
|
+
*/
|
|
140
|
+
type DiagnosticsHostInfo = Partial<Pick<DiagnosticsInput, 'control' | 'version' | 'host' | 'properties' | 'rows' | 'extra'>>;
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Text size: type roles and one scale for every component (the same roles in Power Apps and Power BI).
|
|
144
|
+
*
|
|
145
|
+
* Components size text by role, never by a pixel number, so one setting ("Text size", 75–200 %)
|
|
146
|
+
* makes every label, value and title bigger or smaller together. The same numbers reach CSS
|
|
147
|
+
* (`--nf-text-<role>`) and layout maths (`textSize(role, scale)`), so label fitting and row
|
|
148
|
+
* heights match what the browser draws.
|
|
149
|
+
*/
|
|
150
|
+
/** What the text is for, not how big it is. */
|
|
151
|
+
type TextRole = 'caption' | 'body' | 'label' | 'value' | 'callout' | 'header' | 'title' | 'hero';
|
|
152
|
+
/** Per-role sizes at 100 %, in CSS pixels, that replace the defaults. The scale still applies. */
|
|
153
|
+
type TextSizes = Partial<Record<TextRole, number>>;
|
|
154
|
+
|
|
155
|
+
/** A component theme. Every key becomes a `--nf-<kebab-key>` CSS variable. */
|
|
156
|
+
interface ComponentTheme {
|
|
157
|
+
accent: string;
|
|
158
|
+
accentTint: string;
|
|
159
|
+
accentText: string;
|
|
160
|
+
surface: string;
|
|
161
|
+
surfaceAlt: string;
|
|
162
|
+
ink: string;
|
|
163
|
+
muted: string;
|
|
164
|
+
line: string;
|
|
165
|
+
lineSoft: string;
|
|
166
|
+
phase: string;
|
|
167
|
+
milestone: string;
|
|
168
|
+
baseline: string;
|
|
169
|
+
selected: string;
|
|
170
|
+
focus: string;
|
|
171
|
+
positive: string;
|
|
172
|
+
negative: string;
|
|
173
|
+
tooltipBg: string;
|
|
174
|
+
tooltipInk: string;
|
|
175
|
+
font: string;
|
|
176
|
+
monoFont: string;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
type TimelineZoom = RoadmapZoom;
|
|
180
|
+
/** Dates on an axis, or Now / Next / Later columns. */
|
|
181
|
+
type TimelineMode = 'dates' | 'horizon';
|
|
182
|
+
interface TimelineItem {
|
|
183
|
+
id: string;
|
|
184
|
+
name: string;
|
|
185
|
+
/** ISO date (`YYYY-MM-DD`). No start and no end: shown in the "Not scheduled" tray. */
|
|
186
|
+
start?: string;
|
|
187
|
+
/** ISO date, inclusive. Empty, or the same as start: a milestone (unless `milestone` is false). */
|
|
188
|
+
end?: string;
|
|
189
|
+
/** Overrides the date rule: true = milestone on its start, false = a bar even if one day long. */
|
|
190
|
+
milestone?: boolean;
|
|
191
|
+
/** Swimlane (theme, team, product…). Empty: the "No lane" lane, last. */
|
|
192
|
+
lane?: string;
|
|
193
|
+
/** Drives colour: a semantic word (On track, At risk, Off track, Done, Not started) or any value. */
|
|
194
|
+
status?: string;
|
|
195
|
+
/** Now / Next / Later, for that mode. */
|
|
196
|
+
horizon?: string;
|
|
197
|
+
/** Hex colour override for this item. */
|
|
198
|
+
color?: string;
|
|
199
|
+
/** Ids of items this one depends on (read-only connectors). */
|
|
200
|
+
dependsOn?: string[];
|
|
201
|
+
/** Locks this item: no move or resize. */
|
|
202
|
+
readOnly?: boolean;
|
|
203
|
+
}
|
|
204
|
+
/** The editable fields: dates only in v1 (lanes and horizons are v1.x). */
|
|
205
|
+
interface TimelineFields {
|
|
206
|
+
start: string;
|
|
207
|
+
end: string;
|
|
208
|
+
}
|
|
209
|
+
type TimelineChange = Change<TimelineFields, 'drag' | 'keyboard' | 'undo' | 'redo'>;
|
|
210
|
+
type TimelineEditable = boolean | {
|
|
211
|
+
move?: boolean;
|
|
212
|
+
resize?: boolean;
|
|
213
|
+
};
|
|
214
|
+
interface TimelineProps extends WatermarkHostProps {
|
|
215
|
+
items: TimelineItem[];
|
|
216
|
+
title?: string;
|
|
217
|
+
zoom?: TimelineZoom;
|
|
218
|
+
defaultZoom?: TimelineZoom;
|
|
219
|
+
onZoomChange?: (zoom: TimelineZoom) => void;
|
|
220
|
+
mode?: TimelineMode;
|
|
221
|
+
defaultMode?: TimelineMode;
|
|
222
|
+
onModeChange?: (mode: TimelineMode) => void;
|
|
223
|
+
/** First month of the fiscal year (1–12, default 1): quarters and halves are labelled "Q1 FY27". */
|
|
224
|
+
fiscalYearStart?: number;
|
|
225
|
+
/** Colour items by status (default) or by lane. */
|
|
226
|
+
colorBy?: 'status' | 'lane';
|
|
227
|
+
/** Value → hex, checked before the built-in mapping (e.g. Dataverse choice colours). */
|
|
228
|
+
statusColors?: Record<string, string>;
|
|
229
|
+
laneColors?: Record<string, string>;
|
|
230
|
+
/** Lane order (by name); lanes not listed follow alphabetically, "No lane" last. */
|
|
231
|
+
laneOrder?: string[];
|
|
232
|
+
/** Read-only connectors from `dependsOn`. */
|
|
233
|
+
showDependencies?: boolean;
|
|
234
|
+
/** Override "today" (ISO date): demos and tests. */
|
|
235
|
+
today?: string;
|
|
236
|
+
theme?: 'light' | 'dark' | Partial<ComponentTheme>;
|
|
237
|
+
accent?: string;
|
|
238
|
+
/** Ninth Forge licence key (a Plan key). Missing keys show a small watermark; nothing breaks. */
|
|
239
|
+
/** An action offered when there's nothing to show, e.g. "Load sample data" (PCF on a Ninth Forge sample table). */
|
|
240
|
+
emptyAction?: EmptyAction;
|
|
241
|
+
/** One or more keys; or a promise of them (the PCF reading its licence-key environment variable). */
|
|
242
|
+
licenseKey?: string | PromiseLike<string | undefined>;
|
|
243
|
+
/** Host tenant (PCF: context.orgSettings.tenantId). */
|
|
244
|
+
tenantId?: string;
|
|
245
|
+
/**
|
|
246
|
+
* Show the small "renew within N days" notice while the licence is in its 14-day grace
|
|
247
|
+
* period. The licensing spec shows it to makers only: the PCF passes `true` only for makers
|
|
248
|
+
* (Studio in canvas, an admin or customiser in model-driven). Default `true`; turn it off in a
|
|
249
|
+
* code app your end users see.
|
|
250
|
+
*/
|
|
251
|
+
renewalNotice?: boolean;
|
|
252
|
+
/**
|
|
253
|
+
* Text size, 1 = 100 % (0.75–2). Every label, value and title scales together; rows, lanes
|
|
254
|
+
* and the lane names column grow with it. The PCF's "Text size" input (percent) sets it.
|
|
255
|
+
*/
|
|
256
|
+
textScale?: number;
|
|
257
|
+
/** Per-role sizes at 100 % in px, e.g. `{ body: 14 }`; the scale still applies. */
|
|
258
|
+
textSizes?: TextSizes;
|
|
259
|
+
/**
|
|
260
|
+
* `false` hides the Export menu (print, PNG and Copy diagnostics), e.g. in Power BI, whose
|
|
261
|
+
* sandbox blocks downloads, new windows and usually the clipboard. Default true.
|
|
262
|
+
*/
|
|
263
|
+
exports?: boolean;
|
|
264
|
+
/**
|
|
265
|
+
* "Copy diagnostics" in the Export menu: copies what support needs (version, licence state,
|
|
266
|
+
* host, browser, locale, time zone, mapped property names, row count; never data values or
|
|
267
|
+
* the key). A function adds what the host knows, e.g. the PCF's control name and mapped
|
|
268
|
+
* properties. `false` hides the item. Default: shown.
|
|
269
|
+
*/
|
|
270
|
+
diagnostics?: false | (() => DiagnosticsHostInfo);
|
|
271
|
+
height?: number | string;
|
|
272
|
+
className?: string;
|
|
273
|
+
/** Text direction (default: inherited). Lane names mirror; time runs left to right. */
|
|
274
|
+
dir?: 'ltr' | 'rtl';
|
|
275
|
+
showToolbar?: boolean;
|
|
276
|
+
/** The host is still loading: the empty state says so. */
|
|
277
|
+
loading?: boolean;
|
|
278
|
+
/** Every move, resize and undo. Return a promise for an optimistic save. */
|
|
279
|
+
onItemChange?: (change: TimelineChange) => void | Promise<void>;
|
|
280
|
+
/** Switch editing off, or parts of it. Default: on when `onItemChange` is given. */
|
|
281
|
+
editable?: TimelineEditable;
|
|
282
|
+
/** `info.multi` is true when Ctrl or Cmd was held (hosts that keep a multi-selection). */
|
|
283
|
+
onSelect?: (id: string | null, info: SelectInfo) => void;
|
|
284
|
+
/** Enter or double-click on an item. */
|
|
285
|
+
onOpen?: (item: TimelineItem) => void;
|
|
286
|
+
/**
|
|
287
|
+
* The pointer moved over an item, or the keyboard moved to one (at its bar). Called once with
|
|
288
|
+
* `null` on leaving the items.
|
|
289
|
+
*/
|
|
290
|
+
onHover?: (item: TimelineItem | null, at: PointerInfo) => void;
|
|
291
|
+
/** Item ids kept at full strength; the rest dim. Empty or undefined: nothing dims. */
|
|
292
|
+
highlighted?: readonly string[];
|
|
293
|
+
/** Right-click, the Menu key or Shift+F10 on an item. When set, the browser's menu doesn't open. */
|
|
294
|
+
onContextMenu?: (item: TimelineItem, at: PointerInfo) => void;
|
|
295
|
+
/** Colours from the host. `foreground` and `background` (high contrast) replace every grey. */
|
|
296
|
+
colors?: Partial<TimelineColors>;
|
|
297
|
+
/** `false`: no entrance animation or transitions (export snapshots). Default true. */
|
|
298
|
+
animate?: boolean;
|
|
299
|
+
}
|
|
300
|
+
interface TimelineColors {
|
|
301
|
+
/** The today line. */
|
|
302
|
+
today: string;
|
|
303
|
+
foreground: string;
|
|
304
|
+
background: string;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
declare function Timeline(props: TimelineProps): React.JSX.Element;
|
|
308
|
+
|
|
309
|
+
/** An item with its dates resolved to UTC day numbers. */
|
|
310
|
+
interface Placed {
|
|
311
|
+
item: TimelineItem;
|
|
312
|
+
id: string;
|
|
313
|
+
/** Day number (inclusive). */
|
|
314
|
+
start: number;
|
|
315
|
+
/** Day number (inclusive). Equal to start for milestones. */
|
|
316
|
+
end: number;
|
|
317
|
+
milestone: boolean;
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Where an item goes. Rules (Matt, 2026-10-26):
|
|
321
|
+
* - `milestone` set → it decides (true: a diamond on the start; false: a bar, even one day long)
|
|
322
|
+
* - otherwise an empty end, or an end equal to the start, is a milestone
|
|
323
|
+
* - only an end: a milestone on that date
|
|
324
|
+
* - no dates at all: unscheduled (the "Not scheduled" tray)
|
|
325
|
+
* - an end before the start is swapped, so nothing disappears
|
|
326
|
+
*/
|
|
327
|
+
declare function place(item: TimelineItem): Placed | null;
|
|
328
|
+
/**
|
|
329
|
+
* Pack spans into as few rows as possible without overlaps: sort by start, then longest,
|
|
330
|
+
* then id (deterministic), and put each span in the first row that has ended before it starts.
|
|
331
|
+
* Ends are inclusive day numbers.
|
|
332
|
+
*/
|
|
333
|
+
declare function packRows(spans: readonly {
|
|
334
|
+
id: string;
|
|
335
|
+
start: number;
|
|
336
|
+
end: number;
|
|
337
|
+
}[]): {
|
|
338
|
+
row: Map<string, number>;
|
|
339
|
+
rows: number;
|
|
340
|
+
};
|
|
341
|
+
interface Lane {
|
|
342
|
+
key: string;
|
|
343
|
+
label: string;
|
|
344
|
+
items: Placed[];
|
|
345
|
+
/** Packed row per item id. */
|
|
346
|
+
row: Map<string, number>;
|
|
347
|
+
rows: number;
|
|
348
|
+
collapsed: boolean;
|
|
349
|
+
top: number;
|
|
350
|
+
height: number;
|
|
351
|
+
/** Position among lanes (zebra tint, keyboard). */
|
|
352
|
+
index: number;
|
|
353
|
+
}
|
|
354
|
+
/** Lanes with packed rows and vertical positions, plus the items without dates. */
|
|
355
|
+
declare function buildLanes(items: readonly TimelineItem[], scale: Pick<RoadmapScale, 'dayWidth'>, opts?: {
|
|
356
|
+
laneOrder?: readonly string[];
|
|
357
|
+
collapsed?: ReadonlySet<string>;
|
|
358
|
+
filter?: string;
|
|
359
|
+
textScale?: number;
|
|
360
|
+
}): {
|
|
361
|
+
lanes: Lane[];
|
|
362
|
+
unscheduled: TimelineItem[];
|
|
363
|
+
};
|
|
364
|
+
/** Validated palette for values without a colour (distinct in lightness as well as hue). */
|
|
365
|
+
declare const PALETTE: string[];
|
|
366
|
+
type BarStyle = 'solid' | 'outline' | 'done';
|
|
367
|
+
interface Appearance {
|
|
368
|
+
/** Fill (or outline) colour. */
|
|
369
|
+
color: string;
|
|
370
|
+
/** Text on the fill: always 4.5:1. */
|
|
371
|
+
text: string;
|
|
372
|
+
style: BarStyle;
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* Colour for an item. Order: the item's own colour → the host's map for the value (e.g.
|
|
376
|
+
* Dataverse choice colours) → the meaning of the status word → a palette colour per value.
|
|
377
|
+
* Text on bars is always readable (`accentForText` shades the fill just enough).
|
|
378
|
+
*/
|
|
379
|
+
declare function appearance(item: TimelineItem, o: {
|
|
380
|
+
colorBy: 'status' | 'lane';
|
|
381
|
+
accent: string;
|
|
382
|
+
statusColors?: Readonly<Record<string, string>>;
|
|
383
|
+
laneColors?: Readonly<Record<string, string>>;
|
|
384
|
+
seen: Map<string, string>;
|
|
385
|
+
}): Appearance;
|
|
386
|
+
/** Items per horizon column (case-insensitive), plus any without a recognised horizon. */
|
|
387
|
+
declare function horizonColumns(items: readonly TimelineItem[]): {
|
|
388
|
+
key: string;
|
|
389
|
+
items: TimelineItem[];
|
|
390
|
+
}[];
|
|
391
|
+
|
|
392
|
+
declare const SAMPLE_LANES: string[];
|
|
393
|
+
declare function sampleRoadmap(): TimelineItem[];
|
|
394
|
+
|
|
395
|
+
interface TimelineExport {
|
|
396
|
+
title: string;
|
|
397
|
+
lanes: Lane[];
|
|
398
|
+
unscheduled: TimelineItem[];
|
|
399
|
+
/** The screen's scale: print refits it to the page, PNG uses it as is. */
|
|
400
|
+
scale: RoadmapScale;
|
|
401
|
+
looks: ReadonlyMap<string, Appearance>;
|
|
402
|
+
theme: ComponentTheme;
|
|
403
|
+
today: number;
|
|
404
|
+
/** "26 Oct 2026". */
|
|
405
|
+
printedOn: string;
|
|
406
|
+
showDependencies: boolean;
|
|
407
|
+
mode: TimelineMode;
|
|
408
|
+
fiscalYearStart?: number;
|
|
409
|
+
}
|
|
410
|
+
/** The print document. Pure: same inputs, same HTML. */
|
|
411
|
+
declare function timelinePrintHtml(o: TimelineExport): string;
|
|
412
|
+
|
|
413
|
+
/** This package's version, for Copy diagnostics. `version.test.ts` keeps it equal to package.json. */
|
|
414
|
+
declare const VERSION = "1.0.0-rc.1";
|
|
415
|
+
|
|
416
|
+
export { type Appearance, type Lane, PALETTE, type Placed, SAMPLE_LANES, Timeline, type TimelineChange, type TimelineEditable, type TimelineFields, type TimelineItem, type TimelineMode, type TimelineProps, type TimelineZoom, VERSION, appearance, buildLanes, horizonColumns, packRows, place, sampleRoadmap, timelinePrintHtml };
|