@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.
Files changed (48) hide show
  1. package/AGENTS.md +15 -0
  2. package/components/Button/Button.d.ts +13 -0
  3. package/components/Chart/AreaChart.d.ts +85 -0
  4. package/components/Chart/Axis.d.ts +30 -0
  5. package/components/Chart/BarChart.d.ts +111 -0
  6. package/components/Chart/ChartContainer.d.ts +33 -0
  7. package/components/Chart/ChartLegend.d.ts +9 -0
  8. package/components/Chart/ChartTooltip.d.ts +32 -0
  9. package/components/Chart/LineChart.d.ts +112 -0
  10. package/components/Chart/PieChart.d.ts +100 -0
  11. package/components/Chart/RadarChart.d.ts +86 -0
  12. package/components/Chart/Sparkline.d.ts +31 -0
  13. package/components/Chart/TradingChart.d.ts +89 -0
  14. package/components/Chart/index.d.ts +18 -0
  15. package/components/Chart/scales.d.ts +21 -0
  16. package/components/Chart/trading/indicators.d.ts +28 -0
  17. package/components/Chart/trading/period.d.ts +19 -0
  18. package/components/Chart/trading/types.d.ts +122 -0
  19. package/components/Chart/types.d.ts +60 -0
  20. package/components/Chart/useChartDimensions.d.ts +12 -0
  21. package/components/Popover/Popover.d.ts +16 -1
  22. package/index.css +1 -1
  23. package/index.d.ts +2 -0
  24. package/index.js +3427 -1110
  25. package/llms.txt +373 -2
  26. package/manifest.json +307 -3
  27. package/package.json +1 -1
  28. package/recipes/dashboard-charts.tsx +123 -0
  29. package/recipes/interactive-area-chart.tsx +226 -0
  30. package/recipes/interactive-bar-chart.tsx +211 -0
  31. package/recipes/interactive-line-chart.tsx +221 -0
  32. package/recipes/interactive-pie-chart.tsx +191 -0
  33. package/recipes/trading-chart.tsx +188 -0
  34. package/components/Button/Button.stories.d.ts +0 -17
  35. package/components/Dropdown/Dropdown.stories.d.ts +0 -8
  36. package/components/Form/Form.stories.d.ts +0 -11
  37. package/components/Link/Link.stories.d.ts +0 -9
  38. package/components/List/List.stories.d.ts +0 -9
  39. package/components/Modal/Modal.stories.d.ts +0 -9
  40. package/components/Popover/Popover.stories.d.ts +0 -9
  41. package/components/Table/Table.stories.d.ts +0 -20
  42. package/components/Typography/Typography.stories.d.ts +0 -15
  43. package/components/inputs/Checkbox/Checkbox.stories.d.ts +0 -9
  44. package/components/inputs/Input/Input.stories.d.ts +0 -13
  45. package/components/inputs/Radio/Radio.stories.d.ts +0 -7
  46. package/components/inputs/Select/Select.stories.d.ts +0 -18
  47. package/components/inputs/Textarea/Textarea.stories.d.ts +0 -10
  48. package/test-setup.d.ts +0 -0
@@ -0,0 +1,31 @@
1
+ import { CSSProperties } from 'react';
2
+ export interface SparklineProps {
3
+ /** Numeric series, in left-to-right order. */
4
+ data: number[];
5
+ /** Pixel width. @default 80 */
6
+ width?: number;
7
+ /** Pixel height. @default 24 */
8
+ height?: number;
9
+ /** Stroke color (CSS). @default 'var(--crk-chart-1)' */
10
+ color?: string;
11
+ /** Stroke width in pixels. @default 1.5 */
12
+ strokeWidth?: number;
13
+ /** Interpolation between points. @default 'monotone' */
14
+ curve?: 'linear' | 'monotone';
15
+ /** Fill the area under the line. @default false */
16
+ fill?: boolean;
17
+ /** Draw a dot at the last point. @default false */
18
+ showLastPoint?: boolean;
19
+ /** Accessible label for the chart (`aria-label`). */
20
+ 'aria-label'?: string;
21
+ className?: string;
22
+ style?: CSSProperties;
23
+ }
24
+ /**
25
+ * Tiny inline trend line with no axes, legend, or tooltip — sized in pixels
26
+ * so it can sit inside a table cell, KPI tile, or anywhere a glyph fits.
27
+ *
28
+ * @example
29
+ * <Sparkline data={[1, 3, 2, 4, 3, 5, 4]} />
30
+ */
31
+ export declare const Sparkline: import('react').ForwardRefExoticComponent<SparklineProps & import('react').RefAttributes<SVGSVGElement>>;
@@ -0,0 +1,89 @@
1
+ import { CSSProperties } from 'react';
2
+ import { Bar, CrosshairInfo, Datafeed, IndicatorConfig, Period, Resolution, SeriesType, Timezone, VisibleRange } from './trading/types';
3
+ export interface TradingChartProps {
4
+ datafeed: Datafeed;
5
+ symbol: string;
6
+ resolution: Resolution;
7
+ /**
8
+ * Visible time-range window (e.g. `'1D'`, `'5D'`, `'1M'`, `'1Y'`, `'5Y'`).
9
+ * When set, the chart fetches bars for the last `period` of time and the
10
+ * initial visible range covers the whole window. Overrides `initialLookback`.
11
+ *
12
+ * The chart does not auto-adjust `resolution` when `period` changes — use
13
+ * `suggestResolutionForPeriod()` / `suggestPeriodForResolution()` if you
14
+ * want them coupled in your UI.
15
+ */
16
+ period?: Period;
17
+ /** Main-pane series style. @default 'candle' */
18
+ seriesType?: SeriesType;
19
+ /** Indicators to render. Overlays go on the main pane; volume/rsi get their own sub-pane below. */
20
+ indicators?: IndicatorConfig[];
21
+ /** Decimal places for price labels and tooltip. @default 2 */
22
+ precision?: number;
23
+ /** Initial historical bars to request when `period` is not set. @default 500 */
24
+ initialLookback?: number;
25
+ /** Pixel height of the chart. @default 420 */
26
+ height?: number;
27
+ /** Up-candle / line color. @default 'var(--crk-color-success)' */
28
+ upColor?: string;
29
+ /** Down-candle color. @default 'var(--crk-color-danger)' */
30
+ downColor?: string;
31
+ /** Stroke color for `seriesType="line"` and the area outline. @default 'var(--crk-chart-1)' */
32
+ lineColor?: string;
33
+ /**
34
+ * Controlled timezone — pair with `onTimezoneChange` if the consumer wants
35
+ * to own the value. If omitted, the chart uses `defaultTimezone` and the
36
+ * built-in config panel manages it internally.
37
+ */
38
+ timezone?: Timezone;
39
+ /** Initial timezone when uncontrolled. @default 'local' */
40
+ defaultTimezone?: Timezone;
41
+ /** Fires when the timezone changes — either via the config panel or
42
+ * externally. */
43
+ onTimezoneChange?: (tz: Timezone) => void;
44
+ /**
45
+ * Show the gear button + configuration popover in the chart header.
46
+ * The panel lets the user pick a timezone today; more settings will live
47
+ * here in the future. @default true
48
+ */
49
+ showConfigPanel?: boolean;
50
+ /** Fired when the crosshair moves (`null` when leaving the chart). */
51
+ onCrosshair?: (info: CrosshairInfo | null) => void;
52
+ /** Fired after pan / zoom / data updates. */
53
+ onVisibleRangeChange?: (range: VisibleRange, bars: Bar[]) => void;
54
+ className?: string;
55
+ style?: CSSProperties;
56
+ }
57
+ /**
58
+ * Canvas-rendered candlestick / line / area chart with a TradingView-style
59
+ * datafeed adapter, pan + zoom + crosshair, and a small library of built-in
60
+ * indicators (SMA, EMA, Bollinger Bands as overlays; RSI and Volume in
61
+ * sub-panes).
62
+ *
63
+ * Drop a `Datafeed` in and the chart calls `getBars` on mount, then
64
+ * `subscribeBars` for realtime ticks. Pan-left past the loaded window
65
+ * triggers another `getBars` for older history automatically.
66
+ *
67
+ * @example
68
+ * <TradingChart
69
+ * datafeed={myDatafeed}
70
+ * symbol="AAPL"
71
+ * resolution="60"
72
+ * seriesType="candle"
73
+ * indicators={[
74
+ * { type: 'ema', period: 12, color: 'var(--crk-chart-2)' },
75
+ * { type: 'ema', period: 26, color: 'var(--crk-chart-3)' },
76
+ * { type: 'volume' },
77
+ * { type: 'rsi' },
78
+ * ]}
79
+ * />
80
+ */
81
+ export declare function TradingChart({ datafeed, symbol, resolution, period, seriesType, indicators, precision, initialLookback, height, upColor, downColor, lineColor, timezone, defaultTimezone, onTimezoneChange, showConfigPanel, onCrosshair, onVisibleRangeChange, className, style, }: TradingChartProps): import("react/jsx-runtime").JSX.Element;
82
+ /**
83
+ * Full crosshair date/time label with a timezone tag.
84
+ * Format: `YYYY-MM-DD HH:MM:SS <tz>` — `<tz>` is `+HH:MM` for local,
85
+ * `UTC`, or the short timezone name (`EST`, `BST`, …) for IANA zones.
86
+ */
87
+ export declare function formatCrosshairTime(unixSec: number, timezone: Timezone): string;
88
+ /** Convert a TV-style resolution to an approximate seconds-per-bar count. */
89
+ export declare function approxIntervalSeconds(resolution: Resolution): number;
@@ -0,0 +1,18 @@
1
+ export { LineChart } from './LineChart';
2
+ export type { LineChartProps, LineLabelArgs, LineDotArgs, LinePointClickArgs, } from './LineChart';
3
+ export { AreaChart } from './AreaChart';
4
+ export type { AreaChartProps } from './AreaChart';
5
+ export { BarChart } from './BarChart';
6
+ export type { BarChartProps, BarClickArgs, BarLabelArgs } from './BarChart';
7
+ export { PieChart } from './PieChart';
8
+ export type { PieChartProps, PieLabelArgs, PieSliceClickArgs } from './PieChart';
9
+ export { RadarChart } from './RadarChart';
10
+ export type { RadarChartProps, RadarAxisLabelArgs } from './RadarChart';
11
+ export { TradingChart, formatCrosshairTime } from './TradingChart';
12
+ export type { TradingChartProps } from './TradingChart';
13
+ export type { Bar, Resolution, Period, Timezone, Datafeed, GetBarsArgs, SubscribeBarsArgs, SubscriptionHandle, SeriesType, IndicatorConfig, CrosshairInfo, VisibleRange, } from './trading/types';
14
+ export { sma, ema, bollinger, rsi, volume as volumeSeries } from './trading/indicators';
15
+ export { periodToSeconds, suggestResolutionForPeriod, suggestPeriodForResolution, } from './trading/period';
16
+ export { Sparkline } from './Sparkline';
17
+ export type { SparklineProps } from './Sparkline';
18
+ export type { ChartConfig, SeriesConfig, ChartClasses, ChartMargin } from './types';
@@ -0,0 +1,21 @@
1
+ /** Returns the [min, max] of a numeric series. */
2
+ export declare function extent(values: number[]): [number, number];
3
+ /** Maps a numeric domain `[d0, d1]` to a pixel range `[r0, r1]`. */
4
+ export declare function linearScale(domain: [number, number], range: [number, number]): {
5
+ (v: number): number;
6
+ invert(px: number): number;
7
+ };
8
+ /**
9
+ * Categorical scale — maps each domain entry to the center of an equal-width band.
10
+ * `padding` is the inner gap as a fraction of band width.
11
+ */
12
+ export declare function bandScale<T extends string | number>(domain: T[], range: [number, number], padding?: number): {
13
+ (v: T): number;
14
+ bandWidth(): number;
15
+ step(): number;
16
+ };
17
+ /**
18
+ * Returns approximately `count` "nice" tick values that span `[min, max]`.
19
+ * Uses a 1/2/5 × 10ⁿ progression so labels round cleanly.
20
+ */
21
+ export declare function niceTicks(min: number, max: number, count?: number): number[];
@@ -0,0 +1,28 @@
1
+ import { Bar } from './types';
2
+ /**
3
+ * Simple Moving Average over `period` bars. The first `period - 1` entries
4
+ * are `null` (warm-up) so the resulting array is aligned to `bars`.
5
+ */
6
+ export declare function sma(bars: Bar[], period: number): (number | null)[];
7
+ /**
8
+ * Exponential Moving Average with the standard `α = 2 / (period + 1)`
9
+ * smoothing constant, seeded with the first `period` bars' SMA.
10
+ */
11
+ export declare function ema(bars: Bar[], period: number): (number | null)[];
12
+ export interface BollingerBands {
13
+ middle: (number | null)[];
14
+ upper: (number | null)[];
15
+ lower: (number | null)[];
16
+ }
17
+ /**
18
+ * Bollinger Bands. `middle` is an SMA of `period` closes; `upper`/`lower`
19
+ * are `middle ± stdDev * σ` where σ is the population standard deviation.
20
+ */
21
+ export declare function bollinger(bars: Bar[], period: number, stdDev?: number): BollingerBands;
22
+ /**
23
+ * Relative Strength Index using Wilder's smoothing (the original definition).
24
+ * Output ranges 0–100; first `period` entries are `null`.
25
+ */
26
+ export declare function rsi(bars: Bar[], period?: number): (number | null)[];
27
+ /** Pass-through of the volume series for convenience and downstream typing. */
28
+ export declare function volume(bars: Bar[]): (number | null)[];
@@ -0,0 +1,19 @@
1
+ import { Period, Resolution } from './types';
2
+ /**
3
+ * Convert a `Period` string to seconds. Accepts the typed presets as well as
4
+ * any `<n><unit>` string where unit is `h` / `d` / `w` / `m` / `y`
5
+ * (case-insensitive). Falls back to 30 days on unparseable input.
6
+ */
7
+ export declare function periodToSeconds(period: Period): number;
8
+ /**
9
+ * Recommend a `Resolution` for a given `Period`, targeting roughly 200–500
10
+ * visible bars — the sweet spot where candles stay legible and the price axis
11
+ * has enough headroom. Consumers can override; the coupling is opinionated,
12
+ * not enforced.
13
+ */
14
+ export declare function suggestResolutionForPeriod(period: Period): Resolution;
15
+ /**
16
+ * Recommend a `Period` for a given `Resolution` — the inverse of
17
+ * `suggestResolutionForPeriod`. Same 200–500-bar target.
18
+ */
19
+ export declare function suggestPeriodForResolution(resolution: Resolution): Period;
@@ -0,0 +1,122 @@
1
+ /**
2
+ * A single OHLCV bar. `time` is a unix timestamp **in seconds** (TradingView
3
+ * convention). `volume` is optional — when absent, the volume sub-pane shows
4
+ * nothing meaningful.
5
+ */
6
+ export interface Bar {
7
+ time: number;
8
+ open: number;
9
+ high: number;
10
+ low: number;
11
+ close: number;
12
+ volume?: number;
13
+ }
14
+ /**
15
+ * TradingView-style resolution string — the size of one bar. Minutes are bare
16
+ * numbers (`'1'`, `'5'`, `'60'`), and longer periods use letter suffixes:
17
+ * - `'D'` — daily
18
+ * - `'W'` — weekly
19
+ * - `'M'` — monthly
20
+ *
21
+ * Any other string is accepted (passed through to the datafeed) — useful for
22
+ * exchange-specific intervals (`'1H'`, `'4H'`, `'12H'`, etc.).
23
+ */
24
+ export type Resolution = '1' | '3' | '5' | '15' | '30' | '60' | '120' | '240' | 'D' | 'W' | 'M' | (string & {});
25
+ /**
26
+ * Visible time-range window. Drives the initial X-axis span of the chart.
27
+ * Common presets are typed; any other `<n><unit>` string (`'30d'`, `'2y'`,
28
+ * `'48h'`, …) is accepted and parsed.
29
+ */
30
+ export type Period = '1D' | '5D' | '1M' | '3M' | '6M' | '1Y' | '5Y' | (string & {});
31
+ /**
32
+ * Timezone used to render the crosshair date/time label.
33
+ * - `'local'` — the user's local timezone (offset shown as `+HH:MM`).
34
+ * - `'utc'` — UTC.
35
+ * - Any other string is treated as an IANA timezone name
36
+ * (e.g. `'America/New_York'`, `'Europe/London'`).
37
+ */
38
+ export type Timezone = 'local' | 'utc' | (string & {});
39
+ /** Returned by `subscribeBars` so the chart can later unsubscribe. */
40
+ export type SubscriptionHandle = string | number | symbol | object;
41
+ export interface GetBarsArgs {
42
+ symbol: string;
43
+ resolution: Resolution;
44
+ /** Inclusive lower bound, unix seconds. */
45
+ from: number;
46
+ /** Inclusive upper bound, unix seconds. */
47
+ to: number;
48
+ /** Hint about how many bars to return; the datafeed may return more or fewer. */
49
+ countBack?: number;
50
+ }
51
+ export interface SubscribeBarsArgs {
52
+ symbol: string;
53
+ resolution: Resolution;
54
+ /**
55
+ * Called when a new tick arrives. If the bar's `time` equals the previous
56
+ * bar's `time`, the chart treats it as an update to the in-progress bar;
57
+ * otherwise it's appended as a new bar.
58
+ */
59
+ onTick: (bar: Bar) => void;
60
+ }
61
+ /**
62
+ * Plug-in interface for streaming or batched OHLCV data — modelled on the
63
+ * TradingView Charting Library so adapters port over with minimal churn.
64
+ */
65
+ export interface Datafeed {
66
+ /** Resolve a historical window. Must return bars sorted by `time` ascending. */
67
+ getBars(args: GetBarsArgs): Promise<Bar[]>;
68
+ /** Start streaming live ticks for `symbol` at `resolution`. */
69
+ subscribeBars(args: SubscribeBarsArgs): SubscriptionHandle;
70
+ /** Stop the corresponding subscription. */
71
+ unsubscribeBars(handle: SubscriptionHandle): void;
72
+ }
73
+ /**
74
+ * Visual series mode for the main pane.
75
+ * - `'candle'` — filled candlesticks (open/close body + high/low wick).
76
+ * - `'bar'` — OHLC bars (high/low vertical line + open tick left + close tick right).
77
+ * - `'line'` — close-price line.
78
+ * - `'area'` — close-price line with a translucent fill below.
79
+ */
80
+ export type SeriesType = 'candle' | 'bar' | 'line' | 'area';
81
+ /** Configuration for one indicator. Concrete shape depends on `type`. */
82
+ export type IndicatorConfig = {
83
+ type: 'sma';
84
+ period: number;
85
+ color?: string;
86
+ } | {
87
+ type: 'ema';
88
+ period: number;
89
+ color?: string;
90
+ } | {
91
+ type: 'bollinger';
92
+ period: number;
93
+ stdDev?: number;
94
+ color?: string;
95
+ fillOpacity?: number;
96
+ } | {
97
+ type: 'rsi';
98
+ period?: number;
99
+ color?: string;
100
+ overbought?: number;
101
+ oversold?: number;
102
+ } | {
103
+ type: 'volume';
104
+ upColor?: string;
105
+ downColor?: string;
106
+ };
107
+ /** Reported to consumers when the user moves the crosshair. */
108
+ export interface CrosshairInfo {
109
+ /** Index of the bar under the crosshair, or `null` if off-chart. */
110
+ barIndex: number | null;
111
+ /** Bar at `barIndex`, or `null` if off-chart. */
112
+ bar: Bar | null;
113
+ /** Y-axis value the crosshair sits at, in price units (main pane). */
114
+ priceAtCursor: number | null;
115
+ }
116
+ /** Returned by useful internal helpers; not part of the public API. */
117
+ export interface VisibleRange {
118
+ /** First bar index (fractional during smooth pan). */
119
+ from: number;
120
+ /** Last bar index. */
121
+ to: number;
122
+ }
@@ -0,0 +1,60 @@
1
+ import { ReactNode } from 'react';
2
+ /** Configuration for a single data series in a chart. */
3
+ export interface SeriesConfig {
4
+ /** Visible label in the legend and tooltip. */
5
+ label: string;
6
+ /** CSS color value, e.g. `'var(--crk-chart-1)'` or `'#ff0'`. */
7
+ color: string;
8
+ /**
9
+ * Optional icon to render in the legend instead of the default color
10
+ * swatch. Use an inline SVG for best results; it inherits `color` from
11
+ * the series, so `stroke="currentColor"` / `fill="currentColor"` are
12
+ * recommended.
13
+ */
14
+ icon?: ReactNode;
15
+ }
16
+ /**
17
+ * Keyed by data-field name. Each entry configures one rendered series.
18
+ * The keys here must match keys present on the rows in `data`.
19
+ *
20
+ * @example
21
+ * const config: ChartConfig = {
22
+ * revenue: { label: 'Revenue', color: 'var(--crk-chart-1)' },
23
+ * costs: { label: 'Costs', color: 'var(--crk-chart-2)' },
24
+ * };
25
+ */
26
+ export type ChartConfig = Record<string, SeriesConfig>;
27
+ /** Override class names on internal elements of any chart. */
28
+ export interface ChartClasses {
29
+ root: string;
30
+ svg: string;
31
+ grid: string;
32
+ axis: string;
33
+ axisLabel: string;
34
+ series: string;
35
+ point: string;
36
+ legend: string;
37
+ legendItem: string;
38
+ tooltip: string;
39
+ }
40
+ /** Inner padding (in CSS pixels) between the SVG edge and the plot area. */
41
+ export interface ChartMargin {
42
+ top: number;
43
+ right: number;
44
+ bottom: number;
45
+ left: number;
46
+ }
47
+ /** Active hover state shared by all axis-based charts. */
48
+ export interface ActivePoint {
49
+ /** Index into the chart's `data` array. */
50
+ index: number;
51
+ /** Pixel coordinates (SVG-space) of the focal point. */
52
+ x: number;
53
+ y: number;
54
+ }
55
+ /** Render-prop signature for a custom tooltip body. */
56
+ export type TooltipRenderer<T> = (args: {
57
+ row: T;
58
+ index: number;
59
+ config: ChartConfig;
60
+ }) => ReactNode;
@@ -0,0 +1,12 @@
1
+ import { RefObject } from 'react';
2
+ export interface ChartDimensions {
3
+ width: number;
4
+ height: number;
5
+ }
6
+ /**
7
+ * Tracks the rendered size of `ref` using `ResizeObserver`.
8
+ *
9
+ * `initial` is used until the observer reports the real size; pick something
10
+ * non-zero so SSR / first paint has plausible scales.
11
+ */
12
+ export declare function useChartDimensions(ref: RefObject<HTMLElement | null>, initial?: ChartDimensions): ChartDimensions;
@@ -5,8 +5,23 @@ export interface PopoverClasses {
5
5
  popover: string;
6
6
  }
7
7
  export interface PopoverProps {
8
- /** Trigger content. Wrapped in an internal `<button>`. */
8
+ /**
9
+ * Trigger content. By default, wrapped in an internal `<button>` — pass any
10
+ * `ReactNode` (string, icon, fragment). If you need to pass your own
11
+ * interactive element (e.g. a `<Button>`) without the extra wrapping that
12
+ * would nest `<button>` inside `<button>`, set `asChild` and pass a single
13
+ * React element instead.
14
+ */
9
15
  trigger: React.ReactNode;
16
+ /**
17
+ * Render the trigger as-is (no internal `<button>` wrapper) and merge the
18
+ * onClick / `aria-*` handlers + ref into it. The trigger MUST be a single
19
+ * React element whose root is interactive (e.g. a `<button>`, `<a>`, or a
20
+ * `role="button"` element). Use this when nesting `<button>` inside
21
+ * `<button>` would otherwise produce a hydration warning.
22
+ * @default false
23
+ */
24
+ asChild?: boolean;
10
25
  /** Panel content. Rendered inside a `[role="dialog"]` when open. */
11
26
  content: React.ReactNode;
12
27
  /** Side of the trigger to anchor the panel to. @default 'bottom' */