@omiron33/omi-neuron-web 0.2.17 → 0.2.19
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 +32 -1
- package/dist/{NeuronWeb-CZgKU1-X.d.ts → NeuronWeb-CnamAVi_.d.ts} +24 -3
- package/dist/{NeuronWeb-JVrxQksC.d.cts → NeuronWeb-DkNLfI1I.d.cts} +24 -3
- package/dist/{chunk-CKFZJZLN.cjs → chunk-OUO3CKBM.cjs} +120 -12
- package/dist/chunk-OUO3CKBM.cjs.map +1 -0
- package/dist/{chunk-IGDFH3IX.js → chunk-YWCTYBMF.js} +121 -13
- package/dist/chunk-YWCTYBMF.js.map +1 -0
- package/dist/index.cjs +3 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/visualization/index.cjs +6 -6
- package/dist/visualization/index.d.cts +2 -2
- package/dist/visualization/index.d.ts +2 -2
- package/dist/visualization/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-CKFZJZLN.cjs.map +0 -1
- package/dist/chunk-IGDFH3IX.js.map +0 -1
package/README.md
CHANGED
|
@@ -686,7 +686,7 @@ export interface NeuronWebProps {
|
|
|
686
686
|
|
|
687
687
|
Props currently used inside `NeuronWeb` (others are reserved for future use):
|
|
688
688
|
|
|
689
|
-
- Used: `graphData`, `className`, `style`, `fullHeight`, `isFullScreen`, `isLoading`, `error`, `renderEmptyState`, `renderLoadingState`, `ariaLabel`, `theme`, `layout`, `renderNodeHover`, `renderNodeDetail`, `hoverCard`, `clickCard`, `clickZoom`, `cardsMode`, `onNodeHover`, `onNodeClick`, `onNodeDoubleClick`, `onNodeFocused`, `onBackgroundClick`, `performanceMode`, `focusNodeSlug`, `onFocusConsumed`, `visibleNodeSlugs`.
|
|
689
|
+
- Used: `graphData`, `className`, `style`, `fullHeight`, `isFullScreen`, `isLoading`, `error`, `renderEmptyState`, `renderLoadingState`, `ariaLabel`, `theme`, `layout`, `renderNodeHover`, `renderNodeDetail`, `hoverCard`, `clickCard`, `clickZoom`, `cardsMode`, `onNodeHover`, `onNodeClick`, `onNodeDoubleClick`, `onNodeFocused`, `onBackgroundClick`, `performanceMode`, `focusNodeSlug`, `onFocusConsumed`, `visibleNodeSlugs`, `studyPathRequest`, `onStudyPathComplete`.
|
|
690
690
|
- Used: `cameraFit` (auto-fit bounds to a viewport fraction).
|
|
691
691
|
- Reserved (declared but not used in the component yet): `selectedNode`, `onEdgeClick`, `onCameraChange`, `studyPathRequest`, `onStudyPathComplete`, `domainColors`, `graphData.storyBeats`.
|
|
692
692
|
|
|
@@ -847,6 +847,37 @@ Semantics:
|
|
|
847
847
|
<NeuronWeb graphData={graphData} visibleNodeSlugs={[]} />;
|
|
848
848
|
```
|
|
849
849
|
|
|
850
|
+
### Study path playback (follow the path between nodes)
|
|
851
|
+
|
|
852
|
+
Use `studyPathRequest` to step through an ordered list of nodes. Each step:
|
|
853
|
+
- selects the node
|
|
854
|
+
- tweens the camera to the node (if `clickZoom.enabled`)
|
|
855
|
+
- highlights the edge between the current and next step
|
|
856
|
+
|
|
857
|
+
```tsx
|
|
858
|
+
<NeuronWeb
|
|
859
|
+
graphData={graphData}
|
|
860
|
+
studyPathRequest={{
|
|
861
|
+
steps: [
|
|
862
|
+
{ nodeSlug: 'uap', label: 'Start' },
|
|
863
|
+
{ nodeSlug: 'neph', label: 'Next' },
|
|
864
|
+
{ nodeSlug: 'jude6', label: 'Finish' },
|
|
865
|
+
],
|
|
866
|
+
stepDurationMs: 4200,
|
|
867
|
+
}}
|
|
868
|
+
onStudyPathComplete={() => console.log('study path done')}
|
|
869
|
+
/>
|
|
870
|
+
```
|
|
871
|
+
|
|
872
|
+
Fallback form (two-step path):
|
|
873
|
+
|
|
874
|
+
```tsx
|
|
875
|
+
<NeuronWeb
|
|
876
|
+
graphData={graphData}
|
|
877
|
+
studyPathRequest={{ fromNodeId: 'uap', toNodeId: 'neph' }}
|
|
878
|
+
/>
|
|
879
|
+
```
|
|
880
|
+
|
|
850
881
|
### Click cards + click zoom
|
|
851
882
|
|
|
852
883
|
Enable a persistent card on click and optional zoom-to-node behavior:
|
|
@@ -6,9 +6,30 @@ interface NeuronStoryBeat {
|
|
|
6
6
|
label: string;
|
|
7
7
|
nodeIds: string[];
|
|
8
8
|
}
|
|
9
|
+
interface StudyPathStep {
|
|
10
|
+
nodeSlug?: string;
|
|
11
|
+
nodeId?: string;
|
|
12
|
+
label?: string;
|
|
13
|
+
summary?: string;
|
|
14
|
+
}
|
|
9
15
|
interface StudyPathRequest {
|
|
10
|
-
|
|
11
|
-
|
|
16
|
+
/**
|
|
17
|
+
* Ordered steps to follow (slugs or ids). When provided, this takes precedence.
|
|
18
|
+
*/
|
|
19
|
+
steps?: StudyPathStep[];
|
|
20
|
+
/**
|
|
21
|
+
* Optional label for the study path (consumer UI usage).
|
|
22
|
+
*/
|
|
23
|
+
label?: string;
|
|
24
|
+
/**
|
|
25
|
+
* Time to hold each step before advancing (ms). Defaults to 4200.
|
|
26
|
+
*/
|
|
27
|
+
stepDurationMs?: number;
|
|
28
|
+
/**
|
|
29
|
+
* Minimal fallback when steps are not provided.
|
|
30
|
+
*/
|
|
31
|
+
fromNodeId?: string;
|
|
32
|
+
toNodeId?: string;
|
|
12
33
|
}
|
|
13
34
|
interface NeuronWebTheme {
|
|
14
35
|
colors: {
|
|
@@ -137,6 +158,6 @@ interface NeuronWebProps {
|
|
|
137
158
|
ariaLabel?: string;
|
|
138
159
|
}
|
|
139
160
|
|
|
140
|
-
declare function NeuronWeb({ graphData, className, style, fullHeight, isFullScreen, isLoading, error, focusNodeSlug, onFocusConsumed, visibleNodeSlugs, renderEmptyState, renderLoadingState, ariaLabel, theme, layout, cameraFit, cardsMode, clickCard, clickZoom, renderNodeHover, renderNodeDetail, hoverCard, onNodeHover, onNodeClick, onNodeDoubleClick, onNodeFocused, onBackgroundClick, performanceMode, }: NeuronWebProps): React__default.ReactElement;
|
|
161
|
+
declare function NeuronWeb({ graphData, className, style, fullHeight, isFullScreen, isLoading, error, focusNodeSlug, onFocusConsumed, visibleNodeSlugs, renderEmptyState, renderLoadingState, ariaLabel, theme, layout, cameraFit, cardsMode, clickCard, clickZoom, studyPathRequest, onStudyPathComplete, renderNodeHover, renderNodeDetail, hoverCard, onNodeHover, onNodeClick, onNodeDoubleClick, onNodeFocused, onBackgroundClick, performanceMode, }: NeuronWebProps): React__default.ReactElement;
|
|
141
162
|
|
|
142
163
|
export { type CameraFitOptions as C, type HoverCardOptions as H, type NeuronWebTheme as N, type NeuronWebThemeOverride as a, type NeuronLayoutOptions as b, NeuronWeb as c, type NeuronWebProps as d, type NeuronLayoutMode as e, type ClickCardOptions as f, type ClickZoomOptions as g, type CardsMode as h };
|
|
@@ -6,9 +6,30 @@ interface NeuronStoryBeat {
|
|
|
6
6
|
label: string;
|
|
7
7
|
nodeIds: string[];
|
|
8
8
|
}
|
|
9
|
+
interface StudyPathStep {
|
|
10
|
+
nodeSlug?: string;
|
|
11
|
+
nodeId?: string;
|
|
12
|
+
label?: string;
|
|
13
|
+
summary?: string;
|
|
14
|
+
}
|
|
9
15
|
interface StudyPathRequest {
|
|
10
|
-
|
|
11
|
-
|
|
16
|
+
/**
|
|
17
|
+
* Ordered steps to follow (slugs or ids). When provided, this takes precedence.
|
|
18
|
+
*/
|
|
19
|
+
steps?: StudyPathStep[];
|
|
20
|
+
/**
|
|
21
|
+
* Optional label for the study path (consumer UI usage).
|
|
22
|
+
*/
|
|
23
|
+
label?: string;
|
|
24
|
+
/**
|
|
25
|
+
* Time to hold each step before advancing (ms). Defaults to 4200.
|
|
26
|
+
*/
|
|
27
|
+
stepDurationMs?: number;
|
|
28
|
+
/**
|
|
29
|
+
* Minimal fallback when steps are not provided.
|
|
30
|
+
*/
|
|
31
|
+
fromNodeId?: string;
|
|
32
|
+
toNodeId?: string;
|
|
12
33
|
}
|
|
13
34
|
interface NeuronWebTheme {
|
|
14
35
|
colors: {
|
|
@@ -137,6 +158,6 @@ interface NeuronWebProps {
|
|
|
137
158
|
ariaLabel?: string;
|
|
138
159
|
}
|
|
139
160
|
|
|
140
|
-
declare function NeuronWeb({ graphData, className, style, fullHeight, isFullScreen, isLoading, error, focusNodeSlug, onFocusConsumed, visibleNodeSlugs, renderEmptyState, renderLoadingState, ariaLabel, theme, layout, cameraFit, cardsMode, clickCard, clickZoom, renderNodeHover, renderNodeDetail, hoverCard, onNodeHover, onNodeClick, onNodeDoubleClick, onNodeFocused, onBackgroundClick, performanceMode, }: NeuronWebProps): React__default.ReactElement;
|
|
161
|
+
declare function NeuronWeb({ graphData, className, style, fullHeight, isFullScreen, isLoading, error, focusNodeSlug, onFocusConsumed, visibleNodeSlugs, renderEmptyState, renderLoadingState, ariaLabel, theme, layout, cameraFit, cardsMode, clickCard, clickZoom, studyPathRequest, onStudyPathComplete, renderNodeHover, renderNodeDetail, hoverCard, onNodeHover, onNodeClick, onNodeDoubleClick, onNodeFocused, onBackgroundClick, performanceMode, }: NeuronWebProps): React__default.ReactElement;
|
|
141
162
|
|
|
142
163
|
export { type CameraFitOptions as C, type HoverCardOptions as H, type NeuronWebTheme as N, type NeuronWebThemeOverride as a, type NeuronLayoutOptions as b, NeuronWeb as c, type NeuronWebProps as d, type NeuronLayoutMode as e, type ClickCardOptions as f, type ClickZoomOptions as g, type CardsMode as h };
|
|
@@ -1061,6 +1061,8 @@ function NeuronWeb({
|
|
|
1061
1061
|
cardsMode,
|
|
1062
1062
|
clickCard,
|
|
1063
1063
|
clickZoom,
|
|
1064
|
+
studyPathRequest,
|
|
1065
|
+
onStudyPathComplete,
|
|
1064
1066
|
renderNodeHover,
|
|
1065
1067
|
renderNodeDetail,
|
|
1066
1068
|
hoverCard,
|
|
@@ -1076,9 +1078,12 @@ function NeuronWeb({
|
|
|
1076
1078
|
const clickCardRef = react.useRef(null);
|
|
1077
1079
|
const [hoveredNodeId, setHoveredNodeId] = react.useState(null);
|
|
1078
1080
|
const [selectedNodeId, setSelectedNodeId] = react.useState(null);
|
|
1081
|
+
const [studyPathPlayer, setStudyPathPlayer] = react.useState(null);
|
|
1079
1082
|
const fitStateRef = react.useRef({ hasFit: false, signature: "" });
|
|
1080
1083
|
const firstFilterChangeRef = react.useRef(true);
|
|
1081
1084
|
const [filterTransitioning, setFilterTransitioning] = react.useState(false);
|
|
1085
|
+
const pathEdgeIdsRef = react.useRef([]);
|
|
1086
|
+
const focusEdgesRef = react.useRef(null);
|
|
1082
1087
|
const filteredGraphData = react.useMemo(() => {
|
|
1083
1088
|
if (visibleNodeSlugs === null || visibleNodeSlugs === void 0) {
|
|
1084
1089
|
return graphData;
|
|
@@ -1250,6 +1255,43 @@ function NeuronWeb({
|
|
|
1250
1255
|
});
|
|
1251
1256
|
return map;
|
|
1252
1257
|
}, [workingGraph.edges]);
|
|
1258
|
+
const applyFocusEdges = react.useCallback(
|
|
1259
|
+
(edgeIds) => {
|
|
1260
|
+
if (!edgeRenderer) return;
|
|
1261
|
+
focusEdgesRef.current = edgeIds;
|
|
1262
|
+
const merged = new Set(edgeIds ?? []);
|
|
1263
|
+
pathEdgeIdsRef.current.forEach((id) => merged.add(id));
|
|
1264
|
+
edgeRenderer.setFocusEdges(merged.size ? Array.from(merged) : null);
|
|
1265
|
+
},
|
|
1266
|
+
[edgeRenderer]
|
|
1267
|
+
);
|
|
1268
|
+
const resolvedStudyPathSteps = react.useMemo(() => {
|
|
1269
|
+
if (!studyPathRequest) return null;
|
|
1270
|
+
if (studyPathRequest.steps && studyPathRequest.steps.length) {
|
|
1271
|
+
return studyPathRequest.steps;
|
|
1272
|
+
}
|
|
1273
|
+
if (studyPathRequest.fromNodeId && studyPathRequest.toNodeId) {
|
|
1274
|
+
return [
|
|
1275
|
+
{ nodeId: studyPathRequest.fromNodeId },
|
|
1276
|
+
{ nodeId: studyPathRequest.toNodeId }
|
|
1277
|
+
];
|
|
1278
|
+
}
|
|
1279
|
+
return null;
|
|
1280
|
+
}, [studyPathRequest]);
|
|
1281
|
+
react.useEffect(() => {
|
|
1282
|
+
if (!resolvedStudyPathSteps || resolvedStudyPathSteps.length === 0) {
|
|
1283
|
+
setStudyPathPlayer(null);
|
|
1284
|
+
pathEdgeIdsRef.current = [];
|
|
1285
|
+
applyFocusEdges(focusEdgesRef.current);
|
|
1286
|
+
return;
|
|
1287
|
+
}
|
|
1288
|
+
setStudyPathPlayer({
|
|
1289
|
+
steps: resolvedStudyPathSteps,
|
|
1290
|
+
index: 0,
|
|
1291
|
+
playing: true,
|
|
1292
|
+
stepDurationMs: studyPathRequest?.stepDurationMs ?? 4200
|
|
1293
|
+
});
|
|
1294
|
+
}, [resolvedStudyPathSteps, studyPathRequest?.stepDurationMs, applyFocusEdges]);
|
|
1253
1295
|
const nodeByIdentifier = react.useMemo(() => {
|
|
1254
1296
|
const map = /* @__PURE__ */ new Map();
|
|
1255
1297
|
resolvedNodes.forEach((node) => {
|
|
@@ -1266,6 +1308,70 @@ function NeuronWeb({
|
|
|
1266
1308
|
const clickCardOffset = clickCard?.offset ?? [24, 24];
|
|
1267
1309
|
const clickCardWidth = clickCard?.width ?? 320;
|
|
1268
1310
|
const clickZoomEnabled = clickZoom?.enabled ?? true;
|
|
1311
|
+
react.useEffect(() => {
|
|
1312
|
+
if (!studyPathPlayer) return;
|
|
1313
|
+
const step = studyPathPlayer.steps[studyPathPlayer.index];
|
|
1314
|
+
const stepKey = step?.nodeSlug ?? step?.nodeId ?? null;
|
|
1315
|
+
const node = stepKey ? nodeByIdentifier.get(stepKey) ?? null : null;
|
|
1316
|
+
if (node && nodeRenderer && edgeRenderer) {
|
|
1317
|
+
setSelectedNodeId(node.id);
|
|
1318
|
+
nodeRenderer.setSelectedNode(node.id);
|
|
1319
|
+
nodeRenderer.pulseNode(node.id);
|
|
1320
|
+
if (clickZoomEnabled) {
|
|
1321
|
+
const nodePosition = nodeRenderer.getNodePosition(node.id);
|
|
1322
|
+
if (nodePosition) {
|
|
1323
|
+
animationController?.focusOnNode(nodePosition, () => {
|
|
1324
|
+
if (onNodeFocused) onNodeFocused(node);
|
|
1325
|
+
});
|
|
1326
|
+
}
|
|
1327
|
+
}
|
|
1328
|
+
const slug = node.slug;
|
|
1329
|
+
applyFocusEdges(slug ? edgesBySlug.get(slug) ?? [] : []);
|
|
1330
|
+
}
|
|
1331
|
+
const nextStep = studyPathPlayer.index < studyPathPlayer.steps.length - 1 ? studyPathPlayer.steps[studyPathPlayer.index + 1] : null;
|
|
1332
|
+
const currentSlug = node?.slug ?? (step?.nodeSlug ?? null);
|
|
1333
|
+
const nextKey = nextStep?.nodeSlug ?? nextStep?.nodeId ?? null;
|
|
1334
|
+
const nextNode = nextKey ? nodeByIdentifier.get(nextKey) ?? null : null;
|
|
1335
|
+
const nextSlug = nextNode?.slug ?? (nextStep?.nodeSlug ?? null);
|
|
1336
|
+
if (currentSlug && nextSlug) {
|
|
1337
|
+
pathEdgeIdsRef.current = workingGraph.edges.filter(
|
|
1338
|
+
(edge) => edge.from === currentSlug && edge.to === nextSlug || edge.to === currentSlug && edge.from === nextSlug
|
|
1339
|
+
).map((edge) => edge.id);
|
|
1340
|
+
} else {
|
|
1341
|
+
pathEdgeIdsRef.current = [];
|
|
1342
|
+
}
|
|
1343
|
+
applyFocusEdges(focusEdgesRef.current);
|
|
1344
|
+
}, [
|
|
1345
|
+
studyPathPlayer,
|
|
1346
|
+
nodeByIdentifier,
|
|
1347
|
+
nodeRenderer,
|
|
1348
|
+
edgeRenderer,
|
|
1349
|
+
edgesBySlug,
|
|
1350
|
+
workingGraph.edges,
|
|
1351
|
+
animationController,
|
|
1352
|
+
clickZoomEnabled,
|
|
1353
|
+
onNodeFocused,
|
|
1354
|
+
applyFocusEdges
|
|
1355
|
+
]);
|
|
1356
|
+
react.useEffect(() => {
|
|
1357
|
+
if (!studyPathPlayer || !studyPathPlayer.playing) return;
|
|
1358
|
+
const timer = window.setTimeout(() => {
|
|
1359
|
+
setStudyPathPlayer((prev) => {
|
|
1360
|
+
if (!prev) return prev;
|
|
1361
|
+
if (prev.index >= prev.steps.length - 1) {
|
|
1362
|
+
if (onStudyPathComplete) onStudyPathComplete();
|
|
1363
|
+
return { ...prev, playing: false };
|
|
1364
|
+
}
|
|
1365
|
+
return { ...prev, index: prev.index + 1 };
|
|
1366
|
+
});
|
|
1367
|
+
}, studyPathPlayer.stepDurationMs);
|
|
1368
|
+
return () => window.clearTimeout(timer);
|
|
1369
|
+
}, [studyPathPlayer, onStudyPathComplete]);
|
|
1370
|
+
react.useEffect(() => {
|
|
1371
|
+
if (!studyPathPlayer || studyPathPlayer.playing) return;
|
|
1372
|
+
pathEdgeIdsRef.current = [];
|
|
1373
|
+
applyFocusEdges(focusEdgesRef.current);
|
|
1374
|
+
}, [studyPathPlayer, applyFocusEdges]);
|
|
1269
1375
|
react.useEffect(() => {
|
|
1270
1376
|
if (!sceneManager || !nodeRenderer || !edgeRenderer) return;
|
|
1271
1377
|
nodeRenderer.renderNodes(resolvedNodes);
|
|
@@ -1442,9 +1548,9 @@ function NeuronWeb({
|
|
|
1442
1548
|
if (selectedNodeId && !nodeMap.has(selectedNodeId)) {
|
|
1443
1549
|
setSelectedNodeId(null);
|
|
1444
1550
|
nodeRenderer.setSelectedNode(null);
|
|
1445
|
-
|
|
1551
|
+
applyFocusEdges(null);
|
|
1446
1552
|
}
|
|
1447
|
-
}, [selectedNodeId, nodeMap, nodeRenderer, edgeRenderer]);
|
|
1553
|
+
}, [selectedNodeId, nodeMap, nodeRenderer, edgeRenderer, applyFocusEdges]);
|
|
1448
1554
|
react.useEffect(() => {
|
|
1449
1555
|
if (!focusNodeSlug || !nodeRenderer || !edgeRenderer) return;
|
|
1450
1556
|
const node = nodeByIdentifier.get(focusNodeSlug);
|
|
@@ -1455,7 +1561,7 @@ function NeuronWeb({
|
|
|
1455
1561
|
setSelectedNodeId(node.id);
|
|
1456
1562
|
nodeRenderer.setSelectedNode(node.id);
|
|
1457
1563
|
nodeRenderer.pulseNode(node.id);
|
|
1458
|
-
|
|
1564
|
+
applyFocusEdges(node.slug ? edgesBySlug.get(node.slug) ?? [] : []);
|
|
1459
1565
|
if (clickZoomEnabled) {
|
|
1460
1566
|
const nodePosition = nodeRenderer.getNodePosition(node.id);
|
|
1461
1567
|
if (nodePosition) {
|
|
@@ -1478,7 +1584,8 @@ function NeuronWeb({
|
|
|
1478
1584
|
clickZoomEnabled,
|
|
1479
1585
|
animationController,
|
|
1480
1586
|
onNodeFocused,
|
|
1481
|
-
onFocusConsumed
|
|
1587
|
+
onFocusConsumed,
|
|
1588
|
+
applyFocusEdges
|
|
1482
1589
|
]);
|
|
1483
1590
|
react.useEffect(() => {
|
|
1484
1591
|
if (!interactionManager || !nodeRenderer || !edgeRenderer) return;
|
|
@@ -1488,13 +1595,13 @@ function NeuronWeb({
|
|
|
1488
1595
|
nodeRenderer.setHoveredNode(nodeId);
|
|
1489
1596
|
if (nodeId) {
|
|
1490
1597
|
const slug = nodeSlugById.get(nodeId);
|
|
1491
|
-
|
|
1598
|
+
applyFocusEdges(slug ? edgesBySlug.get(slug) ?? [] : []);
|
|
1492
1599
|
} else {
|
|
1493
1600
|
const selectedSlug = selectedNodeId ? nodeSlugById.get(selectedNodeId) : null;
|
|
1494
1601
|
if (selectedSlug) {
|
|
1495
|
-
|
|
1602
|
+
applyFocusEdges(edgesBySlug.get(selectedSlug) ?? []);
|
|
1496
1603
|
} else {
|
|
1497
|
-
|
|
1604
|
+
applyFocusEdges(null);
|
|
1498
1605
|
}
|
|
1499
1606
|
}
|
|
1500
1607
|
if (onNodeHover) {
|
|
@@ -1514,7 +1621,7 @@ function NeuronWeb({
|
|
|
1514
1621
|
}
|
|
1515
1622
|
}
|
|
1516
1623
|
const slug = nodeSlugById.get(node.id);
|
|
1517
|
-
|
|
1624
|
+
applyFocusEdges(slug ? edgesBySlug.get(slug) ?? [] : []);
|
|
1518
1625
|
if (onNodeClick) {
|
|
1519
1626
|
onNodeClick(node);
|
|
1520
1627
|
}
|
|
@@ -1534,7 +1641,7 @@ function NeuronWeb({
|
|
|
1534
1641
|
setSelectedNodeId(null);
|
|
1535
1642
|
nodeRenderer.setSelectedNode(null);
|
|
1536
1643
|
if (!hoveredNodeId) {
|
|
1537
|
-
|
|
1644
|
+
applyFocusEdges(null);
|
|
1538
1645
|
}
|
|
1539
1646
|
if (onBackgroundClick) onBackgroundClick();
|
|
1540
1647
|
};
|
|
@@ -1552,7 +1659,8 @@ function NeuronWeb({
|
|
|
1552
1659
|
onNodeClick,
|
|
1553
1660
|
onNodeDoubleClick,
|
|
1554
1661
|
onNodeFocused,
|
|
1555
|
-
onBackgroundClick
|
|
1662
|
+
onBackgroundClick,
|
|
1663
|
+
applyFocusEdges
|
|
1556
1664
|
]);
|
|
1557
1665
|
react.useEffect(() => {
|
|
1558
1666
|
if (!sceneManager || !interactionManager) return;
|
|
@@ -1753,5 +1861,5 @@ exports.NeuronWeb = NeuronWeb;
|
|
|
1753
1861
|
exports.SceneManager = SceneManager;
|
|
1754
1862
|
exports.ThemeEngine = ThemeEngine;
|
|
1755
1863
|
exports.applyFuzzyLayout = applyFuzzyLayout;
|
|
1756
|
-
//# sourceMappingURL=chunk-
|
|
1757
|
-
//# sourceMappingURL=chunk-
|
|
1864
|
+
//# sourceMappingURL=chunk-OUO3CKBM.cjs.map
|
|
1865
|
+
//# sourceMappingURL=chunk-OUO3CKBM.cjs.map
|