@neo4j-nvl/react 0.3.8-e5dee203 → 0.3.9-381e4a0c

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/CHANGELOG.md CHANGED
@@ -2,6 +2,30 @@
2
2
 
3
3
  All notable changes to NVL will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
4
4
 
5
+ ## [0.3.9] - 2025-07-23
6
+
7
+ The 0.3.9 release contains several fixes for NVL's interaction handler and adds a new method to NVL to directly extract image data from an NVL instance:
8
+
9
+ ### Added
10
+
11
+ * new export method for image data url called `.getImageDataUrl`
12
+ * new callback triggered when NVL is fully initialized called `onInitialization`.
13
+
14
+ ### Changed
15
+
16
+ * updated license agreement in `LICENSE.txt`.
17
+ * prevent zoom interaction handler to zoom in NVL when ctrl or meta key is pressed.
18
+ * improve handling of leaving NVL container while performing selection using the lasso and box interaction handlers.
19
+
20
+ ### Fixed
21
+
22
+ * fix error on onDragEnd callback.
23
+ * fix race condition when hovering over an element that is being dismissed.
24
+ * fix nodes moving on clicks.
25
+ * prevent crash when providing non-existent node ids to `.setNodePositions` method.
26
+ * fix slow zoom speed for touchpads in zoom interaction handler.
27
+ * Ensure interaction handlers in react component waits for NVL to be initialised first.
28
+
5
29
  ## [0.3.8] - 2025-03-18
6
30
 
7
31
  This release contains a fix for the [NVL result transformer](https://neo4j.com/docs/api/nvl/current/functions/_neo4j_nvl_base.nvlResultTransformer.html).
@@ -23,7 +23,7 @@ export const BasicNvlWrapper = memo(forwardRef(({ nodes, rels, layout, layoutOpt
23
23
  if (nvlRef.current === null) {
24
24
  return null;
25
25
  }
26
- // @ts-ignore suppress the type casting error on spreading
26
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call
27
27
  return nvlRef.current[method](...args);
28
28
  }
29
29
  }),
package/lib/index.d.ts CHANGED
@@ -2,5 +2,7 @@ import { BasicNvlWrapper } from './basic-wrapper/BasicNvlWrapper';
2
2
  import type { BasicReactWrapperProps } from './basic-wrapper/BasicNvlWrapper';
3
3
  import { InteractiveNvlWrapper } from './interactive-nvl-wrapper/InteractiveNvlWrapper';
4
4
  import type { InteractionOptions, InteractiveNvlWrapperProps, MouseEvent, MouseEventCallbacks } from './interactive-nvl-wrapper/types';
5
- export { BasicNvlWrapper, InteractiveNvlWrapper };
6
- export type { MouseEventCallbacks, MouseEvent, BasicReactWrapperProps, InteractionOptions, InteractiveNvlWrapperProps };
5
+ import type { StaticPictureWrapperProps } from './static-picture-wrapper/StaticPictureWrapper';
6
+ import { StaticPictureWrapper } from './static-picture-wrapper/StaticPictureWrapper';
7
+ export { BasicNvlWrapper, InteractiveNvlWrapper, StaticPictureWrapper };
8
+ export type { MouseEventCallbacks, MouseEvent, BasicReactWrapperProps, InteractionOptions, InteractiveNvlWrapperProps, StaticPictureWrapperProps };
package/lib/index.js CHANGED
@@ -1,3 +1,4 @@
1
1
  import { BasicNvlWrapper } from './basic-wrapper/BasicNvlWrapper';
2
2
  import { InteractiveNvlWrapper } from './interactive-nvl-wrapper/InteractiveNvlWrapper';
3
- export { BasicNvlWrapper, InteractiveNvlWrapper };
3
+ import { StaticPictureWrapper } from './static-picture-wrapper/StaticPictureWrapper';
4
+ export { BasicNvlWrapper, InteractiveNvlWrapper, StaticPictureWrapper };
@@ -0,0 +1,22 @@
1
+ import type { Node, NvlOptions, Relationship } from '@neo4j-nvl/base';
2
+ /**
3
+ * The properties that can be passed to the StaticPictureWrapper component.
4
+ */
5
+ export type StaticPictureWrapperProps = {
6
+ /** The nodes to be displayed in the graph. */
7
+ nodes: Node[];
8
+ /** The relationships to be displayed in the graph. */
9
+ rels: Relationship[];
10
+ /** Options to customize the NVL instance. */
11
+ nvlOptions?: NvlOptions;
12
+ /** The width of the static picture. */
13
+ width?: number;
14
+ /** The height of the static picture. */
15
+ height?: number;
16
+ };
17
+ /**
18
+ * A React component that creates a static picture of a graph using NVL.
19
+ * This component is useful for generating static visualizations of graphs without requiring user interaction.
20
+ * NVL is destroyed after capturing the image to free up resources.
21
+ */
22
+ export declare const StaticPictureWrapper: ({ nodes, rels, nvlOptions, width, height }: StaticPictureWrapperProps) => import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,32 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import NVL from '@neo4j-nvl/base';
3
+ import { useEffect, useState } from 'react';
4
+ /**
5
+ * A React component that creates a static picture of a graph using NVL.
6
+ * This component is useful for generating static visualizations of graphs without requiring user interaction.
7
+ * NVL is destroyed after capturing the image to free up resources.
8
+ */
9
+ export const StaticPictureWrapper = ({ nodes, rels, nvlOptions = {}, width = 500, height = 500 }) => {
10
+ const [imgSrc, setImgSrc] = useState();
11
+ useEffect(() => {
12
+ const div = document.createElement('div');
13
+ div.style.width = `${width / window.devicePixelRatio}px`;
14
+ div.style.height = `${height / window.devicePixelRatio}px`;
15
+ const myNvl = new NVL(div, nodes, rels, nvlOptions, {
16
+ onLayoutDone: () => {
17
+ myNvl.fit(myNvl.getNodes().map((n) => n.id));
18
+ },
19
+ onZoomTransitionDone: () => {
20
+ setImgSrc(myNvl.getImageDataUrl());
21
+ setTimeout(() => {
22
+ myNvl.destroy();
23
+ });
24
+ }
25
+ });
26
+ return () => {
27
+ myNvl?.destroy();
28
+ };
29
+ // eslint-disable-next-line react-hooks/exhaustive-deps
30
+ }, [nodes, rels, width, height]);
31
+ return imgSrc !== undefined ? _jsx("img", { src: imgSrc, width: width, height: height, alt: "Graph" }) : null;
32
+ };
@@ -1,15 +1,15 @@
1
1
  import { isEqual } from 'lodash';
2
2
  import { useEffect, useRef } from 'react';
3
- function deepCompareEquals(a, b) {
3
+ const deepCompareEquals = (a, b) => {
4
4
  return isEqual(a, b);
5
- }
6
- function useDeepCompareMemoize(value) {
5
+ };
6
+ const useDeepCompareMemoize = (value) => {
7
7
  const ref = useRef();
8
8
  if (!deepCompareEquals(value, ref.current)) {
9
9
  ref.current = value;
10
10
  }
11
11
  return ref.current;
12
- }
12
+ };
13
13
  export const useDeepCompareEffect = (callback, dependencies) => {
14
14
  // eslint-disable-next-line react-hooks/exhaustive-deps
15
15
  useEffect(callback, dependencies.map(useDeepCompareMemoize));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neo4j-nvl/react",
3
- "version": "0.3.8-e5dee203",
3
+ "version": "0.3.9-381e4a0c",
4
4
  "main": "lib/index.js",
5
5
  "homepage": "https://neo4j.com/docs/nvl/current/",
6
6
  "license": "SEE LICENSE IN 'LICENSE.txt'",
@@ -27,18 +27,22 @@
27
27
  "lib"
28
28
  ],
29
29
  "devDependencies": {
30
+ "@testing-library/dom": "^10.4.0",
30
31
  "@testing-library/jest-dom": "^5.16.5",
31
- "@testing-library/react": "^13.4.0",
32
+ "@testing-library/react": "^16.3.0",
32
33
  "@types/lodash": "4.14.202",
33
34
  "@types/react": "^18.2.58",
34
- "babel-eslint": "^10.1.0"
35
+ "react": "^19.1.1",
36
+ "react-dom": "^19.1.1"
35
37
  },
36
38
  "dependencies": {
37
- "@neo4j-nvl/base": "0.3.8-e5dee203",
38
- "@neo4j-nvl/interaction-handlers": "0.3.8-e5dee203",
39
- "lodash": "4.17.21",
40
- "react": "^18.2.0",
41
- "react-dom": "^18.2.0"
39
+ "@neo4j-nvl/base": "0.3.9-381e4a0c",
40
+ "@neo4j-nvl/interaction-handlers": "0.3.9-381e4a0c",
41
+ "lodash": "4.17.21"
42
42
  },
43
- "stableVersion": "0.3.8"
43
+ "peerDependencies": {
44
+ "react": "^18.0.0 || ^19.0.0",
45
+ "react-dom": "^18.0.0 || ^19.0.0"
46
+ },
47
+ "stableVersion": "0.3.9"
44
48
  }