@llmnative/react 1.36.0 → 1.37.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.
@@ -352,6 +352,14 @@ export interface I18nDict {
352
352
  noAnswer: string;
353
353
  answered: string;
354
354
  };
355
+ /** CR-112 — the charts: empty state, totals, the scale of the heatmaps, the data table. */
356
+ charts: {
357
+ noData: string;
358
+ total: string;
359
+ less: string;
360
+ more: string;
361
+ dataTable: string;
362
+ };
355
363
  }
356
364
  type DeepPartial<T> = {
357
365
  [K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K];
@@ -389,4 +397,13 @@ export declare function useI18n<P extends DotNestedKeyOf<I18nDict>>(namespace: P
389
397
  * like the root `ErrorBoundary` of `<App>`.
390
398
  */
391
399
  export declare function useI18nDictOrEnglish(): I18nDict;
400
+ /**
401
+ * Internal (not exported from the package): the dictionary and the locale of the nearest
402
+ * `<I18nProvider>`, English when there is none — for the charts (CR-112), which format numbers in
403
+ * the locale and may render outside the provider.
404
+ */
405
+ export declare function useI18nOrEnglish(): {
406
+ dict: I18nDict;
407
+ locale: string;
408
+ };
392
409
  export {};
@@ -0,0 +1,56 @@
1
+ import React from 'react';
2
+ import type { FocusEvent as ReactFocusEvent, PointerEvent as ReactPointerEvent, ReactNode } from 'react';
3
+ export interface ChartLegendItem {
4
+ readonly label: string;
5
+ /** Theme token of the swatch, e.g. `'--rf-chart-1'`. */
6
+ readonly token: string;
7
+ readonly shape?: 'square' | 'line' | 'dashed' | 'dot';
8
+ }
9
+ /** The legend of a chart: swatch and label, the text in the text tokens (identity is never colour alone). */
10
+ export declare function ChartLegend({ items }: {
11
+ items: readonly ChartLegendItem[];
12
+ }): React.JSX.Element | null;
13
+ export interface ChartTooltipRow {
14
+ readonly label: string;
15
+ readonly value: string;
16
+ /** Theme token of the series swatch, e.g. `'--rf-chart-1'`. */
17
+ readonly token?: string;
18
+ }
19
+ /**
20
+ * The tooltip of the charts: follows the pointer, or sits by the mark that has the keyboard focus;
21
+ * rendered in a portal so the overflow or transform of a card never clips it. Values use the text
22
+ * tokens; only the swatch carries colour.
23
+ */
24
+ export declare function useChartTooltip(): {
25
+ readonly show: (event: ReactPointerEvent, title: string, rows: readonly ChartTooltipRow[]) => void;
26
+ readonly showAt: (event: ReactFocusEvent<Element>, title: string, rows: readonly ChartTooltipRow[]) => void;
27
+ readonly hide: () => void;
28
+ readonly element: ReactNode;
29
+ };
30
+ /**
31
+ * The data of a chart as a table only screen readers read: its text alternative. `rows` are the
32
+ * buckets (a label and one formatted value per column).
33
+ */
34
+ export declare function ChartDataTable({ caption, columns, rows }: {
35
+ caption: string;
36
+ columns: readonly string[];
37
+ rows: ReadonlyArray<{
38
+ label: string;
39
+ values: readonly string[];
40
+ }>;
41
+ }): React.JSX.Element | null;
42
+ /** What a chart shows with nothing to draw. */
43
+ export declare function ChartEmpty({ height }: {
44
+ height: number;
45
+ }): React.JSX.Element;
46
+ /** The handlers of a hit area: the pointer, and the keyboard while the chart has few of them. */
47
+ export declare function hitHandlers(tooltip: ReturnType<typeof useChartTooltip>, title: string, rows: readonly ChartTooltipRow[], keyboard: boolean): {
48
+ tabIndex?: number | undefined;
49
+ role?: "img" | undefined;
50
+ 'aria-label'?: string | undefined;
51
+ onFocus?: ((event: ReactFocusEvent<Element>) => void) | undefined;
52
+ onBlur?: (() => void) | undefined;
53
+ className?: string | undefined;
54
+ onPointerMove: (event: ReactPointerEvent) => void;
55
+ onPointerLeave: () => void;
56
+ };
@@ -0,0 +1,85 @@
1
+ import React from 'react';
2
+ import { type ChartColor } from './chartCore';
3
+ import { type ChartTooltipRow } from './ChartParts';
4
+ export interface ColumnChartColumn {
5
+ readonly label: string;
6
+ readonly value: number;
7
+ /** Its own colour (e.g. the critical bucket); otherwise the colour of the chart. */
8
+ readonly color?: ChartColor;
9
+ /** Rows of its tooltip; by default its value. */
10
+ readonly tooltip?: readonly ChartTooltipRow[];
11
+ }
12
+ export interface ColumnChartMarker {
13
+ /** Position in column units: 0 the left edge of the first column, n the right edge of the last. */
14
+ readonly position: number;
15
+ readonly label: string;
16
+ readonly dashed?: boolean;
17
+ }
18
+ export interface ColumnChartProps {
19
+ columns: readonly ColumnChartColumn[];
20
+ /** Text alternative of the chart, also the caption of its data table. */
21
+ ariaLabel: string;
22
+ color?: ChartColor;
23
+ format?: (value: number) => string;
24
+ /** Vertical markers (a median, a percentile). */
25
+ markers?: readonly ColumnChartMarker[];
26
+ /** Label at the end of the horizontal axis. */
27
+ axisLabel?: string;
28
+ /** The value on top of each column (default true). */
29
+ showValues?: boolean;
30
+ height?: number;
31
+ className?: string;
32
+ onColumnClick?: (column: ColumnChartColumn, index: number) => void;
33
+ }
34
+ /** CR-112 — one series of columns (a distribution, ordered buckets), value labels on top, optional markers. */
35
+ export declare function ColumnChart({ columns, ariaLabel, color, format: formatProp, markers, axisLabel, showValues, height, className, onColumnClick }: ColumnChartProps): React.JSX.Element;
36
+ export interface ChartSeries {
37
+ readonly id: string;
38
+ readonly label: string;
39
+ /** A slot of the palette (1…8) or a theme token; by default the slot of its position. */
40
+ readonly color?: ChartColor;
41
+ readonly values: readonly number[];
42
+ }
43
+ export interface StackedColumnChartProps {
44
+ series: readonly ChartSeries[];
45
+ /** One label per bucket, on the horizontal axis. */
46
+ labels: readonly string[];
47
+ ariaLabel: string;
48
+ /** Title of the tooltip per bucket; by default its label. */
49
+ titles?: readonly string[];
50
+ /** One axis label every N buckets (the last always shown). */
51
+ labelEvery?: number;
52
+ format?: (value: number) => string;
53
+ /** The total of a comparison period per bucket, drawn as a dashed tick. */
54
+ comparison?: readonly number[];
55
+ comparisonLabel?: string;
56
+ height?: number;
57
+ className?: string;
58
+ }
59
+ /** CR-112 — columns per bucket, stacked by series, gliding between periods; optional comparison tick per column. */
60
+ export declare function StackedColumnChart({ series, labels, ariaLabel, titles, labelEvery, format: formatProp, comparison, comparisonLabel, height, className }: StackedColumnChartProps): React.JSX.Element;
61
+ export interface DivergingBar {
62
+ readonly label: string;
63
+ /** Above the zero line; null: no data (nothing drawn). */
64
+ readonly up: number | null;
65
+ /** Below the zero line; null: no data. */
66
+ readonly down: number | null;
67
+ }
68
+ export interface DivergingBarChartProps {
69
+ bars: readonly DivergingBar[];
70
+ upLabel: string;
71
+ downLabel: string;
72
+ ariaLabel: string;
73
+ upColor?: ChartColor;
74
+ downColor?: ChartColor;
75
+ titles?: readonly string[];
76
+ labelEvery?: number;
77
+ format?: (value: number) => string;
78
+ height?: number;
79
+ className?: string;
80
+ }
81
+ /**
82
+ * CR-112 — two quantities per bucket around a zero line, one scale for both sides (charged above,
83
+ * drawn below; income and costs). Buckets without data stay empty, data at zero shows a hairline.
84
+ */
85
+ export declare function DivergingBarChart({ bars, upLabel, downLabel, ariaLabel, upColor, downColor, titles, labelEvery, format: formatProp, height, className }: DivergingBarChartProps): React.JSX.Element;
@@ -0,0 +1,76 @@
1
+ import React from 'react';
2
+ import { type ChartColor } from './chartCore';
3
+ export interface LineSeries {
4
+ readonly id: string;
5
+ readonly label: string;
6
+ readonly color?: ChartColor;
7
+ /** One value per label; null breaks the line (no data). */
8
+ readonly values: ReadonlyArray<number | null>;
9
+ /** A filled area under the line. */
10
+ readonly area?: boolean;
11
+ /** A comparison series: dashed, muted, no area. */
12
+ readonly dashed?: boolean;
13
+ /** A min–max band around the line (null: no band there). */
14
+ readonly band?: {
15
+ readonly min: ReadonlyArray<number | null>;
16
+ readonly max: ReadonlyArray<number | null>;
17
+ };
18
+ }
19
+ export interface LineChartProps {
20
+ series: readonly LineSeries[];
21
+ labels: readonly string[];
22
+ ariaLabel: string;
23
+ titles?: readonly string[];
24
+ labelEvery?: number;
25
+ format?: (value: number) => string;
26
+ /** A dashed line with a faint band above it (a limit). */
27
+ threshold?: {
28
+ readonly value: number;
29
+ readonly label: string;
30
+ };
31
+ /** A plain reference line (e.g. zero). */
32
+ baseline?: number;
33
+ /** The vertical range; by default from 0 to a rounded maximum of the data. */
34
+ domain?: readonly [number, number];
35
+ height?: number;
36
+ className?: string;
37
+ }
38
+ /**
39
+ * CR-112 — lines over time with a crosshair tooltip. Gaps (null) break a line; optional areas, a
40
+ * min–max band per series, a threshold with its band, a reference line. The lines draw themselves
41
+ * left to right.
42
+ */
43
+ export declare function LineChart({ series, labels, ariaLabel, titles, labelEvery, format: formatProp, threshold, baseline, domain, height, className }: LineChartProps): React.JSX.Element;
44
+ export interface AreaChartProps {
45
+ series: readonly {
46
+ readonly id: string;
47
+ readonly label: string;
48
+ readonly color?: ChartColor;
49
+ readonly values: readonly number[];
50
+ }[];
51
+ labels: readonly string[];
52
+ ariaLabel: string;
53
+ titles?: readonly string[];
54
+ labelEvery?: number;
55
+ format?: (value: number) => string;
56
+ /** Each series on top of the previous ones (default true): a cumulative flow, a composition. */
57
+ stacked?: boolean;
58
+ height?: number;
59
+ className?: string;
60
+ }
61
+ /**
62
+ * CR-112 — areas over time, stacked by default: the cumulative flow of work through its stages, the
63
+ * composition of a total. A crosshair shows every series and the total at a point.
64
+ */
65
+ export declare function AreaChart({ series, labels, ariaLabel, titles, labelEvery, format: formatProp, stacked, height, className }: AreaChartProps): React.JSX.Element;
66
+ export interface SparklineProps {
67
+ /** The trend; null leaves a gap. */
68
+ values: ReadonlyArray<number | null>;
69
+ color?: ChartColor;
70
+ height?: number;
71
+ className?: string;
72
+ /** Text alternative; without it the sparkline is decorative (beside the number it illustrates). */
73
+ ariaLabel?: string;
74
+ }
75
+ /** CR-112 — the trend line of a KPI tile: a filled area, the last point marked, gaps skipped. */
76
+ export declare function Sparkline({ values, color, height, className, ariaLabel }: SparklineProps): React.JSX.Element;
@@ -0,0 +1,73 @@
1
+ import React from 'react';
2
+ import { type ChartColor } from './chartCore';
3
+ import { type ChartLegendItem, type ChartTooltipRow } from './ChartParts';
4
+ export interface BarListRow {
5
+ readonly id: string;
6
+ readonly label: string;
7
+ readonly value: number;
8
+ /** A lighter bar behind the main one (e.g. the delivered behind the active). */
9
+ readonly background?: number;
10
+ readonly color?: ChartColor;
11
+ /** The text after the bar; by default the formatted value. */
12
+ readonly valueText?: string;
13
+ /** A note on the right with its own tone (a change over the previous period). */
14
+ readonly trailing?: {
15
+ readonly text: string;
16
+ readonly tone: 'good' | 'bad' | 'neutral';
17
+ };
18
+ readonly tooltip?: readonly ChartTooltipRow[];
19
+ }
20
+ export interface BarListProps {
21
+ rows: readonly BarListRow[];
22
+ ariaLabel: string;
23
+ color?: ChartColor;
24
+ format?: (value: number) => string;
25
+ /** The value of a full bar; by default the largest. */
26
+ max?: number;
27
+ /** Room for the labels, in px. */
28
+ labelWidth?: number;
29
+ legend?: readonly ChartLegendItem[];
30
+ className?: string;
31
+ onRowClick?: (row: BarListRow) => void;
32
+ }
33
+ /** CR-112 — horizontal bars, label on the left and value at the end: rankings, funnels, averages per group. */
34
+ export declare function BarList({ rows, ariaLabel, color, format: formatProp, max: fixedMax, labelWidth, legend, className, onRowClick }: BarListProps): React.JSX.Element;
35
+ export interface HeatmapProps {
36
+ /** values[row][column]. */
37
+ values: ReadonlyArray<readonly number[]>;
38
+ rowLabels: readonly string[];
39
+ /** One label per column; shown every `columnLabelEvery` columns. */
40
+ columnLabels: readonly string[];
41
+ columnLabelEvery?: number;
42
+ ariaLabel: string;
43
+ color?: ChartColor;
44
+ format?: (value: number) => string;
45
+ /** The title of a cell in its tooltip; by default its row and column. */
46
+ cellTitle?: (row: number, column: number) => string;
47
+ cellHeight?: number;
48
+ className?: string;
49
+ }
50
+ /** CR-112 — a grid of rows × columns (weekday × hour, agent × stage), one hue: darker is more. Cells light up in turn. */
51
+ export declare function Heatmap({ values, rowLabels, columnLabels, columnLabelEvery, ariaLabel, color, format: formatProp, cellTitle, cellHeight, className }: HeatmapProps): React.JSX.Element;
52
+ export interface CalendarHeatmapProps {
53
+ /** One entry per day (ISO date `YYYY-MM-DD`); null: no data that day. Days left out count as no data. */
54
+ days: ReadonlyArray<{
55
+ readonly date: string;
56
+ readonly value: number | null;
57
+ }>;
58
+ ariaLabel: string;
59
+ color?: ChartColor;
60
+ format?: (value: number) => string;
61
+ className?: string;
62
+ }
63
+ /** CR-112 — one square per day, weeks as columns from Monday: darker is more, a scale from less to more. */
64
+ export declare function CalendarHeatmap({ days, ariaLabel, color, format: formatProp, className }: CalendarHeatmapProps): React.JSX.Element;
65
+ /**
66
+ * CR-112 — a number that counts from the previous value (0 on first mount) to `value` with an
67
+ * ease-out, then shows `format(value)` exactly. Server rendering and reduced motion show it at once.
68
+ */
69
+ export declare function AnimatedNumber({ value, format: formatProp, duration }: {
70
+ value: number;
71
+ format?: (value: number) => string;
72
+ duration?: number;
73
+ }): React.JSX.Element;
@@ -0,0 +1,41 @@
1
+ import React from 'react';
2
+ import { type ChartColor } from './chartCore';
3
+ import { type ChartTooltipRow } from './ChartParts';
4
+ export interface ScatterPoint {
5
+ readonly id: string;
6
+ readonly label: string;
7
+ readonly x: number;
8
+ readonly y: number;
9
+ /** A third quantity as the area of the point (e.g. how many turns); all points the same without it. */
10
+ readonly size?: number;
11
+ /** The id of its series (its colour and legend); the first series without it. */
12
+ readonly series?: string;
13
+ /** Rows of its tooltip; by default its x, y and size. */
14
+ readonly tooltip?: readonly ChartTooltipRow[];
15
+ }
16
+ export interface ScatterChartProps {
17
+ points: readonly ScatterPoint[];
18
+ ariaLabel: string;
19
+ /** The groups of points: their label and colour, in the legend. */
20
+ series?: readonly {
21
+ readonly id: string;
22
+ readonly label: string;
23
+ readonly color?: ChartColor;
24
+ }[];
25
+ xLabel: string;
26
+ yLabel: string;
27
+ sizeLabel?: string;
28
+ formatX?: (value: number) => string;
29
+ formatY?: (value: number) => string;
30
+ formatSize?: (value: number) => string;
31
+ /** The label of each point next to it (default true with few points). */
32
+ showLabels?: boolean;
33
+ height?: number;
34
+ className?: string;
35
+ onPointClick?: (point: ScatterPoint) => void;
36
+ }
37
+ /**
38
+ * CR-112 — points by two quantities, an optional third as their area, coloured by series: cost against
39
+ * rework per model, speed against size. Axes from zero to rounded maxima; points fade in.
40
+ */
41
+ export declare function ScatterChart({ points, ariaLabel, series, xLabel, yLabel, sizeLabel, formatX: formatXProp, formatY: formatYProp, formatSize: formatSizeProp, showLabels, height, className, onPointClick, }: ScatterChartProps): React.JSX.Element;
@@ -0,0 +1,36 @@
1
+ import { type RefObject } from 'react';
2
+ /**
3
+ * CR-112 — the shared parts of the charts: scales, colours, motion, width, number format.
4
+ * Colours are theme tokens: a series names one (`'--rf-chart-1'`, `'--rf-primary'`) or a slot of the
5
+ * categorical palette (`1…8`, `--rf-chart-N`); marks read them as `hsl(var(--token))`, so every chart
6
+ * follows the theme and its dark mode.
7
+ */
8
+ /** A theme token (`'--rf-chart-2'`, `'--rf-success'`) or a slot of the categorical palette (1…8). */
9
+ export type ChartColor = string | number;
10
+ /** The CSS custom property of a chart colour; slots cycle through the eight of the palette. */
11
+ export declare function chartToken(color: ChartColor | undefined, fallbackSlot?: number): string;
12
+ /** `hsl(var(--token))`, with an optional alpha. */
13
+ export declare const chartFill: (token: string, alpha?: number) => string;
14
+ export declare const AXIS_TEXT = "hsl(var(--rf-muted-foreground))";
15
+ export declare const GRID_LINE = "hsl(var(--rf-border))";
16
+ /** Rounded axis maximum (1, 2, 2.5, 5 × 10ⁿ) at or above `value`. */
17
+ export declare function niceMax(value: number): number;
18
+ /** Evenly spaced ticks from `min` to `max`, both included. */
19
+ export declare function ticks(min: number, max: number, count?: number): number[];
20
+ /** The number format of the current locale (up to two decimals), the default of every chart. */
21
+ export declare function useChartFormat(format?: (value: number) => string): (value: number) => string;
22
+ /**
23
+ * Values that glide from what was shown before to `target` (from 0 on first mount), each mark
24
+ * `stagger` ms after the previous one, ease-out cubic. Reduced motion shows `target` at once.
25
+ */
26
+ export declare function useAnimatedValues(target: readonly number[], duration?: number, stagger?: number): number[];
27
+ /** 0 → 1 once per `key` change: for fades and lines that draw themselves. */
28
+ export declare function useReveal(key: string, duration?: number, delay?: number): number;
29
+ /**
30
+ * The rendered width of a chart's container in CSS pixels, kept current with a ResizeObserver: the
31
+ * charts use it as the width of their SVG viewBox, so text and marks keep their real size in a narrow
32
+ * card and in a wide one. `fallback` is used before the first measure (and in server rendering).
33
+ */
34
+ export declare function useChartWidth<T extends HTMLElement = HTMLElement>(fallback: number): [RefObject<T | null>, number];
35
+ /** Hit areas take the keyboard while there are few of them; with many, the data table stands in. */
36
+ export declare const KEYBOARD_LIMIT = 40;
@@ -0,0 +1,12 @@
1
+ export { ColumnChart, StackedColumnChart, DivergingBarChart } from './ColumnCharts';
2
+ export type { ColumnChartColumn, ColumnChartMarker, ColumnChartProps, ChartSeries, StackedColumnChartProps, DivergingBar, DivergingBarChartProps } from './ColumnCharts';
3
+ export { LineChart, AreaChart, Sparkline } from './LineCharts';
4
+ export type { LineSeries, LineChartProps, AreaChartProps, SparklineProps } from './LineCharts';
5
+ export { ScatterChart } from './ScatterChart';
6
+ export type { ScatterPoint, ScatterChartProps } from './ScatterChart';
7
+ export { BarList, Heatmap, CalendarHeatmap, AnimatedNumber } from './ListCharts';
8
+ export type { BarListRow, BarListProps, HeatmapProps, CalendarHeatmapProps } from './ListCharts';
9
+ export { ChartLegend, ChartDataTable, useChartTooltip } from './ChartParts';
10
+ export type { ChartLegendItem, ChartTooltipRow } from './ChartParts';
11
+ export { chartToken, chartFill, niceMax, ticks, useAnimatedValues, useReveal, useChartWidth, useChartFormat } from './chartCore';
12
+ export type { ChartColor } from './chartCore';
@@ -32,6 +32,7 @@ export * from './ui/GridSystem';
32
32
  export { default as Image } from './ui/Image';
33
33
  export { default as ImageAvatar } from './ui/ImageAvatar';
34
34
  export { default as Identicon, identiconPattern } from './ui/Identicon';
35
+ export * from './charts';
35
36
  export { default as Loader } from './ui/Loader';
36
37
  export { default as LocaleSwitcher } from './ui/LocaleSwitcher';
37
38
  export type { LocaleSwitcherProps } from './ui/LocaleSwitcher';
package/llms-full.txt CHANGED
@@ -867,6 +867,37 @@ utile quando un comando cambia famiglia sintattica (per esempio da `{{ ... }}` a
867
867
  <LayoutBuilder components={...} />
868
868
  ```
869
869
 
870
+ ### Charts (CR-112)
871
+ Grafici SVG senza dipendenze, dal modulo `charts`. Colori come token del tema: `color` è uno slot della
872
+ palette categoriale (`1…8` → `--rf-chart-N`, definiti in `globals.css` con la variante scura e
873
+ sovrascrivibili dal consumer) o un token (`'--rf-success'`); le serie senza colore prendono lo slot
874
+ della loro posizione. Larghezza dal contenitore (ResizeObserver), animazioni spente con
875
+ `prefers-reduced-motion`, tooltip che segue il puntatore e la tastiera (le aree prendono il focus
876
+ finché sono al massimo 40), tabella dei dati `sr-only` con `ariaLabel` come didascalia, stato vuoto
877
+ `charts.noData`. `format` è facoltativo: di default il numero nella locale dell'app.
878
+
879
+ ```tsx
880
+ <ColumnChart ariaLabel="CR chiuse al giorno" columns={[{ label: 'lun', value: 4 }]} markers={[{ position: 3.5, label: 'mediana', dashed: true }]} onColumnClick={(column) => {}} />
881
+ <StackedColumnChart ariaLabel="Ore per agente" labels={days} labelEvery={2} format={(v) => `${v} h`}
882
+ series={[{ id: 'dev', label: 'Developer', values: dev }, { id: 'qa', label: 'Tester', values: qa, color: 3 }]}
883
+ comparison={previousTotals} comparisonLabel="periodo precedente" />
884
+ <LineChart ariaLabel="Lead time" labels={days} threshold={{ value: 6.5, label: 'obiettivo' }} baseline={0} domain={[0, 10]}
885
+ series={[{ id: 'now', label: 'Ora', values: [3, null, 5], area: true, band: { min, max } }, { id: 'before', label: 'Prima', values: prev, dashed: true }]} />
886
+ <AreaChart ariaLabel="Flusso cumulativo" labels={days} stacked series={[{ id: 'closed', label: 'Chiuse', values: closed }]} />
887
+ <ScatterChart ariaLabel="Costo contro rework" xLabel="Costo" yLabel="Rework" sizeLabel="Turni"
888
+ series={[{ id: 'sonnet', label: 'Sonnet' }]} points={[{ id: '1', label: 'Developer', x: 0.04, y: 0.3, size: 30, series: 'sonnet' }]} onPointClick={(point) => {}} />
889
+ <DivergingBarChart ariaLabel="Valore e costo" upLabel="Valore" downLabel="Costo" bars={[{ label: 'lun', up: 120, down: null }]} />
890
+ <BarList ariaLabel="Costo per agente" rows={[{ id: 'dev', label: 'Developer', value: 1.84, trailing: { text: '+12%', tone: 'bad' } }]} />
891
+ <Heatmap ariaLabel="Turni per ora" rowLabels={agents} columnLabels={hours} columnLabelEvery={2} values={matrix} />
892
+ <CalendarHeatmap ariaLabel="Turni per giorno" days={[{ date: '2026-11-02', value: 4 }, { date: '2026-11-03', value: null }]} />
893
+ <Sparkline values={[1, 3, null, 2]} ariaLabel="Andamento" /> // senza ariaLabel è decorativa
894
+ <AnimatedNumber value={3.85} format={(v) => `$${v.toFixed(2)}`} />
895
+ ```
896
+
897
+ Parti comuni per grafici propri: `useChartTooltip()` (`show`, `showAt`, `hide`, `element`), `ChartLegend`,
898
+ `ChartDataTable`, `useChartWidth(fallback)`, `useAnimatedValues(values)`, `useReveal(key)`,
899
+ `useChartFormat(format?)`, `chartToken(color)`, `chartFill(token, alpha?)`, `niceMax`, `ticks`.
900
+
870
901
  ---
871
902
 
872
903
  ## Blocks
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@llmnative/react",
3
- "version": "1.36.0",
3
+ "version": "1.37.0",
4
4
  "description": "LLM-native React framework for deterministic UI generation. Data-driven by default, schema-driven optional. Ultra-low token consumption — built for AI agents, not just humans.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",