@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 ADDED
@@ -0,0 +1,9 @@
1
+ Copyright (c) 2026 Inspire Labs Pty Ltd, trading as Ninth Forge. All rights reserved.
2
+
3
+ This repository and its contents are proprietary and confidential. No licence is
4
+ granted to use, copy, modify or distribute any part of it except under a written
5
+ agreement with Inspire Labs Pty Ltd. Packages published from this repository are
6
+ licensed under the Ninth Forge End User Licence Agreement at https://ninthforge.com/legal/eula.
7
+
8
+ Free-pack packages and `@ninthforge/tokens` are released under the MIT licence; for
9
+ those packages, the licence file inside the package applies to that package only.
package/README.md CHANGED
@@ -1,3 +1,81 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
1
+ # @ninthforge/timeline
2
+
3
+ An executive roadmap for Microsoft Power Apps code apps and any React app: themes or teams as swimlanes, initiatives as bars packed into rows, milestones as diamonds, and fiscal quarters across the top. It's part of **[Ninth Forge Plan](https://ninthforge.com)**, the same component as the Ninth Forge Timeline control for model-driven and canvas apps.
4
+
5
+ - **Two modes:** Dates (Month, Quarter or Half-year zoom, labelled by your fiscal year, e.g. "Q1 FY27") and Now · Next · Later.
6
+ - **Lanes:** packed into as few rows as possible, collapsible, in your order; items without dates wait in a "Not scheduled" tray.
7
+ - **Editing:**
8
+ - drag to move, drag an edge to resize
9
+ - Alt+arrows from the keyboard
10
+ - undo and redo
11
+ - **Colour** by status or lane, with your own colours per value, and text that always stays readable.
12
+ - **Output and access:**
13
+ - print (board-pack ready) and PNG export
14
+ - light and dark themes with your accent
15
+ - right-to-left layouts and high-contrast mode
16
+ - full keyboard and screen-reader support
17
+ - **Lean and private:**
18
+ - no runtime dependencies beyond React (16.14 or later)
19
+ - no network calls, and the licence check is offline
20
+
21
+ ## Install
22
+
23
+ ```
24
+ npm install @ninthforge/timeline@next
25
+ ```
26
+
27
+ Release candidates (1.0.0-rc.N) are under npm's `next` tag until 1.0.0 on 27 January 2027.
28
+
29
+ ```
30
+ # from 1.0.0
31
+ npm install @ninthforge/timeline
32
+ ```
33
+
34
+ ## Use
35
+
36
+ You hold the data. The timeline shows it and tells you what the user changed.
37
+
38
+ ```tsx
39
+ import { useState } from 'react';
40
+ import { Timeline, type TimelineChange, type TimelineItem } from '@ninthforge/timeline';
41
+
42
+ const initial: TimelineItem[] = [
43
+ { id: 'i1', name: 'Customer portal v2', lane: 'Customer', status: 'At risk', start: '2026-10-05', end: '2027-03-26', horizon: 'Now' },
44
+ { id: 'i2', name: 'Portal launch', lane: 'Customer', start: '2027-03-29', dependsOn: ['i1'] }, // no end: a milestone
45
+ { id: 'i3', name: 'Cloud migration', lane: 'Platform', status: 'On track', start: '2026-07-06', end: '2026-12-18', horizon: 'Now' },
46
+ { id: 'i4', name: 'Board strategy day', lane: 'Growth', status: 'On track', start: '2026-11-20', end: '2026-11-20', milestone: false },
47
+ { id: 'i5', name: 'Voice assistant', lane: 'Customer', status: 'Not started', horizon: 'Later' } // no dates: "Not scheduled"
48
+ ];
49
+
50
+ export function Roadmap({ licenseKey, tenantId }: { licenseKey?: string; tenantId?: string }) {
51
+ const [items, setItems] = useState(initial);
52
+
53
+ // Save to your backend; throw (or reject) to put the item back with a message.
54
+ const onItemChange = async (c: TimelineChange) => {
55
+ setItems((list) => list.map((i) => (i.id !== c.id ? i : { ...i, ...(c.start ? { start: c.start } : {}), ...(c.end ? { end: c.end } : {}) })));
56
+ };
57
+
58
+ return (
59
+ <div style={{ height: 560 }}>
60
+ <Timeline
61
+ title="Group roadmap"
62
+ items={items}
63
+ laneOrder={['Customer', 'Growth', 'Platform']}
64
+ fiscalYearStart={7}
65
+ onItemChange={onItemChange}
66
+ licenseKey={licenseKey}
67
+ tenantId={tenantId}
68
+ />
69
+ </div>
70
+ );
71
+ }
72
+ ```
73
+
74
+ - **Dates** are ISO `YYYY-MM-DD` strings, end inclusive, handled in UTC. Changes come back the same way.
75
+ - **Milestones:** an item with no end, or an end equal to its start, is a milestone. Set `milestone: false` to keep a one-day item as a bar, or `true` to force a milestone.
76
+ - **Colours:** by `status` (On track, At risk, Off track, Done and Not started have built-in meanings) or by lane (`colorBy="lane"`). `statusColors` and `laneColors` map values to your own hex colours.
77
+ - **`fiscalYearStart`** (1–12) is the first month of your fiscal year. The year is named by the year it ends in, so July 2026 starts FY27.
78
+
79
+ ## Licence
80
+
81
+ Ninth Forge Plan is a paid product. Without a key, everything works, with a small "Unlicensed" badge in the corner. Pass your Plan key as `licenseKey` and your Microsoft Entra tenant ID as `tenantId`. The check is offline. Trials and keys: [ninthforge.com](https://ninthforge.com).