@lilt-ui/charts 0.1.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.
Files changed (111) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +107 -0
  3. package/THIRD_PARTY_NOTICES.md +25 -0
  4. package/dist/activity-ring.d.ts +44 -0
  5. package/dist/analysis-BLLWEKBw.js +105 -0
  6. package/dist/cards/activity-ring-card.d.ts +60 -0
  7. package/dist/cards/area-chart-card.d.ts +19 -0
  8. package/dist/cards/area-chart-card.typecheck.d.ts +9 -0
  9. package/dist/cards/bar-chart-card.d.ts +34 -0
  10. package/dist/cards/cartesian-card.d.ts +206 -0
  11. package/dist/cards/chart-card.d.ts +77 -0
  12. package/dist/cards/combo-chart-card.d.ts +51 -0
  13. package/dist/cards/format.d.ts +36 -0
  14. package/dist/cards/funnel-chart-card.d.ts +62 -0
  15. package/dist/cards/heatmap-chart-card.d.ts +107 -0
  16. package/dist/cards/horizontal-bar-chart-card.d.ts +60 -0
  17. package/dist/cards/keys.d.ts +19 -0
  18. package/dist/cards/line-chart-card.d.ts +19 -0
  19. package/dist/cards/progress-card.d.ts +55 -0
  20. package/dist/cards/radar-chart-card.d.ts +93 -0
  21. package/dist/cards/radial-chart-card.d.ts +79 -0
  22. package/dist/cards/rank.d.ts +21 -0
  23. package/dist/cards/sankey-chart-card.d.ts +69 -0
  24. package/dist/cards/scatter-chart-card.d.ts +91 -0
  25. package/dist/cards/slope-chart-card.d.ts +73 -0
  26. package/dist/cards/stat-card.d.ts +68 -0
  27. package/dist/chart-context.d.ts +102 -0
  28. package/dist/chart-plot.d.ts +13 -0
  29. package/dist/chart.d.ts +17 -0
  30. package/dist/data/chart-data.d.ts +24 -0
  31. package/dist/data.d.ts +5 -0
  32. package/dist/data.js +2 -0
  33. package/dist/engine/analysis.d.ts +11 -0
  34. package/dist/engine/bars.d.ts +38 -0
  35. package/dist/engine/comparison.d.ts +3 -0
  36. package/dist/engine/composition.d.ts +6 -0
  37. package/dist/engine/domains.d.ts +13 -0
  38. package/dist/engine/geometry.d.ts +73 -0
  39. package/dist/engine/lifecycle.d.ts +10 -0
  40. package/dist/engine/lookup.d.ts +3 -0
  41. package/dist/engine/normalize.d.ts +21 -0
  42. package/dist/engine/ranking.d.ts +20 -0
  43. package/dist/engine/sankey.d.ts +36 -0
  44. package/dist/engine/scatter.d.ts +15 -0
  45. package/dist/engine/slope.d.ts +46 -0
  46. package/dist/engine/stack.d.ts +11 -0
  47. package/dist/export-chart-svg.d.ts +8 -0
  48. package/dist/index.d.ts +73 -0
  49. package/dist/index.js +11309 -0
  50. package/dist/interaction/adaptive-readout.d.ts +16 -0
  51. package/dist/interaction/axis-cursor.d.ts +30 -0
  52. package/dist/interaction/brush-gesture.d.ts +15 -0
  53. package/dist/interaction/brush-view.d.ts +12 -0
  54. package/dist/interaction/chart-controller.d.ts +6 -0
  55. package/dist/interaction/chart-sync.d.ts +35 -0
  56. package/dist/interaction/comparison-answer.d.ts +11 -0
  57. package/dist/interaction/comparison-layer.d.ts +19 -0
  58. package/dist/interaction/comparison-tooltip.d.ts +14 -0
  59. package/dist/interaction/focus-overview.d.ts +10 -0
  60. package/dist/interaction/inspection-layer.d.ts +29 -0
  61. package/dist/interaction/legend.d.ts +50 -0
  62. package/dist/interaction/pin-marker.d.ts +12 -0
  63. package/dist/interaction/tooltip-context.d.ts +4 -0
  64. package/dist/interaction/tooltip-view.d.ts +26 -0
  65. package/dist/interaction/tooltip.d.ts +10 -0
  66. package/dist/interaction/use-category-state.d.ts +24 -0
  67. package/dist/interaction/use-pinned-selection.d.ts +3 -0
  68. package/dist/interaction/value-legend.d.ts +32 -0
  69. package/dist/interaction/visibility.d.ts +8 -0
  70. package/dist/lifecycle/loading-layer.d.ts +38 -0
  71. package/dist/lifecycle/skeleton-sheen.d.ts +18 -0
  72. package/dist/lifecycle/status-content.d.ts +6 -0
  73. package/dist/model/cartesian-model.d.ts +132 -0
  74. package/dist/model/cartesian-model.typecheck.d.ts +1 -0
  75. package/dist/model/use-chart-state.d.ts +6 -0
  76. package/dist/motion/animated-number.d.ts +54 -0
  77. package/dist/motion/bounded-text.d.ts +13 -0
  78. package/dist/motion/entrance.d.ts +9 -0
  79. package/dist/motion/number-format.d.ts +4 -0
  80. package/dist/motion/use-chart-motion.d.ts +10 -0
  81. package/dist/motion/use-focus-domain.d.ts +7 -0
  82. package/dist/motion/use-glide.d.ts +13 -0
  83. package/dist/motion/use-series-weights.d.ts +2 -0
  84. package/dist/paint.d.ts +11 -0
  85. package/dist/primitives/annotations.d.ts +4 -0
  86. package/dist/primitives/area.d.ts +8 -0
  87. package/dist/primitives/axes.d.ts +9 -0
  88. package/dist/primitives/bar-shape.d.ts +39 -0
  89. package/dist/primitives/bar.d.ts +7 -0
  90. package/dist/primitives/change-comparison.d.ts +3 -0
  91. package/dist/primitives/grid.d.ts +3 -0
  92. package/dist/primitives/interval-band.d.ts +4 -0
  93. package/dist/primitives/line.d.ts +8 -0
  94. package/dist/primitives/plot-background.d.ts +10 -0
  95. package/dist/primitives/reference-line.d.ts +4 -0
  96. package/dist/primitives/runoff.d.ts +49 -0
  97. package/dist/runtime/chart-runtime.d.ts +95 -0
  98. package/dist/styles.css +2 -0
  99. package/dist/toolkit/chart-brush.d.ts +3 -0
  100. package/dist/toolkit/chart-overview.d.ts +3 -0
  101. package/dist/toolkit/chart-range-summary.d.ts +5 -0
  102. package/dist/toolkit/chart-readout.d.ts +3 -0
  103. package/dist/toolkit/chart-toolbar.d.ts +3 -0
  104. package/dist/toolkit/comparison-details.d.ts +7 -0
  105. package/dist/types.d.ts +555 -0
  106. package/dist/use-chart-width.d.ts +5 -0
  107. package/media/cards-dark.webp +0 -0
  108. package/media/cards-light.webp +0 -0
  109. package/media/hero-dark.webp +0 -0
  110. package/media/hero-light.webp +0 -0
  111. package/package.json +71 -0
@@ -0,0 +1,16 @@
1
+ import { ReactElement, ReactNode } from 'react';
2
+ import { ChartSnapshot } from '../chart-context';
3
+ import { ChartSelection, ChartSeries, ChartTooltipContext } from '../types';
4
+ export interface AdaptiveReadoutProps<T> {
5
+ snapshot: ChartSnapshot<T>;
6
+ series: readonly ChartSeries<T>[];
7
+ selection: ChartSelection<T> | null;
8
+ sharedX?: number;
9
+ peer: boolean;
10
+ pinned: boolean;
11
+ onRelease: () => void;
12
+ onCompareFromHere?: () => void;
13
+ renderContent?: (context: ChartTooltipContext) => ReactNode;
14
+ reducedMotion: boolean;
15
+ }
16
+ export declare function AdaptiveReadout<T>({ snapshot, series, selection, sharedX, peer, pinned, onRelease, onCompareFromHere, renderContent, reducedMotion, }: AdaptiveReadoutProps<T>): ReactElement;
@@ -0,0 +1,30 @@
1
+ import { MotionValue } from 'motion/react';
2
+ import { ChartAxisStyle, ChartHoverStyle } from '../types';
3
+ /** Visual center of x tick labels below the plot; pills center on the same line. */
4
+ export declare const X_LABEL_CENTER = 22;
5
+ /** The inspection pill positions, shared so axis labels can react to the approaching pill. */
6
+ export interface AxisCursor {
7
+ /** Center of the x pill, which stays inside the plot near its edges. */
8
+ x: MotionValue<number>;
9
+ /** The inspected position itself, for marks that must line up with the crosshair. */
10
+ pointerX: MotionValue<number>;
11
+ y: MotionValue<number>;
12
+ /** 1 while this chart owns an inspection, else 0. */
13
+ active: MotionValue<number>;
14
+ style: ChartAxisStyle;
15
+ pill: ChartHoverStyle;
16
+ /** Padding between the plot edges and axis labels or pills, for plots that run edge to edge. */
17
+ inset: number;
18
+ /** Continue lines and areas, faded, from the first and last observations to the plot edges. */
19
+ runoff: boolean;
20
+ /** How far edge labels may hang past the plot edges to stay centered on their ticks. */
21
+ overhang: number;
22
+ /** Where the value pill sits: on the y axis, or above the hovered mark. */
23
+ pillPosition: 'axis' | 'mark';
24
+ }
25
+ export declare const AxisCursorContext: import('react').Context<AxisCursor>;
26
+ export declare function useAxisCursor(): AxisCursor;
27
+ /** 1 when far from the pill, easing to 0 when the pill is on top of the label. */
28
+ export declare function proximityOpacity(distance: number, reach: number, active: number): number;
29
+ /** Pills sit on the y axis when it has labels, and above the hovered mark when it does not. */
30
+ export declare function resolvePillPosition(position: 'auto' | 'axis' | 'mark', style: ChartAxisStyle): 'axis' | 'mark';
@@ -0,0 +1,15 @@
1
+ export type BrushDrag = {
2
+ kind: 'start' | 'end' | 'move' | 'create';
3
+ anchor: number;
4
+ start: number;
5
+ end: number;
6
+ pointerId: number;
7
+ };
8
+ /** A cancelled drag cannot publish a range when pointer-up arrives later. */
9
+ export declare function createBrushGesture(): {
10
+ readonly active: BrushDrag | null;
11
+ start(drag: BrushDrag): void;
12
+ move(index: number, last: number): readonly [number, number] | null;
13
+ finish(index: number, last: number): readonly [number, number] | null;
14
+ cancel(): void;
15
+ };
@@ -0,0 +1,12 @@
1
+ import { ReactElement } from 'react';
2
+ import { ChartSnapshot } from '../chart-context';
3
+ import { ChartRange } from '../types';
4
+ interface BrushViewProps<T> {
5
+ snapshot: ChartSnapshot<T>;
6
+ range: ChartRange | null;
7
+ seriesId: string;
8
+ reducedMotion: boolean;
9
+ onFocus: (range: ChartRange | null) => void;
10
+ }
11
+ export declare function BrushView<T>({ snapshot, range, seriesId, reducedMotion, onFocus, }: BrushViewProps<T>): ReactElement;
12
+ export {};
@@ -0,0 +1,6 @@
1
+ import { ChartController } from '../types';
2
+ /**
3
+ * Creates a tiny framework-agnostic interaction store. Reuse one instance to link charts,
4
+ * or pass it to compact and expanded chart mounts to preserve the user's place.
5
+ */
6
+ export declare function createChartController(): ChartController;
@@ -0,0 +1,35 @@
1
+ import { ChartController } from '../types';
2
+ import { ResolvedX, XKind } from '../cards/keys';
3
+ /** The hovered or pinned position a sync group shares, in the x field's own terms. */
4
+ export interface ChartSyncPosition {
5
+ /** The hovered x value: the Date, number, or label of the row under the pointer. */
6
+ readonly value: Date | number | string;
7
+ readonly kind: XKind;
8
+ readonly pinned: boolean;
9
+ }
10
+ interface SyncState {
11
+ readonly key: number | string;
12
+ readonly kind: XKind;
13
+ readonly pinned: boolean;
14
+ /** The card whose pointer or keyboard set this position. */
15
+ readonly source: string;
16
+ }
17
+ /** Inspections this bridge writes into a card's controller carry this owner. */
18
+ export declare const SYNC_OWNER = "sync";
19
+ /**
20
+ * Read a sync group's shared position from any component, e.g. to show the hovered date in your
21
+ * own dashboard header. Returns null while nothing in the group is hovered or pinned.
22
+ */
23
+ export declare function useChartSync(name: string | undefined): ChartSyncPosition | null;
24
+ /**
25
+ * Where a shared position lands in one card: labels match exactly, and dates or numbers snap to
26
+ * the nearest row within half a step, so a weekly card follows a daily one. Returns null when the
27
+ * card has no row there.
28
+ */
29
+ export declare function syncTarget(state: Pick<SyncState, 'key' | 'kind'>, kind: XKind, labels: readonly string[], positions: readonly number[]): number | null;
30
+ /**
31
+ * Link a card's hover and pin to every other card in the same named group. The card's own
32
+ * controller stays the source of truth; this bridge only copies positions between controllers.
33
+ */
34
+ export declare function useCardSync<Row>(name: string | undefined, controller: ChartController, data: readonly Row[], x: string, resolved: ResolvedX<Row>): void;
35
+ export {};
@@ -0,0 +1,11 @@
1
+ import { ChartComparison, ChartComparisonSeries, ChartPercentagePolicy, ChartRange, ChartSeries } from '../types';
2
+ import { NormalizedData } from '../engine/normalize';
3
+ export interface ComparisonAnswer {
4
+ values: string;
5
+ change: string;
6
+ percentage: string | null;
7
+ unavailable: string | null;
8
+ }
9
+ /** Every visible descriptor keeps its own units, gaps and baseline policy. */
10
+ export declare function comparisonRows<T>(data: NormalizedData<T>, range: ChartRange, series: readonly ChartSeries<T>[], formatValue: (value: number) => string, percentage?: ChartPercentagePolicy): readonly ChartComparisonSeries[];
11
+ export declare function comparisonAnswer(comparison: ChartComparison, formatValue: (value: number) => string): ComparisonAnswer;
@@ -0,0 +1,19 @@
1
+ import { KeyboardEvent, PointerEvent, ReactElement } from 'react';
2
+ import { ChartComparison, ChartComparisonSeries } from '../types';
3
+ import { ChartSnapshot } from '../chart-context';
4
+ export type ComparisonEndpoint = 'start' | 'end';
5
+ interface ComparisonLayerProps<T> {
6
+ snapshot: ChartSnapshot<T>;
7
+ comparison: ChartComparison;
8
+ rows: readonly ChartComparisonSeries[];
9
+ reducedMotion: boolean;
10
+ preview?: boolean;
11
+ onEndpointPointerDown?: (handle: ComparisonEndpoint, event: PointerEvent<HTMLDivElement>) => void;
12
+ onEndpointPointerMove?: (handle: ComparisonEndpoint, event: PointerEvent<HTMLDivElement>) => void;
13
+ onEndpointPointerUp?: (handle: ComparisonEndpoint, event: PointerEvent<HTMLDivElement>) => void;
14
+ onEndpointCancel?: () => void;
15
+ onEndpointCommit?: () => void;
16
+ onEndpointKeyDown?: (handle: ComparisonEndpoint, event: KeyboardEvent<HTMLDivElement>) => void;
17
+ }
18
+ export declare function ComparisonLayer<T>({ snapshot, comparison, rows, reducedMotion, onEndpointPointerDown, onEndpointPointerMove, onEndpointPointerUp, onEndpointCancel, onEndpointCommit, onEndpointKeyDown, preview, }: ComparisonLayerProps<T>): ReactElement;
19
+ export {};
@@ -0,0 +1,14 @@
1
+ import { ReactNode } from 'react';
2
+ import { ChartComparisonContext } from '../types';
3
+ /** Placement only. Comparison content is explicitly supplied by the consumer. */
4
+ export declare function ComparisonTooltip({ comparison, renderContent, startX, endX, top, width, height, className, ariaLabel, }: {
5
+ comparison: ChartComparisonContext;
6
+ renderContent: (context: ChartComparisonContext) => ReactNode;
7
+ startX: number;
8
+ endX: number;
9
+ top: number;
10
+ width: number;
11
+ height: number;
12
+ className?: string;
13
+ ariaLabel?: string;
14
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,10 @@
1
+ import { ReactElement } from 'react';
2
+ import { ChartRange } from '../types';
3
+ import { ChartSnapshot } from '../chart-context';
4
+ interface FocusOverviewProps<T> {
5
+ snapshot: ChartSnapshot<T>;
6
+ range: ChartRange;
7
+ series: string;
8
+ }
9
+ export declare function FocusOverview<T>({ snapshot, range, series }: FocusOverviewProps<T>): ReactElement;
10
+ export {};
@@ -0,0 +1,29 @@
1
+ import { ReactElement, ReactNode } from 'react';
2
+ import { ChartSelection, ChartSeries, ChartTooltipContext } from '../types';
3
+ import { ChartSnapshot } from '../chart-context';
4
+ interface InspectionLayerProps<T> {
5
+ snapshot: ChartSnapshot<T>;
6
+ selection: ChartSelection<T> | null;
7
+ series: readonly ChartSeries<T>[];
8
+ seriesColors?: Readonly<Record<string, string>>;
9
+ paintId?: (seriesId: string, treatment: 'fade' | 'hatch' | 'dots') => string;
10
+ renderContent?: (context: ChartTooltipContext) => ReactNode;
11
+ inspectionSeries?: string;
12
+ /** Stacked pills: the stack `total`, the active series' own value, or its stacked edge. */
13
+ stackedPill?: 'total' | 'series' | 'stack';
14
+ pinIcon?: ReactNode;
15
+ tooltipClassName?: string;
16
+ tooltipAriaLabel?: string;
17
+ width: number;
18
+ height: number;
19
+ reducedMotion: boolean;
20
+ highlightMaskId: string;
21
+ crossGradientId: string;
22
+ compactPlot?: boolean;
23
+ inlineOnly?: boolean;
24
+ hideAxisBadges?: boolean;
25
+ peer?: boolean;
26
+ onCompareFromHere?: () => void;
27
+ }
28
+ export declare function InspectionLayer<T>({ snapshot, selection, series, seriesColors, paintId, renderContent, inspectionSeries, stackedPill, pinIcon, tooltipClassName, tooltipAriaLabel, width, height, reducedMotion, highlightMaskId, crossGradientId, compactPlot, inlineOnly, hideAxisBadges, peer, onCompareFromHere, }: InspectionLayerProps<T>): ReactElement;
29
+ export {};
@@ -0,0 +1,50 @@
1
+ import { ReactElement, ReactNode } from 'react';
2
+ import { ChartComparisonSeries, ChartLegendValue, LegendProps } from '../types';
3
+ import { CartesianChartModel } from '../model/cartesian-model';
4
+ type ModelLegendEntry<Id extends string> = ChartLegendValue & {
5
+ id: Id;
6
+ color: string;
7
+ };
8
+ export type ModelObservationLegendEntry<Row> = ChartLegendValue & {
9
+ color: string;
10
+ x: number;
11
+ row: Row;
12
+ sourceIndex: number;
13
+ };
14
+ type ModelLegendBase<Row, Id extends string> = Omit<LegendProps, 'series' | 'by' | 'renderValue' | 'renderLabel' | 'renderSwatch' | 'renderDifference' | 'renderItem'> & {
15
+ model: CartesianChartModel<Row, Id>;
16
+ };
17
+ type ModelSeriesLegendProps<Row, Id extends string> = ModelLegendBase<Row, Id> & {
18
+ by?: 'series';
19
+ series?: NoInfer<Id>;
20
+ renderValue?: (entry: ModelLegendEntry<Id>) => ReactNode;
21
+ renderLabel?: (entry: ModelLegendEntry<Id>) => ReactNode;
22
+ renderSwatch?: (entry: ModelLegendEntry<Id>) => ReactNode;
23
+ renderDifference?: (difference: ChartComparisonSeries<Id>, entry: ModelLegendEntry<Id>) => ReactNode;
24
+ renderItem?: (entry: ModelLegendEntry<Id>, actions: {
25
+ toggle: () => void;
26
+ focus: () => void;
27
+ isolate: () => void;
28
+ comparison: ChartComparisonSeries<Id> | null;
29
+ }) => ReactNode;
30
+ };
31
+ type ModelObservationLegendProps<Row, Id extends string> = ModelLegendBase<Row, Id> & {
32
+ by: 'observation';
33
+ series: NoInfer<Id>;
34
+ renderValue?: (entry: ModelObservationLegendEntry<Row>) => ReactNode;
35
+ renderLabel?: (entry: ModelObservationLegendEntry<Row>) => ReactNode;
36
+ renderSwatch?: (entry: ModelObservationLegendEntry<Row>) => ReactNode;
37
+ renderItem?: (entry: ModelObservationLegendEntry<Row>, actions: {
38
+ toggle: () => void;
39
+ focus: () => void;
40
+ isolate: () => void;
41
+ comparison: null;
42
+ }) => ReactNode;
43
+ };
44
+ export type ModelLegendProps<Row, Id extends string> = ModelSeriesLegendProps<Row, Id> | ModelObservationLegendProps<Row, Id>;
45
+ /** Normal-flow presentation; placement belongs to the consumer's layout. */
46
+ export declare function Legend<Row, Id extends string>(props: ModelLegendProps<Row, Id>): ReactElement | null;
47
+ export declare function Legend(props?: LegendProps & {
48
+ model?: never;
49
+ }): ReactElement | null;
50
+ export {};
@@ -0,0 +1,12 @@
1
+ import { ReactElement } from 'react';
2
+ export declare const PIN_SIZE = 24;
3
+ /**
4
+ * The marker above a pinned crosshair. It fades in with a soft blur, follows the pinned point,
5
+ * and releases the pin when clicked; on hover it shows the release glyph instead of the pin.
6
+ */
7
+ export declare function PinMarker({ left, top, reducedMotion, onRelease, }: {
8
+ left: number;
9
+ top: number;
10
+ reducedMotion: boolean;
11
+ onRelease: () => void;
12
+ }): ReactElement;
@@ -0,0 +1,4 @@
1
+ import { ChartSnapshot } from '../chart-context';
2
+ import { NormalizedRow } from '../engine/normalize';
3
+ import { ChartSeries, ChartTooltipContext } from '../types';
4
+ export declare function tooltipContext<T>(snapshot: ChartSnapshot<T>, row: NormalizedRow<T>, series: readonly ChartSeries<T>[], pinned: boolean, activeSeriesId?: string | null): ChartTooltipContext<T>;
@@ -0,0 +1,26 @@
1
+ import { ReactNode } from 'react';
2
+ import { ChartComparisonContext, ChartTooltipContext } from '../types';
3
+ import { AdaptiveReadoutProps } from './adaptive-readout';
4
+ export interface TooltipView {
5
+ inspection: ChartTooltipContext | null;
6
+ comparison: ChartComparisonContext | null;
7
+ colors: Readonly<Record<string, string>>;
8
+ x: number;
9
+ compareStartX: number;
10
+ compareEndX: number;
11
+ top: number;
12
+ width: number;
13
+ height: number;
14
+ reducedMotion: boolean;
15
+ compact: boolean;
16
+ narrow: boolean;
17
+ peer: boolean;
18
+ adaptive: Omit<AdaptiveReadoutProps<unknown>, 'renderContent'> | null;
19
+ onRelease: () => void;
20
+ onCompareFromHere?: () => void;
21
+ }
22
+ export declare function TooltipViewProvider({ value, children, }: {
23
+ value: TooltipView;
24
+ children: ReactNode;
25
+ }): import("react/jsx-runtime").JSX.Element;
26
+ export declare function useTooltipView(): TooltipView;
@@ -0,0 +1,10 @@
1
+ import { ReactElement } from 'react';
2
+ import { TooltipProps } from '../types';
3
+ import { CartesianChartModel } from '../model/cartesian-model';
4
+ /** A real, optional HTML part in ChartPlot's tooltip slot. */
5
+ export declare function Tooltip<Row, Id extends string>(props: TooltipProps<Row, Id> & {
6
+ model: CartesianChartModel<Row, Id>;
7
+ }): ReactElement | null;
8
+ export declare function Tooltip(props?: TooltipProps & {
9
+ model?: never;
10
+ }): ReactElement | null;
@@ -0,0 +1,24 @@
1
+ import { KeyboardEvent } from 'react';
2
+ import { CategorySelection, ChartStatus } from '../types';
3
+ import { RankingRow } from '../engine/ranking';
4
+ /** Retain accepted observations during refreshes; only a new identity clears them. */
5
+ export declare function useAcceptedRows<R>(incoming: readonly R[] | null, status: ChartStatus, resetKey?: string | number): {
6
+ rows: readonly R[] | null;
7
+ firstLoad: boolean;
8
+ skeleton: boolean;
9
+ };
10
+ export declare function useCategoryState<T>(rows: readonly RankingRow<T>[], interactive: boolean, onChange: ((selection: CategorySelection<T> | null) => void) | undefined, resetKey?: string | number, columns?: number, selectedId?: string | null, onSelectedIdChange?: (id: string | null) => void, hasAcceptedRows?: boolean, externalHoverId?: string | null): {
11
+ active: RankingRow<T> | undefined;
12
+ pinned: string | null;
13
+ bind: (id: string, index: number) => {
14
+ ref: (node: HTMLButtonElement | null) => void;
15
+ tabIndex: number;
16
+ 'aria-pressed': boolean;
17
+ onPointerEnter: () => void;
18
+ onPointerLeave: () => void;
19
+ onFocus: () => void;
20
+ onBlur: () => void;
21
+ onClick: () => void;
22
+ onKeyDown: (event: KeyboardEvent<HTMLButtonElement>) => void;
23
+ };
24
+ };
@@ -0,0 +1,3 @@
1
+ import { SetStateAction } from 'react';
2
+ /** User selection can be owned by a dashboard; hover remains local to the chart. */
3
+ export declare function usePinnedSelection(controlled: string | null | undefined, onChange?: (id: string | null) => void): readonly [string | null, (next: SetStateAction<string | null>) => void, () => void];
@@ -0,0 +1,32 @@
1
+ import { CSSProperties, ReactNode } from 'react';
2
+ export interface ValueLegendEntry {
3
+ id: string;
4
+ label: string;
5
+ color: string;
6
+ value: number | null;
7
+ formattedValue: string;
8
+ }
9
+ export interface ValueLegendProps<Entries extends readonly ValueLegendEntry[]> {
10
+ items: Entries;
11
+ variant?: 'cards' | 'inline';
12
+ activeId?: NoInfer<Entries[number]['id']> | null;
13
+ selectedId?: NoInfer<Entries[number]['id']> | null;
14
+ onHoverIdChange?: (id: NoInfer<Entries[number]['id']> | null) => void;
15
+ onSelectedIdChange?: (id: NoInfer<Entries[number]['id']> | null) => void;
16
+ /** Series currently hidden from the chart. */
17
+ hiddenIds?: readonly NoInfer<Entries[number]['id']>[];
18
+ /**
19
+ * Makes the legend a visibility control: clicking a tile hides or shows its series, and each
20
+ * tile offers "Only" and "Show all". The last visible series can't be hidden.
21
+ */
22
+ onHiddenIdsChange?: (ids: NoInfer<Entries[number]['id']>[]) => void;
23
+ renderLabel?: (entry: Entries[number]) => ReactNode;
24
+ renderValue?: (entry: Entries[number]) => ReactNode;
25
+ renderSwatch?: (entry: Entries[number]) => ReactNode;
26
+ renderItem?: (entry: Entries[number]) => ReactNode;
27
+ 'aria-label'?: string;
28
+ className?: string;
29
+ style?: CSSProperties;
30
+ }
31
+ /** Family-neutral values and layout. The consumer supplies measurements and interaction ownership. */
32
+ export declare function ValueLegend<const Entries extends readonly ValueLegendEntry[]>({ items, variant, activeId, selectedId, onHoverIdChange, onSelectedIdChange, hiddenIds, onHiddenIdsChange, renderLabel, renderValue, renderSwatch, renderItem, 'aria-label': ariaLabel, className, style, }: ValueLegendProps<Entries>): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,8 @@
1
+ export interface VisibilityIsolation {
2
+ id: string;
3
+ restore: readonly string[];
4
+ expected: readonly string[];
5
+ previous: readonly string[];
6
+ }
7
+ export declare function sameVisibleSet(a: readonly string[], b: readonly string[]): boolean;
8
+ export declare function reconcileIsolation(isolation: VisibilityIsolation | null, visible: readonly string[], available: readonly string[]): VisibilityIsolation | null;
@@ -0,0 +1,38 @@
1
+ import { ReactElement } from 'react';
2
+ import { ChartAxisStyle } from '../types';
3
+ export interface LoadingLayerProps {
4
+ width: number;
5
+ height: number;
6
+ left: number;
7
+ right: number;
8
+ top: number;
9
+ bottom: number;
10
+ visible: boolean;
11
+ opacity: number;
12
+ reducedMotion: boolean;
13
+ id: string;
14
+ /** The marks the skeleton stands in for. */
15
+ marks?: 'line' | 'bars' | 'area-stack' | 'bar-stack';
16
+ compact?: boolean;
17
+ barCount?: number;
18
+ seriesCount?: number;
19
+ showLine?: boolean;
20
+ /** Mirror the real axis: which placeholders and grid rows to draw. Defaults to `classic`. */
21
+ axis?: ChartAxisStyle;
22
+ /** Padding between the plot edges and label placeholders, as on the real axis. */
23
+ inset?: number;
24
+ /** Gap between the plot edges and the skeleton shape; 0 when marks run edge to edge. */
25
+ edge?: number;
26
+ }
27
+ export declare const SKELETON_CONTOUR: number[];
28
+ export interface SkeletonGeometry {
29
+ plotWidth: number;
30
+ plotBottom: number;
31
+ contour: string;
32
+ areaPath: string;
33
+ gridRows: string;
34
+ yBars: string;
35
+ xBars: string;
36
+ }
37
+ export declare function buildSkeletonGeometry({ width, height, left, right, top, bottom, axis, inset, edge, }: Pick<LoadingLayerProps, 'width' | 'height' | 'left' | 'right' | 'top' | 'bottom' | 'axis' | 'inset' | 'edge'>): SkeletonGeometry;
38
+ export declare function LoadingLayer({ width, height, left, right, top, bottom, visible, opacity, reducedMotion, id, marks, compact, barCount, seriesCount, showLine, axis, inset: labelInset, edge, }: LoadingLayerProps): ReactElement | null;
@@ -0,0 +1,18 @@
1
+ import { ReactNode } from 'react';
2
+ export interface SkeletonSheenProps {
3
+ /** The skeleton shapes. Their CSS paints them with `--lilt-skeleton-paint`. */
4
+ children: ReactNode;
5
+ /** The area the sheen sweeps across, in the SVG's own units. */
6
+ width: number;
7
+ height: number;
8
+ x?: number;
9
+ y?: number;
10
+ /** Draw the shapes without the moving highlight. */
11
+ reduced?: boolean;
12
+ }
13
+ /**
14
+ * Skeleton shapes with the same moving highlight as the Cartesian loading state. The shapes are
15
+ * drawn once for the eye and once more, in white, as the mask the highlight shows through, so
16
+ * the sheen lights only the placeholder and never the space around it.
17
+ */
18
+ export declare function SkeletonSheen({ children, width, height, x, y, reduced, }: SkeletonSheenProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,6 @@
1
+ import { ReactNode } from 'react';
2
+ export declare function StatusContent({ kind, message, retry, }: {
3
+ kind: 'empty' | 'error' | 'refresh-error';
4
+ message: string;
5
+ retry?: () => ReactNode;
6
+ }): React.ReactElement;
@@ -0,0 +1,132 @@
1
+ import { ChartComparisonResult, ChartPercentagePolicy, ChartController, ChartSeries, ChartYConfig, ChartTooltipContext, NumericXConfig, TimeXConfig, ChartRange } from '../types';
2
+ import { LegendSnapshot } from '../runtime/chart-runtime';
3
+ export type CartesianModelLegendItem<Id extends string> = LegendSnapshot['series'][number] & {
4
+ id: Id;
5
+ };
6
+ export type CartesianModelObservation<Row> = LegendSnapshot['observations'][number] & {
7
+ row: Row;
8
+ };
9
+ export interface CartesianModelState<Row, SeriesId extends string> {
10
+ readonly availability: 'loading' | 'ready' | 'error';
11
+ readonly acceptedRevision: number;
12
+ readonly inspection: ChartTooltipContext<Row, SeriesId> | null;
13
+ readonly comparison: ChartComparisonResult<SeriesId, Row> | null;
14
+ readonly visibleSeries: readonly SeriesId[];
15
+ readonly legend: readonly CartesianModelLegendItem<SeriesId>[];
16
+ readonly observations: readonly CartesianModelObservation<Row>[];
17
+ }
18
+ export interface CartesianModelFrame<Row, Id extends string> {
19
+ readonly data: readonly Row[];
20
+ readonly x: TimeXConfig<Row> | NumericXConfig<Row>;
21
+ readonly y?: ChartYConfig;
22
+ readonly series: readonly (ChartSeries<Row> & {
23
+ readonly id: Id;
24
+ })[];
25
+ }
26
+ export interface CartesianModelInput<Row, Id extends string> extends CartesianModelFrame<Row, Id> {
27
+ readonly status?: 'loading' | 'ready' | 'error';
28
+ readonly resetKey?: string | number;
29
+ readonly control?: CartesianModelControl<Id>;
30
+ }
31
+ export interface CartesianModelControl<Id extends string> {
32
+ readonly inspection?: {
33
+ readonly x: number;
34
+ readonly pinned: boolean;
35
+ } | null;
36
+ readonly visibleSeries?: readonly Id[];
37
+ readonly comparison?: ChartRange | null;
38
+ readonly onInspectionRequest?: (inspection: {
39
+ readonly x: number;
40
+ readonly pinned: boolean;
41
+ } | null) => void;
42
+ readonly onVisibleSeriesRequest?: (ids: readonly Id[]) => void;
43
+ readonly onComparisonRequest?: (range: ChartRange | null) => void;
44
+ }
45
+ export interface CartesianSummaryQuery<Id extends string> {
46
+ readonly measure: Id;
47
+ readonly scope?: ChartRange | null;
48
+ readonly aggregate: 'sum' | 'mean' | 'min' | 'max' | 'first' | 'last' | 'change';
49
+ readonly missing?: 'exclude' | 'require-complete';
50
+ }
51
+ export interface CartesianSummaryResult<Id extends string> {
52
+ readonly measure: Id;
53
+ readonly value: number | null;
54
+ readonly formattedValue: string;
55
+ readonly unit: string | null;
56
+ readonly coverage: {
57
+ readonly observed: number;
58
+ readonly missing: number;
59
+ readonly total: number;
60
+ };
61
+ readonly unavailableReason: string | null;
62
+ }
63
+ export interface CartesianModelActions<SeriesId extends string> {
64
+ readonly inspect: (x: number) => void;
65
+ readonly clearInspection: () => void;
66
+ readonly pin: (x: number) => void;
67
+ readonly release: () => void;
68
+ readonly setVisibleSeries: (ids: readonly SeriesId[]) => void;
69
+ readonly focusSeries: (id: SeriesId | null) => void;
70
+ readonly compare: (range: ChartRange, percentage?: ChartPercentagePolicy) => void;
71
+ readonly clearComparison: () => void;
72
+ readonly focusComparison: () => void;
73
+ readonly fullRange: () => void;
74
+ }
75
+ /** Carries the source row and declared series IDs across JSX component boundaries. */
76
+ export interface CartesianChartModel<Row, SeriesId extends string> {
77
+ readonly data: readonly Row[];
78
+ readonly x: TimeXConfig<Row> | NumericXConfig<Row>;
79
+ readonly series: readonly (ChartSeries<Row> & {
80
+ readonly id: SeriesId;
81
+ })[];
82
+ readonly getFrame: () => CartesianModelFrame<Row, SeriesId>;
83
+ readonly getAcceptedFrame: () => CartesianModelFrame<Row, SeriesId> | null;
84
+ readonly getAvailability: () => CartesianModelState<Row, SeriesId>['availability'];
85
+ readonly getResetKey: () => string | number | undefined;
86
+ /** Internal view projection of persistent inspection, comparison and focus. */
87
+ readonly getController: () => ChartController;
88
+ readonly update: (frame: CartesianModelInput<Row, SeriesId>) => void;
89
+ readonly summarize: (query: CartesianSummaryQuery<SeriesId>) => CartesianSummaryResult<SeriesId>;
90
+ readonly actions: CartesianModelActions<SeriesId>;
91
+ readonly getSnapshot: () => CartesianModelState<Row, SeriesId>;
92
+ readonly subscribe: (listener: () => void) => () => void;
93
+ }
94
+ type ModelActions = {
95
+ inspect: (x: number) => void;
96
+ clearInspection: () => void;
97
+ pin: (x: number) => void;
98
+ release: () => void;
99
+ setVisibleSeries: (ids: readonly string[]) => void;
100
+ focusSeries: (id: string | null) => void;
101
+ compare: (range: ChartRange) => void;
102
+ clearComparison: () => void;
103
+ focusComparison: () => void;
104
+ fullRange: () => void;
105
+ };
106
+ /** Internal publication from the accepted Cartesian plot; presentation never recalculates values. */
107
+ export declare function publishCartesianModel<Row, Id extends string>(model: CartesianChartModel<Row, Id>, state: Pick<CartesianModelState<Row, Id>, 'inspection' | 'comparison' | 'visibleSeries' | 'legend'>, actions: ModelActions): void;
108
+ /** Release a view's callbacks without changing the model's accepted frame or persistent state. */
109
+ export declare function detachCartesianModel<Row, Id extends string>(model: CartesianChartModel<Row, Id>): void;
110
+ /** Subscribe from any React component that has the handle, including outside Chart. */
111
+ export declare function useCartesianModelState<Row, Id extends string>(model: CartesianChartModel<Row, Id>): CartesianModelState<Row, Id>;
112
+ /** Define descriptors once; literal IDs and source-row metadata remain inferred. */
113
+ export declare function createCartesianChartModel<Row, const Series extends readonly ChartSeries<NoInfer<Row>>[]>({ data, x, y, series, status, resetKey, control, }: {
114
+ readonly data: readonly Row[];
115
+ readonly x: TimeXConfig<NoInfer<Row>> | NumericXConfig<NoInfer<Row>>;
116
+ readonly y?: ChartYConfig;
117
+ readonly series: Series;
118
+ readonly status?: 'loading' | 'ready' | 'error';
119
+ readonly resetKey?: string | number;
120
+ readonly control?: CartesianModelControl<Series[number]['id']>;
121
+ }): CartesianChartModel<Row, Series[number]['id']>;
122
+ /** Keep a Cartesian handle stable while ready input frames change. */
123
+ export declare function useCartesianChartModel<Row, const Series extends readonly ChartSeries<NoInfer<Row>>[]>(input: {
124
+ readonly data: readonly Row[];
125
+ readonly x: TimeXConfig<NoInfer<Row>> | NumericXConfig<NoInfer<Row>>;
126
+ readonly y?: ChartYConfig;
127
+ readonly series: Series;
128
+ readonly status?: 'loading' | 'ready' | 'error';
129
+ readonly resetKey?: string | number;
130
+ readonly control?: CartesianModelControl<Series[number]['id']>;
131
+ }, status?: 'ready' | 'loading' | 'error'): CartesianChartModel<Row, Series[number]['id']>;
132
+ export {};
@@ -0,0 +1 @@
1
+ export declare function ModelComposition(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,6 @@
1
+ export interface ChartStateSource<Snapshot> {
2
+ getSnapshot: () => Snapshot;
3
+ subscribe: (listener: () => void) => () => void;
4
+ }
5
+ /** Subscribe to one model slice without changing the type carried by its handle. */
6
+ export declare function useChartState<Snapshot, Selected>(model: ChartStateSource<Snapshot>, selector: (snapshot: Snapshot) => Selected): Selected;