@opendata-ai/openchart-react 2.0.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/README.md ADDED
@@ -0,0 +1,95 @@
1
+ # @opendata-ai/openchart-react
2
+
3
+ React components for OpenChart. Renders chart specs as SVG and table specs as DOM, with full React lifecycle management.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @opendata-ai/openchart-react @opendata-ai/openchart-core
9
+ ```
10
+
11
+ ## Quick start
12
+
13
+ ```tsx
14
+ import { Chart } from '@opendata-ai/openchart-react';
15
+ import { lineChart } from '@opendata-ai/openchart-core';
16
+
17
+ const data = [
18
+ { date: '2024-01', value: 100 },
19
+ { date: '2024-02', value: 150 },
20
+ { date: '2024-03', value: 130 },
21
+ ];
22
+
23
+ const spec = lineChart(data, 'date', 'value');
24
+
25
+ function App() {
26
+ return <Chart spec={spec} />;
27
+ }
28
+ ```
29
+
30
+ See the [core README](../core/README.md) for all available spec builders.
31
+
32
+ ## Components
33
+
34
+ | Component | Purpose |
35
+ |-----------|---------|
36
+ | `Chart` | Renders any chart spec (line, bar, column, pie, scatter, etc.) |
37
+ | `DataTable` | Renders table specs with sorting, search, and pagination |
38
+ | `Graph` | Renders network graph specs with force-directed layout |
39
+ | `Visualization` | Routes to the correct component based on spec type |
40
+ | `VizThemeProvider` | Provides theme and dark mode context to child components |
41
+
42
+ ## Visualization
43
+
44
+ The recommended entry point when you're rendering arbitrary `VizSpec` values and don't know the type ahead of time. It inspects the spec and routes to `Chart`, `DataTable`, or `Graph` automatically.
45
+
46
+ ```tsx
47
+ import { Visualization } from '@opendata-ai/openchart-react';
48
+ import type { VizSpec } from '@opendata-ai/openchart-core';
49
+
50
+ function RenderSpec({ spec }: { spec: VizSpec }) {
51
+ // Renders Chart, DataTable, or Graph based on spec.type
52
+ return <Visualization spec={spec} />;
53
+ }
54
+ ```
55
+
56
+ If you need event handlers or component-specific props, use the specific component directly instead.
57
+
58
+ ## Dark mode and theming
59
+
60
+ Wrap your app (or a subtree) with `VizThemeProvider` to set theme and dark mode for all child visualizations. All `Chart`, `DataTable`, and `Graph` components inside the provider inherit its values.
61
+
62
+ ```tsx
63
+ import { VizThemeProvider, Chart } from '@opendata-ai/openchart-react';
64
+
65
+ function Dashboard({ specs }) {
66
+ return (
67
+ <VizThemeProvider theme={myTheme} darkMode="auto">
68
+ <Chart spec={specs[0]} />
69
+ <Chart spec={specs[1]} />
70
+ </VizThemeProvider>
71
+ );
72
+ }
73
+ ```
74
+
75
+ `darkMode` accepts `"auto"` (follows system preference), `"force"` (always dark), or `"off"` (always light).
76
+
77
+ For one-off overrides, pass `darkMode` or `theme` directly on an individual component. Component-level props take priority over the provider.
78
+
79
+ ```tsx
80
+ <VizThemeProvider theme={defaultTheme} darkMode="auto">
81
+ <Chart spec={spec1} />
82
+ {/* This one stays light regardless of system preference */}
83
+ <Chart spec={spec2} darkMode="off" />
84
+ </VizThemeProvider>
85
+ ```
86
+
87
+ ## Hooks
88
+
89
+ For lower-level control or custom rendering, these hooks give you direct access to the compilation and rendering pipeline:
90
+
91
+ - `useChart(spec, options?)` - Returns `{ ref, chart, layout }`. Attach `ref` to a container div
92
+ - `useGraph()` - Returns `{ ref, search, zoomToFit, ... }`. Pair with `<Graph ref={ref} />`
93
+ - `useTable(spec, options?)` - Returns `{ ref, table, layout }`. Attach `ref` to a container div
94
+ - `useTableState(options?)` - Manages table sorting, pagination, and search state
95
+ - `useDarkMode(preference?)` - Resolves dark mode preference against system settings
@@ -0,0 +1,292 @@
1
+ export { ChartLayout, ChartSpec, CompileOptions, TableLayout, TableSpec, VizSpec } from '@opendata-ai/openchart-engine';
2
+ import * as react_jsx_runtime from 'react/jsx-runtime';
3
+ import { ChartEventHandlers, ChartSpec, GraphSpec, ThemeConfig, DarkMode, TableSpec, SortState, ChartLayout, VizSpec } from '@opendata-ai/openchart-core';
4
+ import * as react from 'react';
5
+ import { CSSProperties, ReactNode } from 'react';
6
+ import { GraphInstance, MountOptions, ChartInstance, TableInstance, TableState, TableMountOptions } from '@opendata-ai/openchart-vanilla';
7
+
8
+ interface ChartProps extends ChartEventHandlers {
9
+ /** The visualization spec to render. */
10
+ spec: ChartSpec | GraphSpec;
11
+ /** Theme overrides. */
12
+ theme?: ThemeConfig;
13
+ /** Dark mode: "auto", "force", or "off". */
14
+ darkMode?: DarkMode;
15
+ /** Callback when a data point is clicked. @deprecated Use onMarkClick instead. */
16
+ onDataPointClick?: (data: Record<string, unknown>) => void;
17
+ /** CSS class name for the wrapper div. */
18
+ className?: string;
19
+ /** Inline styles for the wrapper div. */
20
+ style?: CSSProperties;
21
+ }
22
+ /**
23
+ * React component that renders a visualization from a spec.
24
+ *
25
+ * Uses the vanilla adapter internally. The spec is compiled and rendered
26
+ * as SVG inside a wrapper div. Spec changes trigger re-renders via the
27
+ * vanilla adapter's update() method.
28
+ */
29
+ declare function Chart({ spec, theme: themeProp, darkMode, onDataPointClick, onMarkClick, onMarkHover, onMarkLeave, onLegendToggle, onAnnotationClick, onAnnotationEdit, onEdit, className, style, }: ChartProps): react_jsx_runtime.JSX.Element;
30
+
31
+ interface DataTableProps {
32
+ /** The table spec to render. */
33
+ spec: TableSpec;
34
+ /** Theme overrides. */
35
+ theme?: ThemeConfig;
36
+ /** Dark mode: "auto", "force", or "off". */
37
+ darkMode?: DarkMode;
38
+ /** Row click handler. */
39
+ onRowClick?: (row: Record<string, unknown>) => void;
40
+ /** Callback when sort changes. */
41
+ onSortChange?: (sort: SortState | null) => void;
42
+ /** Callback when search changes. */
43
+ onSearchChange?: (query: string) => void;
44
+ /** Callback when page changes. */
45
+ onPageChange?: (page: number) => void;
46
+ /** CSS class name for the wrapper div. */
47
+ className?: string;
48
+ /** Inline styles for the wrapper div. */
49
+ style?: CSSProperties;
50
+ /** Controlled sort state. */
51
+ sort?: SortState | null;
52
+ /** Controlled search query. */
53
+ search?: string;
54
+ /** Controlled page number. */
55
+ page?: number;
56
+ }
57
+ /**
58
+ * React component that renders a data table from a TableSpec.
59
+ *
60
+ * Uses the vanilla adapter internally. Supports controlled and uncontrolled
61
+ * modes for sort, search, and pagination state.
62
+ */
63
+ declare function DataTable({ spec, theme: themeProp, darkMode, onRowClick, onSortChange, onSearchChange, onPageChange, className, style, sort, search, page, }: DataTableProps): react_jsx_runtime.JSX.Element;
64
+
65
+ /**
66
+ * useGraph: hook for imperative graph control.
67
+ *
68
+ * Provides a ref to pass to <Graph /> and exposes graph methods
69
+ * (search, zoom, select) for programmatic control of the graph instance.
70
+ */
71
+
72
+ interface UseGraphReturn {
73
+ /** Ref to pass to <Graph ref={ref} />. */
74
+ ref: React.RefObject<GraphHandle | null>;
75
+ /** Search for nodes matching a query string. */
76
+ search: (query: string) => void;
77
+ /** Clear the current search. */
78
+ clearSearch: () => void;
79
+ /** Zoom to fit all nodes in view. */
80
+ zoomToFit: () => void;
81
+ /** Zoom and center on a specific node. */
82
+ zoomToNode: (nodeId: string) => void;
83
+ /** Select a node by id. */
84
+ selectNode: (nodeId: string) => void;
85
+ /** Get the currently selected node ids. */
86
+ getSelectedNodes: () => string[];
87
+ }
88
+ /** Handle exposed by Graph component via forwardRef. */
89
+ interface GraphHandle {
90
+ search: (query: string) => void;
91
+ clearSearch: () => void;
92
+ zoomToFit: () => void;
93
+ zoomToNode: (nodeId: string) => void;
94
+ selectNode: (nodeId: string) => void;
95
+ getSelectedNodes: () => string[];
96
+ /** The underlying GraphInstance from the vanilla adapter. */
97
+ instance: GraphInstance | null;
98
+ }
99
+ /**
100
+ * Hook for imperative graph control.
101
+ *
102
+ * Usage:
103
+ * ```tsx
104
+ * const { ref, search, zoomToFit } = useGraph();
105
+ * return <Graph ref={ref} spec={spec} />;
106
+ * ```
107
+ */
108
+ declare function useGraph(): UseGraphReturn;
109
+
110
+ interface GraphProps {
111
+ /** The graph spec to render. */
112
+ spec: GraphSpec;
113
+ /** Theme overrides. */
114
+ theme?: ThemeConfig;
115
+ /** Dark mode: "auto", "force", or "off". */
116
+ darkMode?: DarkMode;
117
+ /** Callback when a node is clicked. */
118
+ onNodeClick?: (node: Record<string, unknown>) => void;
119
+ /** Callback when a node is double-clicked. */
120
+ onNodeDoubleClick?: (node: Record<string, unknown>) => void;
121
+ /** Callback when selection changes. */
122
+ onSelectionChange?: (nodeIds: string[]) => void;
123
+ /** CSS class name for the wrapper div. */
124
+ className?: string;
125
+ /** Inline styles for the wrapper div. */
126
+ style?: CSSProperties;
127
+ }
128
+ /**
129
+ * React component that renders a force-directed graph from a GraphSpec.
130
+ *
131
+ * Uses the vanilla adapter internally. The spec is compiled and rendered
132
+ * on a canvas inside a wrapper div. Spec changes trigger re-renders via the
133
+ * vanilla adapter's update() method.
134
+ *
135
+ * Supports ref for imperative control via useGraph() hook:
136
+ * ```tsx
137
+ * const { ref, search, zoomToFit } = useGraph();
138
+ * return <Graph ref={ref} spec={spec} />;
139
+ * ```
140
+ */
141
+ declare const Graph: react.ForwardRefExoticComponent<GraphProps & react.RefAttributes<GraphHandle>>;
142
+
143
+ /**
144
+ * React hooks for chart lifecycle and dark mode resolution.
145
+ *
146
+ * useChart: manual control over a chart instance (for advanced usage).
147
+ * useDarkMode: resolves the DarkMode preference to a boolean.
148
+ */
149
+
150
+ interface UseChartOptions {
151
+ /** Theme overrides. */
152
+ theme?: MountOptions['theme'];
153
+ /** Dark mode setting. */
154
+ darkMode?: MountOptions['darkMode'];
155
+ /** Data point click handler. */
156
+ onDataPointClick?: MountOptions['onDataPointClick'];
157
+ /** Enable responsive resizing. Defaults to true. */
158
+ responsive?: boolean;
159
+ }
160
+ interface UseChartReturn {
161
+ /** Ref to attach to the container div. */
162
+ ref: React.RefObject<HTMLDivElement | null>;
163
+ /** The chart instance (null until mounted). */
164
+ chart: ChartInstance | null;
165
+ /** The current compiled layout (null until mounted). */
166
+ layout: ChartLayout | null;
167
+ }
168
+ /**
169
+ * Hook for manual chart lifecycle control.
170
+ *
171
+ * Attach the returned ref to a container div. The chart mounts
172
+ * automatically and updates when the spec changes.
173
+ *
174
+ * @param spec - The visualization spec.
175
+ * @param options - Mount options.
176
+ * @returns { ref, chart, layout }
177
+ */
178
+ declare function useChart(spec: ChartSpec | GraphSpec, options?: UseChartOptions): UseChartReturn;
179
+ /**
180
+ * Resolve a DarkMode preference to a boolean.
181
+ *
182
+ * - "force" -> true
183
+ * - "off" -> false
184
+ * - "auto" -> matches system preference (reactive to changes)
185
+ *
186
+ * @param mode - The dark mode preference.
187
+ * @returns Whether dark mode is active.
188
+ */
189
+ declare function useDarkMode(mode?: DarkMode): boolean;
190
+
191
+ /**
192
+ * useTable: hook for manual table lifecycle control.
193
+ *
194
+ * Attaches to a container ref, mounts a vanilla table instance,
195
+ * and exposes the instance and current state.
196
+ */
197
+
198
+ interface UseTableReturn {
199
+ /** Ref to attach to the container div. */
200
+ ref: React.RefObject<HTMLDivElement | null>;
201
+ /** The table instance (null until mounted). */
202
+ table: TableInstance | null;
203
+ /** The current table state (sort, search, page). */
204
+ state: TableState;
205
+ }
206
+ /**
207
+ * Hook for manual table lifecycle control.
208
+ *
209
+ * Attach the returned ref to a container div. The table mounts
210
+ * automatically and updates when the spec changes.
211
+ *
212
+ * @param spec - The table spec.
213
+ * @param options - Mount options.
214
+ * @returns { ref, table, state }
215
+ */
216
+ declare function useTable(spec: TableSpec, options?: TableMountOptions): UseTableReturn;
217
+
218
+ /**
219
+ * useTableState: managed state hook for controlled table usage.
220
+ *
221
+ * Provides individual sort/search/page state with setters and a
222
+ * resetState function to return to initial values.
223
+ */
224
+
225
+ interface UseTableStateReturn {
226
+ sort: SortState | null;
227
+ setSort: (sort: SortState | null) => void;
228
+ search: string;
229
+ setSearch: (query: string) => void;
230
+ page: number;
231
+ setPage: (page: number) => void;
232
+ resetState: () => void;
233
+ }
234
+ interface UseTableStateOptions {
235
+ sort?: SortState | null;
236
+ search?: string;
237
+ page?: number;
238
+ }
239
+ /**
240
+ * Hook for managing table state (sort, search, page).
241
+ *
242
+ * Use with the DataTable component's controlled props:
243
+ * ```tsx
244
+ * const { sort, search, page, setSort, setSearch, setPage } = useTableState();
245
+ * <DataTable
246
+ * spec={spec}
247
+ * sort={sort}
248
+ * search={search}
249
+ * page={page}
250
+ * onSortChange={setSort}
251
+ * onSearchChange={setSearch}
252
+ * onPageChange={setPage}
253
+ * />
254
+ * ```
255
+ */
256
+ declare function useTableState(initialState?: UseTableStateOptions): UseTableStateReturn;
257
+
258
+ /** Read the current theme from the nearest VizThemeProvider. */
259
+ declare function useVizTheme(): ThemeConfig | undefined;
260
+ /** Read the current dark mode preference from the nearest VizThemeProvider. */
261
+ declare function useVizDarkMode(): DarkMode | undefined;
262
+ interface VizThemeProviderProps {
263
+ /** Theme config to provide to descendant viz components. */
264
+ theme: ThemeConfig | undefined;
265
+ /** Dark mode preference to provide to descendant viz components. */
266
+ darkMode?: DarkMode;
267
+ children: ReactNode;
268
+ }
269
+ /** Provides a theme and dark mode preference to all nested Chart, DataTable, and Graph components. */
270
+ declare function VizThemeProvider({ theme, darkMode, children }: VizThemeProviderProps): react_jsx_runtime.JSX.Element;
271
+
272
+ interface VisualizationProps {
273
+ /** The visualization spec to render. */
274
+ spec: VizSpec;
275
+ /** Theme overrides. */
276
+ theme?: ThemeConfig;
277
+ /** Dark mode: "auto", "force", or "off". */
278
+ darkMode?: DarkMode;
279
+ /** CSS class name for the wrapper div. */
280
+ className?: string;
281
+ /** Inline styles for the wrapper div. */
282
+ style?: CSSProperties;
283
+ }
284
+ /**
285
+ * Routes a VizSpec to the appropriate rendering component.
286
+ *
287
+ * Accepts any VizSpec and renders it with the correct component based on the
288
+ * spec's type field. For event handlers, use Chart, DataTable, or Graph directly.
289
+ */
290
+ declare function Visualization({ spec, theme, darkMode, className, style }: VisualizationProps): react_jsx_runtime.JSX.Element;
291
+
292
+ export { Chart, type ChartProps, DataTable, type DataTableProps, Graph, type GraphHandle, type GraphProps, type UseChartOptions, type UseChartReturn, type UseGraphReturn, type UseTableReturn, type UseTableStateOptions, type UseTableStateReturn, Visualization, type VisualizationProps, VizThemeProvider, type VizThemeProviderProps, useChart, useDarkMode, useGraph, useTable, useTableState, useVizDarkMode, useVizTheme };