@overdoser/react-toolkit 0.0.6 → 0.0.8
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/AGENTS.md +15 -0
- package/components/Button/Button.d.ts +13 -0
- package/components/Chart/AreaChart.d.ts +85 -0
- package/components/Chart/Axis.d.ts +30 -0
- package/components/Chart/BarChart.d.ts +111 -0
- package/components/Chart/ChartContainer.d.ts +33 -0
- package/components/Chart/ChartLegend.d.ts +9 -0
- package/components/Chart/ChartTooltip.d.ts +32 -0
- package/components/Chart/LineChart.d.ts +112 -0
- package/components/Chart/PieChart.d.ts +100 -0
- package/components/Chart/RadarChart.d.ts +86 -0
- package/components/Chart/Sparkline.d.ts +31 -0
- package/components/Chart/TradingChart.d.ts +89 -0
- package/components/Chart/index.d.ts +18 -0
- package/components/Chart/scales.d.ts +21 -0
- package/components/Chart/trading/indicators.d.ts +28 -0
- package/components/Chart/trading/period.d.ts +19 -0
- package/components/Chart/trading/types.d.ts +122 -0
- package/components/Chart/types.d.ts +60 -0
- package/components/Chart/useChartDimensions.d.ts +12 -0
- package/components/Popover/Popover.d.ts +16 -1
- package/index.css +1 -1
- package/index.d.ts +2 -0
- package/index.js +3427 -1110
- package/llms.txt +373 -2
- package/manifest.json +307 -3
- package/package.json +1 -1
- package/recipes/dashboard-charts.tsx +123 -0
- package/recipes/interactive-area-chart.tsx +226 -0
- package/recipes/interactive-bar-chart.tsx +211 -0
- package/recipes/interactive-line-chart.tsx +221 -0
- package/recipes/interactive-pie-chart.tsx +191 -0
- package/recipes/trading-chart.tsx +188 -0
- package/components/Button/Button.stories.d.ts +0 -17
- package/components/Dropdown/Dropdown.stories.d.ts +0 -8
- package/components/Form/Form.stories.d.ts +0 -11
- package/components/Link/Link.stories.d.ts +0 -9
- package/components/List/List.stories.d.ts +0 -9
- package/components/Modal/Modal.stories.d.ts +0 -9
- package/components/Popover/Popover.stories.d.ts +0 -9
- package/components/Table/Table.stories.d.ts +0 -20
- package/components/Typography/Typography.stories.d.ts +0 -15
- package/components/inputs/Checkbox/Checkbox.stories.d.ts +0 -9
- package/components/inputs/Input/Input.stories.d.ts +0 -13
- package/components/inputs/Radio/Radio.stories.d.ts +0 -7
- package/components/inputs/Select/Select.stories.d.ts +0 -18
- package/components/inputs/Textarea/Textarea.stories.d.ts +0 -10
- package/test-setup.d.ts +0 -0
package/AGENTS.md
CHANGED
|
@@ -54,6 +54,15 @@ For exhaustive component reference (every prop, every variant, every signature),
|
|
|
54
54
|
- All data in memory → don't pass `onSort`; pass `pagination` (without `totalRows`) for client-side paging.
|
|
55
55
|
- Data from a server → pass `sortConfig` + `onSort`, and `pagination` with `totalRows`.
|
|
56
56
|
|
|
57
|
+
- **Need a chart?**
|
|
58
|
+
- Time series / trend → `<LineChart>` or `<AreaChart>` (use Area when the magnitude matters more than the precise line).
|
|
59
|
+
- Categorical comparison → `<BarChart>`.
|
|
60
|
+
- Share-of-whole / proportion → `<PieChart>` (donut variant via `innerRadius`).
|
|
61
|
+
- Multi-dimensional comparison across a fixed set of axes → `<RadarChart>` (spider chart).
|
|
62
|
+
- OHLCV / financial markets → `<TradingChart>` (canvas-rendered; plug-in `Datafeed`, pan + zoom + indicators).
|
|
63
|
+
- Tiny inline trend (table cell, KPI tile) → `<Sparkline>`.
|
|
64
|
+
- Axis-based charts share a `config` object: `{ [dataKey]: { label, color } }`. `PieChart` uses `nameKey` + `valueKey` (+ optional `colorKey`) instead. Colors via `var(--crk-chart-1)` … `var(--crk-chart-5)`.
|
|
65
|
+
|
|
57
66
|
- **Multi-step / wizard form?** Use one `useForm()` per step OR a single `<Form>` wrapping all steps with conditional rendering. The toolkit doesn't ship a stepper.
|
|
58
67
|
|
|
59
68
|
## Common shapes (copy-paste)
|
|
@@ -97,6 +106,12 @@ Full copy-paste-able files live alongside this doc. Each is one self-contained f
|
|
|
97
106
|
- [recipes/confirm-modal.tsx](./recipes/confirm-modal.tsx) — Reusable destructive-action confirm dialog.
|
|
98
107
|
- [recipes/searchable-multi-select.tsx](./recipes/searchable-multi-select.tsx) — Multi-select with search and form integration.
|
|
99
108
|
- [recipes/dropdown-menu.tsx](./recipes/dropdown-menu.tsx) — Row action menu with `Dropdown` + `DropdownItem`.
|
|
109
|
+
- [recipes/dashboard-charts.tsx](./recipes/dashboard-charts.tsx) — Multi-chart dashboard layout with KPI tiles + Sparkline.
|
|
110
|
+
- [recipes/interactive-bar-chart.tsx](./recipes/interactive-bar-chart.tsx) — Series-toggle pattern for `BarChart` (one series visible at a time) with three selector UIs exported: `InteractiveBarChartTiles`, `InteractiveBarChartNavigator`, `InteractiveBarChartDropdown`.
|
|
111
|
+
- [recipes/interactive-line-chart.tsx](./recipes/interactive-line-chart.tsx) — Series-toggle pattern (one series visible at a time) with three selector UIs exported: `InteractiveLineChartTiles`, `InteractiveLineChartNavigator`, `InteractiveLineChartDropdown`.
|
|
112
|
+
- [recipes/interactive-area-chart.tsx](./recipes/interactive-area-chart.tsx) — Data-range filter (not series toggle): all series stay visible, the selector picks the time window. Three selector UIs exported: `InteractiveAreaChartTiles`, `InteractiveAreaChartNavigator`, `InteractiveAreaChartDropdown`.
|
|
113
|
+
- [recipes/interactive-pie-chart.tsx](./recipes/interactive-pie-chart.tsx) — Metric/period filter for `PieChart`: all slices stay visible, the selector picks which metric drives the pie. Three exports: `InteractivePieChartTiles`, `InteractivePieChartNavigator`, `InteractivePieChartDropdown`.
|
|
114
|
+
- [recipes/trading-chart.tsx](./recipes/trading-chart.tsx) — Full-stack `TradingChart` with a resolution selector, in-memory datafeed adapter, and the SMA/EMA/Bollinger/RSI/Volume indicator stack. Swap `createMemoryDatafeed` for your own REST/WebSocket adapter; everything else carries over.
|
|
100
115
|
|
|
101
116
|
## Anti-patterns to refuse
|
|
102
117
|
|
|
@@ -19,6 +19,19 @@ export interface ButtonProps extends ComponentPropsWithRef<'button'> {
|
|
|
19
19
|
loadingStyle?: 'dots' | 'shimmer' | 'border';
|
|
20
20
|
/** Stretch the button to fill its container's width. @default false */
|
|
21
21
|
fullWidth?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Square the button — for buttons whose only child is an icon (prev/next
|
|
24
|
+
* arrows, close, add, etc.). Width matches the same `size`'s normal-button
|
|
25
|
+
* height so icon and text buttons line up in a toolbar. SVG children are
|
|
26
|
+
* auto-sized to `1em`. Always pair with `aria-label`.
|
|
27
|
+
*
|
|
28
|
+
* Use inline SVG for icons rather than unicode glyphs (`‹` `›` `×` `+`) —
|
|
29
|
+
* SVG paths center geometrically; font glyphs depend on font metrics and
|
|
30
|
+
* may sit a hair above/below the visual centre.
|
|
31
|
+
*
|
|
32
|
+
* @default false
|
|
33
|
+
*/
|
|
34
|
+
iconOnly?: boolean;
|
|
22
35
|
}
|
|
23
36
|
/**
|
|
24
37
|
* Styled `<button>` with variants, sizes, and three loading-state animations.
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { CSSProperties, ReactNode } from 'react';
|
|
2
|
+
import { ChartClasses, ChartConfig, ChartMargin } from './types';
|
|
3
|
+
export interface AreaChartProps<T extends Record<string, unknown>> {
|
|
4
|
+
/** Row data. Each row must include `xKey` plus every key referenced in `config`. */
|
|
5
|
+
data: T[];
|
|
6
|
+
/** Data field providing the category labels on the X axis. */
|
|
7
|
+
xKey: keyof T & string;
|
|
8
|
+
/** Series configuration keyed by data-field name. */
|
|
9
|
+
config: ChartConfig;
|
|
10
|
+
/** Width-to-height ratio. @default 16 / 9 */
|
|
11
|
+
aspectRatio?: number;
|
|
12
|
+
/** Fixed pixel height. Overrides `aspectRatio`. */
|
|
13
|
+
height?: number;
|
|
14
|
+
/**
|
|
15
|
+
* Interpolation between points.
|
|
16
|
+
* - `'monotone'` (default): smooth Catmull-Rom-to-Bezier curve.
|
|
17
|
+
* - `'linear'`: straight segments.
|
|
18
|
+
* - `'step'`: step-after — value holds until the next x, then jumps.
|
|
19
|
+
* @default 'monotone'
|
|
20
|
+
*/
|
|
21
|
+
curve?: 'linear' | 'monotone' | 'step';
|
|
22
|
+
/**
|
|
23
|
+
* Stack series on top of each other instead of overlaying them. Each row's
|
|
24
|
+
* series stack in `config` insertion order, bottom to top.
|
|
25
|
+
* @default false
|
|
26
|
+
*/
|
|
27
|
+
stacked?: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* How stacked series are offset. Only applies when `stacked` is true.
|
|
30
|
+
* - `'none'`: stack at raw values.
|
|
31
|
+
* - `'expand'`: normalize each row to sum to 1 (percentage stack).
|
|
32
|
+
* @default 'none'
|
|
33
|
+
*/
|
|
34
|
+
stackOffset?: 'none' | 'expand';
|
|
35
|
+
/** Use a vertical linear gradient (opaque top → transparent bottom) for each series' fill. @default false */
|
|
36
|
+
fillGradient?: boolean;
|
|
37
|
+
/** Show horizontal grid lines. @default true */
|
|
38
|
+
showGrid?: boolean;
|
|
39
|
+
/** Show the X axis. @default true */
|
|
40
|
+
showXAxis?: boolean;
|
|
41
|
+
/** Show the Y axis. @default true */
|
|
42
|
+
showYAxis?: boolean;
|
|
43
|
+
/** Show the legend below the chart. @default true */
|
|
44
|
+
showLegend?: boolean;
|
|
45
|
+
/** Show the hover tooltip. @default true */
|
|
46
|
+
showTooltip?: boolean;
|
|
47
|
+
/** Approximate Y tick count. @default 5 */
|
|
48
|
+
yTickCount?: number;
|
|
49
|
+
/** Format Y axis tick labels. */
|
|
50
|
+
yFormat?: (v: number) => string;
|
|
51
|
+
/** Format X axis tick labels. */
|
|
52
|
+
xFormat?: (v: string) => string;
|
|
53
|
+
/** Format numeric values inside the default tooltip. */
|
|
54
|
+
valueFormat?: (v: number) => string;
|
|
55
|
+
/** Custom tooltip body. */
|
|
56
|
+
renderTooltip?: (row: T) => ReactNode;
|
|
57
|
+
/** Override the auto-computed plot margins. */
|
|
58
|
+
margin?: Partial<ChartMargin>;
|
|
59
|
+
/** Content rendered when `data` is empty. @default 'No data' */
|
|
60
|
+
emptyMessage?: ReactNode;
|
|
61
|
+
className?: string;
|
|
62
|
+
style?: CSSProperties;
|
|
63
|
+
/** Override class names on internal elements. */
|
|
64
|
+
classes?: Partial<ChartClasses>;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Themeable, responsive area chart. Covers the shadcn area-chart family via
|
|
68
|
+
* composable props:
|
|
69
|
+
* - **default / linear / step**: `curve`.
|
|
70
|
+
* - **legend / axes**: `showLegend`, `showXAxis`, `showYAxis` (all default true).
|
|
71
|
+
* - **stacked**: `stacked`.
|
|
72
|
+
* - **stacked-expand**: `stacked` + `stackOffset="expand"` (normalizes each row to 100%).
|
|
73
|
+
* - **gradient**: `fillGradient`.
|
|
74
|
+
* - **icons**: set `icon` on each entry in `config` (rendered in the legend in place of the swatch).
|
|
75
|
+
* - **interactive**: keep multiple series in `data`, pass only the active series to `config`. See `recipes/interactive-area-chart.tsx`.
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* <AreaChart
|
|
79
|
+
* data={data}
|
|
80
|
+
* xKey="month"
|
|
81
|
+
* config={{ visits: { label: 'Visits', color: 'var(--crk-chart-1)' } }}
|
|
82
|
+
* fillGradient
|
|
83
|
+
* />
|
|
84
|
+
*/
|
|
85
|
+
export declare function AreaChart<T extends Record<string, unknown>>({ data, xKey, config, aspectRatio, height, curve, stacked, stackOffset, fillGradient, showGrid, showXAxis, showYAxis, showLegend, showTooltip, yTickCount, yFormat, xFormat, valueFormat, renderTooltip, margin: marginOverride, emptyMessage, className, style, classes, }: AreaChartProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { ChartClasses } from './types';
|
|
2
|
+
export interface YAxisProps {
|
|
3
|
+
/** Pixel positions and tick values for the Y axis. */
|
|
4
|
+
ticks: {
|
|
5
|
+
value: number;
|
|
6
|
+
y: number;
|
|
7
|
+
}[];
|
|
8
|
+
/** X coordinate of the axis line. */
|
|
9
|
+
x: number;
|
|
10
|
+
/** Plot width — used to draw horizontal grid lines. */
|
|
11
|
+
plotWidth: number;
|
|
12
|
+
format?: (v: number) => string;
|
|
13
|
+
showGrid?: boolean;
|
|
14
|
+
classes?: Partial<ChartClasses>;
|
|
15
|
+
}
|
|
16
|
+
/** Y axis with optional horizontal grid lines. */
|
|
17
|
+
export declare function YAxis({ ticks, x, plotWidth, format, showGrid, classes }: YAxisProps): import("react/jsx-runtime").JSX.Element;
|
|
18
|
+
export interface XAxisProps {
|
|
19
|
+
/** Pixel positions and labels for the X axis. */
|
|
20
|
+
ticks: {
|
|
21
|
+
label: string;
|
|
22
|
+
x: number;
|
|
23
|
+
}[];
|
|
24
|
+
/** Y coordinate of the axis line. */
|
|
25
|
+
y: number;
|
|
26
|
+
format?: (label: string) => string;
|
|
27
|
+
classes?: Partial<ChartClasses>;
|
|
28
|
+
}
|
|
29
|
+
/** X axis labels along the bottom of the plot. */
|
|
30
|
+
export declare function XAxis({ ticks, y, format, classes }: XAxisProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { CSSProperties, ReactNode } from 'react';
|
|
2
|
+
import { ChartClasses, ChartConfig, ChartMargin } from './types';
|
|
3
|
+
export interface BarLabelArgs<T> {
|
|
4
|
+
row: T;
|
|
5
|
+
value: number;
|
|
6
|
+
seriesKey: string;
|
|
7
|
+
index: number;
|
|
8
|
+
}
|
|
9
|
+
export interface BarClickArgs<T> {
|
|
10
|
+
row: T;
|
|
11
|
+
value: number;
|
|
12
|
+
seriesKey: string;
|
|
13
|
+
index: number;
|
|
14
|
+
}
|
|
15
|
+
export interface BarChartProps<T extends Record<string, unknown>> {
|
|
16
|
+
/** Row data. Each row must include `xKey` plus every key referenced in `config`. */
|
|
17
|
+
data: T[];
|
|
18
|
+
/** Data field providing the category labels. */
|
|
19
|
+
xKey: keyof T & string;
|
|
20
|
+
/** Series configuration keyed by data-field name. */
|
|
21
|
+
config: ChartConfig;
|
|
22
|
+
/** Bar layout direction. `'horizontal'` swaps the axes so bars extend left→right. @default 'vertical' */
|
|
23
|
+
orientation?: 'vertical' | 'horizontal';
|
|
24
|
+
/** Stack series within each category instead of placing them side-by-side. Ignored with a single series. @default false */
|
|
25
|
+
stacked?: boolean;
|
|
26
|
+
/** Width-to-height ratio. @default 16 / 9 */
|
|
27
|
+
aspectRatio?: number;
|
|
28
|
+
/** Fixed pixel height. Overrides `aspectRatio`. */
|
|
29
|
+
height?: number;
|
|
30
|
+
/** Inner padding between category groups, fraction of band width. @default 0.2 */
|
|
31
|
+
groupPadding?: number;
|
|
32
|
+
/** Inner padding between bars within a grouped group, fraction of bar width. Ignored when stacked. @default 0.1 */
|
|
33
|
+
barPadding?: number;
|
|
34
|
+
/** Corner radius applied to the value-end of each bar. @default 4 */
|
|
35
|
+
barRadius?: number;
|
|
36
|
+
/** Show grid lines along the value axis. @default true */
|
|
37
|
+
showGrid?: boolean;
|
|
38
|
+
/** Show the legend. @default true */
|
|
39
|
+
showLegend?: boolean;
|
|
40
|
+
/** Show the hover tooltip. @default true */
|
|
41
|
+
showTooltip?: boolean;
|
|
42
|
+
/** Render numeric labels on bars. @default false */
|
|
43
|
+
showValues?: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Where to render value labels relative to each bar.
|
|
46
|
+
* - `'outside'`: beyond the value end.
|
|
47
|
+
* - `'inside'`: inside the bar at the value end, no rotation.
|
|
48
|
+
* - `'inside-start'`: inside the bar at the start (baseline). On vertical bars,
|
|
49
|
+
* the text is rotated ±90° so it reads along the bar's length.
|
|
50
|
+
* @default 'outside'
|
|
51
|
+
*/
|
|
52
|
+
valuePosition?: 'outside' | 'inside' | 'inside-start';
|
|
53
|
+
/** Custom label content. Return `null` to skip a bar. Overrides `valueFormat` for labels. */
|
|
54
|
+
renderLabel?: (args: BarLabelArgs<T>) => ReactNode;
|
|
55
|
+
/**
|
|
56
|
+
* Bar coloring strategy.
|
|
57
|
+
* - `'series'` (default): uses `config[seriesKey].color`.
|
|
58
|
+
* - `'index'`: uses `colors[rowIndex % colors.length]`, ignoring series-config colors.
|
|
59
|
+
* Useful for single-series "one color per category" charts.
|
|
60
|
+
* @default 'series'
|
|
61
|
+
*/
|
|
62
|
+
colorBy?: 'series' | 'index';
|
|
63
|
+
/** Palette used when `colorBy='index'`. @default the 5 `--crk-chart-N` tokens */
|
|
64
|
+
colors?: string[];
|
|
65
|
+
/** Override color applied to bar segments whose value is negative. */
|
|
66
|
+
negativeColor?: string;
|
|
67
|
+
/** Highlight one category index; other groups fade. Pair with `onBarClick` for click-to-select UIs. */
|
|
68
|
+
activeIndex?: number;
|
|
69
|
+
/** Called when a bar is clicked. */
|
|
70
|
+
onBarClick?: (args: BarClickArgs<T>) => void;
|
|
71
|
+
/** Approximate value-axis tick count. @default 5 */
|
|
72
|
+
yTickCount?: number;
|
|
73
|
+
/** Format value-axis tick labels. */
|
|
74
|
+
yFormat?: (v: number) => string;
|
|
75
|
+
/** Format category-axis tick labels. */
|
|
76
|
+
xFormat?: (v: string) => string;
|
|
77
|
+
/** Format numeric values inside the default tooltip and inside labels (when `renderLabel` is not set). */
|
|
78
|
+
valueFormat?: (v: number) => string;
|
|
79
|
+
/** Custom tooltip body. */
|
|
80
|
+
renderTooltip?: (row: T) => ReactNode;
|
|
81
|
+
/** Override the auto-computed plot margins. */
|
|
82
|
+
margin?: Partial<ChartMargin>;
|
|
83
|
+
/** Content rendered when `data` is empty. @default 'No data' */
|
|
84
|
+
emptyMessage?: ReactNode;
|
|
85
|
+
className?: string;
|
|
86
|
+
style?: CSSProperties;
|
|
87
|
+
/** Override class names on internal elements. */
|
|
88
|
+
classes?: Partial<ChartClasses>;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Themeable, responsive bar chart that handles the full set of shadcn-style
|
|
92
|
+
* variants through composable props:
|
|
93
|
+
* - **default / multiple**: grouped vertical bars (no special props).
|
|
94
|
+
* - **horizontal**: `orientation="horizontal"`.
|
|
95
|
+
* - **stacked**: `stacked`.
|
|
96
|
+
* - **label / label-custom**: `showValues`, `valuePosition`, `renderLabel`.
|
|
97
|
+
* - **mixed**: `colorBy="index"` (+ optional `colors`).
|
|
98
|
+
* - **negative**: works out of the box; pair with `negativeColor` to recolor below zero.
|
|
99
|
+
* - **active / interactive**: `activeIndex` + `onBarClick`.
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
* <BarChart
|
|
103
|
+
* data={data}
|
|
104
|
+
* xKey="month"
|
|
105
|
+
* config={{
|
|
106
|
+
* revenue: { label: 'Revenue', color: 'var(--crk-chart-1)' },
|
|
107
|
+
* costs: { label: 'Costs', color: 'var(--crk-chart-2)' },
|
|
108
|
+
* }}
|
|
109
|
+
* />
|
|
110
|
+
*/
|
|
111
|
+
export declare function BarChart<T extends Record<string, unknown>>({ data, xKey, config, orientation, stacked, aspectRatio, height, groupPadding, barPadding, barRadius, showGrid, showLegend, showTooltip, showValues, valuePosition, renderLabel, colorBy, colors, negativeColor, activeIndex, onBarClick, yTickCount, yFormat, xFormat, valueFormat, renderTooltip, margin: marginOverride, emptyMessage, className, style, classes, }: BarChartProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { CSSProperties, ReactNode } from 'react';
|
|
2
|
+
import { ChartClasses } from './types';
|
|
3
|
+
export interface ChartContainerProps {
|
|
4
|
+
/**
|
|
5
|
+
* Width-to-height ratio. The container fills its parent width, then sets
|
|
6
|
+
* height = width / aspectRatio. Ignored when `height` is set.
|
|
7
|
+
* @default 16 / 9
|
|
8
|
+
*/
|
|
9
|
+
aspectRatio?: number;
|
|
10
|
+
/** Fixed pixel height. Overrides `aspectRatio`. */
|
|
11
|
+
height?: number;
|
|
12
|
+
className?: string;
|
|
13
|
+
style?: CSSProperties;
|
|
14
|
+
classes?: Partial<ChartClasses>;
|
|
15
|
+
/** Optional legend rendered below the SVG. */
|
|
16
|
+
legend?: ReactNode;
|
|
17
|
+
/** Optional HTML overlay (e.g., tooltip) absolutely positioned over the SVG. */
|
|
18
|
+
overlay?: ReactNode;
|
|
19
|
+
/** Renders the SVG body given the observed plot size. */
|
|
20
|
+
children: (size: {
|
|
21
|
+
width: number;
|
|
22
|
+
height: number;
|
|
23
|
+
}) => ReactNode;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Responsive wrapper used by every chart in the toolkit.
|
|
27
|
+
*
|
|
28
|
+
* Tracks its rendered width via `ResizeObserver`, computes height from
|
|
29
|
+
* `aspectRatio` or uses an explicit `height`, and exposes the resulting size
|
|
30
|
+
* to its render-function child. Renders a `<svg>` at that size and provides
|
|
31
|
+
* an absolutely-positioned overlay slot for tooltips.
|
|
32
|
+
*/
|
|
33
|
+
export declare const ChartContainer: import('react').ForwardRefExoticComponent<ChartContainerProps & import('react').RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ChartClasses, ChartConfig } from './types';
|
|
2
|
+
export interface ChartLegendProps {
|
|
3
|
+
config: ChartConfig;
|
|
4
|
+
/** Optional ordering — defaults to the order of `Object.keys(config)`. */
|
|
5
|
+
order?: string[];
|
|
6
|
+
classes?: Partial<ChartClasses>;
|
|
7
|
+
}
|
|
8
|
+
/** Renders a horizontal swatch + label for each entry in `config`. */
|
|
9
|
+
export declare function ChartLegend({ config, order, classes }: ChartLegendProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { ChartClasses, ChartConfig } from './types';
|
|
3
|
+
export interface ChartTooltipProps<T> {
|
|
4
|
+
/** Row at the active index. */
|
|
5
|
+
row: T | null;
|
|
6
|
+
/** Container-relative pixel position. */
|
|
7
|
+
x: number;
|
|
8
|
+
y: number;
|
|
9
|
+
/** Width of the parent SVG, used to flip the tooltip when near the right edge. */
|
|
10
|
+
containerWidth: number;
|
|
11
|
+
/** Chart config — drives series rendering inside the default tooltip. */
|
|
12
|
+
config: ChartConfig;
|
|
13
|
+
/** Render-prop override for the body content. */
|
|
14
|
+
render?: (row: T) => ReactNode;
|
|
15
|
+
/** Format numeric values in the default body. @default `String` */
|
|
16
|
+
valueFormat?: (v: number) => string;
|
|
17
|
+
/** Format the title (defaults to a `xKey` lookup). */
|
|
18
|
+
titleKey?: string;
|
|
19
|
+
/**
|
|
20
|
+
* Resolve the bullet color for a given series in the active row.
|
|
21
|
+
* Return `undefined` to fall back to `config[seriesKey].color`.
|
|
22
|
+
* Lets charts that vary bar/segment color per row (negative-value
|
|
23
|
+
* overrides, `colorBy='index'`, etc.) keep the tooltip swatch in sync.
|
|
24
|
+
*/
|
|
25
|
+
resolveColor?: (seriesKey: string) => string | undefined;
|
|
26
|
+
classes?: Partial<ChartClasses>;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Floating HTML tooltip rendered as an overlay over the chart SVG.
|
|
30
|
+
* Positions itself near `(x, y)` and flips horizontally when close to the right edge.
|
|
31
|
+
*/
|
|
32
|
+
export declare function ChartTooltip<T extends Record<string, unknown>>({ row, x, y, containerWidth, config, render, valueFormat, titleKey, resolveColor, classes, }: ChartTooltipProps<T>): import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { CSSProperties, ReactNode } from 'react';
|
|
2
|
+
import { ChartClasses, ChartConfig, ChartMargin } from './types';
|
|
3
|
+
export interface LineLabelArgs<T> {
|
|
4
|
+
row: T;
|
|
5
|
+
value: number;
|
|
6
|
+
seriesKey: string;
|
|
7
|
+
index: number;
|
|
8
|
+
}
|
|
9
|
+
export interface LineDotArgs<T> {
|
|
10
|
+
row: T;
|
|
11
|
+
value: number;
|
|
12
|
+
seriesKey: string;
|
|
13
|
+
index: number;
|
|
14
|
+
/** SVG-space coordinate of the point. */
|
|
15
|
+
x: number;
|
|
16
|
+
y: number;
|
|
17
|
+
/** Color the default dot would have used (resolved through `dotColorKey` if set). */
|
|
18
|
+
color: string;
|
|
19
|
+
/** Whether this point is the currently-active (hovered or controlled) point. */
|
|
20
|
+
active: boolean;
|
|
21
|
+
}
|
|
22
|
+
export interface LinePointClickArgs<T> {
|
|
23
|
+
row: T;
|
|
24
|
+
value: number;
|
|
25
|
+
seriesKey: string;
|
|
26
|
+
index: number;
|
|
27
|
+
}
|
|
28
|
+
export interface LineChartProps<T extends Record<string, unknown>> {
|
|
29
|
+
/** Row data. Each row must include `xKey` plus every key referenced in `config`. */
|
|
30
|
+
data: T[];
|
|
31
|
+
/** Data field providing the category labels on the X axis. */
|
|
32
|
+
xKey: keyof T & string;
|
|
33
|
+
/** Series configuration keyed by data-field name. */
|
|
34
|
+
config: ChartConfig;
|
|
35
|
+
/** Width-to-height ratio. @default 16 / 9 */
|
|
36
|
+
aspectRatio?: number;
|
|
37
|
+
/** Fixed pixel height. Overrides `aspectRatio`. */
|
|
38
|
+
height?: number;
|
|
39
|
+
/**
|
|
40
|
+
* Interpolation between points.
|
|
41
|
+
* - `'monotone'` (default): smooth Catmull-Rom-to-Bezier curve.
|
|
42
|
+
* - `'linear'`: straight segments.
|
|
43
|
+
* - `'step'`: stepped line (value holds horizontally until the next x).
|
|
44
|
+
* @default 'monotone'
|
|
45
|
+
*/
|
|
46
|
+
curve?: 'linear' | 'monotone' | 'step';
|
|
47
|
+
/** Draw a dot at every data point. @default true */
|
|
48
|
+
showPoints?: boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Data field whose value provides the dot color (per row). When set, each
|
|
51
|
+
* dot's fill comes from `row[dotColorKey]` instead of the series color.
|
|
52
|
+
* The line itself keeps the series color.
|
|
53
|
+
*/
|
|
54
|
+
dotColorKey?: keyof T & string;
|
|
55
|
+
/** Custom dot renderer. Replaces the default `<circle>` per point. */
|
|
56
|
+
renderDot?: (args: LineDotArgs<T>) => ReactNode;
|
|
57
|
+
/** Render numeric labels next to each point. @default false */
|
|
58
|
+
showValues?: boolean;
|
|
59
|
+
/** Where to place the value labels. @default 'top' */
|
|
60
|
+
valuePosition?: 'top' | 'bottom';
|
|
61
|
+
/** Custom label content. Overrides `valueFormat` for labels. Return `null` to skip. */
|
|
62
|
+
renderLabel?: (args: LineLabelArgs<T>) => ReactNode;
|
|
63
|
+
/** Highlight a specific point index; non-active points fade. Pair with `onPointClick` for click-to-select UIs. */
|
|
64
|
+
activeIndex?: number;
|
|
65
|
+
/** Called when a point (or the area around it) is clicked. */
|
|
66
|
+
onPointClick?: (args: LinePointClickArgs<T>) => void;
|
|
67
|
+
/** Show horizontal grid lines. @default true */
|
|
68
|
+
showGrid?: boolean;
|
|
69
|
+
/** Show the legend below the chart. @default true */
|
|
70
|
+
showLegend?: boolean;
|
|
71
|
+
/** Show the hover tooltip. @default true */
|
|
72
|
+
showTooltip?: boolean;
|
|
73
|
+
/** Approximate Y tick count. @default 5 */
|
|
74
|
+
yTickCount?: number;
|
|
75
|
+
/** Format Y axis tick labels. */
|
|
76
|
+
yFormat?: (v: number) => string;
|
|
77
|
+
/** Format X axis tick labels. */
|
|
78
|
+
xFormat?: (v: string) => string;
|
|
79
|
+
/** Format numeric values inside the default tooltip and inside value labels (when `renderLabel` is not set). */
|
|
80
|
+
valueFormat?: (v: number) => string;
|
|
81
|
+
/** Custom tooltip body. */
|
|
82
|
+
renderTooltip?: (row: T) => ReactNode;
|
|
83
|
+
/** Override the auto-computed plot margins. */
|
|
84
|
+
margin?: Partial<ChartMargin>;
|
|
85
|
+
/** Content rendered when `data` is empty. @default 'No data' */
|
|
86
|
+
emptyMessage?: ReactNode;
|
|
87
|
+
className?: string;
|
|
88
|
+
style?: CSSProperties;
|
|
89
|
+
/** Override class names on internal elements. */
|
|
90
|
+
classes?: Partial<ChartClasses>;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Themeable, responsive line chart. One component covers the full shadcn
|
|
94
|
+
* line-chart family via composable props:
|
|
95
|
+
* - **default / multiple / linear / step**: `curve` + multiple keys in `config`.
|
|
96
|
+
* - **dots**: `showPoints` (on by default).
|
|
97
|
+
* - **dots-custom**: `renderDot`.
|
|
98
|
+
* - **dots-colors**: `dotColorKey` (each row's `[dotColorKey]` field is the dot's fill).
|
|
99
|
+
* - **label / label-custom**: `showValues` + `valuePosition`, or `renderLabel`.
|
|
100
|
+
* - **interactive**: `activeIndex` + `onPointClick`.
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* <LineChart
|
|
104
|
+
* data={[{ month: 'Jan', revenue: 100, costs: 50 }]}
|
|
105
|
+
* xKey="month"
|
|
106
|
+
* config={{
|
|
107
|
+
* revenue: { label: 'Revenue', color: 'var(--crk-chart-1)' },
|
|
108
|
+
* costs: { label: 'Costs', color: 'var(--crk-chart-2)' },
|
|
109
|
+
* }}
|
|
110
|
+
* />
|
|
111
|
+
*/
|
|
112
|
+
export declare function LineChart<T extends Record<string, unknown>>({ data, xKey, config, aspectRatio, height, curve, showPoints, dotColorKey, renderDot, showValues, valuePosition, renderLabel, activeIndex, onPointClick, showGrid, showLegend, showTooltip, yTickCount, yFormat, xFormat, valueFormat, renderTooltip, margin: marginOverride, emptyMessage, className, style, classes, }: LineChartProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { CSSProperties, ReactNode } from 'react';
|
|
2
|
+
import { ChartClasses } from './types';
|
|
3
|
+
export interface PieLabelArgs<T> {
|
|
4
|
+
row: T;
|
|
5
|
+
value: number;
|
|
6
|
+
/** Slice share of the total (0–1). */
|
|
7
|
+
fraction: number;
|
|
8
|
+
index: number;
|
|
9
|
+
}
|
|
10
|
+
export interface PieSliceClickArgs<T> {
|
|
11
|
+
row: T;
|
|
12
|
+
value: number;
|
|
13
|
+
index: number;
|
|
14
|
+
}
|
|
15
|
+
export interface PieChartProps<T extends Record<string, unknown>> {
|
|
16
|
+
/** Row data — one slice per row. */
|
|
17
|
+
data: T[];
|
|
18
|
+
/** Row field providing the numeric slice value. */
|
|
19
|
+
valueKey: keyof T & string;
|
|
20
|
+
/** Row field providing the slice label (used in legend, tooltip, labels). */
|
|
21
|
+
nameKey: keyof T & string;
|
|
22
|
+
/** Optional row field whose value is used as the slice fill (CSS color string). Falls back to `colors`. */
|
|
23
|
+
colorKey?: keyof T & string;
|
|
24
|
+
/** Color palette indexed by row order. @default the five `--crk-chart-N` tokens */
|
|
25
|
+
colors?: string[];
|
|
26
|
+
/** Width-to-height ratio. @default 1 (square) */
|
|
27
|
+
aspectRatio?: number;
|
|
28
|
+
/** Fixed pixel height. Overrides `aspectRatio`. */
|
|
29
|
+
height?: number;
|
|
30
|
+
/**
|
|
31
|
+
* Inner radius — `0` for a pie, `>0` for a donut. Accepts a number (pixels)
|
|
32
|
+
* or a percentage string (`'50%'`). @default 0
|
|
33
|
+
*/
|
|
34
|
+
innerRadius?: number | string;
|
|
35
|
+
/**
|
|
36
|
+
* Outer radius. Accepts a number (pixels) or a percentage string.
|
|
37
|
+
* @default '90%'
|
|
38
|
+
*/
|
|
39
|
+
outerRadius?: number | string;
|
|
40
|
+
/** Slice separator stroke width. Set to `0` for the "separator-none" look. @default 2 */
|
|
41
|
+
strokeWidth?: number;
|
|
42
|
+
/** Stroke color (between slices). @default 'var(--crk-color-bg)' */
|
|
43
|
+
strokeColor?: string;
|
|
44
|
+
/** Gap between slices, in degrees (purely visual). @default 0 */
|
|
45
|
+
padAngle?: number;
|
|
46
|
+
/** Render slice labels (the row's nameKey by default; override with `renderLabel`). @default false */
|
|
47
|
+
showLabels?: boolean;
|
|
48
|
+
/** Label position relative to its slice. @default 'outside' */
|
|
49
|
+
valuePosition?: 'outside' | 'inside';
|
|
50
|
+
/**
|
|
51
|
+
* Draw a thin leader line from each slice edge to its outside label. Has
|
|
52
|
+
* no effect when `valuePosition` is `'inside'`. @default true
|
|
53
|
+
*/
|
|
54
|
+
showLabelLines?: boolean;
|
|
55
|
+
/** Custom label content. Return `null` to skip a slice. */
|
|
56
|
+
renderLabel?: (args: PieLabelArgs<T>) => ReactNode;
|
|
57
|
+
/** Content rendered in the centre of the chart — typical pattern for donut summaries. */
|
|
58
|
+
centerLabel?: ReactNode;
|
|
59
|
+
/** Highlight one slice (pulls it outward); other slices fade. */
|
|
60
|
+
activeIndex?: number;
|
|
61
|
+
/** Fires when a slice is clicked. */
|
|
62
|
+
onSliceClick?: (args: PieSliceClickArgs<T>) => void;
|
|
63
|
+
/** Show the legend below the chart. @default true */
|
|
64
|
+
showLegend?: boolean;
|
|
65
|
+
/** Show the hover tooltip. @default true */
|
|
66
|
+
showTooltip?: boolean;
|
|
67
|
+
/** Format the numeric value inside the tooltip and labels. */
|
|
68
|
+
valueFormat?: (v: number) => string;
|
|
69
|
+
/** Custom tooltip body. */
|
|
70
|
+
renderTooltip?: (row: T) => ReactNode;
|
|
71
|
+
/** Content rendered when `data` is empty. @default 'No data' */
|
|
72
|
+
emptyMessage?: ReactNode;
|
|
73
|
+
className?: string;
|
|
74
|
+
style?: CSSProperties;
|
|
75
|
+
/** Override class names on internal elements. */
|
|
76
|
+
classes?: Partial<ChartClasses>;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Responsive pie / donut chart. Covers the shadcn pie-chart family:
|
|
80
|
+
* - **simple / donut**: `innerRadius` (0 → pie, > 0 → donut).
|
|
81
|
+
* - **legend**: `showLegend` (on by default).
|
|
82
|
+
* - **separator-none**: `strokeWidth={0}`.
|
|
83
|
+
* - **label / label-custom**: `showLabels` + `valuePosition`, or `renderLabel`.
|
|
84
|
+
* - **donut-text**: `centerLabel` (any ReactNode rendered at the centre).
|
|
85
|
+
* - **donut-active**: `activeIndex={n}` (pulls the slice outward, fades others).
|
|
86
|
+
* - **interactive**: data-filter pattern — see `recipes/interactive-pie-chart.tsx`.
|
|
87
|
+
*
|
|
88
|
+
* Stacked / nested-rings (shadcn's "stacked" variant) is not currently
|
|
89
|
+
* supported by this component.
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* <PieChart
|
|
93
|
+
* data={[{ browser: 'Chrome', visitors: 275 }, { browser: 'Safari', visitors: 200 }]}
|
|
94
|
+
* nameKey="browser"
|
|
95
|
+
* valueKey="visitors"
|
|
96
|
+
* innerRadius="60%"
|
|
97
|
+
* centerLabel={<strong>475</strong>}
|
|
98
|
+
* />
|
|
99
|
+
*/
|
|
100
|
+
export declare function PieChart<T extends Record<string, unknown>>({ data, valueKey, nameKey, colorKey, colors, aspectRatio, height, innerRadius, outerRadius, strokeWidth, strokeColor, padAngle, showLabels, valuePosition, showLabelLines, renderLabel, centerLabel, activeIndex, onSliceClick, showLegend, showTooltip, valueFormat, renderTooltip, emptyMessage, className, style, classes, }: PieChartProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { CSSProperties, ReactNode } from 'react';
|
|
2
|
+
import { ChartClasses, ChartConfig } from './types';
|
|
3
|
+
export interface RadarAxisLabelArgs<T> {
|
|
4
|
+
row: T;
|
|
5
|
+
/** Row index = vertex index. */
|
|
6
|
+
index: number;
|
|
7
|
+
/** Vertex angle in degrees (0 = top, clockwise). */
|
|
8
|
+
angle: number;
|
|
9
|
+
/** Pixel coordinates of the outer-ring vertex. */
|
|
10
|
+
x: number;
|
|
11
|
+
y: number;
|
|
12
|
+
/** Suggested SVG `text-anchor` based on which side of the chart this vertex sits on. */
|
|
13
|
+
textAnchor: 'start' | 'middle' | 'end';
|
|
14
|
+
}
|
|
15
|
+
export interface RadarChartProps<T extends Record<string, unknown>> {
|
|
16
|
+
/** Row data — one vertex per row. */
|
|
17
|
+
data: T[];
|
|
18
|
+
/** Row field providing the axis (vertex) label. */
|
|
19
|
+
axisKey: keyof T & string;
|
|
20
|
+
/** Series configuration keyed by data-field name. */
|
|
21
|
+
config: ChartConfig;
|
|
22
|
+
/** Width-to-height ratio. @default 1 (square) */
|
|
23
|
+
aspectRatio?: number;
|
|
24
|
+
/** Fixed pixel height. Overrides `aspectRatio`. */
|
|
25
|
+
height?: number;
|
|
26
|
+
/** Grid ring shape. @default 'polygon' */
|
|
27
|
+
gridType?: 'polygon' | 'circle';
|
|
28
|
+
/** Show concentric grid rings. @default true */
|
|
29
|
+
showGrid?: boolean;
|
|
30
|
+
/** Show radial spokes from center to each axis vertex. @default true */
|
|
31
|
+
showRadialLines?: boolean;
|
|
32
|
+
/** Show the categorical axis labels at each vertex. @default true */
|
|
33
|
+
showAxisLabels?: boolean;
|
|
34
|
+
/** Show the radius (value) axis labels along the top spoke. @default false */
|
|
35
|
+
showRadiusAxis?: boolean;
|
|
36
|
+
/** Approximate number of concentric grid rings / radius ticks. @default 5 */
|
|
37
|
+
levels?: number;
|
|
38
|
+
/** Draw a dot at every series vertex. @default true */
|
|
39
|
+
showPoints?: boolean;
|
|
40
|
+
/** Fill opacity for each series polygon. Pass `0` for the "lines-only" look. @default 0.4 */
|
|
41
|
+
fillOpacity?: number;
|
|
42
|
+
/** Stroke width for each series polygon outline. @default 2 */
|
|
43
|
+
strokeWidth?: number;
|
|
44
|
+
/** Custom axis-label renderer. Return `null` to skip a vertex. */
|
|
45
|
+
renderAxisLabel?: (args: RadarAxisLabelArgs<T>) => ReactNode;
|
|
46
|
+
/** Format the axis label text in the default renderer. */
|
|
47
|
+
axisFormat?: (label: string) => string;
|
|
48
|
+
/** Format numeric values inside the default tooltip and the radius axis labels. */
|
|
49
|
+
valueFormat?: (v: number) => string;
|
|
50
|
+
/** Custom tooltip body. */
|
|
51
|
+
renderTooltip?: (row: T) => ReactNode;
|
|
52
|
+
/** Show the legend below the chart. @default true */
|
|
53
|
+
showLegend?: boolean;
|
|
54
|
+
/** Show the hover tooltip. @default true */
|
|
55
|
+
showTooltip?: boolean;
|
|
56
|
+
/** Content rendered when `data` is empty. @default 'No data' */
|
|
57
|
+
emptyMessage?: ReactNode;
|
|
58
|
+
className?: string;
|
|
59
|
+
style?: CSSProperties;
|
|
60
|
+
/** Override class names on internal elements. */
|
|
61
|
+
classes?: Partial<ChartClasses>;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Themeable, responsive radar (spider) chart. Covers the full shadcn
|
|
65
|
+
* radar-chart family via composable props:
|
|
66
|
+
* - **default / multiple / legend**: base (multiple keys in `config`).
|
|
67
|
+
* - **dots**: `showPoints` (on by default).
|
|
68
|
+
* - **lines-only**: `fillOpacity={0}`.
|
|
69
|
+
* - **grid-circle / grid-circle-fill / grid-circle-no-lines**: `gridType="circle"` (+ `showRadialLines={false}` for the third).
|
|
70
|
+
* - **grid-fill / grid-custom**: defaults; theme via `classes` and the chart tokens.
|
|
71
|
+
* - **grid-none**: `showGrid={false}`.
|
|
72
|
+
* - **icons**: set `icon` on each entry in `config` (rendered in the legend).
|
|
73
|
+
* - **label-custom**: `renderAxisLabel`.
|
|
74
|
+
* - **radius**: `showRadiusAxis`.
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* <RadarChart
|
|
78
|
+
* data={[{ month: 'Jan', desktop: 186, mobile: 80 }]}
|
|
79
|
+
* axisKey="month"
|
|
80
|
+
* config={{
|
|
81
|
+
* desktop: { label: 'Desktop', color: 'var(--crk-chart-1)' },
|
|
82
|
+
* mobile: { label: 'Mobile', color: 'var(--crk-chart-2)' },
|
|
83
|
+
* }}
|
|
84
|
+
* />
|
|
85
|
+
*/
|
|
86
|
+
export declare function RadarChart<T extends Record<string, unknown>>({ data, axisKey, config, aspectRatio, height, gridType, showGrid, showRadialLines, showAxisLabels, showRadiusAxis, levels, showPoints, fillOpacity, strokeWidth, renderAxisLabel, axisFormat, valueFormat, renderTooltip, showLegend, showTooltip, emptyMessage, className, style, classes, }: RadarChartProps<T>): import("react/jsx-runtime").JSX.Element;
|