@neo4j-nvl/interaction-handlers 0.3.7 → 0.3.8-15dd54ce
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 +37 -0
- package/lib/__tests__/drag-node-interaction.test.js +63 -3
- package/lib/__tests__/pan-interaction.test.d.ts +1 -0
- package/lib/__tests__/pan-interaction.test.js +115 -0
- package/lib/interaction-handlers/base.d.ts +6 -0
- package/lib/interaction-handlers/base.js +19 -0
- package/lib/interaction-handlers/drag-node-interaction.d.ts +2 -1
- package/lib/interaction-handlers/drag-node-interaction.js +11 -5
- package/lib/interaction-handlers/pan-interaction.d.ts +1 -0
- package/lib/interaction-handlers/pan-interaction.js +10 -0
- package/package.json +4 -3
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,43 @@
|
|
|
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.8] - 2025-03-18
|
|
6
|
+
|
|
7
|
+
This release contains a fix for the [NVL result transformer](https://neo4j.com/docs/api/nvl/current/functions/_neo4j_nvl_base.nvlResultTransformer.html).
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
* NVL result transformer to be able to handle deeply nested records
|
|
12
|
+
|
|
13
|
+
## [0.3.7] - 2025-02-28
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
* Export zoom functionalities as a named function
|
|
18
|
+
* Add a `positions` prop to the react wrapper
|
|
19
|
+
* Color custimzation options
|
|
20
|
+
* Aria attributes for NVL canvas and option to disable them
|
|
21
|
+
* Option to disable web workers
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
|
|
25
|
+
* Change default threshold when relationship captions are displayed
|
|
26
|
+
* update default selection color and default node color to be aligned with the Neo4j Design Library
|
|
27
|
+
|
|
28
|
+
### Deprecated
|
|
29
|
+
|
|
30
|
+
* `selectedBorderColor` - use `styling.selectedBorderColor` instead
|
|
31
|
+
* `nodeDefaultBorderColor` - use `styling.nodeDefaultBorderColor` instead
|
|
32
|
+
|
|
33
|
+
### Fixed
|
|
34
|
+
|
|
35
|
+
* Fix icon colors not being inverted for dark node colors
|
|
36
|
+
* fix bug where selected border color was not processed if a default border color was not provided in options
|
|
37
|
+
* Address several warnings during initialization
|
|
38
|
+
* Address multi-select callback inconsistencies
|
|
39
|
+
* Canvas renderer performance improvements
|
|
40
|
+
* ensure properties provided via `nvlOptions` are also updated on prop change in React wrappers
|
|
41
|
+
|
|
5
42
|
## [0.3.6] - 2025-02-21
|
|
6
43
|
|
|
7
44
|
NVL 0.3.6 improves the API docs and adds a result transformer for the Neo4j JavaScript Driver, as well as small improvements and bug fixes.
|
|
@@ -43,7 +43,7 @@ describe('DragNodeInteraction', () => {
|
|
|
43
43
|
const container = myNVL.getContainer();
|
|
44
44
|
container.dispatchEvent(mouseDownEvent);
|
|
45
45
|
container.dispatchEvent(mouseMoveEvent);
|
|
46
|
-
|
|
46
|
+
document.body.dispatchEvent(mouseUpEvent);
|
|
47
47
|
return new Promise((resolve) => {
|
|
48
48
|
expect(dragStartCallbackMock).toHaveBeenCalledTimes(1);
|
|
49
49
|
expect(dragStartCallbackMock).toHaveBeenCalledWith([{ id: '0', x: 10, y: 10 }], mouseMoveEvent);
|
|
@@ -79,7 +79,7 @@ describe('DragNodeInteraction', () => {
|
|
|
79
79
|
const container = myNVL.getContainer();
|
|
80
80
|
container.dispatchEvent(mouseDownEvent);
|
|
81
81
|
container.dispatchEvent(mouseMoveEvent);
|
|
82
|
-
|
|
82
|
+
document.body.dispatchEvent(mouseUpEvent);
|
|
83
83
|
return new Promise((resolve) => {
|
|
84
84
|
expect(dragStartCallbackMock).toHaveBeenCalledTimes(1);
|
|
85
85
|
expect(dragStartCallbackMock).toHaveBeenCalledWith([
|
|
@@ -99,6 +99,34 @@ describe('DragNodeInteraction', () => {
|
|
|
99
99
|
resolve();
|
|
100
100
|
});
|
|
101
101
|
});
|
|
102
|
+
test('dragging should not be invoked when the mouse is not on a node', () => {
|
|
103
|
+
dragNodeInteraction.updateCallback('onDragStart', dragStartCallbackMock);
|
|
104
|
+
dragNodeInteraction.updateCallback('onDrag', dragCallbackMock);
|
|
105
|
+
dragNodeInteraction.updateCallback('onDragEnd', dragEndCallbackMock);
|
|
106
|
+
const mouseDownEvent = new MouseEvent('mousedown', {
|
|
107
|
+
clientX: 100,
|
|
108
|
+
clientY: 100
|
|
109
|
+
});
|
|
110
|
+
const mouseMoveEvent = new MouseEvent('mousemove', {
|
|
111
|
+
buttons: 1,
|
|
112
|
+
clientX: 150,
|
|
113
|
+
clientY: 150
|
|
114
|
+
});
|
|
115
|
+
const mouseUpEvent = new MouseEvent('mouseup', {
|
|
116
|
+
clientX: 150,
|
|
117
|
+
clientY: 150
|
|
118
|
+
});
|
|
119
|
+
const container = myNVL.getContainer();
|
|
120
|
+
container.dispatchEvent(mouseDownEvent);
|
|
121
|
+
container.dispatchEvent(mouseMoveEvent);
|
|
122
|
+
document.body.dispatchEvent(mouseUpEvent);
|
|
123
|
+
return new Promise((resolve) => {
|
|
124
|
+
expect(dragStartCallbackMock).toHaveBeenCalledTimes(0);
|
|
125
|
+
expect(dragCallbackMock).toHaveBeenCalledTimes(0);
|
|
126
|
+
expect(dragEndCallbackMock).toHaveBeenCalledTimes(0);
|
|
127
|
+
resolve();
|
|
128
|
+
});
|
|
129
|
+
});
|
|
102
130
|
test('dragging should not be invoked when the mouse is moved less than the drag threshold', () => {
|
|
103
131
|
dragNodeInteraction.updateCallback('onDragStart', dragStartCallbackMock);
|
|
104
132
|
dragNodeInteraction.updateCallback('onDrag', dragCallbackMock);
|
|
@@ -120,7 +148,7 @@ describe('DragNodeInteraction', () => {
|
|
|
120
148
|
const container = myNVL.getContainer();
|
|
121
149
|
container.dispatchEvent(mouseDownEvent);
|
|
122
150
|
container.dispatchEvent(mouseMoveEvent);
|
|
123
|
-
|
|
151
|
+
document.body.dispatchEvent(mouseUpEvent);
|
|
124
152
|
return new Promise((resolve) => {
|
|
125
153
|
expect(dragStartCallbackMock).toHaveBeenCalledTimes(0);
|
|
126
154
|
expect(dragCallbackMock).toHaveBeenCalledTimes(0);
|
|
@@ -128,4 +156,36 @@ describe('DragNodeInteraction', () => {
|
|
|
128
156
|
resolve();
|
|
129
157
|
});
|
|
130
158
|
});
|
|
159
|
+
test('dragging outside the container should stop dragging but keep selection disabled until mouse release', () => {
|
|
160
|
+
dragNodeInteraction.updateCallback('onDragStart', dragStartCallbackMock);
|
|
161
|
+
dragNodeInteraction.updateCallback('onDrag', dragCallbackMock);
|
|
162
|
+
dragNodeInteraction.updateCallback('onDragEnd', dragEndCallbackMock);
|
|
163
|
+
const mouseDownEvent = new MouseEvent('mousedown', {
|
|
164
|
+
clientX: 10,
|
|
165
|
+
clientY: 10
|
|
166
|
+
});
|
|
167
|
+
const mouseMoveEvent = new MouseEvent('mousemove', {
|
|
168
|
+
buttons: 1,
|
|
169
|
+
clientX: 20,
|
|
170
|
+
clientY: 20
|
|
171
|
+
});
|
|
172
|
+
const mouseLeaveEvent = new MouseEvent('mouseleave', {
|
|
173
|
+
clientX: 1,
|
|
174
|
+
clientY: 1
|
|
175
|
+
});
|
|
176
|
+
const bodyMouseUpEvent = new MouseEvent('mouseup');
|
|
177
|
+
const container = myNVL.getContainer();
|
|
178
|
+
container.dispatchEvent(mouseDownEvent);
|
|
179
|
+
container.dispatchEvent(mouseMoveEvent);
|
|
180
|
+
container.dispatchEvent(mouseLeaveEvent);
|
|
181
|
+
return new Promise((resolve) => {
|
|
182
|
+
expect(dragStartCallbackMock).toHaveBeenCalledTimes(1);
|
|
183
|
+
expect(dragCallbackMock).toHaveBeenCalledTimes(1);
|
|
184
|
+
expect(document.body.style.getPropertyValue('user-select')).toBe('none');
|
|
185
|
+
document.body.dispatchEvent(bodyMouseUpEvent);
|
|
186
|
+
expect(document.body.style.getPropertyValue('user-select')).toBe('');
|
|
187
|
+
expect(dragEndCallbackMock).toHaveBeenCalledTimes(1);
|
|
188
|
+
resolve();
|
|
189
|
+
});
|
|
190
|
+
});
|
|
131
191
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import '@testing-library/jest-dom';
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import NVL from '@neo4j-nvl/base';
|
|
2
|
+
import '@testing-library/jest-dom';
|
|
3
|
+
import { PanInteraction } from '../interaction-handlers/pan-interaction';
|
|
4
|
+
jest.mock('@neo4j-nvl/layout-workers');
|
|
5
|
+
describe('PanInteraction', () => {
|
|
6
|
+
let panInteraction;
|
|
7
|
+
let myNVL;
|
|
8
|
+
const panCallbackMock = jest.fn();
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
myNVL = new NVL(document.createElement('div'), [
|
|
11
|
+
{ id: '0', x: 10, y: 10 },
|
|
12
|
+
{ id: '1', x: 200, y: 200 }
|
|
13
|
+
], [{ id: '10', from: '0', to: '1' }], { disableWebGL: true, initialZoom: 1, layout: 'free' });
|
|
14
|
+
panInteraction = new PanInteraction(myNVL);
|
|
15
|
+
});
|
|
16
|
+
afterEach(() => {
|
|
17
|
+
panInteraction.destroy();
|
|
18
|
+
myNVL.destroy();
|
|
19
|
+
panCallbackMock.mockReset();
|
|
20
|
+
});
|
|
21
|
+
test('performing a simple pan operation should invoke the expected callback', () => {
|
|
22
|
+
panInteraction.updateCallback('onPan', panCallbackMock);
|
|
23
|
+
const mouseDownEvent = new MouseEvent('mousedown', {
|
|
24
|
+
clientX: 100,
|
|
25
|
+
clientY: 100
|
|
26
|
+
});
|
|
27
|
+
const mouseMoveEvent = new MouseEvent('mousemove', {
|
|
28
|
+
buttons: 1,
|
|
29
|
+
clientX: 120,
|
|
30
|
+
clientY: 120
|
|
31
|
+
});
|
|
32
|
+
const mouseUpEvent = new MouseEvent('mouseup', {
|
|
33
|
+
clientX: 120,
|
|
34
|
+
clientY: 120
|
|
35
|
+
});
|
|
36
|
+
const container = myNVL.getContainer();
|
|
37
|
+
const initialPan = myNVL.getPan();
|
|
38
|
+
container.dispatchEvent(mouseDownEvent);
|
|
39
|
+
container.dispatchEvent(mouseMoveEvent);
|
|
40
|
+
container.dispatchEvent(mouseUpEvent);
|
|
41
|
+
return new Promise((resolve) => {
|
|
42
|
+
expect(panCallbackMock).toHaveBeenCalledTimes(1);
|
|
43
|
+
expect(panCallbackMock).toHaveBeenCalledWith({
|
|
44
|
+
x: initialPan.x - 20,
|
|
45
|
+
y: initialPan.y - 20
|
|
46
|
+
}, mouseMoveEvent);
|
|
47
|
+
const newPan = myNVL.getPan();
|
|
48
|
+
expect(newPan).not.toEqual(initialPan);
|
|
49
|
+
resolve();
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
test('panning should not work when clicking on nodes by default', () => {
|
|
53
|
+
panInteraction.updateCallback('onPan', panCallbackMock);
|
|
54
|
+
const mouseDownEvent = new MouseEvent('mousedown', {
|
|
55
|
+
clientX: 10,
|
|
56
|
+
clientY: 10
|
|
57
|
+
});
|
|
58
|
+
const mouseMoveEvent = new MouseEvent('mousemove', {
|
|
59
|
+
buttons: 1,
|
|
60
|
+
clientX: 30,
|
|
61
|
+
clientY: 30
|
|
62
|
+
});
|
|
63
|
+
const container = myNVL.getContainer();
|
|
64
|
+
container.dispatchEvent(mouseDownEvent);
|
|
65
|
+
container.dispatchEvent(mouseMoveEvent);
|
|
66
|
+
return new Promise((resolve) => {
|
|
67
|
+
expect(panCallbackMock).not.toHaveBeenCalled();
|
|
68
|
+
resolve();
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
test('should update targets to allow panning on nodes', () => {
|
|
72
|
+
panInteraction.updateCallback('onPan', panCallbackMock);
|
|
73
|
+
panInteraction.updateTargets(['node'], false);
|
|
74
|
+
const mouseDownEvent = new MouseEvent('mousedown', {
|
|
75
|
+
clientX: 10,
|
|
76
|
+
clientY: 10
|
|
77
|
+
});
|
|
78
|
+
const mouseMoveEvent = new MouseEvent('mousemove', {
|
|
79
|
+
buttons: 1,
|
|
80
|
+
clientX: 50,
|
|
81
|
+
clientY: 50
|
|
82
|
+
});
|
|
83
|
+
const container = myNVL.getContainer();
|
|
84
|
+
const initialPan = myNVL.getPan();
|
|
85
|
+
container.dispatchEvent(mouseDownEvent);
|
|
86
|
+
container.dispatchEvent(mouseMoveEvent);
|
|
87
|
+
return new Promise((resolve) => {
|
|
88
|
+
expect(panCallbackMock).toHaveBeenCalledTimes(1);
|
|
89
|
+
expect(panCallbackMock).toHaveBeenCalledWith({
|
|
90
|
+
x: initialPan.x - 40,
|
|
91
|
+
y: initialPan.y - 40
|
|
92
|
+
}, mouseMoveEvent);
|
|
93
|
+
resolve();
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
test('panning outside the container should disable text selection until mouse release', () => {
|
|
97
|
+
panInteraction.updateCallback('onPan', panCallbackMock);
|
|
98
|
+
const mouseDownEvent = new MouseEvent('mousedown', {
|
|
99
|
+
clientX: 100,
|
|
100
|
+
clientY: 100
|
|
101
|
+
});
|
|
102
|
+
const mouseMoveEvent = new MouseEvent('mousemove', {
|
|
103
|
+
buttons: 1,
|
|
104
|
+
clientX: 120,
|
|
105
|
+
clientY: 120
|
|
106
|
+
});
|
|
107
|
+
const bodyMouseUpEvent = new MouseEvent('mouseup');
|
|
108
|
+
const container = myNVL.getContainer();
|
|
109
|
+
container.dispatchEvent(mouseDownEvent);
|
|
110
|
+
container.dispatchEvent(mouseMoveEvent);
|
|
111
|
+
expect(document.body.style.getPropertyValue('user-select')).toBe('none');
|
|
112
|
+
document.body.dispatchEvent(bodyMouseUpEvent);
|
|
113
|
+
expect(document.body.style.getPropertyValue('user-select')).toBe('');
|
|
114
|
+
});
|
|
115
|
+
});
|
|
@@ -48,6 +48,12 @@ declare abstract class BaseInteraction<T extends Record<string, ((...args: unkno
|
|
|
48
48
|
* @param name - The name of the event
|
|
49
49
|
*/
|
|
50
50
|
removeCallback: (name: keyof T | string) => void;
|
|
51
|
+
/**
|
|
52
|
+
* Enables or disables global text selection during a drag or pan operation.
|
|
53
|
+
* @param enable - Whether to enable or disable global text selection
|
|
54
|
+
* @param eventFunction - The event function to be added/removed when text selection is disabled/enabled
|
|
55
|
+
*/
|
|
56
|
+
toggleGlobalTextSelection: (enable: boolean, eventFunction?: ((this: HTMLElement, ev: MouseEvent) => void) | undefined) => void;
|
|
51
57
|
/**
|
|
52
58
|
* @internal
|
|
53
59
|
*/
|
|
@@ -71,5 +71,24 @@ class BaseInteraction {
|
|
|
71
71
|
removeCallback = (name) => {
|
|
72
72
|
this.callbackMap.delete(name);
|
|
73
73
|
};
|
|
74
|
+
/**
|
|
75
|
+
* Enables or disables global text selection during a drag or pan operation.
|
|
76
|
+
* @param enable - Whether to enable or disable global text selection
|
|
77
|
+
* @param eventFunction - The event function to be added/removed when text selection is disabled/enabled
|
|
78
|
+
*/
|
|
79
|
+
toggleGlobalTextSelection = (enable, eventFunction) => {
|
|
80
|
+
if (enable) {
|
|
81
|
+
document.body.style.removeProperty('user-select');
|
|
82
|
+
if (eventFunction) {
|
|
83
|
+
document.body.removeEventListener('mouseup', eventFunction);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
document.body.style.setProperty('user-select', 'none', 'important');
|
|
88
|
+
if (eventFunction) {
|
|
89
|
+
document.body.addEventListener('mouseup', eventFunction);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
};
|
|
74
93
|
}
|
|
75
94
|
export { BaseInteraction };
|
|
@@ -44,7 +44,8 @@ export declare class DragNodeInteraction extends BaseInteraction<DragNodeInterac
|
|
|
44
44
|
constructor(nvl: NVL, options?: {});
|
|
45
45
|
private handleMouseDown;
|
|
46
46
|
private handleMouseMove;
|
|
47
|
-
private
|
|
47
|
+
private handleBodyMouseUp;
|
|
48
|
+
private resetState;
|
|
48
49
|
/**
|
|
49
50
|
* Removes all related event listeners from the container.
|
|
50
51
|
*/
|
|
@@ -28,7 +28,6 @@ export class DragNodeInteraction extends BaseInteraction {
|
|
|
28
28
|
this.moveSelectedNodes = false;
|
|
29
29
|
this.addEventListener('mousedown', this.handleMouseDown);
|
|
30
30
|
this.addEventListener('mousemove', this.handleMouseMove);
|
|
31
|
-
this.addEventListener('mouseup', this.handleMouseUp);
|
|
32
31
|
}
|
|
33
32
|
handleMouseDown = (event) => {
|
|
34
33
|
this.mousePosition = { x: event.clientX, y: event.clientY };
|
|
@@ -62,6 +61,7 @@ export class DragNodeInteraction extends BaseInteraction {
|
|
|
62
61
|
return;
|
|
63
62
|
}
|
|
64
63
|
if (!this.isDragging) {
|
|
64
|
+
this.toggleGlobalTextSelection(false, this.handleBodyMouseUp);
|
|
65
65
|
if (this.moveSelectedNodes) {
|
|
66
66
|
this.callCallbackIfRegistered('onDragStart', this.selectedNodes, evt);
|
|
67
67
|
}
|
|
@@ -89,15 +89,21 @@ export class DragNodeInteraction extends BaseInteraction {
|
|
|
89
89
|
this.callCallbackIfRegistered('onDrag', [this.mouseDownNode.data], evt);
|
|
90
90
|
}
|
|
91
91
|
};
|
|
92
|
-
|
|
93
|
-
|
|
92
|
+
handleBodyMouseUp = (evt) => {
|
|
93
|
+
this.toggleGlobalTextSelection(true, this.handleBodyMouseUp);
|
|
94
|
+
if (this.isDragging && this.mouseDownNode !== null) {
|
|
94
95
|
if (this.moveSelectedNodes) {
|
|
95
96
|
this.callCallbackIfRegistered('onDragEnd', this.selectedNodes, evt);
|
|
96
97
|
}
|
|
97
98
|
else {
|
|
98
|
-
this.callCallbackIfRegistered('onDragEnd', [this.mouseDownNode
|
|
99
|
+
this.callCallbackIfRegistered('onDragEnd', [this.mouseDownNode.data], evt);
|
|
99
100
|
}
|
|
100
101
|
}
|
|
102
|
+
if (this.isDragging) {
|
|
103
|
+
this.resetState();
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
resetState = () => {
|
|
101
107
|
this.isDragging = false;
|
|
102
108
|
this.mouseDownNode = null;
|
|
103
109
|
this.isDrawing = false;
|
|
@@ -108,8 +114,8 @@ export class DragNodeInteraction extends BaseInteraction {
|
|
|
108
114
|
* Removes all related event listeners from the container.
|
|
109
115
|
*/
|
|
110
116
|
destroy = () => {
|
|
117
|
+
this.toggleGlobalTextSelection(true, this.handleBodyMouseUp);
|
|
111
118
|
this.removeEventListener('mousedown', this.handleMouseDown);
|
|
112
119
|
this.removeEventListener('mousemove', this.handleMouseMove);
|
|
113
|
-
this.removeEventListener('mouseup', this.handleMouseUp);
|
|
114
120
|
};
|
|
115
121
|
}
|
|
@@ -33,6 +33,7 @@ export declare class PanInteraction extends BaseInteraction<PanInteractionCallba
|
|
|
33
33
|
private mousePosition;
|
|
34
34
|
private targets;
|
|
35
35
|
private shouldPan;
|
|
36
|
+
private isPanning;
|
|
36
37
|
/**
|
|
37
38
|
* Creates a new instance of the pan interaction handler.
|
|
38
39
|
* @param nvl - The NVL instance to attach the interaction handler to
|
|
@@ -10,6 +10,7 @@ export class PanInteraction extends BaseInteraction {
|
|
|
10
10
|
mousePosition;
|
|
11
11
|
targets;
|
|
12
12
|
shouldPan;
|
|
13
|
+
isPanning = false;
|
|
13
14
|
/**
|
|
14
15
|
* Creates a new instance of the pan interaction handler.
|
|
15
16
|
* @param nvl - The NVL instance to attach the interaction handler to
|
|
@@ -61,6 +62,10 @@ export class PanInteraction extends BaseInteraction {
|
|
|
61
62
|
if (!this.shouldPan || evt.buttons !== 1) {
|
|
62
63
|
return;
|
|
63
64
|
}
|
|
65
|
+
if (!this.isPanning) {
|
|
66
|
+
this.toggleGlobalTextSelection(false, this.handleMouseUp);
|
|
67
|
+
this.isPanning = true;
|
|
68
|
+
}
|
|
64
69
|
const zoom = this.nvlInstance.getScale();
|
|
65
70
|
const { x, y } = this.nvlInstance.getPan();
|
|
66
71
|
const dx = ((evt.clientX - this.mousePosition.x) / zoom) * window.devicePixelRatio;
|
|
@@ -70,12 +75,17 @@ export class PanInteraction extends BaseInteraction {
|
|
|
70
75
|
this.mousePosition = { x: evt.clientX, y: evt.clientY };
|
|
71
76
|
};
|
|
72
77
|
handleMouseUp = () => {
|
|
78
|
+
if (this.isPanning) {
|
|
79
|
+
this.toggleGlobalTextSelection(true, this.handleMouseUp);
|
|
80
|
+
this.isPanning = false;
|
|
81
|
+
}
|
|
73
82
|
this.shouldPan = false;
|
|
74
83
|
};
|
|
75
84
|
/**
|
|
76
85
|
* Removes the related event listeners from the canvas.
|
|
77
86
|
*/
|
|
78
87
|
destroy() {
|
|
88
|
+
this.toggleGlobalTextSelection(true, this.handleMouseUp);
|
|
79
89
|
this.removeEventListener('mousedown', this.handleMouseDown, true);
|
|
80
90
|
this.removeEventListener('mousemove', this.handleMouseMove, true);
|
|
81
91
|
this.removeEventListener('mouseup', this.handleMouseUp, true);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@neo4j-nvl/interaction-handlers",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.8-15dd54ce",
|
|
4
4
|
"license": "SEE LICENSE IN 'LICENSE.txt'",
|
|
5
5
|
"homepage": "https://neo4j.com/docs/nvl/current/",
|
|
6
6
|
"description": "Interaction handlers for the Neo4j Visualization Library",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"eslint": "yarn global:eslint ./src/"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@neo4j-nvl/base": "0.3.
|
|
30
|
+
"@neo4j-nvl/base": "0.3.8-15dd54ce",
|
|
31
31
|
"concaveman": "^1.2.1",
|
|
32
32
|
"lodash": "4.17.21"
|
|
33
33
|
},
|
|
@@ -36,5 +36,6 @@
|
|
|
36
36
|
"@testing-library/react": "^13.4.0",
|
|
37
37
|
"@types/concaveman": "1.1.6",
|
|
38
38
|
"@types/lodash": "4.14.202"
|
|
39
|
-
}
|
|
39
|
+
},
|
|
40
|
+
"stableVersion": "0.3.8"
|
|
40
41
|
}
|