KQ-2093 · COST/STREAMS
Cost Streams
Assistant spend drawn as streams flowing from projects through features to models, each as thick as its money and coloured by the project it left; switching the month drives every node and stream from where it is to the new month's layout on one springs.glide spring, carrying on from any frame a second switch interrupts, while the total rolls on springs.snap and a line names the feature that moved most. Hovering or focusing a node lifts its streams and dims the rest, and Enter or a click isolates it — the plot re-lays out with only its flows at the same money scale on the same morph. Tab moves node to node, Enter isolates, Escape releases, the months are a tablist, and in a narrow container the streams become a nested list of bars.
Oct · $10.9k · isolated none · partial
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/cost-streams
Props
- projects
- CostNode[]
- default defaultCostProjects
- Where spend starts, top to bottom: { id, name }.
- features
- CostFeature[]
- default defaultCostFeatures
- What spends it: { id, name, project? }; a feature's streams take its project's colour.
- models
- CostNode[]
- default defaultCostModels
- What bills it, top to bottom.
- months
- CostMonth[]
- default defaultCostMonths
- The months, oldest first: { id, label, flows: { project, feature, model, amount }[], partialThrough? }.
- month / defaultMonth
- string
- default — / the last month
- The month shown, controlled or initial.
- onMonthChange
- (id, month) => void
- default —
- Fires from the tab or arrow key that changed the month.
- isolated / defaultIsolated
- string | null
- default — / null
- The node whose flows are isolated, controlled or initial.
- onSelectNode
- (id | null, kind) => void
- default —
- Fires when Enter or a click isolates a node, or with null when it is released.
- onExport
- (monthId, flows) => void
- default —
- Export was pressed. Omit it and the button is not drawn.
- status
- "ready" | "loading" | "error"
- default "ready"
- Spend arrived, is on its way, or failed. A month with no flows shows the empty state.
- onRetry
- () => void
- default —
- Try again was pressed after spend failed to load.
- title
- string
- default "Gaugeworks · assistant spend"
- The panel's heading.
- subtitle
- string
- default "Four products · by feature and model"
- Under the heading.
- formatMoney
- (amount: number) => string
- default "$18,420", by hand
- How money is printed.
- colors
- string[]
- default pigments turned from the accent's hue
- Project colours in project order.
- plotHeight
- number
- default 300
- The flow's height in px.
- curvature
- number
- default 0.5
- How far each stream's handles reach: 0 a straight band, 1 a deep S.
- nodeWidth
- number
- default 10
- Thickness of the node bars in px; streams start at their edges.
- accent
- "cobalt" | "plum" | "mint" | "ink" | string
- default "cobalt"
- The tab indicator, the isolation chip and the hue the project colours turn from.
- disabled
- boolean
- default false
- Read only: months and isolation cannot change.
- className
- string
- default —
- Classes for the panel.
| Prop | Type | Default | Description |
|---|---|---|---|
| projects | CostNode[] | defaultCostProjects | Where spend starts, top to bottom: { id, name }. |
| features | CostFeature[] | defaultCostFeatures | What spends it: { id, name, project? }; a feature's streams take its project's colour. |
| models | CostNode[] | defaultCostModels | What bills it, top to bottom. |
| months | CostMonth[] | defaultCostMonths | The months, oldest first: { id, label, flows: { project, feature, model, amount }[], partialThrough? }. |
| month / defaultMonth | string | — / the last month | The month shown, controlled or initial. |
| onMonthChange | (id, month) => void | — | Fires from the tab or arrow key that changed the month. |
| isolated / defaultIsolated | string | null | — / null | The node whose flows are isolated, controlled or initial. |
| onSelectNode | (id | null, kind) => void | — | Fires when Enter or a click isolates a node, or with null when it is released. |
| onExport | (monthId, flows) => void | — | Export was pressed. Omit it and the button is not drawn. |
| status | "ready" | "loading" | "error" | "ready" | Spend arrived, is on its way, or failed. A month with no flows shows the empty state. |
| onRetry | () => void | — | Try again was pressed after spend failed to load. |
| title | string | "Gaugeworks · assistant spend" | The panel's heading. |
| subtitle | string | "Four products · by feature and model" | Under the heading. |
| formatMoney | (amount: number) => string | "$18,420", by hand | How money is printed. |
| colors | string[] | pigments turned from the accent's hue | Project colours in project order. |
| plotHeight | number | 300 | The flow's height in px. |
| curvature | number | 0.5 | How far each stream's handles reach: 0 a straight band, 1 a deep S. |
| nodeWidth | number | 10 | Thickness of the node bars in px; streams start at their edges. |
| accent | "cobalt" | "plum" | "mint" | "ink" | string | "cobalt" | The tab indicator, the isolation chip and the hue the project colours turn from. |
| disabled | boolean | false | Read only: months and isolation cannot change. |
| className | string | — | Classes for the panel. |