@open-tomato/charts 0.0.0-stage → 0.1.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.
Files changed (75) hide show
  1. package/README.md +286 -2
  2. package/dist/engine/BarChart/BarChart.d.ts +4 -0
  3. package/dist/engine/BarChart/BarChart.option.d.ts +4 -0
  4. package/dist/engine/BarChart/index.d.ts +2 -0
  5. package/dist/engine/BoxPlot/BoxPlot.d.ts +4 -0
  6. package/dist/engine/BoxPlot/BoxPlot.option.d.ts +4 -0
  7. package/dist/engine/BoxPlot/index.d.ts +2 -0
  8. package/dist/engine/Bullet/Bullet.d.ts +4 -0
  9. package/dist/engine/Bullet/Bullet.option.d.ts +4 -0
  10. package/dist/engine/Bullet/index.d.ts +2 -0
  11. package/dist/engine/Donut/Donut.d.ts +4 -0
  12. package/dist/engine/Donut/Donut.option.d.ts +4 -0
  13. package/dist/engine/Donut/index.d.ts +2 -0
  14. package/dist/engine/Gauge/Gauge.d.ts +4 -0
  15. package/dist/engine/Gauge/Gauge.option.d.ts +4 -0
  16. package/dist/engine/Gauge/index.d.ts +2 -0
  17. package/dist/engine/HeatmapGrid/HeatmapGrid.d.ts +4 -0
  18. package/dist/engine/HeatmapGrid/HeatmapGrid.option.d.ts +4 -0
  19. package/dist/engine/HeatmapGrid/index.d.ts +2 -0
  20. package/dist/engine/Histogram/Histogram.d.ts +4 -0
  21. package/dist/engine/Histogram/Histogram.option.d.ts +4 -0
  22. package/dist/engine/Histogram/index.d.ts +2 -0
  23. package/dist/engine/LineChart/LineChart.d.ts +19 -0
  24. package/dist/engine/LineChart/LineChart.option.d.ts +4 -0
  25. package/dist/engine/LineChart/index.d.ts +2 -0
  26. package/dist/engine/NetworkGraph/NetworkGraph.d.ts +4 -0
  27. package/dist/engine/NetworkGraph/NetworkGraph.option.d.ts +8 -0
  28. package/dist/engine/NetworkGraph/index.d.ts +2 -0
  29. package/dist/engine/Nightingale/Nightingale.d.ts +4 -0
  30. package/dist/engine/Nightingale/Nightingale.option.d.ts +4 -0
  31. package/dist/engine/Nightingale/index.d.ts +2 -0
  32. package/dist/engine/Radar/Radar.d.ts +4 -0
  33. package/dist/engine/Radar/Radar.option.d.ts +4 -0
  34. package/dist/engine/Radar/index.d.ts +2 -0
  35. package/dist/engine/Sankey/Sankey.d.ts +4 -0
  36. package/dist/engine/Sankey/Sankey.option.d.ts +6 -0
  37. package/dist/engine/Sankey/index.d.ts +2 -0
  38. package/dist/engine/ScatterChart/ScatterChart.d.ts +4 -0
  39. package/dist/engine/ScatterChart/ScatterChart.option.d.ts +6 -0
  40. package/dist/engine/ScatterChart/index.d.ts +2 -0
  41. package/dist/engine/Sunburst/Sunburst.d.ts +4 -0
  42. package/dist/engine/Sunburst/Sunburst.option.d.ts +19 -0
  43. package/dist/engine/Sunburst/index.d.ts +2 -0
  44. package/dist/engine/Treemap/Treemap.d.ts +4 -0
  45. package/dist/engine/Treemap/Treemap.option.d.ts +4 -0
  46. package/dist/engine/Treemap/index.d.ts +2 -0
  47. package/dist/engine/chrome.d.ts +90 -0
  48. package/dist/engine/core.d.ts +58 -0
  49. package/dist/engine/echartsEngine.d.ts +3 -0
  50. package/dist/engine/fixtures.d.ts +61 -0
  51. package/dist/engine/headless/headless.d.ts +86 -0
  52. package/dist/engine/headless/index.d.ts +10 -0
  53. package/dist/engine/headless/index.js +142 -0
  54. package/dist/engine/index.d.ts +1 -0
  55. package/dist/engine/shared.d.ts +59 -0
  56. package/dist/engine/shared.variants.d.ts +40 -0
  57. package/dist/index-4bxmxw89.js +1786 -0
  58. package/dist/index-85mb21rn.js +69 -0
  59. package/dist/index.d.ts +11 -0
  60. package/dist/index.js +618 -0
  61. package/dist/lib/cn.d.ts +7 -0
  62. package/dist/lib/index.d.ts +2 -0
  63. package/dist/seam/ChartEngineProvider.d.ts +12 -0
  64. package/dist/seam/FormatProvider.d.ts +25 -0
  65. package/dist/seam/format.d.ts +171 -0
  66. package/dist/seam/format.schema.d.ts +14 -0
  67. package/dist/seam/height.d.ts +15 -0
  68. package/dist/seam/index.d.ts +12 -0
  69. package/dist/seam/tones.d.ts +49 -0
  70. package/dist/seam/types.d.ts +322 -0
  71. package/dist/seam/useResolvedTokens.d.ts +7 -0
  72. package/dist/theme/index.d.ts +3 -0
  73. package/dist/theme/index.js +30 -0
  74. package/dist/theme/tokens.d.ts +40 -0
  75. package/package.json +82 -4
@@ -0,0 +1,2 @@
1
+ /** Shared helpers every layer may import: `cn` today. */
2
+ export { cn } from './cn.js';
@@ -0,0 +1,12 @@
1
+ import type { ChartPrimitives } from './types.js';
2
+ import { type ReactElement, type ReactNode } from 'react';
3
+ /** The props of {@link ChartEngineProvider}. */
4
+ export interface ChartEngineProviderProps {
5
+ /** The engine every chart below draws with. */
6
+ readonly engine: ChartPrimitives;
7
+ readonly children: ReactNode;
8
+ }
9
+ /** Puts one engine in scope for the charts below it. */
10
+ export declare function ChartEngineProvider({ engine, children }: ChartEngineProviderProps): ReactElement;
11
+ /** The engine in scope; throws outside a provider so a missing wrap is loud. */
12
+ export declare function useChartEngine(): ChartPrimitives;
@@ -0,0 +1,25 @@
1
+ /**
2
+ * The format context as React state: `FormatProvider` puts a locale, a
3
+ * currency and the custom formatters in scope, and `useFormatter` turns a
4
+ * `ValueFormat` into a primitive's `valueFormat` function over them. Kept
5
+ * apart from `format.ts`, so the headless engine imports no React.
6
+ */
7
+ import { type ReactElement, type ReactNode } from 'react';
8
+ import { type FormatContext, type ValueFormat, type ValueFormatter } from './format.js';
9
+ /** The props of {@link FormatProvider}. */
10
+ export interface FormatProviderProps {
11
+ /** The locale, currency and custom formatters below; keep the object stable across renders. */
12
+ readonly context: FormatContext;
13
+ readonly children: ReactNode;
14
+ }
15
+ /** Puts one format context in scope for the charts below it. */
16
+ export declare function FormatProvider({ context, children }: FormatProviderProps): ReactElement;
17
+ /** The format context in scope; the defaults (`en-GB`, `USD`, `UTC`) outside a provider. */
18
+ export declare function useFormatContext(): FormatContext;
19
+ /**
20
+ * `spec` as a `valueFormat` function over the context in scope, or
21
+ * undefined when `spec` is, so the primitive keeps its own default. The
22
+ * function is rebuilt only when the spec's content or the context changes,
23
+ * so an inline spec literal does not redraw the chart.
24
+ */
25
+ export declare function useFormatter(spec?: ValueFormat): ValueFormatter | undefined;
@@ -0,0 +1,171 @@
1
+ /**
2
+ * Value formatting shared by the engines and the atoms: the plain helpers
3
+ * (`formatCompact`, `formatDay` and the rest), and the declarative
4
+ * `ValueFormat` spec, which `formatterFor` turns into the `(value) => string`
5
+ * function every primitive's `valueFormat` takes. No React and no zod, so
6
+ * the headless engine carries it; the zod schemas are in `format.schema.ts`
7
+ * and the React context in `FormatProvider.tsx`.
8
+ *
9
+ * Every date is written in UTC, so a tick label never depends on the
10
+ * machine's timezone.
11
+ */
12
+ /** 1,284 → "1.3K", 4,200,000 → "4.2M"; integers below 1,000 stay as they are. */
13
+ export declare function formatCompact(value: number): string;
14
+ /** 0.78 → "78%". */
15
+ export declare function formatPercent(fraction: number): string;
16
+ /** 45 → "45 min", 90 → "1.5 h". */
17
+ export declare function formatMinutes(minutes: number): string;
18
+ /** A day as "1 Nov", in a fixed locale and in UTC, so the label never depends on the viewer. */
19
+ export declare function formatDay(date: Date): string;
20
+ /** The week starting on a date, as "w/c 1 Nov", in UTC. */
21
+ export declare function formatWeek(date: Date): string;
22
+ /**
23
+ * A count of seconds as "1h 3m 10s": zero units left out ("1h 10s"),
24
+ * "0s" for nothing, sub-second precision dropped, a negative count
25
+ * clamped to "0s".
26
+ */
27
+ export declare function formatElapsed(seconds: number): string;
28
+ /**
29
+ * An instant relative to `now`, on a ladder: the same UTC day reads as a
30
+ * clock time ("23:30"); then "6 hours ago", "yesterday", "3 days ago",
31
+ * "last week", "2 weeks ago", "last month", "4 months ago", "last year",
32
+ * "2 years ago". Months and years use average lengths. An instant after
33
+ * `now` mirrors the ladder ("tomorrow", "in 3 days").
34
+ */
35
+ export declare function formatRelative(value: Date | number, now: Date | number, locale?: string): string;
36
+ /** The kinds a {@link ValueFormat} can name. */
37
+ export declare const VALUE_FORMAT_KINDS: readonly ["raw", "number", "compact", "percent", "money", "unit", "duration", "elapsed", "date", "relative", "custom"];
38
+ /** How a `date` format writes its value: "1 Nov", "w/c 1 Nov", "23:30", "1 Nov, 23:30", "Nov 2026". */
39
+ export declare const DATE_PATTERNS: readonly ["day", "week", "time", "datetime", "month"];
40
+ /** The unit a `duration` format reads its value in. */
41
+ export declare const DURATION_UNITS: readonly ["minutes", "seconds", "ms"];
42
+ /** What a `percent` format's value is: a fraction (0.78) or already a percent (78). */
43
+ export declare const PERCENT_BASES: readonly ["fraction", "percent"];
44
+ /** Which side of the number a `unit` format puts its unit. */
45
+ export declare const UNIT_POSITIONS: readonly ["after", "before"];
46
+ export type ValueFormatKind = typeof VALUE_FORMAT_KINDS[number];
47
+ export type DatePattern = typeof DATE_PATTERNS[number];
48
+ export type DurationUnit = typeof DURATION_UNITS[number];
49
+ export type PercentBase = typeof PERCENT_BASES[number];
50
+ export type UnitPosition = typeof UNIT_POSITIONS[number];
51
+ /**
52
+ * How a value is written, as data a spec or a data point can carry. Each
53
+ * kind reads the locale and the currency from the {@link FormatContext}
54
+ * unless it names its own. `digits` is the number of fraction digits, fixed.
55
+ */
56
+ export type ValueFormat =
57
+ /** `String(value)`, or `value.toFixed(digits)`. */
58
+ {
59
+ readonly kind: 'raw';
60
+ readonly digits?: number;
61
+ }
62
+ /** `Intl.NumberFormat` in the context's locale; `grouping` is on unless false. */
63
+ | {
64
+ readonly kind: 'number';
65
+ readonly digits?: number;
66
+ readonly grouping?: boolean;
67
+ }
68
+ /** `formatCompact`: 1,000 → "1K", 1,200,000 → "1.2M", in every locale. */
69
+ | {
70
+ readonly kind: 'compact';
71
+ }
72
+ /** 0.78 → "78%" (`of: 'fraction'`, the default), or 78 → "78%" (`of: 'percent'`); `signed` writes "+12%" and "-30%". */
73
+ | {
74
+ readonly kind: 'percent';
75
+ readonly digits?: number;
76
+ readonly of?: PercentBase;
77
+ readonly signed?: boolean;
78
+ }
79
+ /** A currency amount; the currency is the context's when the format names none. `compact` writes "$1.2K". */
80
+ | {
81
+ readonly kind: 'money';
82
+ readonly currency?: string;
83
+ readonly digits?: number;
84
+ readonly compact?: boolean;
85
+ }
86
+ /** "45 min" (`after`, the default, with a space) or "£45" (`before`, no space). */
87
+ | {
88
+ readonly kind: 'unit';
89
+ readonly unit: string;
90
+ readonly position?: UnitPosition;
91
+ }
92
+ /** A duration read in `from`, written by `formatMinutes`: "45 min", "1.5 h". */
93
+ | {
94
+ readonly kind: 'duration';
95
+ readonly from: DurationUnit;
96
+ }
97
+ /** A duration read in `from`, written by `formatElapsed`: "1h 3m 10s". */
98
+ | {
99
+ readonly kind: 'elapsed';
100
+ readonly from: DurationUnit;
101
+ }
102
+ /** An epoch in ms, written in UTC by `pattern`. */
103
+ | {
104
+ readonly kind: 'date';
105
+ readonly pattern: DatePattern;
106
+ }
107
+ /** An epoch in ms, written by `formatRelative` against the context's `now`, or the wall clock. */
108
+ | {
109
+ readonly kind: 'relative';
110
+ }
111
+ /** A formatter the context registers under `id` in `customFormatters`. */
112
+ | {
113
+ readonly kind: 'custom';
114
+ readonly id: string;
115
+ };
116
+ /** A value-to-text function, the shape of every primitive's `valueFormat`. */
117
+ export type ValueFormatter = (value: number) => string;
118
+ /** What a {@link ValueFormat} reads when it does not say: the locale, the currency, the custom formatters. */
119
+ export interface FormatContext {
120
+ /** A BCP 47 tag; `en-GB` when absent. */
121
+ readonly locale?: string;
122
+ /** An ISO 4217 code for `money`; `USD` when absent. */
123
+ readonly currency?: string;
124
+ /** Dates are always written in UTC; the field names it so a contract can carry it. */
125
+ readonly timeZone?: 'UTC';
126
+ /** Formatters a `custom` format names by id, registered by the hub or an app. */
127
+ readonly customFormatters?: Readonly<Record<string, ValueFormatter>>;
128
+ /** The instant a `relative` format counts from, as an epoch in ms; the wall clock when absent. */
129
+ readonly now?: number;
130
+ }
131
+ /** A {@link FormatContext} with every default filled in; `now` stays open, so a relative value reads the clock when it is written. */
132
+ export interface ResolvedFormatContext {
133
+ readonly locale: string;
134
+ readonly currency: string;
135
+ readonly timeZone: 'UTC';
136
+ readonly customFormatters: Readonly<Record<string, ValueFormatter>>;
137
+ readonly now?: number;
138
+ }
139
+ /** The defaults: `en-GB`, `USD`, `UTC`, no custom formatters. */
140
+ export declare const DEFAULT_FORMAT_CONTEXT: ResolvedFormatContext;
141
+ /** The context with its gaps filled from {@link DEFAULT_FORMAT_CONTEXT}. */
142
+ export declare function resolveFormatContext(context?: FormatContext): ResolvedFormatContext;
143
+ /**
144
+ * A date or an epoch in ms, written in UTC by `pattern` in `locale`
145
+ * (`en-GB` by default). `datetime` joins the day and the time with a comma
146
+ * rather than taking the locale's own joiner, which differs between ICU
147
+ * versions. `week` prefixes the day with "w/c" in every locale.
148
+ */
149
+ export declare function formatDate(value: Date | number, pattern: DatePattern, locale?: string): string;
150
+ /**
151
+ * The function that writes values as `spec` says, over `context`'s locale,
152
+ * currency and custom formatters. Throws when a `custom` id is not
153
+ * registered, or when `spec` names no known kind.
154
+ */
155
+ export declare function formatterFor(spec: ValueFormat, context?: FormatContext): ValueFormatter;
156
+ /** A value with its own unit and, optionally, its own format, which wins over the chart's. */
157
+ export interface Measured {
158
+ readonly value: number;
159
+ /** Written after the number when the format writes no unit of its own. */
160
+ readonly unit?: string;
161
+ /** This value's format; it wins over the spec's. */
162
+ readonly format?: ValueFormat;
163
+ }
164
+ /**
165
+ * A measured value as text. The format is the point's own, else
166
+ * `specFormat`, else a `number` in the context's locale; the context fills
167
+ * whatever the format leaves out. The point's `unit` follows a bare number
168
+ * ("45 min"); a format with a unit of its own (percent, money, unit,
169
+ * duration, elapsed, date, relative, custom) keeps it alone.
170
+ */
171
+ export declare function formatMeasured(measured: Measured, context?: FormatContext, specFormat?: ValueFormat): string;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * The format spec as zod v4 schemas, for a contract that carries a
3
+ * `ValueFormat` or a `FormatContext` as data (`@open-tomato/atlas-ui`'s
4
+ * card contract embeds them). The types live in `format.ts`; each schema is
5
+ * annotated with its type because the repo compiles with
6
+ * `isolatedDeclarations`, and the annotation also holds the schema to it.
7
+ * Widen the type and the schema together.
8
+ */
9
+ import type { FormatContext, ValueFormat } from './format.js';
10
+ import { z } from 'zod';
11
+ /** A `ValueFormat`, discriminated on `kind`. */
12
+ export declare const valueFormatSchema: z.ZodType<ValueFormat>;
13
+ /** A `FormatContext`; `customFormatters` holds functions, so it validates only in code, never from JSON. */
14
+ export declare const formatContextSchema: z.ZodType<FormatContext>;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * How tall a chart draws. A number is a plot height in px. `'fill'` takes
3
+ * the full height of the chart's container, which must have a height of
4
+ * its own (a sized box, a flex or grid cell that is stretched); the chart
5
+ * then follows that container as it resizes.
6
+ */
7
+ export type ChartHeight = number | 'fill';
8
+ /** Plot height in px when a chart is given none. */
9
+ export declare const DEFAULT_CHART_HEIGHT = 220;
10
+ /**
11
+ * The height in px a layout works with: the given px, or for `'fill'` the
12
+ * measured px of the container, or the default while nothing is measured
13
+ * yet (the first render, a headless drawing that did not resolve it).
14
+ */
15
+ export declare function plotHeightOf(height: ChartHeight | undefined, measured?: number): number;
@@ -0,0 +1,12 @@
1
+ /** The seam: ChartPrimitives types, chart tones, formatters and the ChartEngineProvider. Engine-free. */
2
+ export * from './types.js';
3
+ export * from './height.js';
4
+ export { ALL_TONES, CHROME_ROLES, SEQUENTIAL_STEPS, chartTone, readTokens, tokensFrom, toneVar, } from './tones.js';
5
+ export type { ChartToneVariantProps, ChartToneVariants, ResolvedTokens } from './tones.js';
6
+ export { useResolvedTokens } from './useResolvedTokens.js';
7
+ export * from './format.js';
8
+ export * from './format.schema.js';
9
+ export { FormatProvider, useFormatContext, useFormatter } from './FormatProvider.js';
10
+ export type { FormatProviderProps } from './FormatProvider.js';
11
+ export { ChartEngineProvider, useChartEngine } from './ChartEngineProvider.js';
12
+ export type { ChartEngineProviderProps } from './ChartEngineProvider.js';
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Tone helpers shared by every engine. The names come from the theme's one
3
+ * token list (`../theme/`), so there is no second list to keep in step.
4
+ *
5
+ * - `chartTone`: the CVA variant that sets `color`, so SVG marks paint with
6
+ * `currentColor`.
7
+ * - `toneVar`: the same token as a CSS `var()` string, for engines that take a
8
+ * colour string per series.
9
+ * - `readTokens`: the tokens read from the computed style of `<html>`, for
10
+ * canvas engines that cannot read CSS variables (ECharts);
11
+ * `useResolvedTokens` (`useResolvedTokens.ts`) re-reads them on a flip.
12
+ * - `tokensFrom`: the same map from values a caller holds, for the headless
13
+ * engine, which has no page to read.
14
+ *
15
+ * No React here, so the headless engine can import it.
16
+ */
17
+ import type { ChartTone } from './types.js';
18
+ import { type VariantProps } from 'class-variance-authority';
19
+ import { type TokenName } from '../theme/index.js';
20
+ /**
21
+ * The CVA variants that set `color` to a tone's token. The class names are
22
+ * written out in full so Tailwind can see them in this file.
23
+ */
24
+ export declare const chartTone: (props?: ChartToneVariantProps) => string;
25
+ /** The variant props `chartTone` takes. */
26
+ export interface ChartToneVariantProps {
27
+ readonly tone?: ChartTone | null;
28
+ }
29
+ /** The variant props, as CVA reads them off the variants function. */
30
+ export type ChartToneVariants = VariantProps<typeof chartTone>;
31
+ /** Every tone, in the order the theme lists its tokens: series, status, poles, then the two neutrals. */
32
+ export declare const ALL_TONES: readonly ChartTone[];
33
+ /** The sequential ramp (light to dark) as token names, for heatmaps. */
34
+ export declare const SEQUENTIAL_STEPS: readonly string[];
35
+ /** Chrome roles the engines need beside the series tones. */
36
+ export declare const CHROME_ROLES: readonly string[];
37
+ /** `var(--color-<token>)` for a tone or a chrome role. */
38
+ export declare function toneVar(toneOrRole: ChartTone | string): string;
39
+ /** Concrete colour strings keyed by tone and by token name (`series-1`, `ink`, `seq-300`). */
40
+ export type ResolvedTokens = Record<string, string>;
41
+ /** Reads every token from the computed style of `<html>`; a name the theme leaves undefined reads as an empty string. */
42
+ export declare function readTokens(): ResolvedTokens;
43
+ /**
44
+ * The resolved tokens from values the caller holds, keyed by token name
45
+ * without its prefix (`series-1`, `ink`, `seq-300`): every token is kept
46
+ * under its name and every tone under its own, `neutral` reading `ink-2`.
47
+ * A headless caller has no CSS variables to read, so it passes the full set.
48
+ */
49
+ export declare function tokensFrom(values: Readonly<Record<TokenName, string>>): ResolvedTokens;
@@ -0,0 +1,322 @@
1
+ /**
2
+ * The ChartPrimitives seam: the one interface every engine implements, so a
3
+ * card never imports a chart library. Props carry data and tones only;
4
+ * colours are resolved by the engine from the CSS tokens (see tones.ts).
5
+ */
6
+ import type { ChartHeight } from './height.js';
7
+ import type { POLE_TOKENS, SERIES_TOKENS, STATUS_TOKENS, TokenName } from '../theme/index.js';
8
+ import type { ComponentType } from 'react';
9
+ export type EngineId = 'echarts';
10
+ /** A series colour name: `series-1` to `series-8`. */
11
+ export type SeriesTone = TokenName<typeof SERIES_TOKENS[number]>;
12
+ /** A status colour name: `good`, `warning`, `serious`, `critical`. */
13
+ export type StatusTone = TokenName<typeof STATUS_TOKENS[number]>;
14
+ /** A balance pole colour name: the rim colour and the `-core` colour at the centre. */
15
+ export type PoleTone = TokenName<typeof POLE_TOKENS[number]>;
16
+ /** A role, never a hex: the engines paint marks with the token behind it. */
17
+ export type ChartTone = SeriesTone | StatusTone | PoleTone | 'neutral' | 'muted';
18
+ export interface ChartCommonProps {
19
+ /**
20
+ * Plot height: px, or `'fill'` for the full height of the container, which
21
+ * must have a height of its own (a maximised card's box). 220px when absent.
22
+ * The width always follows the container.
23
+ */
24
+ height?: ChartHeight;
25
+ className?: string;
26
+ /** Read by assistive tech on the chart root; required. */
27
+ ariaLabel: string;
28
+ /** Formats a value for axis ticks, direct labels and tooltips. */
29
+ valueFormat?: (value: number) => string;
30
+ /**
31
+ * Mount animation and animated layouts. Defaults to true; stories, captures
32
+ * and tests that need a still picture pass false.
33
+ */
34
+ animate?: boolean;
35
+ }
36
+ export interface BarSeries {
37
+ id: string;
38
+ label: string;
39
+ tone: ChartTone;
40
+ /** One value per category, same order as `categories`. */
41
+ values: readonly number[];
42
+ }
43
+ export interface BarChartProps extends ChartCommonProps {
44
+ categories: readonly string[];
45
+ series: readonly BarSeries[];
46
+ /** grouped: side by side; stacked: sums; stacked100: shares of the category total. */
47
+ mode?: 'grouped' | 'stacked' | 'stacked100';
48
+ orientation?: 'vertical' | 'horizontal';
49
+ /** A reference line across the value axis (a WIP limit, a target). */
50
+ limit?: {
51
+ value: number;
52
+ label: string;
53
+ };
54
+ }
55
+ export interface TimePoint {
56
+ x: Date;
57
+ y: number;
58
+ }
59
+ export interface LineSeries {
60
+ id: string;
61
+ label: string;
62
+ tone: ChartTone;
63
+ points: readonly TimePoint[];
64
+ }
65
+ export interface LineChartProps extends ChartCommonProps {
66
+ series: readonly LineSeries[];
67
+ /** line: strokes only; area: one series with a 10% wash; stacked-area: sums. */
68
+ variant?: 'line' | 'area' | 'stacked-area';
69
+ /** A horizontal reference (an average, a target). */
70
+ baseline?: {
71
+ value: number;
72
+ label: string;
73
+ };
74
+ xFormat?: (date: Date) => string;
75
+ /** Pins the time axis's ticks to a step: `week` starts on a Monday and ticks every seven days, for a weekly `xFormat`. */
76
+ xStep?: 'week';
77
+ /** A range selector under the plot (a brush or data zoom); the plot shows the selected range. */
78
+ zoom?: boolean;
79
+ /** Fires when the selected range changes; null when the whole range is back. */
80
+ onRangeChange?: (range: {
81
+ from: Date;
82
+ to: Date;
83
+ } | null) => void;
84
+ }
85
+ export interface ScatterPoint {
86
+ x: Date;
87
+ y: number;
88
+ label: string;
89
+ }
90
+ export interface ScatterChartProps extends ChartCommonProps {
91
+ points: readonly ScatterPoint[];
92
+ /** A smoothed line over the points (a moving average), same x domain. */
93
+ trend?: readonly TimePoint[];
94
+ trendLabel?: string;
95
+ pointsLabel: string;
96
+ yLabel: string;
97
+ xFormat?: (date: Date) => string;
98
+ }
99
+ export interface HistogramBin {
100
+ from: number;
101
+ to: number;
102
+ count: number;
103
+ }
104
+ export interface HistogramProps extends ChartCommonProps {
105
+ bins: readonly HistogramBin[];
106
+ /** The unit of the binned value, for the x axis ("min"). */
107
+ unit: string;
108
+ }
109
+ export interface BoxGroup {
110
+ label: string;
111
+ min: number;
112
+ q1: number;
113
+ median: number;
114
+ q3: number;
115
+ max: number;
116
+ outliers?: readonly number[];
117
+ }
118
+ export interface BoxPlotProps extends ChartCommonProps {
119
+ groups: readonly BoxGroup[];
120
+ unit: string;
121
+ }
122
+ export interface GaugeProps extends ChartCommonProps {
123
+ value: number;
124
+ max: number;
125
+ label: string;
126
+ /** Fractions of max where the fill turns warning, then critical. */
127
+ thresholds?: {
128
+ warning: number;
129
+ critical: number;
130
+ };
131
+ /**
132
+ * A second reading on a thin inner arc (last week, the plan). When `value`
133
+ * passes `max` the main arc is full and critical, the text says the true
134
+ * share (124%), and a marker sits at the max.
135
+ */
136
+ compare?: {
137
+ value: number;
138
+ label: string;
139
+ };
140
+ }
141
+ export interface BulletProps extends ChartCommonProps {
142
+ value: number;
143
+ target: number;
144
+ max: number;
145
+ /** Band ends as fractions of max: good up to [0], warning up to [1], serious after. */
146
+ ranges: [number, number];
147
+ label: string;
148
+ /** false when a smaller value is the good one (a failure share). */
149
+ higherIsBetter?: boolean;
150
+ }
151
+ export interface DonutSlice {
152
+ id: string;
153
+ label: string;
154
+ tone: ChartTone;
155
+ value: number;
156
+ }
157
+ export interface DonutProps extends ChartCommonProps {
158
+ slices: readonly DonutSlice[];
159
+ /** A second set of slices on a thinner inner ring (the previous period), same ids and tones. */
160
+ compare?: {
161
+ label: string;
162
+ slices: readonly DonutSlice[];
163
+ };
164
+ centerValue?: string;
165
+ centerLabel?: string;
166
+ }
167
+ export interface TreemapNode {
168
+ id: string;
169
+ label: string;
170
+ value: number;
171
+ group: string;
172
+ }
173
+ export interface TreemapProps extends ChartCommonProps {
174
+ nodes: readonly TreemapNode[];
175
+ groupTones: Readonly<Record<string, ChartTone>>;
176
+ unit: string;
177
+ }
178
+ export interface HeatmapGridProps extends ChartCommonProps {
179
+ rows: readonly string[];
180
+ cols: readonly string[];
181
+ /** cells[rowIndex][colIndex]; the sequential blue ramp maps 0..max. */
182
+ cells: readonly (readonly number[])[];
183
+ /** Show every nth column label (weeks: 4). */
184
+ colLabelEvery?: number;
185
+ unit: string;
186
+ /** The cell is a button when set: click or Enter fires it. */
187
+ onCellClick?: (cell: HeatmapCell) => void;
188
+ /** The cell drawn with a selection ring. */
189
+ selected?: {
190
+ row: number;
191
+ col: number;
192
+ } | null;
193
+ }
194
+ export interface HeatmapCell {
195
+ row: number;
196
+ col: number;
197
+ value: number;
198
+ }
199
+ export interface GraphNode {
200
+ id: string;
201
+ label: string;
202
+ /** The group names the tone and, in a Sankey, the column. */
203
+ group: string;
204
+ /** Node weight (size in a network map). */
205
+ value?: number;
206
+ }
207
+ export interface GraphLink {
208
+ source: string;
209
+ target: string;
210
+ value: number;
211
+ }
212
+ export interface NetworkGraphProps extends ChartCommonProps {
213
+ nodes: readonly GraphNode[];
214
+ links: readonly GraphLink[];
215
+ groupTones: Readonly<Record<string, ChartTone>>;
216
+ onNodeClick?: (node: GraphNode) => void;
217
+ }
218
+ export interface SankeyProps extends ChartCommonProps {
219
+ /** A DAG; the engine lays columns out by group order when it can. */
220
+ nodes: readonly GraphNode[];
221
+ links: readonly GraphLink[];
222
+ groupTones: Readonly<Record<string, ChartTone>>;
223
+ /** Column order of the groups, left to right. */
224
+ groupOrder: readonly string[];
225
+ }
226
+ export interface RoseSlice {
227
+ id: string;
228
+ label: string;
229
+ value: number;
230
+ /** The group names the tone through `groupTones`; `tone` wins when set. */
231
+ group?: string;
232
+ tone?: ChartTone;
233
+ }
234
+ /** A Nightingale rose: equal angles, the radius encodes the value, so the biggest slice is the tallest. */
235
+ export interface NightingaleProps extends ChartCommonProps {
236
+ slices: readonly RoseSlice[];
237
+ groupTones?: Readonly<Record<string, ChartTone>>;
238
+ unit: string;
239
+ }
240
+ export interface SunburstNode {
241
+ id: string;
242
+ label: string;
243
+ /** Leaf value; a parent's value is the sum of its children when left out. */
244
+ value?: number;
245
+ group?: string;
246
+ tone?: ChartTone;
247
+ children?: readonly SunburstNode[];
248
+ }
249
+ /** A layered sunburst: the inner ring is the first level, each outer ring a level deeper. */
250
+ export interface SunburstProps extends ChartCommonProps {
251
+ nodes: readonly SunburstNode[];
252
+ groupTones?: Readonly<Record<string, ChartTone>>;
253
+ unit: string;
254
+ /** Fires with the ids from the root to the clicked node. */
255
+ onNodeClick?: (path: string[]) => void;
256
+ }
257
+ export interface RadarAxis {
258
+ id: string;
259
+ label: string;
260
+ /** The pole this axis is pulled toward; axes of one pole are contiguous. */
261
+ pole: string;
262
+ }
263
+ /** One of the directions the shape can tilt toward: a wedge behind its axes, coloured core to rim. */
264
+ export interface RadarPole {
265
+ id: string;
266
+ label: string;
267
+ /** The colour at the rim of the wedge. */
268
+ tone: ChartTone;
269
+ /** The colour at the centre of the wedge. */
270
+ coreTone: ChartTone;
271
+ /** A glyph drawn at the wedge's outer edge (an emoji is fine). */
272
+ icon?: string;
273
+ }
274
+ export interface RadarSeries {
275
+ id: string;
276
+ label: string;
277
+ tone: ChartTone;
278
+ /** One value per axis, same order as `axes`, on the 0..max scale. */
279
+ values: readonly number[];
280
+ }
281
+ /** A radar whose axes are grouped into poles, so the shape's bulge reads as a tilt toward one pole. */
282
+ export interface RadarProps extends ChartCommonProps {
283
+ axes: readonly RadarAxis[];
284
+ poles: readonly RadarPole[];
285
+ series: readonly RadarSeries[];
286
+ /** The outer edge of the scale; 1 is the baseline ring when values are ratios to a baseline. */
287
+ max?: number;
288
+ /** A ring drawn at this value with a label (the baseline). */
289
+ baseline?: {
290
+ value: number;
291
+ label: string;
292
+ };
293
+ /**
294
+ * How much history stands behind the baseline: `weeks` of `of`. The ring and
295
+ * the wedge cores inside it solidify as the share grows; absent means full.
296
+ */
297
+ history?: {
298
+ weeks: number;
299
+ of: number;
300
+ };
301
+ }
302
+ export interface ChartPrimitives {
303
+ id: EngineId;
304
+ label: string;
305
+ /** What this engine could not draw natively and how the gap is covered. */
306
+ notes: readonly string[];
307
+ BarChart: ComponentType<BarChartProps>;
308
+ LineChart: ComponentType<LineChartProps>;
309
+ ScatterChart: ComponentType<ScatterChartProps>;
310
+ Histogram: ComponentType<HistogramProps>;
311
+ BoxPlot: ComponentType<BoxPlotProps>;
312
+ Gauge: ComponentType<GaugeProps>;
313
+ Bullet: ComponentType<BulletProps>;
314
+ Donut: ComponentType<DonutProps>;
315
+ Treemap: ComponentType<TreemapProps>;
316
+ HeatmapGrid: ComponentType<HeatmapGridProps>;
317
+ NetworkGraph: ComponentType<NetworkGraphProps>;
318
+ Sankey: ComponentType<SankeyProps>;
319
+ Nightingale: ComponentType<NightingaleProps>;
320
+ Sunburst: ComponentType<SunburstProps>;
321
+ Radar: ComponentType<RadarProps>;
322
+ }
@@ -0,0 +1,7 @@
1
+ import { type ResolvedTokens } from './tones.js';
2
+ /**
3
+ * The tokens as concrete colour strings, keyed by tone and by token name,
4
+ * re-read when the theme attribute changes on `<html>`. A write that leaves
5
+ * every colour as it was returns the same object, so a chart is not redrawn.
6
+ */
7
+ export declare function useResolvedTokens(): ResolvedTokens;
@@ -0,0 +1,3 @@
1
+ /** The theme contract: token names only; the consuming app ships the values. */
2
+ export { DARK_THEME, DELTA_TOKENS, POLE_TOKENS, SEQUENTIAL_TOKENS, SERIES_TOKENS, STATUS_TOKENS, SURFACE_TOKENS, THEME_ATTRIBUTE, THEME_TOKENS, TOKEN_PREFIX, tokenName, tokenNames, tokenVar, } from './tokens.js';
3
+ export type { ThemeToken, TokenName } from './tokens.js';
@@ -0,0 +1,30 @@
1
+ import {
2
+ DARK_THEME,
3
+ DELTA_TOKENS,
4
+ POLE_TOKENS,
5
+ SEQUENTIAL_TOKENS,
6
+ SERIES_TOKENS,
7
+ STATUS_TOKENS,
8
+ SURFACE_TOKENS,
9
+ THEME_ATTRIBUTE,
10
+ THEME_TOKENS,
11
+ TOKEN_PREFIX,
12
+ tokenName,
13
+ tokenNames,
14
+ tokenVar
15
+ } from "../index-85mb21rn.js";
16
+ export {
17
+ tokenVar,
18
+ tokenNames,
19
+ tokenName,
20
+ TOKEN_PREFIX,
21
+ THEME_TOKENS,
22
+ THEME_ATTRIBUTE,
23
+ SURFACE_TOKENS,
24
+ STATUS_TOKENS,
25
+ SERIES_TOKENS,
26
+ SEQUENTIAL_TOKENS,
27
+ POLE_TOKENS,
28
+ DELTA_TOKENS,
29
+ DARK_THEME
30
+ };