@reltio/components 1.4.1991 → 1.4.1993

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.
Files changed (39) hide show
  1. package/cjs/HOCs/withDragHandle/styles.d.ts +1 -1
  2. package/cjs/RCTree/RCTree.d.ts +10 -4
  3. package/cjs/RCTree/RCTree.js +66 -27
  4. package/cjs/RCTree/helper.d.ts +21 -2
  5. package/cjs/RCTree/helper.js +161 -6
  6. package/cjs/RCTree/styles.d.ts +1 -1
  7. package/cjs/RCTree/styles.js +52 -23
  8. package/cjs/RCTree/types.d.ts +11 -0
  9. package/cjs/RCTree/types.js +7 -0
  10. package/cjs/RCTree/useDelayedDragEventCall.d.ts +6 -0
  11. package/cjs/RCTree/useDelayedDragEventCall.js +26 -0
  12. package/cjs/RCTree/useDnd.d.ts +47 -0
  13. package/cjs/RCTree/useDnd.js +112 -0
  14. package/cjs/RCTree/useScrollOnDrag.d.ts +6 -0
  15. package/cjs/RCTree/useScrollOnDrag.js +87 -0
  16. package/cjs/index.d.ts +1 -1
  17. package/cjs/index.js +2 -1
  18. package/cjs/test-utils/index.d.ts +1 -0
  19. package/cjs/test-utils/index.js +25 -1
  20. package/esm/HOCs/withDragHandle/styles.d.ts +1 -1
  21. package/esm/RCTree/RCTree.d.ts +10 -4
  22. package/esm/RCTree/RCTree.js +67 -28
  23. package/esm/RCTree/helper.d.ts +21 -2
  24. package/esm/RCTree/helper.js +151 -6
  25. package/esm/RCTree/styles.d.ts +1 -1
  26. package/esm/RCTree/styles.js +52 -23
  27. package/esm/RCTree/types.d.ts +11 -0
  28. package/esm/RCTree/types.js +6 -1
  29. package/esm/RCTree/useDelayedDragEventCall.d.ts +6 -0
  30. package/esm/RCTree/useDelayedDragEventCall.js +22 -0
  31. package/esm/RCTree/useDnd.d.ts +47 -0
  32. package/esm/RCTree/useDnd.js +108 -0
  33. package/esm/RCTree/useScrollOnDrag.d.ts +6 -0
  34. package/esm/RCTree/useScrollOnDrag.js +83 -0
  35. package/esm/index.d.ts +1 -1
  36. package/esm/index.js +1 -1
  37. package/esm/test-utils/index.d.ts +1 -0
  38. package/esm/test-utils/index.js +23 -0
  39. package/package.json +2 -2
@@ -18,27 +18,73 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
18
18
  }
19
19
  return to.concat(ar || Array.prototype.slice.call(from));
20
20
  };
21
- import { assocPath, intersperse, map, pipe, path, remove, split } from 'ramda';
21
+ import { always, assoc, assocPath, ifElse, intersperse, insert, last, map, pipe, path, remove, split } from 'ramda';
22
+ import { AddNodePosition } from './types';
23
+ var DEPTH_LEVEL_INDENT = 16;
24
+ var DROP_INDICATOR_NODE_KEY = '-1';
22
25
  export var defaultIsLeaf = function (_a) {
23
26
  var _b = _a.children, children = _b === void 0 ? [] : _b;
24
27
  return !children.length;
25
28
  };
26
29
  export var convertTreeData = function (_a) {
27
- var data = _a.data, _b = _a.parentPath, parentPath = _b === void 0 ? [] : _b, isLeaf = _a.isLeaf;
30
+ var data = _a.data, isLeaf = _a.isLeaf;
28
31
  return data.map(function (item) {
29
32
  var _a;
30
- var path = __spreadArray(__spreadArray([], parentPath, true), [item.nodeId], false);
31
- return __assign({ key: String(item.nodeId), title: (_a = item.title) !== null && _a !== void 0 ? _a : '', value: __assign(__assign({}, item), { path: path }), isLeaf: isLeaf(item) }, (item.children &&
33
+ return __assign({ key: String(item.nodeId), title: (_a = item.title) !== null && _a !== void 0 ? _a : '', value: __assign({}, item), isLeaf: isLeaf(item) }, (item.children &&
32
34
  item.children.length && {
33
- children: convertTreeData({ data: item.children, parentPath: path, isLeaf: isLeaf })
35
+ children: convertTreeData({ data: item.children, isLeaf: isLeaf })
34
36
  }));
35
37
  });
36
38
  };
37
39
  var getPathFromPosition = pipe(split('-'), remove(0, 1), map(Number), intersperse('children'));
40
+ export var getNodeAtPosition = function (treeData, pos) {
41
+ var nodePath = getPathFromPosition(pos);
42
+ return nodePath.length > 0 ? path(nodePath, treeData) : null;
43
+ };
44
+ export var getParentPos = function (pos) {
45
+ return pos.split('-').slice(0, -1).join('-');
46
+ };
38
47
  export var changeNodeAtPosition = function (treeData, pos, changeNode) {
39
48
  var nodePath = getPathFromPosition(pos);
40
49
  var node = path(nodePath, treeData);
41
- return node ? assocPath(nodePath, changeNode(node), treeData) : null;
50
+ return node ? assocPath(nodePath, changeNode(node), treeData) : treeData;
51
+ };
52
+ export var removeNodeAtPosition = function (treeData, pos) {
53
+ var nodePath = getPathFromPosition(pos);
54
+ var childrenPath = nodePath.slice(0, -1);
55
+ var nodeIndex = Number(nodePath[nodePath.length - 1]);
56
+ if (childrenPath.length > 0) {
57
+ var children = path(childrenPath)(treeData);
58
+ var newChildren = remove(nodeIndex, 1, children);
59
+ return assocPath(childrenPath, newChildren, treeData);
60
+ }
61
+ return remove(nodeIndex, 1, treeData);
62
+ };
63
+ export var insertNodeAtPosition = function (treeData, pos, dropPosition, node) {
64
+ var nodePath = getPathFromPosition(pos);
65
+ var childrenPath = nodePath.slice(0, -1);
66
+ var nodeIndex = Number(nodePath[nodePath.length - 1]);
67
+ var newNodeIndex = dropPosition === AddNodePosition.Top ? nodeIndex : nodeIndex + 1;
68
+ if (childrenPath.length > 0) {
69
+ var children = path(childrenPath, treeData);
70
+ if (!children)
71
+ return treeData;
72
+ var newChildren = insert(newNodeIndex, node, children);
73
+ return assocPath(childrenPath, newChildren, treeData);
74
+ }
75
+ return insert(newNodeIndex, node, treeData);
76
+ };
77
+ export var moveNode = function (treeData, dragNode, dragNodePos, dropPositionInfo) {
78
+ var pos = dropPositionInfo.pos, dropPosition = dropPositionInfo.dropPosition, _a = dropPositionInfo.addToEnd, addToEnd = _a === void 0 ? false : _a;
79
+ var removeNode = function (treeData) { return removeNodeAtPosition(treeData, dragNodePos); };
80
+ var addNode = function (treeData) {
81
+ return dropPosition === AddNodePosition.AsChild
82
+ ? changeNodeAtPosition(treeData, pos, function (node) {
83
+ return pipe(ifElse(always(addToEnd), assoc('children', __spreadArray(__spreadArray([], (node.children || []), true), [dragNode], false)), assoc('children', __spreadArray([dragNode], (node.children || []), true))), assoc('expanded', true))(node);
84
+ })
85
+ : insertNodeAtPosition(treeData, pos, dropPosition, dragNode);
86
+ };
87
+ return pipe(removeNode, addNode)(treeData);
42
88
  };
43
89
  export var getExpandedKeys = function (nodes) {
44
90
  if (nodes === void 0) { nodes = []; }
@@ -46,3 +92,102 @@ export var getExpandedKeys = function (nodes) {
46
92
  return expandedKeys.concat(node.expanded ? [String(node.nodeId)] : []).concat(getExpandedKeys(node.children));
47
93
  }, []);
48
94
  };
95
+ export var slideNodePos = function (dropNodePos, nodePos, backward) {
96
+ if (backward === void 0) { backward = false; }
97
+ var nodePosition = nodePos.split('-');
98
+ var nodeDepth = nodePosition.length - 1;
99
+ var nodeParentPosition = nodePosition.slice(0, -1);
100
+ var nodeParentPos = nodeParentPosition.join('-');
101
+ var dropNodePosition = dropNodePos.split('-');
102
+ if (dropNodePos.startsWith(nodeParentPos)) {
103
+ var nodeLastIndex = Number(last(nodePosition));
104
+ var dropNodeIndexToChange = Number(dropNodePosition[nodeDepth]);
105
+ if (backward) {
106
+ if (nodeLastIndex < dropNodeIndexToChange) {
107
+ return dropNodePos.replace([nodeParentPos, dropNodeIndexToChange].join('-'), [nodeParentPos, dropNodeIndexToChange - 1].join('-'));
108
+ }
109
+ }
110
+ else {
111
+ if (nodeLastIndex <= dropNodeIndexToChange) {
112
+ return dropNodePos.replace([nodeParentPos, dropNodeIndexToChange].join('-'), [nodeParentPos, dropNodeIndexToChange + 1].join('-'));
113
+ }
114
+ }
115
+ }
116
+ return dropNodePos;
117
+ };
118
+ var getNodeTopElement = function (target) {
119
+ return target.closest('.rc-tree-treenode');
120
+ };
121
+ var calcAddNodePosition = function (event) {
122
+ var nodeElement = getNodeTopElement(event.target);
123
+ if (!nodeElement)
124
+ return null;
125
+ var offsetY = event.clientY - nodeElement.getBoundingClientRect().top;
126
+ var treeNodeHeight = nodeElement.offsetHeight;
127
+ return offsetY < treeNodeHeight / 2 ? AddNodePosition.Top : AddNodePosition.Bottom;
128
+ };
129
+ var findDepthPosition = function (event, dropNode) {
130
+ var nodeElement = getNodeTopElement(event.target);
131
+ if (!nodeElement)
132
+ return null;
133
+ var dropNodeLevel = dropNode.pos.split('-').length - 1;
134
+ var leftPadding = parseFloat(window.getComputedStyle(nodeElement).paddingLeft) || 0;
135
+ var offsetX = event.clientX - nodeElement.getBoundingClientRect().left - leftPadding;
136
+ return Math.min(dropNodeLevel + 1, Math.max(Math.round(offsetX / DEPTH_LEVEL_INDENT), dropNodeLevel));
137
+ };
138
+ var changePosLastIndex = function (pos, change) {
139
+ var position = pos.split('-');
140
+ var lastIndex = Number(last(position));
141
+ return position
142
+ .slice(0, -1)
143
+ .concat(String(change(lastIndex)))
144
+ .join('-');
145
+ };
146
+ var getCurrentDropNodePos = function (dropPositionInfo) {
147
+ switch (dropPositionInfo.dropPosition) {
148
+ case AddNodePosition.Top:
149
+ return dropPositionInfo.pos;
150
+ case AddNodePosition.Bottom:
151
+ return changePosLastIndex(dropPositionInfo.pos, function (index) { return index + 1; });
152
+ case AddNodePosition.AsChild:
153
+ return "".concat(dropPositionInfo.pos, "-0");
154
+ }
155
+ };
156
+ export var getDropNodePosition = function (event, dropNode, prevDropPositionInfo) {
157
+ var addNodePosition = calcAddNodePosition(event);
158
+ var depthPosition = findDepthPosition(event, dropNode);
159
+ if (addNodePosition === null || depthPosition === null)
160
+ return null;
161
+ var pos = !prevDropPositionInfo || prevDropPositionInfo.addToEnd
162
+ ? dropNode.pos
163
+ : slideNodePos(dropNode.pos, getCurrentDropNodePos(prevDropPositionInfo), true);
164
+ var dropNodeDepth = pos.split('-').length - 1;
165
+ var position = pos.split('-');
166
+ var lastIndex = Number(last(position));
167
+ if (depthPosition === dropNodeDepth) {
168
+ return { pos: pos, dropPosition: addNodePosition };
169
+ }
170
+ if (addNodePosition === AddNodePosition.Top) {
171
+ if (lastIndex > 0) {
172
+ return {
173
+ pos: position
174
+ .slice(0, -1)
175
+ .concat(String(lastIndex - 1))
176
+ .join('-'),
177
+ dropPosition: AddNodePosition.AsChild,
178
+ addToEnd: true
179
+ };
180
+ }
181
+ if (position.length > 2)
182
+ return { pos: position.slice(0, -1).join('-'), dropPosition: AddNodePosition.AsChild, addToEnd: false };
183
+ return { pos: pos, dropPosition: AddNodePosition.Top };
184
+ }
185
+ return { pos: pos, dropPosition: AddNodePosition.AsChild };
186
+ };
187
+ export var isDropIndicatorNode = function (node) { return (node === null || node === void 0 ? void 0 : node.key) === DROP_INDICATOR_NODE_KEY; };
188
+ export var gatherNodeKeys = function (node) {
189
+ return node ? __spreadArray([node.key], (node.children ? node.children.flatMap(gatherNodeKeys) : []), true) : [];
190
+ };
191
+ export var preventNodeDragging = function (event) {
192
+ event.preventDefault();
193
+ };
@@ -1 +1 @@
1
- export declare const useStyles: (props?: any) => import("@mui/styles").ClassNameMap<"expandButton" | "collapseButton" | "switcherButtonWrapper" | "switcherButton" | "treeWrapper" | "@global">;
1
+ export declare const useStyles: (props?: any) => import("@mui/styles").ClassNameMap<"expandButton" | "collapseButton" | "dropIndicator" | "switcherButtonWrapper" | "switcherButton" | "treeWrapper" | "dropNotAllowed" | "draggedChildrenNode" | "dragHandle" | "dragHandleDragging" | "@global">;
@@ -1,10 +1,10 @@
1
1
  import { makeStyles } from '@mui/styles';
2
- export var useStyles = makeStyles(function () { return ({
2
+ export var useStyles = makeStyles(function (theme) { return ({
3
3
  switcherButtonWrapper: {
4
- paddingTop: '9px',
5
- paddingLeft: '6px',
6
- width: '16px',
7
- height: '16px',
4
+ paddingTop: '11px',
5
+ paddingLeft: '4px',
6
+ width: '12px',
7
+ height: '12px',
8
8
  cursor: 'pointer'
9
9
  },
10
10
  switcherButton: {
@@ -24,6 +24,39 @@ export var useStyles = makeStyles(function () { return ({
24
24
  treeWrapper: {
25
25
  border: 'none'
26
26
  },
27
+ dropIndicator: {
28
+ '&:before': {
29
+ content: '""',
30
+ backgroundColor: '#e0eef9',
31
+ border: '1px dashed #2184D4',
32
+ position: 'absolute',
33
+ top: 0,
34
+ right: '23px',
35
+ bottom: 0,
36
+ left: '-22px',
37
+ zIndex: 1
38
+ },
39
+ '&>div': {
40
+ opacity: 0
41
+ }
42
+ },
43
+ dropNotAllowed: {
44
+ '&:before': {
45
+ backgroundColor: '#ffedee',
46
+ borderColor: '#FF6673'
47
+ }
48
+ },
49
+ draggedChildrenNode: {
50
+ opacity: 0.5
51
+ },
52
+ dragHandle: {
53
+ cursor: 'move',
54
+ color: theme.palette.text.secondary,
55
+ width: '16px'
56
+ },
57
+ dragHandleDragging: {
58
+ visibility: 'hidden'
59
+ },
27
60
  /* rc-tree/assets/index.css */
28
61
  '@global': {
29
62
  '.rc-tree': {
@@ -49,12 +82,6 @@ export var useStyles = makeStyles(function () { return ({
49
82
  boxShadow: 'inset 0 0 0 2px red',
50
83
  content: "''"
51
84
  },
52
- '.rc-tree .rc-tree-treenode.drop-container ~ .rc-tree-treenode': {
53
- borderLeft: '2px solid chocolate'
54
- },
55
- '.rc-tree .rc-tree-treenode.drop-target': {
56
- backgroundColor: 'yellowgreen'
57
- },
58
85
  '.rc-tree .rc-tree-treenode.drop-target ~ .rc-tree-treenode': {
59
86
  borderLeft: 'none'
60
87
  },
@@ -152,11 +179,6 @@ export var useStyles = makeStyles(function () { return ({
152
179
  '.rc-tree-treenode-active': {
153
180
  background: 'rgba(0, 0, 0, 0.1)'
154
181
  },
155
- '.rc-tree-node-selected': {
156
- backgroundColor: '#ffe6b0',
157
- boxShadow: '0 0 0 1px #ffb951',
158
- opacity: 0.8
159
- },
160
182
  '.rc-tree-icon__open': {
161
183
  marginRight: '2px',
162
184
  verticalAlign: 'top',
@@ -185,11 +207,6 @@ export var useStyles = makeStyles(function () { return ({
185
207
  display: 'inline-block',
186
208
  width: '16px'
187
209
  },
188
- '.rc-tree-draggable-icon': {
189
- display: 'inline-flex',
190
- justifyContent: 'center',
191
- width: '16px'
192
- },
193
210
  //Custom styles
194
211
  '.rc-tree .rc-tree-treenode .rc-tree-node-content-wrapper': {
195
212
  position: 'relative',
@@ -200,8 +217,8 @@ export var useStyles = makeStyles(function () { return ({
200
217
  verticalAlign: 'top',
201
218
  cursor: 'pointer',
202
219
  height: 'auto',
203
- width: '100%',
204
- paddingRight: '11px'
220
+ paddingRight: '11px',
221
+ flexGrow: 1
205
222
  },
206
223
  '.rc-tree .rc-tree-treenode': {
207
224
  margin: 0,
@@ -222,6 +239,18 @@ export var useStyles = makeStyles(function () { return ({
222
239
  '.rc-tree-title': {
223
240
  display: 'inline-block',
224
241
  width: '100%'
242
+ },
243
+ '.rc-tree-draggable-icon': {
244
+ display: 'inline-flex',
245
+ justifyContent: 'center',
246
+ width: '16px',
247
+ visibility: 'hidden'
248
+ },
249
+ '.rc-tree-treenode-draggable:hover .rc-tree-draggable-icon': {
250
+ visibility: 'visible'
251
+ },
252
+ '.rc-tree-switcher-noop': {
253
+ width: '16px'
225
254
  }
226
255
  }
227
256
  }); });
@@ -7,7 +7,18 @@ export type RCTreeNode = {
7
7
  };
8
8
  export type InternalRCNode = {
9
9
  value: RCTreeNode;
10
+ pos?: string;
10
11
  } & FieldDataNode<{
11
12
  key: string;
12
13
  title?: string;
13
14
  }>;
15
+ export type DropPositionInfo = {
16
+ pos: string;
17
+ dropPosition: number;
18
+ addToEnd?: boolean;
19
+ };
20
+ export declare enum AddNodePosition {
21
+ Bottom = 1,
22
+ Top = -1,
23
+ AsChild = 0
24
+ }
@@ -1 +1,6 @@
1
- export {};
1
+ export var AddNodePosition;
2
+ (function (AddNodePosition) {
3
+ AddNodePosition[AddNodePosition["Bottom"] = 1] = "Bottom";
4
+ AddNodePosition[AddNodePosition["Top"] = -1] = "Top";
5
+ AddNodePosition[AddNodePosition["AsChild"] = 0] = "AsChild";
6
+ })(AddNodePosition || (AddNodePosition = {}));
@@ -0,0 +1,6 @@
1
+ import { DragEvent } from 'react';
2
+ import { InternalRCNode } from './types';
3
+ export declare const useDelayedDragEventCall: (callback: (params: {
4
+ event: DragEvent<HTMLDivElement>;
5
+ node: InternalRCNode;
6
+ }) => void, delay?: number) => ({ event, node }: any) => void;
@@ -0,0 +1,22 @@
1
+ import { useCallback, useRef } from 'react';
2
+ import { equals } from 'ramda';
3
+ var DELAY_TIMEOUT = 50;
4
+ export var useDelayedDragEventCall = function (callback, delay) {
5
+ if (delay === void 0) { delay = DELAY_TIMEOUT; }
6
+ var prevMousePosition = useRef(null);
7
+ var lastTimeChanged = useRef(0);
8
+ return useCallback(function (_a) {
9
+ var event = _a.event, node = _a.node;
10
+ var now = Date.now();
11
+ var newMousePosition = { x: event.clientX, y: event.clientY };
12
+ if (!equals(prevMousePosition === null || prevMousePosition === void 0 ? void 0 : prevMousePosition.current, newMousePosition)) {
13
+ lastTimeChanged.current = now;
14
+ }
15
+ var waitedTime = now - (lastTimeChanged === null || lastTimeChanged === void 0 ? void 0 : lastTimeChanged.current);
16
+ if (waitedTime > delay) {
17
+ lastTimeChanged.current = now;
18
+ callback({ event: event, node: node });
19
+ }
20
+ prevMousePosition.current = newMousePosition;
21
+ }, [callback, delay]);
22
+ };
@@ -0,0 +1,47 @@
1
+ import { DragEvent } from 'react';
2
+ import { InternalRCNode, RCTreeNode } from './types';
3
+ type Props = {
4
+ treeData: RCTreeNode[];
5
+ containerRef: React.RefObject<HTMLDivElement>;
6
+ expandNode: (pos: string, expanded: boolean) => void;
7
+ onLoadChildren?: (treeNode: RCTreeNode) => Promise<void>;
8
+ onChange?: (node: RCTreeNode[]) => void;
9
+ onDrop?: (treeData: RCTreeNode[], dragNode: RCTreeNode, parentNode: RCTreeNode) => void;
10
+ canDrop?: (params: {
11
+ nextParent: RCTreeNode;
12
+ node: RCTreeNode;
13
+ }) => boolean;
14
+ canDrag?: (params: {
15
+ node: RCTreeNode;
16
+ }) => boolean;
17
+ };
18
+ export declare const useDnd: ({ treeData, containerRef, expandNode, onLoadChildren, onChange, onDrop: onDropProp, canDrop, canDrag }: Props) => {
19
+ treeProps: {
20
+ onDragStart: ({ node }: {
21
+ node: InternalRCNode;
22
+ }) => void;
23
+ onDragOver: ({ event, node }: {
24
+ event: DragEvent<HTMLDivElement>;
25
+ node: InternalRCNode;
26
+ }) => void;
27
+ onDragLeave: ({ event, node }: {
28
+ event: any;
29
+ node: any;
30
+ }) => void;
31
+ onDrop: () => void;
32
+ dropIndicatorRender: () => any;
33
+ allowDrop: ({ dragNode, dropNode }: {
34
+ dragNode: InternalRCNode;
35
+ dropNode: InternalRCNode;
36
+ }) => boolean;
37
+ };
38
+ nodeDraggable: (node: InternalRCNode) => boolean;
39
+ dropNode: InternalRCNode;
40
+ dragNode: InternalRCNode;
41
+ dropPositionInfo: {
42
+ pos: string;
43
+ dropPosition: number;
44
+ addToEnd?: boolean;
45
+ };
46
+ };
47
+ export {};
@@ -0,0 +1,108 @@
1
+ import { useCallback, useMemo, useState } from 'react';
2
+ import { equals } from 'ramda';
3
+ import { AddNodePosition } from './types';
4
+ import { useScrollOnDrag } from './useScrollOnDrag';
5
+ import { useDelayedDragEventCall } from './useDelayedDragEventCall';
6
+ import { getDropNodePosition, getExpandedKeys, getNodeAtPosition, getParentPos, isDropIndicatorNode, moveNode, slideNodePos } from './helper';
7
+ export var useDnd = function (_a) {
8
+ var treeData = _a.treeData, containerRef = _a.containerRef, expandNode = _a.expandNode, onLoadChildren = _a.onLoadChildren, onChange = _a.onChange, onDropProp = _a.onDrop, canDrop = _a.canDrop, canDrag = _a.canDrag;
9
+ var _b = useState(null), dragNode = _b[0], setDragNode = _b[1];
10
+ var _c = useState(null), dropNode = _c[0], setDropNode = _c[1];
11
+ var _d = useState(null), dropPositionInfo = _d[0], setDropPositionInfo = _d[1];
12
+ var _e = useScrollOnDrag(containerRef), onStartDragging = _e.onStartDragging, onEndDragging = _e.onEndDragging, getIsScrolling = _e.getIsScrolling;
13
+ var handleDropOutsideTree = function () {
14
+ setDragNode(null);
15
+ setDropNode(null);
16
+ onEndDragging();
17
+ window.removeEventListener('mousemove', handleDropOutsideTree);
18
+ };
19
+ var onDragStart = function (_a) {
20
+ var node = _a.node;
21
+ setDragNode(node);
22
+ onStartDragging();
23
+ window.addEventListener('mousemove', handleDropOutsideTree);
24
+ };
25
+ var expandedKeys = useMemo(function () {
26
+ return getExpandedKeys(treeData);
27
+ }, [treeData]);
28
+ var expandDropNodeAtPosition = useCallback(function (pos, expanded) {
29
+ var node = getNodeAtPosition(treeData, pos);
30
+ if (node && !expandedKeys.includes(node.nodeId)) {
31
+ expandNode(pos, expanded);
32
+ if (node.pending && onLoadChildren) {
33
+ onLoadChildren(node);
34
+ }
35
+ }
36
+ }, [expandNode, expandedKeys, onLoadChildren, treeData]);
37
+ var expandDropNode = useCallback(function (newDropPositionInfo) {
38
+ if (onChange && newDropPositionInfo.dropPosition === AddNodePosition.AsChild) {
39
+ var currentParentNodePos = slideNodePos(newDropPositionInfo.pos, dragNode.pos);
40
+ if (currentParentNodePos.split('-').length > 1) {
41
+ expandDropNodeAtPosition(currentParentNodePos, true);
42
+ }
43
+ }
44
+ }, [dragNode, expandDropNodeAtPosition, onChange]);
45
+ var handleSetDropNode = useCallback(function (_a) {
46
+ var event = _a.event, node = _a.node;
47
+ var newDropPositionInfo = getDropNodePosition(event, node, dropPositionInfo) || dropPositionInfo;
48
+ if (!equals(newDropPositionInfo, dropPositionInfo) && (!isDropIndicatorNode(node) || !dropNode)) {
49
+ setDropPositionInfo(newDropPositionInfo);
50
+ expandDropNode(newDropPositionInfo);
51
+ }
52
+ if (node.key !== (dropNode === null || dropNode === void 0 ? void 0 : dropNode.key)) {
53
+ setDropNode(node);
54
+ }
55
+ }, [dropNode, dropPositionInfo, expandDropNode]);
56
+ var delayedHandleDragOver = useDelayedDragEventCall(handleSetDropNode);
57
+ var onDragOver = function (_a) {
58
+ var event = _a.event, node = _a.node;
59
+ var isScrolling = getIsScrolling();
60
+ if (!isScrolling)
61
+ delayedHandleDragOver({ event: event, node: node });
62
+ };
63
+ var dropIndicatorRender = function () {
64
+ return null;
65
+ };
66
+ var onDragLeave = function (_a) {
67
+ var _b, _c;
68
+ var event = _a.event, node = _a.node;
69
+ var draggedChildrenNodes = ((_b = dragNode === null || dragNode === void 0 ? void 0 : dragNode.value) === null || _b === void 0 ? void 0 : _b.expanded) ? getExpandedKeys((_c = dragNode.value) === null || _c === void 0 ? void 0 : _c.children) : [];
70
+ if (draggedChildrenNodes.includes(node.key)) {
71
+ handleSetDropNode({ event: event, node: node });
72
+ }
73
+ };
74
+ var onDrop = function () {
75
+ if (dragNode && isDropIndicatorNode(dropNode)) {
76
+ var parentNodePosition = dropPositionInfo.dropPosition === AddNodePosition.AsChild
77
+ ? dropPositionInfo.pos
78
+ : getParentPos(dropPositionInfo.pos);
79
+ var parentNode = getNodeAtPosition(treeData, parentNodePosition);
80
+ var newTreeData = moveNode(treeData, dragNode.value, dragNode.pos, dropPositionInfo);
81
+ onDropProp(newTreeData, dragNode.value, parentNode);
82
+ }
83
+ setDragNode(null);
84
+ setDropNode(null);
85
+ onEndDragging();
86
+ };
87
+ var allowDrop = useCallback(function (_a) {
88
+ var dragNode = _a.dragNode, dropNode = _a.dropNode;
89
+ return canDrop({ nextParent: dropNode.value, node: dragNode.value });
90
+ }, [canDrop]);
91
+ var nodeDraggable = useCallback(function (node) {
92
+ return canDrag({ node: node.value });
93
+ }, [canDrag]);
94
+ return {
95
+ treeProps: {
96
+ onDragStart: onDragStart,
97
+ onDragOver: onDragOver,
98
+ onDragLeave: onDragLeave,
99
+ onDrop: onDrop,
100
+ dropIndicatorRender: dropIndicatorRender,
101
+ allowDrop: allowDrop
102
+ },
103
+ nodeDraggable: nodeDraggable,
104
+ dropNode: dropNode,
105
+ dragNode: dragNode,
106
+ dropPositionInfo: dropPositionInfo
107
+ };
108
+ };
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ export declare const useScrollOnDrag: (scrollContainer: React.MutableRefObject<HTMLDivElement>) => {
3
+ onStartDragging: () => void;
4
+ onEndDragging: () => void;
5
+ getIsScrolling: () => boolean;
6
+ };
@@ -0,0 +1,83 @@
1
+ import { useCallback, useEffect, useRef } from 'react';
2
+ import { throttle } from '@reltio/mdm-sdk';
3
+ var SCROLL_MARGIN = 50;
4
+ var SPEED_MULTIPLIER = 25;
5
+ var UPDATE_DATA_INTERVAL = 100;
6
+ export var useScrollOnDrag = function (scrollContainer) {
7
+ var scrolling = useRef(false);
8
+ var running = useRef(false);
9
+ var scrollData = useRef(null);
10
+ var getIsScrolling = function () {
11
+ return scrolling === null || scrolling === void 0 ? void 0 : scrolling.current;
12
+ };
13
+ var onStartDragging = function () {
14
+ var container = scrollContainer === null || scrollContainer === void 0 ? void 0 : scrollContainer.current;
15
+ if (container && typeof container.addEventListener === 'function') {
16
+ container.addEventListener('dragover', updateScrollData);
17
+ window.addEventListener('dragover', updateScrollData);
18
+ running.current = true;
19
+ }
20
+ };
21
+ var updateScrollData = useCallback(throttle(function (event) {
22
+ var container = scrollContainer === null || scrollContainer === void 0 ? void 0 : scrollContainer.current;
23
+ if (!container || !running.current)
24
+ return;
25
+ var holder = container.getElementsByClassName('rc-tree-list-holder')[0];
26
+ var calcSpeed = function () {
27
+ var clientY = event.clientY, clientX = event.clientX;
28
+ var _a = container.getBoundingClientRect(), top = _a.top, bottom = _a.bottom, left = _a.left, right = _a.right;
29
+ var maxScroll = holder.scrollHeight - holder.clientHeight;
30
+ var insideContainer = clientY > top && clientY < bottom && clientX >= left && clientX <= right;
31
+ if (insideContainer) {
32
+ if (clientY - top < SCROLL_MARGIN && holder.scrollTop > 0) {
33
+ return (clientY - top - SCROLL_MARGIN) / SCROLL_MARGIN;
34
+ }
35
+ else if (bottom - clientY < SCROLL_MARGIN && holder.scrollTop < maxScroll) {
36
+ return -(bottom - clientY - SCROLL_MARGIN) / SCROLL_MARGIN;
37
+ }
38
+ }
39
+ return 0;
40
+ };
41
+ if (holder) {
42
+ scrollData.current = calcSpeed();
43
+ if (scrollData.current) {
44
+ runScrolling(holder);
45
+ }
46
+ }
47
+ }, UPDATE_DATA_INTERVAL), []);
48
+ var removeListeners = useCallback(function () {
49
+ var container = scrollContainer === null || scrollContainer === void 0 ? void 0 : scrollContainer.current;
50
+ if (container && typeof container.removeEventListener === 'function') {
51
+ container.removeEventListener('dragover', updateScrollData);
52
+ }
53
+ window.removeEventListener('dragover', updateScrollData);
54
+ }, [scrollContainer, updateScrollData]);
55
+ var onEndDragging = useCallback(function () {
56
+ scrolling.current = false;
57
+ scrollData.current = null;
58
+ running.current = false;
59
+ removeListeners();
60
+ }, [removeListeners]);
61
+ var runScrolling = function (holder) {
62
+ if (scrolling === null || scrolling === void 0 ? void 0 : scrolling.current) {
63
+ return;
64
+ }
65
+ scrolling.current = true;
66
+ var scroll = function () {
67
+ if (scrolling.current && scrollData.current) {
68
+ holder.scrollTop += scrollData.current * SPEED_MULTIPLIER;
69
+ requestAnimationFrame(scroll);
70
+ }
71
+ else {
72
+ scrolling.current = false;
73
+ }
74
+ };
75
+ scroll();
76
+ };
77
+ useEffect(function () {
78
+ return function () {
79
+ removeListeners();
80
+ };
81
+ }, [removeListeners]);
82
+ return { onStartDragging: onStartDragging, onEndDragging: onEndDragging, getIsScrolling: getIsScrolling };
83
+ };
package/esm/index.d.ts CHANGED
@@ -284,7 +284,7 @@ export * from './types';
284
284
  export * from './constants';
285
285
  export { TestPerspectivesSettingsProvider } from './test-utils/TestPerspectiveSettingsProvider';
286
286
  export { TestStylesProvider } from './test-utils/TestStylesProvider';
287
- export { awaitMockPromises, deepFreeze, delayPromise, getMuiIconByName, getMuiIconsByName, mockBasicTableSizing, fixClicksOnResizablePanes, mockElementSizes, rerenderWrapper, FakeMouseEvent } from './test-utils';
287
+ export { awaitMockPromises, deepFreeze, delayPromise, getMuiIconByName, getMuiIconsByName, mockBasicTableSizing, fixClicksOnResizablePanes, mockElementSizes, rerenderWrapper, FakeMouseEvent, mockComputedStyles } from './test-utils';
288
288
  export * from './features/activity-log';
289
289
  export * from './features/crosswalks';
290
290
  export * from './features/graph';
package/esm/index.js CHANGED
@@ -287,7 +287,7 @@ export * from './constants';
287
287
  // test-utils
288
288
  export { TestPerspectivesSettingsProvider } from './test-utils/TestPerspectiveSettingsProvider';
289
289
  export { TestStylesProvider } from './test-utils/TestStylesProvider';
290
- export { awaitMockPromises, deepFreeze, delayPromise, getMuiIconByName, getMuiIconsByName, mockBasicTableSizing, fixClicksOnResizablePanes, mockElementSizes, rerenderWrapper, FakeMouseEvent } from './test-utils';
290
+ export { awaitMockPromises, deepFreeze, delayPromise, getMuiIconByName, getMuiIconsByName, mockBasicTableSizing, fixClicksOnResizablePanes, mockElementSizes, rerenderWrapper, FakeMouseEvent, mockComputedStyles } from './test-utils';
291
291
  // features / activity-log
292
292
  export * from './features/activity-log';
293
293
  // features / crosswalks
@@ -11,6 +11,7 @@ export declare const mockElementSizes: (element?: HTMLElement, defaults?: {
11
11
  mock: () => void;
12
12
  unmock: () => void;
13
13
  };
14
+ export declare const mockComputedStyles: (styles?: {}) => () => void;
14
15
  export declare const mockBasicTableSizing: ({ width, height }?: {
15
16
  width?: number;
16
17
  height?: number;