@graphein/react 0.19.0 → 0.21.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 +8 -2
- package/dist/index.d.ts +7 -10
- package/dist/index.js +70 -39
- package/dist/index.js.map +1 -1
- package/package.json +5 -4
package/README.md
CHANGED
|
@@ -34,8 +34,14 @@ export function Dashboard() {
|
|
|
34
34
|
```
|
|
35
35
|
|
|
36
36
|
`<Chart spec={…} />` renders into a fill-by-default container; pass a new `spec`
|
|
37
|
-
to update in place, and it tears down on unmount.
|
|
38
|
-
|
|
37
|
+
to update in place, and it tears down on unmount. `<Chart>` and `<Dashboard>`
|
|
38
|
+
forward ordinary `<div>` props and refs. For headless control over your own
|
|
39
|
+
element, use the `useChart(spec)` hook (returns a ref to attach).
|
|
40
|
+
|
|
41
|
+
Selection state is safe under React 18 concurrency: `useSelection` subscribes via
|
|
42
|
+
`useSyncExternalStore`, changing only the shared `store` does not drop the next
|
|
43
|
+
spec update, and forwarded refs point at the host `<div>` while `onReady` exposes
|
|
44
|
+
the Graphein chart/dashboard instance.
|
|
39
45
|
|
|
40
46
|
## Documentation
|
|
41
47
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { RefObject, HTMLAttributes } from 'react';
|
|
2
3
|
import { ChartInstance, SelectionStore, SelectionChangeListener, ChartSpec, DashboardInstance, DashboardSpec, SelectionValue } from 'graphein';
|
|
3
4
|
export { ChartInstance, ChartSpec, DashboardInstance, DashboardSpec, SelectionChangeListener, SelectionStore, SelectionValue, createSelectionStore } from 'graphein';
|
|
4
5
|
|
|
@@ -36,11 +37,9 @@ interface UseChartOptions {
|
|
|
36
37
|
*/
|
|
37
38
|
declare function useChart<T extends HTMLElement = HTMLDivElement>(spec: ChartSpec, options?: UseChartOptions): RefObject<T | null>;
|
|
38
39
|
|
|
39
|
-
interface ChartProps extends UseChartOptions {
|
|
40
|
+
interface ChartProps extends UseChartOptions, Omit<HTMLAttributes<HTMLDivElement>, 'children'> {
|
|
40
41
|
/** The Graphein chart spec to render. */
|
|
41
42
|
spec: ChartSpec;
|
|
42
|
-
className?: string;
|
|
43
|
-
style?: CSSProperties;
|
|
44
43
|
}
|
|
45
44
|
/**
|
|
46
45
|
* Declarative React wrapper around the Graphein core runtime.
|
|
@@ -55,7 +54,7 @@ interface ChartProps extends UseChartOptions {
|
|
|
55
54
|
* </div>
|
|
56
55
|
* ```
|
|
57
56
|
*/
|
|
58
|
-
declare
|
|
57
|
+
declare const Chart: react.ForwardRefExoticComponent<ChartProps & react.RefAttributes<HTMLDivElement>>;
|
|
59
58
|
|
|
60
59
|
interface UseDashboardOptions {
|
|
61
60
|
/** Called with the live instance after each mount and update. */
|
|
@@ -88,11 +87,9 @@ interface UseDashboardOptions {
|
|
|
88
87
|
*/
|
|
89
88
|
declare function useDashboard<T extends HTMLElement = HTMLDivElement>(spec: DashboardSpec, options?: UseDashboardOptions): RefObject<T | null>;
|
|
90
89
|
|
|
91
|
-
interface DashboardProps extends UseDashboardOptions {
|
|
90
|
+
interface DashboardProps extends UseDashboardOptions, Omit<HTMLAttributes<HTMLDivElement>, 'children'> {
|
|
92
91
|
/** The Graphein dashboard spec to render. */
|
|
93
92
|
spec: DashboardSpec;
|
|
94
|
-
className?: string;
|
|
95
|
-
style?: CSSProperties;
|
|
96
93
|
}
|
|
97
94
|
/**
|
|
98
95
|
* Declarative React wrapper around the Graphein dashboard runtime.
|
|
@@ -105,7 +102,7 @@ interface DashboardProps extends UseDashboardOptions {
|
|
|
105
102
|
* <Dashboard spec={{ type: 'dashboard', data, views, interactions: 'auto' }} />
|
|
106
103
|
* ```
|
|
107
104
|
*/
|
|
108
|
-
declare
|
|
105
|
+
declare const Dashboard: react.ForwardRefExoticComponent<DashboardProps & react.RefAttributes<HTMLDivElement>>;
|
|
109
106
|
|
|
110
107
|
/** Anything that exposes a selection bus: a store, or a chart/dashboard instance. */
|
|
111
108
|
type SelectionSource = SelectionStore | {
|
|
@@ -140,6 +137,6 @@ declare function useSelection(source: SelectionSource, name: string): [Selection
|
|
|
140
137
|
* as React state. Core spec/instance types are re-exported for convenience.
|
|
141
138
|
*/
|
|
142
139
|
|
|
143
|
-
declare const VERSION = "0.
|
|
140
|
+
declare const VERSION = "0.21.0";
|
|
144
141
|
|
|
145
142
|
export { Chart, type ChartProps, Dashboard, type DashboardProps, type SelectionSource, type UseChartOptions, type UseDashboardOptions, VERSION, useChart, useDashboard, useSelection };
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
// src/Chart.ts
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
createElement,
|
|
4
|
+
forwardRef,
|
|
5
|
+
useCallback
|
|
6
|
+
} from "react";
|
|
3
7
|
|
|
4
8
|
// src/useChart.ts
|
|
5
9
|
import { useEffect, useRef } from "react";
|
|
@@ -19,35 +23,35 @@ function useChart(spec, options = {}) {
|
|
|
19
23
|
storeRef.current = options.store;
|
|
20
24
|
const inspectRef = useRef(options.inspect);
|
|
21
25
|
inspectRef.current = options.inspect;
|
|
22
|
-
const
|
|
26
|
+
const instanceSpecRef = useRef(null);
|
|
23
27
|
useEffect(() => {
|
|
24
28
|
const el = ref.current;
|
|
25
29
|
if (!el) return;
|
|
26
|
-
const
|
|
30
|
+
const mountedSpec = specRef.current;
|
|
31
|
+
const instance = render(el, mountedSpec, {
|
|
27
32
|
store: storeRef.current,
|
|
28
33
|
inspect: inspectRef.current
|
|
29
34
|
});
|
|
30
35
|
instanceRef.current = instance;
|
|
36
|
+
instanceSpecRef.current = mountedSpec;
|
|
31
37
|
const offSelection = instance.on(
|
|
32
38
|
"selectionchange",
|
|
33
39
|
(name, value) => onSelectionChangeRef.current?.(name, value)
|
|
34
40
|
);
|
|
35
|
-
skipNextUpdate.current = true;
|
|
36
41
|
onReadyRef.current?.(instance);
|
|
37
42
|
return () => {
|
|
38
43
|
offSelection();
|
|
39
44
|
instance.destroy();
|
|
40
45
|
instanceRef.current = null;
|
|
46
|
+
instanceSpecRef.current = null;
|
|
41
47
|
};
|
|
42
48
|
}, [options.store]);
|
|
43
49
|
useEffect(() => {
|
|
44
|
-
if (skipNextUpdate.current) {
|
|
45
|
-
skipNextUpdate.current = false;
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
50
|
const instance = instanceRef.current;
|
|
49
51
|
if (!instance) return;
|
|
52
|
+
if (instanceSpecRef.current === spec) return;
|
|
50
53
|
instance.update(spec);
|
|
54
|
+
instanceSpecRef.current = spec;
|
|
51
55
|
onReadyRef.current?.(instance);
|
|
52
56
|
}, [spec]);
|
|
53
57
|
return ref;
|
|
@@ -55,17 +59,34 @@ function useChart(spec, options = {}) {
|
|
|
55
59
|
|
|
56
60
|
// src/Chart.ts
|
|
57
61
|
var FILL = { width: "100%", height: "100%" };
|
|
58
|
-
|
|
59
|
-
|
|
62
|
+
var Chart = forwardRef(function Chart2({
|
|
63
|
+
spec,
|
|
64
|
+
onReady,
|
|
65
|
+
store,
|
|
66
|
+
onSelectionChange,
|
|
67
|
+
inspect,
|
|
68
|
+
style,
|
|
69
|
+
...divProps
|
|
70
|
+
}, forwardedRef) {
|
|
71
|
+
const ref = useChart(spec, { onReady, store, onSelectionChange, inspect });
|
|
72
|
+
const attachRef = useCallback((node) => {
|
|
73
|
+
ref.current = node;
|
|
74
|
+
if (typeof forwardedRef === "function") forwardedRef(node);
|
|
75
|
+
else if (forwardedRef) forwardedRef.current = node;
|
|
76
|
+
}, [forwardedRef, ref]);
|
|
60
77
|
return createElement("div", {
|
|
61
|
-
|
|
62
|
-
|
|
78
|
+
...divProps,
|
|
79
|
+
ref: attachRef,
|
|
63
80
|
style: style ? { ...FILL, ...style } : FILL
|
|
64
81
|
});
|
|
65
|
-
}
|
|
82
|
+
});
|
|
66
83
|
|
|
67
84
|
// src/Dashboard.ts
|
|
68
|
-
import {
|
|
85
|
+
import {
|
|
86
|
+
createElement as createElement2,
|
|
87
|
+
forwardRef as forwardRef2,
|
|
88
|
+
useCallback as useCallback2
|
|
89
|
+
} from "react";
|
|
69
90
|
|
|
70
91
|
// src/useDashboard.ts
|
|
71
92
|
import { useEffect as useEffect2, useRef as useRef2 } from "react";
|
|
@@ -85,35 +106,35 @@ function useDashboard(spec, options = {}) {
|
|
|
85
106
|
storeRef.current = options.store;
|
|
86
107
|
const inspectRef = useRef2(options.inspect);
|
|
87
108
|
inspectRef.current = options.inspect;
|
|
88
|
-
const
|
|
109
|
+
const instanceSpecRef = useRef2(null);
|
|
89
110
|
useEffect2(() => {
|
|
90
111
|
const el = ref.current;
|
|
91
112
|
if (!el) return;
|
|
92
|
-
const
|
|
113
|
+
const mountedSpec = specRef.current;
|
|
114
|
+
const instance = renderDashboard(el, mountedSpec, {
|
|
93
115
|
store: storeRef.current,
|
|
94
116
|
inspect: inspectRef.current
|
|
95
117
|
});
|
|
96
118
|
instanceRef.current = instance;
|
|
119
|
+
instanceSpecRef.current = mountedSpec;
|
|
97
120
|
const offSelection = instance.on(
|
|
98
121
|
"selectionchange",
|
|
99
122
|
(name, value) => onSelectionChangeRef.current?.(name, value)
|
|
100
123
|
);
|
|
101
|
-
skipNextUpdate.current = true;
|
|
102
124
|
onReadyRef.current?.(instance);
|
|
103
125
|
return () => {
|
|
104
126
|
offSelection();
|
|
105
127
|
instance.destroy();
|
|
106
128
|
instanceRef.current = null;
|
|
129
|
+
instanceSpecRef.current = null;
|
|
107
130
|
};
|
|
108
131
|
}, [options.store]);
|
|
109
132
|
useEffect2(() => {
|
|
110
|
-
if (skipNextUpdate.current) {
|
|
111
|
-
skipNextUpdate.current = false;
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
133
|
const instance = instanceRef.current;
|
|
115
134
|
if (!instance) return;
|
|
135
|
+
if (instanceSpecRef.current === spec) return;
|
|
116
136
|
instance.update(spec);
|
|
137
|
+
instanceSpecRef.current = spec;
|
|
117
138
|
onReadyRef.current?.(instance);
|
|
118
139
|
}, [spec]);
|
|
119
140
|
return ref;
|
|
@@ -121,36 +142,46 @@ function useDashboard(spec, options = {}) {
|
|
|
121
142
|
|
|
122
143
|
// src/Dashboard.ts
|
|
123
144
|
var FILL2 = { width: "100%" };
|
|
124
|
-
|
|
125
|
-
|
|
145
|
+
var Dashboard = forwardRef2(function Dashboard2({
|
|
146
|
+
spec,
|
|
147
|
+
onReady,
|
|
148
|
+
store,
|
|
149
|
+
onSelectionChange,
|
|
150
|
+
inspect,
|
|
151
|
+
style,
|
|
152
|
+
...divProps
|
|
153
|
+
}, forwardedRef) {
|
|
154
|
+
const ref = useDashboard(spec, { onReady, store, onSelectionChange, inspect });
|
|
155
|
+
const attachRef = useCallback2((node) => {
|
|
156
|
+
ref.current = node;
|
|
157
|
+
if (typeof forwardedRef === "function") forwardedRef(node);
|
|
158
|
+
else if (forwardedRef) forwardedRef.current = node;
|
|
159
|
+
}, [forwardedRef, ref]);
|
|
126
160
|
return createElement2("div", {
|
|
127
|
-
|
|
128
|
-
|
|
161
|
+
...divProps,
|
|
162
|
+
ref: attachRef,
|
|
129
163
|
style: style ? { ...FILL2, ...style } : FILL2
|
|
130
164
|
});
|
|
131
|
-
}
|
|
165
|
+
});
|
|
132
166
|
|
|
133
167
|
// src/useSelection.ts
|
|
134
|
-
import { useCallback
|
|
168
|
+
import { useCallback as useCallback3, useSyncExternalStore } from "react";
|
|
135
169
|
function resolveStore(source) {
|
|
136
170
|
if (!source) return null;
|
|
137
171
|
return "store" in source ? source.store : source;
|
|
138
172
|
}
|
|
139
173
|
function useSelection(source, name) {
|
|
140
174
|
const store = resolveStore(source);
|
|
141
|
-
const
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
}
|
|
147
|
-
setValue(store.get(name) ?? null);
|
|
148
|
-
const unsubscribe = store.subscribe((changed, next) => {
|
|
149
|
-
if (changed === name) setValue(next);
|
|
175
|
+
const subscribe = useCallback3((notify) => {
|
|
176
|
+
if (!store) return () => {
|
|
177
|
+
};
|
|
178
|
+
return store.subscribe((changed) => {
|
|
179
|
+
if (changed === name) notify();
|
|
150
180
|
});
|
|
151
|
-
return unsubscribe;
|
|
152
181
|
}, [store, name]);
|
|
153
|
-
const
|
|
182
|
+
const getSnapshot = useCallback3(() => store?.get(name) ?? null, [store, name]);
|
|
183
|
+
const value = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
184
|
+
const set = useCallback3(
|
|
154
185
|
(next) => {
|
|
155
186
|
store?.set(name, next ?? null);
|
|
156
187
|
},
|
|
@@ -161,7 +192,7 @@ function useSelection(source, name) {
|
|
|
161
192
|
|
|
162
193
|
// src/index.ts
|
|
163
194
|
import { createSelectionStore } from "graphein";
|
|
164
|
-
var VERSION = "0.
|
|
195
|
+
var VERSION = "0.21.0";
|
|
165
196
|
export {
|
|
166
197
|
Chart,
|
|
167
198
|
Dashboard,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/Chart.ts","../src/useChart.ts","../src/Dashboard.ts","../src/useDashboard.ts","../src/useSelection.ts","../src/index.ts"],"sourcesContent":["import { createElement, type CSSProperties, type ReactElement } from 'react';\nimport type { ChartSpec } from 'graphein';\nimport { useChart, type UseChartOptions } from './useChart';\n\nexport interface ChartProps extends UseChartOptions {\n /** The Graphein chart spec to render. */\n spec: ChartSpec;\n className?: string;\n style?: CSSProperties;\n}\n\nconst FILL: CSSProperties = { width: '100%', height: '100%' };\n\n/**\n * Declarative React wrapper around the Graphein core runtime.\n *\n * Renders a container `<div>` that fills its parent (override via `style`) and\n * draws `spec` into it. Pass a new `spec` to update; unmounting tears the chart\n * down. Give the parent an explicit size for best results.\n *\n * ```tsx\n * <div style={{ height: 360 }}>\n * <Chart spec={{ type: 'line', data, encoding: { x, y } }} />\n * </div>\n * ```\n */\nexport function Chart({ spec, className, style, ...options }: ChartProps): ReactElement {\n const ref = useChart<HTMLDivElement>(spec, options);\n return createElement('div', {\n ref,\n className,\n style: style ? { ...FILL, ...style } : FILL,\n });\n}\n","import { useEffect, useRef, type RefObject } from 'react';\nimport {\n render,\n type ChartInstance,\n type ChartSpec,\n type SelectionChangeListener,\n type SelectionStore,\n} from 'graphein';\n\nexport interface UseChartOptions {\n /** Called with the live instance after each mount and update. */\n onReady?: (instance: ChartInstance) => void;\n /**\n * A shared selection bus. Pass the same store to several charts (or a\n * dashboard) to link them — cross-highlight / cross-filter. Should be stable\n * across renders (e.g. `useMemo(() => createSelectionStore(), [])`); changing\n * its identity remounts the chart.\n */\n store?: SelectionStore;\n /** Called whenever any selection this chart is bound to changes. */\n onSelectionChange?: SelectionChangeListener;\n /**\n * Publish the chart's config to a `data-graphein-spec` DOM attribute and\n * re-render when an external tool edits it. Defaults to `true`; set `false` to\n * opt out. Read once at mount.\n */\n inspect?: boolean;\n}\n\n/**\n * Mount an Graphein chart into a DOM node and keep it in sync with `spec`.\n *\n * Returns a ref to attach to the container element. The chart is created on\n * mount, re-rendered via `instance.update()` whenever `spec` changes identity,\n * and torn down on unmount. The effect lifecycle is StrictMode-safe (double\n * mount → destroy → mount produces no leaked instances or duplicate renders).\n *\n * ```tsx\n * const ref = useChart(spec);\n * return <div ref={ref} style={{ width: '100%', height: 360 }} />;\n * ```\n */\nexport function useChart<T extends HTMLElement = HTMLDivElement>(\n spec: ChartSpec,\n options: UseChartOptions = {},\n): RefObject<T | null> {\n const ref = useRef<T | null>(null);\n const instanceRef = useRef<ChartInstance | null>(null);\n // Hold the latest spec / callback in refs so the mount effect (which runs\n // once) always reads current values without re-subscribing.\n const specRef = useRef(spec);\n specRef.current = spec;\n const onReadyRef = useRef(options.onReady);\n onReadyRef.current = options.onReady;\n const onSelectionChangeRef = useRef(options.onSelectionChange);\n onSelectionChangeRef.current = options.onSelectionChange;\n const storeRef = useRef(options.store);\n storeRef.current = options.store;\n const inspectRef = useRef(options.inspect);\n inspectRef.current = options.inspect;\n const skipNextUpdate = useRef(true);\n\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n const instance = render(el, specRef.current, {\n store: storeRef.current,\n inspect: inspectRef.current,\n });\n instanceRef.current = instance;\n const offSelection = instance.on('selectionchange', (name, value) =>\n onSelectionChangeRef.current?.(name, value),\n );\n // The update effect runs once right after this on mount; skip that pass so\n // we don't redundantly re-render the freshly created chart.\n skipNextUpdate.current = true;\n onReadyRef.current?.(instance);\n return () => {\n offSelection();\n instance.destroy();\n instanceRef.current = null;\n };\n }, [options.store]);\n\n useEffect(() => {\n if (skipNextUpdate.current) {\n skipNextUpdate.current = false;\n return;\n }\n const instance = instanceRef.current;\n if (!instance) return;\n instance.update(spec);\n onReadyRef.current?.(instance);\n }, [spec]);\n\n return ref;\n}\n","import { createElement, type CSSProperties, type ReactElement } from 'react';\nimport type { DashboardSpec } from 'graphein';\nimport { useDashboard, type UseDashboardOptions } from './useDashboard';\n\nexport interface DashboardProps extends UseDashboardOptions {\n /** The Graphein dashboard spec to render. */\n spec: DashboardSpec;\n className?: string;\n style?: CSSProperties;\n}\n\nconst FILL: CSSProperties = { width: '100%' };\n\n/**\n * Declarative React wrapper around the Graphein dashboard runtime.\n *\n * Renders a container `<div>` (full width by default; height comes from the\n * dashboard's grid rows) and draws `spec` into it. Pass a new `spec` to update;\n * unmounting tears it down. Auto-wires cross-interaction unless `spec` opts out.\n *\n * ```tsx\n * <Dashboard spec={{ type: 'dashboard', data, views, interactions: 'auto' }} />\n * ```\n */\nexport function Dashboard({ spec, className, style, ...options }: DashboardProps): ReactElement {\n const ref = useDashboard<HTMLDivElement>(spec, options);\n return createElement('div', {\n ref,\n className,\n style: style ? { ...FILL, ...style } : FILL,\n });\n}\n","import { useEffect, useRef, type RefObject } from 'react';\nimport {\n renderDashboard,\n type DashboardInstance,\n type DashboardSpec,\n type SelectionChangeListener,\n type SelectionStore,\n} from 'graphein';\n\nexport interface UseDashboardOptions {\n /** Called with the live instance after each mount and update. */\n onReady?: (instance: DashboardInstance) => void;\n /**\n * A shared selection bus. Omit to let the dashboard own one internally; pass\n * one (stable across renders) to drive it from React via {@link useSelection}\n * or to link it with standalone charts. Changing its identity remounts.\n */\n store?: SelectionStore;\n /** Called whenever any selection in the dashboard changes. */\n onSelectionChange?: SelectionChangeListener;\n /**\n * Publish each view's config (and the dashboard's) to `data-graphein-spec` DOM\n * attributes and re-render on external edits. Defaults to `true`; set `false` to\n * opt out for the whole dashboard. Read once at mount.\n */\n inspect?: boolean;\n}\n\n/**\n * Mount an Graphein dashboard into a DOM node and keep it in sync with `spec`.\n *\n * Mirrors {@link useChart}: created on mount, updated in place when `spec`\n * changes identity, torn down on unmount, StrictMode-safe.\n *\n * ```tsx\n * const ref = useDashboard(dashboardSpec);\n * return <div ref={ref} style={{ width: '100%' }} />;\n * ```\n */\nexport function useDashboard<T extends HTMLElement = HTMLDivElement>(\n spec: DashboardSpec,\n options: UseDashboardOptions = {},\n): RefObject<T | null> {\n const ref = useRef<T | null>(null);\n const instanceRef = useRef<DashboardInstance | null>(null);\n const specRef = useRef(spec);\n specRef.current = spec;\n const onReadyRef = useRef(options.onReady);\n onReadyRef.current = options.onReady;\n const onSelectionChangeRef = useRef(options.onSelectionChange);\n onSelectionChangeRef.current = options.onSelectionChange;\n const storeRef = useRef(options.store);\n storeRef.current = options.store;\n const inspectRef = useRef(options.inspect);\n inspectRef.current = options.inspect;\n const skipNextUpdate = useRef(true);\n\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n const instance = renderDashboard(el, specRef.current, {\n store: storeRef.current,\n inspect: inspectRef.current,\n });\n instanceRef.current = instance;\n const offSelection = instance.on('selectionchange', (name, value) =>\n onSelectionChangeRef.current?.(name, value),\n );\n skipNextUpdate.current = true;\n onReadyRef.current?.(instance);\n return () => {\n offSelection();\n instance.destroy();\n instanceRef.current = null;\n };\n }, [options.store]);\n\n useEffect(() => {\n if (skipNextUpdate.current) {\n skipNextUpdate.current = false;\n return;\n }\n const instance = instanceRef.current;\n if (!instance) return;\n instance.update(spec);\n onReadyRef.current?.(instance);\n }, [spec]);\n\n return ref;\n}\n","import { useCallback, useEffect, useState } from 'react';\nimport type { SelectionStore, SelectionValue } from 'graphein';\n\n/** Anything that exposes a selection bus: a store, or a chart/dashboard instance. */\nexport type SelectionSource =\n | SelectionStore\n | { store: SelectionStore }\n | null\n | undefined;\n\nfunction resolveStore(source: SelectionSource): SelectionStore | null {\n if (!source) return null;\n return 'store' in source ? source.store : source;\n}\n\n/**\n * Read and write a named selection as React state.\n *\n * Pass a shared {@link SelectionStore} (or a chart/dashboard instance, which\n * exposes one as `.store`) plus the param name. Returns the current value and a\n * setter that publishes to the bus — driving cross-highlight / cross-filter\n * across every visual bound to that store.\n *\n * ```tsx\n * const store = useMemo(() => createSelectionStore(), []);\n * const [region, setRegion] = useSelection(store, 'region');\n * // …\n * <Dashboard spec={spec} store={store} />\n * <button onClick={() => setRegion({ kind: 'set', field: 'region', values: ['West'] })}>\n * West\n * </button>\n * ```\n */\nexport function useSelection(\n source: SelectionSource,\n name: string,\n): [SelectionValue | null, (value: SelectionValue | null) => void] {\n const store = resolveStore(source);\n const [value, setValue] = useState<SelectionValue | null>(() => store?.get(name) ?? null);\n\n useEffect(() => {\n if (!store) {\n setValue(null);\n return;\n }\n setValue(store.get(name) ?? null);\n const unsubscribe = store.subscribe((changed, next) => {\n if (changed === name) setValue(next);\n });\n return unsubscribe;\n }, [store, name]);\n\n const set = useCallback(\n (next: SelectionValue | null) => {\n store?.set(name, next ?? null);\n },\n [store, name],\n );\n\n return [value, set];\n}\n","/**\n * @graphein/react — a thin React wrapper around the `graphein` runtime.\n *\n * `<Chart spec={…} />` for a single chart or `<Dashboard spec={…} />` for a\n * cross-interacting page; the `useChart` / `useDashboard` hooks give headless\n * control over your own container, and `useSelection` reads/writes a selection\n * as React state. Core spec/instance types are re-exported for convenience.\n */\nexport { Chart, type ChartProps } from './Chart';\nexport { useChart, type UseChartOptions } from './useChart';\nexport { Dashboard, type DashboardProps } from './Dashboard';\nexport { useDashboard, type UseDashboardOptions } from './useDashboard';\nexport { useSelection, type SelectionSource } from './useSelection';\nexport { createSelectionStore } from 'graphein';\nexport type {\n ChartSpec,\n ChartInstance,\n DashboardSpec,\n DashboardInstance,\n SelectionStore,\n SelectionValue,\n SelectionChangeListener,\n} from 'graphein';\n\nexport const VERSION = '0.0.0';\n"],"mappings":"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","names":["createElement","useEffect","useRef","FILL","createElement","useEffect"]}
|
|
1
|
+
{"version":3,"sources":["../src/Chart.ts","../src/useChart.ts","../src/Dashboard.ts","../src/useDashboard.ts","../src/useSelection.ts","../src/index.ts"],"sourcesContent":["import {\n createElement,\n forwardRef,\n useCallback,\n type CSSProperties,\n type HTMLAttributes,\n type MutableRefObject,\n type ReactElement,\n} from 'react';\nimport type { ChartSpec } from 'graphein';\nimport { useChart, type UseChartOptions } from './useChart';\n\nexport interface ChartProps extends UseChartOptions, Omit<HTMLAttributes<HTMLDivElement>, 'children'> {\n /** The Graphein chart spec to render. */\n spec: ChartSpec;\n}\n\nconst FILL: CSSProperties = { width: '100%', height: '100%' };\n\n/**\n * Declarative React wrapper around the Graphein core runtime.\n *\n * Renders a container `<div>` that fills its parent (override via `style`) and\n * draws `spec` into it. Pass a new `spec` to update; unmounting tears the chart\n * down. Give the parent an explicit size for best results.\n *\n * ```tsx\n * <div style={{ height: 360 }}>\n * <Chart spec={{ type: 'line', data, encoding: { x, y } }} />\n * </div>\n * ```\n */\nexport const Chart = forwardRef<HTMLDivElement, ChartProps>(function Chart({\n spec,\n onReady,\n store,\n onSelectionChange,\n inspect,\n style,\n ...divProps\n}, forwardedRef): ReactElement {\n const ref = useChart<HTMLDivElement>(spec, { onReady, store, onSelectionChange, inspect });\n const attachRef = useCallback((node: HTMLDivElement | null) => {\n ref.current = node;\n if (typeof forwardedRef === 'function') forwardedRef(node);\n else if (forwardedRef) (forwardedRef as MutableRefObject<HTMLDivElement | null>).current = node;\n }, [forwardedRef, ref]);\n return createElement('div', {\n ...divProps,\n ref: attachRef,\n style: style ? { ...FILL, ...style } : FILL,\n });\n});\n","import { useEffect, useRef, type RefObject } from 'react';\nimport {\n render,\n type ChartInstance,\n type ChartSpec,\n type SelectionChangeListener,\n type SelectionStore,\n} from 'graphein';\n\nexport interface UseChartOptions {\n /** Called with the live instance after each mount and update. */\n onReady?: (instance: ChartInstance) => void;\n /**\n * A shared selection bus. Pass the same store to several charts (or a\n * dashboard) to link them — cross-highlight / cross-filter. Should be stable\n * across renders (e.g. `useMemo(() => createSelectionStore(), [])`); changing\n * its identity remounts the chart.\n */\n store?: SelectionStore;\n /** Called whenever any selection this chart is bound to changes. */\n onSelectionChange?: SelectionChangeListener;\n /**\n * Publish the chart's config to a `data-graphein-spec` DOM attribute and\n * re-render when an external tool edits it. Defaults to `true`; set `false` to\n * opt out. Read once at mount.\n */\n inspect?: boolean;\n}\n\n/**\n * Mount an Graphein chart into a DOM node and keep it in sync with `spec`.\n *\n * Returns a ref to attach to the container element. The chart is created on\n * mount, re-rendered via `instance.update()` whenever `spec` changes identity,\n * and torn down on unmount. The effect lifecycle is StrictMode-safe (double\n * mount → destroy → mount produces no leaked instances or duplicate renders).\n *\n * ```tsx\n * const ref = useChart(spec);\n * return <div ref={ref} style={{ width: '100%', height: 360 }} />;\n * ```\n */\nexport function useChart<T extends HTMLElement = HTMLDivElement>(\n spec: ChartSpec,\n options: UseChartOptions = {},\n): RefObject<T | null> {\n const ref = useRef<T | null>(null);\n const instanceRef = useRef<ChartInstance | null>(null);\n // Hold the latest spec / callback in refs so the mount effect (which runs\n // once) always reads current values without re-subscribing.\n const specRef = useRef(spec);\n specRef.current = spec;\n const onReadyRef = useRef(options.onReady);\n onReadyRef.current = options.onReady;\n const onSelectionChangeRef = useRef(options.onSelectionChange);\n onSelectionChangeRef.current = options.onSelectionChange;\n const storeRef = useRef(options.store);\n storeRef.current = options.store;\n const inspectRef = useRef(options.inspect);\n inspectRef.current = options.inspect;\n const instanceSpecRef = useRef<ChartSpec | null>(null);\n\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n const mountedSpec = specRef.current;\n const instance = render(el, mountedSpec, {\n store: storeRef.current,\n inspect: inspectRef.current,\n });\n instanceRef.current = instance;\n instanceSpecRef.current = mountedSpec;\n const offSelection = instance.on('selectionchange', (name, value) =>\n onSelectionChangeRef.current?.(name, value),\n );\n onReadyRef.current?.(instance);\n return () => {\n offSelection();\n instance.destroy();\n instanceRef.current = null;\n instanceSpecRef.current = null;\n };\n }, [options.store]);\n\n useEffect(() => {\n const instance = instanceRef.current;\n if (!instance) return;\n if (instanceSpecRef.current === spec) return;\n instance.update(spec);\n instanceSpecRef.current = spec;\n onReadyRef.current?.(instance);\n }, [spec]);\n\n return ref;\n}\n","import {\n createElement,\n forwardRef,\n useCallback,\n type CSSProperties,\n type HTMLAttributes,\n type MutableRefObject,\n type ReactElement,\n} from 'react';\nimport type { DashboardSpec } from 'graphein';\nimport { useDashboard, type UseDashboardOptions } from './useDashboard';\n\nexport interface DashboardProps extends UseDashboardOptions, Omit<HTMLAttributes<HTMLDivElement>, 'children'> {\n /** The Graphein dashboard spec to render. */\n spec: DashboardSpec;\n}\n\nconst FILL: CSSProperties = { width: '100%' };\n\n/**\n * Declarative React wrapper around the Graphein dashboard runtime.\n *\n * Renders a container `<div>` (full width by default; height comes from the\n * dashboard's grid rows) and draws `spec` into it. Pass a new `spec` to update;\n * unmounting tears it down. Auto-wires cross-interaction unless `spec` opts out.\n *\n * ```tsx\n * <Dashboard spec={{ type: 'dashboard', data, views, interactions: 'auto' }} />\n * ```\n */\nexport const Dashboard = forwardRef<HTMLDivElement, DashboardProps>(function Dashboard({\n spec,\n onReady,\n store,\n onSelectionChange,\n inspect,\n style,\n ...divProps\n}, forwardedRef): ReactElement {\n const ref = useDashboard<HTMLDivElement>(spec, { onReady, store, onSelectionChange, inspect });\n const attachRef = useCallback((node: HTMLDivElement | null) => {\n ref.current = node;\n if (typeof forwardedRef === 'function') forwardedRef(node);\n else if (forwardedRef) (forwardedRef as MutableRefObject<HTMLDivElement | null>).current = node;\n }, [forwardedRef, ref]);\n return createElement('div', {\n ...divProps,\n ref: attachRef,\n style: style ? { ...FILL, ...style } : FILL,\n });\n});\n","import { useEffect, useRef, type RefObject } from 'react';\nimport {\n renderDashboard,\n type DashboardInstance,\n type DashboardSpec,\n type SelectionChangeListener,\n type SelectionStore,\n} from 'graphein';\n\nexport interface UseDashboardOptions {\n /** Called with the live instance after each mount and update. */\n onReady?: (instance: DashboardInstance) => void;\n /**\n * A shared selection bus. Omit to let the dashboard own one internally; pass\n * one (stable across renders) to drive it from React via {@link useSelection}\n * or to link it with standalone charts. Changing its identity remounts.\n */\n store?: SelectionStore;\n /** Called whenever any selection in the dashboard changes. */\n onSelectionChange?: SelectionChangeListener;\n /**\n * Publish each view's config (and the dashboard's) to `data-graphein-spec` DOM\n * attributes and re-render on external edits. Defaults to `true`; set `false` to\n * opt out for the whole dashboard. Read once at mount.\n */\n inspect?: boolean;\n}\n\n/**\n * Mount an Graphein dashboard into a DOM node and keep it in sync with `spec`.\n *\n * Mirrors {@link useChart}: created on mount, updated in place when `spec`\n * changes identity, torn down on unmount, StrictMode-safe.\n *\n * ```tsx\n * const ref = useDashboard(dashboardSpec);\n * return <div ref={ref} style={{ width: '100%' }} />;\n * ```\n */\nexport function useDashboard<T extends HTMLElement = HTMLDivElement>(\n spec: DashboardSpec,\n options: UseDashboardOptions = {},\n): RefObject<T | null> {\n const ref = useRef<T | null>(null);\n const instanceRef = useRef<DashboardInstance | null>(null);\n const specRef = useRef(spec);\n specRef.current = spec;\n const onReadyRef = useRef(options.onReady);\n onReadyRef.current = options.onReady;\n const onSelectionChangeRef = useRef(options.onSelectionChange);\n onSelectionChangeRef.current = options.onSelectionChange;\n const storeRef = useRef(options.store);\n storeRef.current = options.store;\n const inspectRef = useRef(options.inspect);\n inspectRef.current = options.inspect;\n const instanceSpecRef = useRef<DashboardSpec | null>(null);\n\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n const mountedSpec = specRef.current;\n const instance = renderDashboard(el, mountedSpec, {\n store: storeRef.current,\n inspect: inspectRef.current,\n });\n instanceRef.current = instance;\n instanceSpecRef.current = mountedSpec;\n const offSelection = instance.on('selectionchange', (name, value) =>\n onSelectionChangeRef.current?.(name, value),\n );\n onReadyRef.current?.(instance);\n return () => {\n offSelection();\n instance.destroy();\n instanceRef.current = null;\n instanceSpecRef.current = null;\n };\n }, [options.store]);\n\n useEffect(() => {\n const instance = instanceRef.current;\n if (!instance) return;\n if (instanceSpecRef.current === spec) return;\n instance.update(spec);\n instanceSpecRef.current = spec;\n onReadyRef.current?.(instance);\n }, [spec]);\n\n return ref;\n}\n","import { useCallback, useSyncExternalStore } from 'react';\nimport type { SelectionStore, SelectionValue } from 'graphein';\n\n/** Anything that exposes a selection bus: a store, or a chart/dashboard instance. */\nexport type SelectionSource =\n | SelectionStore\n | { store: SelectionStore }\n | null\n | undefined;\n\nfunction resolveStore(source: SelectionSource): SelectionStore | null {\n if (!source) return null;\n return 'store' in source ? source.store : source;\n}\n\n/**\n * Read and write a named selection as React state.\n *\n * Pass a shared {@link SelectionStore} (or a chart/dashboard instance, which\n * exposes one as `.store`) plus the param name. Returns the current value and a\n * setter that publishes to the bus — driving cross-highlight / cross-filter\n * across every visual bound to that store.\n *\n * ```tsx\n * const store = useMemo(() => createSelectionStore(), []);\n * const [region, setRegion] = useSelection(store, 'region');\n * // …\n * <Dashboard spec={spec} store={store} />\n * <button onClick={() => setRegion({ kind: 'set', field: 'region', values: ['West'] })}>\n * West\n * </button>\n * ```\n */\nexport function useSelection(\n source: SelectionSource,\n name: string,\n): [SelectionValue | null, (value: SelectionValue | null) => void] {\n const store = resolveStore(source);\n\n const subscribe = useCallback((notify: () => void) => {\n if (!store) return () => {};\n return store.subscribe((changed) => {\n if (changed === name) notify();\n });\n }, [store, name]);\n\n const getSnapshot = useCallback(() => store?.get(name) ?? null, [store, name]);\n const value = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n\n const set = useCallback(\n (next: SelectionValue | null) => {\n store?.set(name, next ?? null);\n },\n [store, name],\n );\n\n return [value, set];\n}\n","/**\n * @graphein/react — a thin React wrapper around the `graphein` runtime.\n *\n * `<Chart spec={…} />` for a single chart or `<Dashboard spec={…} />` for a\n * cross-interacting page; the `useChart` / `useDashboard` hooks give headless\n * control over your own container, and `useSelection` reads/writes a selection\n * as React state. Core spec/instance types are re-exported for convenience.\n */\nexport { Chart, type ChartProps } from './Chart';\nexport { useChart, type UseChartOptions } from './useChart';\nexport { Dashboard, type DashboardProps } from './Dashboard';\nexport { useDashboard, type UseDashboardOptions } from './useDashboard';\nexport { useSelection, type SelectionSource } from './useSelection';\nexport { createSelectionStore } from 'graphein';\nexport type {\n ChartSpec,\n ChartInstance,\n DashboardSpec,\n DashboardInstance,\n SelectionStore,\n SelectionValue,\n SelectionChangeListener,\n} from 'graphein';\n\nexport const VERSION = '0.21.0';\n"],"mappings":"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","names":["Chart","createElement","forwardRef","useCallback","useEffect","useRef","FILL","forwardRef","Dashboard","useCallback","createElement","useCallback"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@graphein/react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Graphein React wrapper — declarative <Chart spec={...} /> for the Graphein visualization engine.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -46,17 +46,18 @@
|
|
|
46
46
|
"access": "public"
|
|
47
47
|
},
|
|
48
48
|
"scripts": {
|
|
49
|
-
"
|
|
49
|
+
"sync:version": "node ../core/scripts/sync-version.mjs .",
|
|
50
|
+
"build": "npm run sync:version && tsup",
|
|
50
51
|
"dev": "tsup --watch",
|
|
51
52
|
"test": "vitest run",
|
|
52
53
|
"typecheck": "tsc --noEmit",
|
|
53
|
-
"prepack": "tsup"
|
|
54
|
+
"prepack": "npm run sync:version && tsup"
|
|
54
55
|
},
|
|
55
56
|
"peerDependencies": {
|
|
56
57
|
"react": ">=18"
|
|
57
58
|
},
|
|
58
59
|
"dependencies": {
|
|
59
|
-
"graphein": "^0.
|
|
60
|
+
"graphein": "^0.21.0"
|
|
60
61
|
},
|
|
61
62
|
"devDependencies": {
|
|
62
63
|
"@types/react": "^19.2.17",
|