@lilt-ui/charts 0.2.0 → 0.4.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.
- package/CHANGELOG.md +44 -0
- package/README.md +45 -0
- package/dist/cards/area-chart-card.d.ts +10 -1
- package/dist/cards/cartesian-card.d.ts +35 -6
- package/dist/cards/chart-card.d.ts +12 -1
- package/dist/cards/line-chart-card.d.ts +10 -1
- package/dist/{cartesian-card-BDZs0v6E.js → cartesian-card-Cj1o38DC.js} +2771 -2987
- package/dist/chart.d.ts +1 -1
- package/dist/finance/cards/depth-chart-card.d.ts +2 -2
- package/dist/finance.js +220 -219
- package/dist/index.d.ts +5 -4
- package/dist/index.js +1792 -1628
- package/dist/interaction/axis-cursor.d.ts +12 -2
- package/dist/interaction/chart-sync.d.ts +11 -1
- package/dist/interaction/inspection-layer.d.ts +6 -0
- package/dist/interaction/pin-glyphs.d.ts +8 -0
- package/dist/interaction/pin-marker.d.ts +9 -1
- package/dist/interaction/use-category-state.d.ts +2 -0
- package/dist/interaction/use-touch-glide.d.ts +26 -0
- package/dist/model/cartesian-model.d.ts +3 -3
- package/dist/motion/use-glide.d.ts +7 -3
- package/dist/primitives/axis-segments.d.ts +23 -0
- package/dist/report-context-Cz0AYdV2.js +895 -0
- package/dist/styles.css +1 -1
- package/dist/types.d.ts +34 -3
- package/dist/watch/board/board-state.d.ts +74 -0
- package/dist/watch/board/board-toast.d.ts +19 -0
- package/dist/watch/board/chart-board.d.ts +97 -0
- package/dist/watch/board/report-context.d.ts +3 -0
- package/dist/watch/engine/describe.d.ts +9 -0
- package/dist/watch/engine/explain.d.ts +48 -0
- package/dist/watch/engine/normal.d.ts +114 -0
- package/dist/watch/engine/robust.d.ts +7 -0
- package/dist/watch/engine/rules.d.ts +22 -0
- package/dist/watch/engine/status.d.ts +39 -0
- package/dist/watch/index.d.ts +14 -0
- package/dist/watch/normal-layer.d.ts +18 -0
- package/dist/watch.d.ts +2 -0
- package/dist/watch.js +628 -0
- package/package.json +6 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { MotionValue } from 'motion/react';
|
|
2
|
-
import { ChartAxisStyle, ChartHoverStyle } from '../types';
|
|
2
|
+
import { ChartAxis, ChartAxisStyle, ChartHoverStyle } from '../types';
|
|
3
3
|
/** Visual center of x tick labels below the plot; pills center on the same line. */
|
|
4
4
|
export declare const X_LABEL_CENTER = 22;
|
|
5
5
|
/** The inspection pill positions, shared so axis labels can react to the approaching pill. */
|
|
@@ -11,7 +11,8 @@ export interface AxisCursor {
|
|
|
11
11
|
y: MotionValue<number>;
|
|
12
12
|
/** 1 while this chart owns an inspection, else 0. */
|
|
13
13
|
active: MotionValue<number>;
|
|
14
|
-
|
|
14
|
+
/** The preset each axis uses. */
|
|
15
|
+
axis: ResolvedAxis;
|
|
15
16
|
pill: ChartHoverStyle;
|
|
16
17
|
/** Padding between the plot edges and axis labels or pills, for plots that run edge to edge. */
|
|
17
18
|
inset: number;
|
|
@@ -26,5 +27,14 @@ export declare const AxisCursorContext: import('react').Context<AxisCursor>;
|
|
|
26
27
|
export declare function useAxisCursor(): AxisCursor;
|
|
27
28
|
/** 1 when far from the pill, easing to 0 when the pill is on top of the label. */
|
|
28
29
|
export declare function proximityOpacity(distance: number, reach: number, active: number): number;
|
|
30
|
+
/** The preset each axis uses, and a segmented axis's color scale. */
|
|
31
|
+
export interface ResolvedAxis {
|
|
32
|
+
x: ChartAxisStyle;
|
|
33
|
+
y: ChartAxisStyle;
|
|
34
|
+
xGradient?: boolean | readonly string[];
|
|
35
|
+
yGradient?: boolean | readonly string[];
|
|
36
|
+
}
|
|
37
|
+
/** Split an `axis` prop into one preset per axis. An axis left out is `minimal`. */
|
|
38
|
+
export declare function resolveAxis(axis: ChartAxis | undefined): ResolvedAxis;
|
|
29
39
|
/** Pills sit on the y axis when it has labels, and above the hovered mark when it does not. */
|
|
30
40
|
export declare function resolvePillPosition(position: 'auto' | 'axis' | 'mark', style: ChartAxisStyle): 'axis' | 'mark';
|
|
@@ -13,6 +13,8 @@ interface SyncState {
|
|
|
13
13
|
readonly pinned: boolean;
|
|
14
14
|
/** The card whose pointer or keyboard set this position. */
|
|
15
15
|
readonly source: string;
|
|
16
|
+
/** That card's name, so linked cards can say where a pin came from. */
|
|
17
|
+
readonly label?: string;
|
|
16
18
|
}
|
|
17
19
|
/** Inspections this bridge writes into a card's controller carry this owner. */
|
|
18
20
|
export declare const SYNC_OWNER = "sync";
|
|
@@ -27,9 +29,17 @@ export declare function useChartSync(name: string | undefined): ChartSyncPositio
|
|
|
27
29
|
* card has no row there.
|
|
28
30
|
*/
|
|
29
31
|
export declare function syncTarget(state: Pick<SyncState, 'key' | 'kind'>, kind: XKind, labels: readonly string[], positions: readonly number[]): number | null;
|
|
32
|
+
export interface CardSyncOptions {
|
|
33
|
+
/** The card's name, shown on linked cards' pins: "Pinned from Revenue". */
|
|
34
|
+
label?: string;
|
|
35
|
+
/** Releases the card's own pin when a linked card releases the group's. */
|
|
36
|
+
release?: () => void;
|
|
37
|
+
}
|
|
30
38
|
/**
|
|
31
39
|
* Link a card's hover and pin to every other card in the same named group. The card's own
|
|
32
40
|
* controller stays the source of truth; this bridge only copies positions between controllers.
|
|
41
|
+
* A pin is shared unless it is local, as Alt-click makes it; a shared pin can be released from
|
|
42
|
+
* any card in the group, and local pins stay put.
|
|
33
43
|
*/
|
|
34
|
-
export declare function useCardSync<Row>(name: string | undefined, controller: ChartController, data: readonly Row[], x: string, resolved: ResolvedX<Row
|
|
44
|
+
export declare function useCardSync<Row>(name: string | undefined, controller: ChartController, data: readonly Row[], x: string, resolved: ResolvedX<Row>, { label, release }?: CardSyncOptions): void;
|
|
35
45
|
export {};
|
|
@@ -2,6 +2,12 @@ import { ReactElement, ReactNode } from 'react';
|
|
|
2
2
|
import { ChartSelection, ChartSeries, ChartTooltipContext } from '../types';
|
|
3
3
|
import { ChartSnapshot } from '../chart-context';
|
|
4
4
|
import { PlotMark } from '../marks/contract';
|
|
5
|
+
/** How the crosshair travels between points; pins travel the same way. */
|
|
6
|
+
export declare const SPRING_TRANSITION: {
|
|
7
|
+
stiffness: number;
|
|
8
|
+
damping: number;
|
|
9
|
+
mass: number;
|
|
10
|
+
};
|
|
5
11
|
interface InspectionLayerProps<T> {
|
|
6
12
|
snapshot: ChartSnapshot<T>;
|
|
7
13
|
selection: ChartSelection<T> | null;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ReactElement } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Lilt's pin, shared by every control that pins something. With `release`, the struck-through
|
|
4
|
+
* pin waits underneath and takes over on hover or focus, meaning "unpin".
|
|
5
|
+
*/
|
|
6
|
+
export declare function PinGlyphs({ release }: {
|
|
7
|
+
release?: boolean;
|
|
8
|
+
}): ReactElement;
|
|
@@ -3,10 +3,18 @@ export declare const PIN_SIZE = 24;
|
|
|
3
3
|
/**
|
|
4
4
|
* The marker above a pinned crosshair. It fades in with a soft blur, follows the pinned point,
|
|
5
5
|
* and releases the pin when clicked; on hover it shows the release glyph instead of the pin.
|
|
6
|
+
* On a linked chart the pin arrived from elsewhere, so the marker is a ghost of the one that
|
|
7
|
+
* was clicked: it still releases the group's pin, but keyboard users meet only the original.
|
|
6
8
|
*/
|
|
7
|
-
export declare function PinMarker({ left, top, reducedMotion, onRelease, }: {
|
|
9
|
+
export declare function PinMarker({ left, top, reducedMotion, ghost, from, local, onRelease, }: {
|
|
8
10
|
left: number;
|
|
9
11
|
top: number;
|
|
10
12
|
reducedMotion: boolean;
|
|
13
|
+
/** Pinned from a linked chart. */
|
|
14
|
+
ghost?: boolean;
|
|
15
|
+
/** The linked chart's name, for the tooltip. */
|
|
16
|
+
from?: string;
|
|
17
|
+
/** Pinned on this chart only. */
|
|
18
|
+
local?: boolean;
|
|
11
19
|
onRelease: () => void;
|
|
12
20
|
}): ReactElement;
|
|
@@ -10,7 +10,9 @@ export declare function useAcceptedRows<R>(incoming: readonly R[] | null, status
|
|
|
10
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
11
|
active: RankingRow<T> | undefined;
|
|
12
12
|
pinned: string | null;
|
|
13
|
+
glideRef: (node: Element | null) => void;
|
|
13
14
|
bind: (id: string, index: number) => {
|
|
15
|
+
'data-glide-id': string;
|
|
14
16
|
ref: (node: HTMLButtonElement | null) => void;
|
|
15
17
|
tabIndex: number;
|
|
16
18
|
'aria-pressed': boolean;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/** How long a still finger rests before it glides in any direction instead of scrolling. */
|
|
2
|
+
export declare const TOUCH_HOLD_MS = 320;
|
|
3
|
+
/** How far a finger travels before it counts as a swipe rather than a tap. */
|
|
4
|
+
export declare const TOUCH_SLOP = 8;
|
|
5
|
+
export interface TouchGlideOptions<T> {
|
|
6
|
+
/** What sits under the finger: an item id, a spoke index, or null for empty glass. */
|
|
7
|
+
resolve: (clientX: number, clientY: number, root: Element) => T | null;
|
|
8
|
+
/** Called as the finger glides, and with null when the gesture ends without a lift. */
|
|
9
|
+
onGlide: (value: T | null) => void;
|
|
10
|
+
/** A glide lifted over an item: pin it. */
|
|
11
|
+
onLift?: (value: T | null) => void;
|
|
12
|
+
/** A tap with no glide. Leave unset where the item's own click already handles taps. */
|
|
13
|
+
onTap?: (value: T | null) => void;
|
|
14
|
+
disabled?: boolean;
|
|
15
|
+
}
|
|
16
|
+
/** Finds the nearest `data-glide-id` under a point, for families whose marks are elements. */
|
|
17
|
+
export declare function glideTarget(clientX: number, clientY: number, root: Element): string | null;
|
|
18
|
+
/**
|
|
19
|
+
* Touch for charts whose marks are separate elements, or are found by position. A finger has no
|
|
20
|
+
* hover and a touch stays with the element it first landed on, so this follows the point under
|
|
21
|
+
* the finger instead. A sideways swipe glides at once (the plot pans only vertically); a press and
|
|
22
|
+
* hold glides in any direction without scrolling the page; lifting after a glide pins.
|
|
23
|
+
*
|
|
24
|
+
* Returns a callback ref for the plot, so a plot that mounts after loading is still wired.
|
|
25
|
+
*/
|
|
26
|
+
export declare function useTouchGlide<T>(options: TouchGlideOptions<T>): (node: Element | null) => void;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ChartComparisonResult, ChartPercentagePolicy, ChartController, ChartSeries, ChartYConfig, ChartTooltipContext, NumericXConfig, TimeXConfig, ChartRange } from '../types';
|
|
1
|
+
import { ChartComparisonResult, ChartPercentagePolicy, ChartController, ChartSeries, ChartYConfig, ChartTooltipContext, NumericXConfig, TimeXConfig, ChartRange, ChartPinOptions } from '../types';
|
|
2
2
|
import { LegendSnapshot } from '../runtime/chart-runtime';
|
|
3
3
|
export type CartesianModelLegendItem<Id extends string> = LegendSnapshot['series'][number] & {
|
|
4
4
|
id: Id;
|
|
@@ -63,7 +63,7 @@ export interface CartesianSummaryResult<Id extends string> {
|
|
|
63
63
|
export interface CartesianModelActions<SeriesId extends string> {
|
|
64
64
|
readonly inspect: (x: number) => void;
|
|
65
65
|
readonly clearInspection: () => void;
|
|
66
|
-
readonly pin: (x: number) => void;
|
|
66
|
+
readonly pin: (x: number, options?: ChartPinOptions) => void;
|
|
67
67
|
readonly release: () => void;
|
|
68
68
|
readonly setVisibleSeries: (ids: readonly SeriesId[]) => void;
|
|
69
69
|
readonly focusSeries: (id: SeriesId | null) => void;
|
|
@@ -94,7 +94,7 @@ export interface CartesianChartModel<Row, SeriesId extends string> {
|
|
|
94
94
|
type ModelActions = {
|
|
95
95
|
inspect: (x: number) => void;
|
|
96
96
|
clearInspection: () => void;
|
|
97
|
-
pin: (x: number) => void;
|
|
97
|
+
pin: (x: number, options?: ChartPinOptions) => void;
|
|
98
98
|
release: () => void;
|
|
99
99
|
setVisibleSeries: (ids: readonly string[]) => void;
|
|
100
100
|
focusSeries: (id: string | null) => void;
|
|
@@ -6,8 +6,12 @@ export interface GlideSpring {
|
|
|
6
6
|
}
|
|
7
7
|
/**
|
|
8
8
|
* A motion value that springs to each target it is given and always lands exactly on it.
|
|
9
|
-
* Every move is its own
|
|
10
|
-
*
|
|
11
|
-
*
|
|
9
|
+
* Every move is its own glide to a known destination, rather than a spring that follows another
|
|
10
|
+
* value, so an interrupted gesture or a paused frame can never leave it resting short of its
|
|
11
|
+
* target. A new target takes over from wherever the value is, keeping its speed.
|
|
12
|
+
*
|
|
13
|
+
* The spring advances by at most one frame's time per frame. When the page stalls, such as while
|
|
14
|
+
* linked charts re-render together, the glide carries on from where it was instead of jumping
|
|
15
|
+
* ahead to where the clock says it should be.
|
|
12
16
|
*/
|
|
13
17
|
export declare function useGlide(initial: number, spring: GlideSpring): readonly [MotionValue<number>, (to: number, instant?: boolean) => void];
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { ReactElement } from 'react';
|
|
2
|
+
import { MotionValue } from 'motion/react';
|
|
3
|
+
/** One stop of a segmented axis gradient, low values first. */
|
|
4
|
+
export interface AxisGradientStop {
|
|
5
|
+
color: string;
|
|
6
|
+
opacity?: number;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* A segmented axis: rounded segments between ticks instead of one continuous line, with a gap at
|
|
10
|
+
* each tick. With a gradient, one scale runs the length of the axis, low values first, so the
|
|
11
|
+
* axis reads as a range; the segment under the pointer lights up.
|
|
12
|
+
*/
|
|
13
|
+
export declare function AxisSegments({ stops, cross, vertical, gradient, cursor, active, opacity, }: {
|
|
14
|
+
/** Pixel positions that bound the segments, in any order. */
|
|
15
|
+
stops: readonly number[];
|
|
16
|
+
/** Where the segments sit across the axis: x for a vertical axis, y for a horizontal one. */
|
|
17
|
+
cross: number;
|
|
18
|
+
vertical: boolean;
|
|
19
|
+
gradient: readonly AxisGradientStop[] | null;
|
|
20
|
+
cursor: MotionValue<number>;
|
|
21
|
+
active: MotionValue<number>;
|
|
22
|
+
opacity?: number;
|
|
23
|
+
}): ReactElement | null;
|