@elliemae/ds-treeview 2.2.0 → 2.2.2
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/cjs/TreeView.js +2 -6
- package/cjs/TreeViewContext.js +2 -8
- package/cjs/config/useTreeview.js +3 -13
- package/cjs/hoc/DnDTreeContext.js +18 -0
- package/cjs/hoc/SortableItemContext.js +21 -0
- package/cjs/hoc/WithConditionalDnDContext.js +138 -0
- package/cjs/hoc/WithDnDSortableItemContext.js +70 -0
- package/cjs/index.js +0 -1
- package/cjs/parts/DnDHandle.js +46 -0
- package/cjs/parts/DropIndicator.js +75 -0
- package/cjs/parts/TreeItem.js +43 -68
- package/cjs/parts/TreeList.js +15 -17
- package/cjs/plugins/dnd/TreeDndPlugin.js +0 -37
- package/cjs/plugins/dnd/index.js +0 -1
- package/cjs/plugins/index.js +0 -1
- package/cjs/react-desc-prop-types.js +1 -0
- package/cjs/utils/keyboard-helpers.js +6 -5
- package/cjs/utils/tree-helpers.js +28 -2
- package/cjs/utils/useTree.js +4 -2
- package/esm/TreeView.js +2 -6
- package/esm/TreeViewContext.js +2 -8
- package/esm/config/useTreeview.js +4 -14
- package/esm/hoc/DnDTreeContext.js +14 -0
- package/esm/hoc/SortableItemContext.js +17 -0
- package/esm/hoc/WithConditionalDnDContext.js +128 -0
- package/esm/hoc/WithDnDSortableItemContext.js +61 -0
- package/esm/index.js +1 -1
- package/esm/parts/DnDHandle.js +38 -0
- package/esm/parts/DropIndicator.js +68 -0
- package/esm/parts/TreeItem.js +42 -67
- package/esm/parts/TreeList.js +16 -17
- package/esm/plugins/dnd/TreeDndPlugin.js +1 -33
- package/esm/plugins/dnd/index.js +1 -1
- package/esm/plugins/index.js +1 -1
- package/esm/react-desc-prop-types.js +1 -0
- package/esm/utils/keyboard-helpers.js +6 -5
- package/esm/utils/tree-helpers.js +28 -3
- package/esm/utils/useTree.js +5 -3
- package/package.json +34 -18
- package/types/hoc/DnDTreeContext.d.ts +14 -0
- package/types/hoc/SortableItemContext.d.ts +19 -0
- package/types/hoc/WithConditionalDnDContext.d.ts +4 -0
- package/types/hoc/WithDnDSortableItemContext.d.ts +4 -0
- package/types/parts/DnDHandle.d.ts +6 -0
- package/types/parts/DropIndicator.d.ts +10 -0
- package/types/parts/TreeItem.d.ts +4 -11
- package/types/parts/TreeList.d.ts +0 -4
- package/types/plugins/dnd/TreeDndPlugin.d.ts +0 -2
- package/types/react-desc-prop-types.d.ts +17 -3
- package/types/sharedTypes.d.ts +1 -8
- package/types/utils/keyboard-helpers.d.ts +2 -1
- package/types/utils/refs-helpers.d.ts +1 -1
- package/types/utils/tree-helpers.d.ts +4 -1
- package/types/utils/useTree.d.ts +1 -0
- package/cjs/utils/dnd-helpers.js +0 -140
- package/cjs/utils/useDnDHelpers.js +0 -220
- package/esm/utils/dnd-helpers.js +0 -132
- package/esm/utils/useDnDHelpers.js +0 -216
- package/types/utils/dnd-helpers.d.ts +0 -39
- package/types/utils/useDnDHelpers.d.ts +0 -26
|
@@ -1,220 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
-
|
|
5
|
-
require('core-js/modules/esnext.async-iterator.constructor.js');
|
|
6
|
-
require('core-js/modules/esnext.async-iterator.drop.js');
|
|
7
|
-
require('core-js/modules/esnext.iterator.constructor.js');
|
|
8
|
-
require('core-js/modules/esnext.iterator.drop.js');
|
|
9
|
-
require('core-js/modules/web.dom-collections.iterator.js');
|
|
10
|
-
var React = require('react');
|
|
11
|
-
var lodash = require('lodash');
|
|
12
|
-
var TreeViewContext = require('../TreeViewContext.js');
|
|
13
|
-
var treeHelpers = require('./tree-helpers.js');
|
|
14
|
-
var dndHelpers = require('./dnd-helpers.js');
|
|
15
|
-
|
|
16
|
-
const useDnDHelpers = () => {
|
|
17
|
-
const ctx = React.useContext(TreeViewContext["default"]);
|
|
18
|
-
const {
|
|
19
|
-
props: {
|
|
20
|
-
data,
|
|
21
|
-
onOrderChange,
|
|
22
|
-
restrictDragAndDrop
|
|
23
|
-
},
|
|
24
|
-
relativeMouseCord,
|
|
25
|
-
setRelativeMouseCord,
|
|
26
|
-
visibleItems,
|
|
27
|
-
isDragging,
|
|
28
|
-
setIsDragging,
|
|
29
|
-
isKeyboardDragging,
|
|
30
|
-
setIsKeyboardDragging,
|
|
31
|
-
setDraggedItem,
|
|
32
|
-
setFocusedItem,
|
|
33
|
-
triggerTreeRerender,
|
|
34
|
-
tree,
|
|
35
|
-
treeRoot,
|
|
36
|
-
draggedItem
|
|
37
|
-
} = ctx;
|
|
38
|
-
const onSortEnd = React.useCallback(_ref => {
|
|
39
|
-
let {
|
|
40
|
-
oldIndex,
|
|
41
|
-
newIndex,
|
|
42
|
-
isKeySorting
|
|
43
|
-
} = _ref;
|
|
44
|
-
const {
|
|
45
|
-
isBefore,
|
|
46
|
-
isAfter,
|
|
47
|
-
item: overItem,
|
|
48
|
-
isValid
|
|
49
|
-
} = relativeMouseCord;
|
|
50
|
-
|
|
51
|
-
if (draggedItem && tree && treeRoot && overItem) {
|
|
52
|
-
let newItems = lodash.cloneDeep(data); // if dropping in same position do nothing
|
|
53
|
-
// if the drop is not allowed do nothing
|
|
54
|
-
|
|
55
|
-
if (oldIndex === newIndex || !isValid) {
|
|
56
|
-
// onOrderChange(newItems, data);
|
|
57
|
-
setIsDragging(false);
|
|
58
|
-
setDraggedItem(null);
|
|
59
|
-
triggerTreeRerender();
|
|
60
|
-
return;
|
|
61
|
-
} // if we are moving from topToBottom the offset changes
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
const movementDirection = newIndex > oldIndex ? 'topToBottom' : 'bottomToTop';
|
|
65
|
-
let newNestedIndex;
|
|
66
|
-
let newParentNode;
|
|
67
|
-
|
|
68
|
-
if (isKeySorting) {
|
|
69
|
-
const kinship = dndHelpers.inferKeyboardKinshipDrop({
|
|
70
|
-
items: visibleItems,
|
|
71
|
-
newIndex
|
|
72
|
-
});
|
|
73
|
-
newNestedIndex = kinship.newNestedIndex;
|
|
74
|
-
newParentNode = kinship.newParentNode;
|
|
75
|
-
} else {
|
|
76
|
-
const kinship = dndHelpers.inferHoverItemKinshipDrop({
|
|
77
|
-
isBefore,
|
|
78
|
-
isAfter,
|
|
79
|
-
overItem,
|
|
80
|
-
movementDirection,
|
|
81
|
-
draggedItem
|
|
82
|
-
});
|
|
83
|
-
newNestedIndex = kinship.newNestedIndex;
|
|
84
|
-
newParentNode = kinship.newParentNode;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
const newMovedItemNode = tree.parse(draggedItem.node.model);
|
|
88
|
-
treeHelpers.getNodeById(treeRoot, draggedItem.id).drop();
|
|
89
|
-
|
|
90
|
-
if (newParentNode && typeof newNestedIndex === 'number') {
|
|
91
|
-
newParentNode.addChildAtIndex(newMovedItemNode, newNestedIndex);
|
|
92
|
-
|
|
93
|
-
if (newParentNode.isRoot()) {
|
|
94
|
-
newItems = [...newParentNode.model.children];
|
|
95
|
-
} else {
|
|
96
|
-
newItems = [...treeRoot.model.children];
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
onOrderChange(newItems, data, draggedItem);
|
|
101
|
-
setIsDragging(false);
|
|
102
|
-
setDraggedItem(null);
|
|
103
|
-
triggerTreeRerender();
|
|
104
|
-
}
|
|
105
|
-
}, [data, draggedItem, relativeMouseCord, visibleItems, tree, treeRoot, onOrderChange, triggerTreeRerender, setIsDragging, setDraggedItem]);
|
|
106
|
-
const onSortStart = React.useCallback(() => {}, // ({ node, index, collection, isKeySorting }, event) => {
|
|
107
|
-
// console.log('node :>> ', node);
|
|
108
|
-
// console.log('isKeySorting :>> ', isKeySorting);
|
|
109
|
-
// console.log('event :>> ', event);
|
|
110
|
-
// const item = collection?.[index] || visibleItems[index];
|
|
111
|
-
// setIsDragging(true);
|
|
112
|
-
// setDraggedItem(item);
|
|
113
|
-
// },
|
|
114
|
-
[]);
|
|
115
|
-
const updateBeforeSortStart = React.useCallback(beforeStartArgs => new Promise(resolve => {
|
|
116
|
-
const {
|
|
117
|
-
index,
|
|
118
|
-
isKeySorting
|
|
119
|
-
} = beforeStartArgs;
|
|
120
|
-
const item = visibleItems[index];
|
|
121
|
-
const {
|
|
122
|
-
isExpanded
|
|
123
|
-
} = item.node.model;
|
|
124
|
-
|
|
125
|
-
if (isExpanded) {
|
|
126
|
-
item.node.model.isExpanded = false;
|
|
127
|
-
triggerTreeRerender();
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
setRelativeMouseCord(TreeViewContext.defaultRelativeMouseCoord);
|
|
131
|
-
setIsKeyboardDragging(isKeySorting);
|
|
132
|
-
setIsDragging(true);
|
|
133
|
-
setDraggedItem(item);
|
|
134
|
-
treeHelpers.focusItem(null);
|
|
135
|
-
setFocusedItem(null);
|
|
136
|
-
if (document.activeElement && typeof document.activeElement.blur === 'function') document.activeElement.blur();
|
|
137
|
-
resolve(true);
|
|
138
|
-
}), [visibleItems, setRelativeMouseCord, setIsKeyboardDragging, setIsDragging, setDraggedItem, setFocusedItem, triggerTreeRerender]); // tracks mouse coords relative to an element to check if the drop happens
|
|
139
|
-
// at the top/center/bottom of an element to choose where to move the element
|
|
140
|
-
// requested in the specs
|
|
141
|
-
|
|
142
|
-
const onMouseDragOverItem = React.useCallback(_ref2 => {
|
|
143
|
-
let {
|
|
144
|
-
event,
|
|
145
|
-
item,
|
|
146
|
-
itemIndex,
|
|
147
|
-
setIsDraggingOverThis,
|
|
148
|
-
openFolderOnHoverTimeout
|
|
149
|
-
} = _ref2;
|
|
150
|
-
const {
|
|
151
|
-
node
|
|
152
|
-
} = item;
|
|
153
|
-
const {
|
|
154
|
-
nodeItemRef
|
|
155
|
-
} = node.model;
|
|
156
|
-
|
|
157
|
-
if (isDragging && !isKeyboardDragging && draggedItem) {
|
|
158
|
-
var _nodeItemRef$current;
|
|
159
|
-
|
|
160
|
-
const rect = nodeItemRef === null || nodeItemRef === void 0 ? void 0 : (_nodeItemRef$current = nodeItemRef.current) === null || _nodeItemRef$current === void 0 ? void 0 : _nodeItemRef$current.getBoundingClientRect();
|
|
161
|
-
|
|
162
|
-
if (rect) {
|
|
163
|
-
const x = event.clientX - rect.left; // x position within the element.
|
|
164
|
-
|
|
165
|
-
const y = event.clientY - rect.top; // y position within the element.
|
|
166
|
-
// by spec we need to track where the drop will happens
|
|
167
|
-
// if drop happens on top 25% drop before
|
|
168
|
-
// if drop happens on bottom of 25% drop after
|
|
169
|
-
// if drop happens in the middle 50% either invalid or drop into children
|
|
170
|
-
|
|
171
|
-
const {
|
|
172
|
-
height: elementHeight
|
|
173
|
-
} = rect;
|
|
174
|
-
const dropBeforeMaxY = elementHeight * 0.25;
|
|
175
|
-
const dropAfterMinY = elementHeight - elementHeight * 0.25;
|
|
176
|
-
const isBefore = y < dropBeforeMaxY;
|
|
177
|
-
const isAfter = y > dropAfterMinY;
|
|
178
|
-
const isValid = dndHelpers.isDropValid({
|
|
179
|
-
isBefore,
|
|
180
|
-
isAfter,
|
|
181
|
-
draggedItem,
|
|
182
|
-
overItem: item,
|
|
183
|
-
restrictDragAndDrop
|
|
184
|
-
});
|
|
185
|
-
setRelativeMouseCord({
|
|
186
|
-
isBefore,
|
|
187
|
-
isAfter,
|
|
188
|
-
isValid,
|
|
189
|
-
item,
|
|
190
|
-
x,
|
|
191
|
-
y,
|
|
192
|
-
relativeElementDOMRect: rect,
|
|
193
|
-
relativeElementIndex: itemIndex
|
|
194
|
-
});
|
|
195
|
-
setIsDraggingOverThis(true);
|
|
196
|
-
|
|
197
|
-
if (!(openFolderOnHoverTimeout !== null && openFolderOnHoverTimeout !== void 0 && openFolderOnHoverTimeout.current) && // only set the interval if it wasn't set already once
|
|
198
|
-
(draggedItem === null || draggedItem === void 0 ? void 0 : draggedItem.id) !== (item === null || item === void 0 ? void 0 : item.id) && ( // don't open ghost element
|
|
199
|
-
item.isGroup || item.children.length > 0) && // only open groups
|
|
200
|
-
!restrictDragAndDrop) {
|
|
201
|
-
openFolderOnHoverTimeout.current = setTimeout(() => {
|
|
202
|
-
item.node.model.isExpanded = true;
|
|
203
|
-
openFolderOnHoverTimeout.current = null;
|
|
204
|
-
triggerTreeRerender();
|
|
205
|
-
}, 1000);
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
} else {
|
|
209
|
-
setRelativeMouseCord(TreeViewContext.defaultRelativeMouseCoord);
|
|
210
|
-
}
|
|
211
|
-
}, [isDragging, isKeyboardDragging, draggedItem, restrictDragAndDrop, setRelativeMouseCord, triggerTreeRerender]);
|
|
212
|
-
return {
|
|
213
|
-
updateBeforeSortStart,
|
|
214
|
-
onSortStart,
|
|
215
|
-
onSortEnd,
|
|
216
|
-
onMouseDragOverItem
|
|
217
|
-
};
|
|
218
|
-
};
|
|
219
|
-
|
|
220
|
-
exports.useDnDHelpers = useDnDHelpers;
|
package/esm/utils/dnd-helpers.js
DELETED
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
import { getItemsParentNode, itemsShareSameParent } from './tree-helpers.js';
|
|
2
|
-
|
|
3
|
-
/* eslint-disable max-lines */
|
|
4
|
-
const keyCodes = {
|
|
5
|
-
lift: [32, 13],
|
|
6
|
-
drop: [32, 13],
|
|
7
|
-
cancel: [27],
|
|
8
|
-
up: [38, 37],
|
|
9
|
-
down: [40, 39]
|
|
10
|
-
};
|
|
11
|
-
const sameParentAsHoverItemDrop = _ref => {
|
|
12
|
-
let {
|
|
13
|
-
isBefore,
|
|
14
|
-
isAfter,
|
|
15
|
-
draggedItem,
|
|
16
|
-
overItem,
|
|
17
|
-
movementDirection
|
|
18
|
-
} = _ref;
|
|
19
|
-
const hoveredItemNodeNestedIndex = overItem.node.getIndex();
|
|
20
|
-
let newParentNode = getItemsParentNode([overItem], true);
|
|
21
|
-
const {
|
|
22
|
-
treeDepth: draggedItemTreeDepth
|
|
23
|
-
} = draggedItem;
|
|
24
|
-
const {
|
|
25
|
-
treeDepth: overItemTreeDepth
|
|
26
|
-
} = overItem;
|
|
27
|
-
const directionOffset = // we don't apply the offset for direction
|
|
28
|
-
// if moving from less nested to more nested
|
|
29
|
-
// or moving bottom to top
|
|
30
|
-
// the offset is required when moving elemnts down in their nest level
|
|
31
|
-
draggedItemTreeDepth <= overItemTreeDepth && movementDirection === 'topToBottom' ? -1 : 0;
|
|
32
|
-
let newNestedIndex;
|
|
33
|
-
if (isBefore) newNestedIndex = hoveredItemNodeNestedIndex + directionOffset;else if (isAfter) newNestedIndex = hoveredItemNodeNestedIndex + 1 + directionOffset;else {
|
|
34
|
-
newNestedIndex = overItem.children.length; // append as last child of the group
|
|
35
|
-
|
|
36
|
-
newParentNode = overItem.node;
|
|
37
|
-
}
|
|
38
|
-
if (newNestedIndex < 0) newNestedIndex = 0;
|
|
39
|
-
return {
|
|
40
|
-
newNestedIndex,
|
|
41
|
-
newParentNode
|
|
42
|
-
};
|
|
43
|
-
};
|
|
44
|
-
const inferHoverItemKinshipDrop = _ref2 => {
|
|
45
|
-
let {
|
|
46
|
-
isBefore,
|
|
47
|
-
isAfter,
|
|
48
|
-
draggedItem,
|
|
49
|
-
overItem,
|
|
50
|
-
movementDirection
|
|
51
|
-
} = _ref2;
|
|
52
|
-
const hoverItemModel = overItem.node.model;
|
|
53
|
-
const isGroupAndIsExpanded = hoverItemModel.isExpanded && hoverItemModel.children.length > 0;
|
|
54
|
-
|
|
55
|
-
if (isAfter && isGroupAndIsExpanded) {
|
|
56
|
-
return {
|
|
57
|
-
newNestedIndex: 0,
|
|
58
|
-
// append after the group, so basically as first child
|
|
59
|
-
newParentNode: overItem.node
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if (isBefore || isAfter && !isGroupAndIsExpanded) {
|
|
64
|
-
return sameParentAsHoverItemDrop({
|
|
65
|
-
isBefore,
|
|
66
|
-
isAfter,
|
|
67
|
-
draggedItem,
|
|
68
|
-
overItem,
|
|
69
|
-
movementDirection
|
|
70
|
-
});
|
|
71
|
-
} // drop inside
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
return {
|
|
75
|
-
newNestedIndex: overItem.children.length,
|
|
76
|
-
// append as last child of the group
|
|
77
|
-
newParentNode: overItem.node
|
|
78
|
-
};
|
|
79
|
-
};
|
|
80
|
-
const isDropValid = _ref3 => {
|
|
81
|
-
let {
|
|
82
|
-
isBefore,
|
|
83
|
-
isAfter,
|
|
84
|
-
draggedItem,
|
|
85
|
-
overItem,
|
|
86
|
-
restrictDragAndDrop
|
|
87
|
-
} = _ref3;
|
|
88
|
-
const {
|
|
89
|
-
id: movedId
|
|
90
|
-
} = draggedItem;
|
|
91
|
-
const {
|
|
92
|
-
id: hoverId
|
|
93
|
-
} = overItem;
|
|
94
|
-
const isInside = !isBefore && !isAfter;
|
|
95
|
-
if (movedId === hoverId) return false;
|
|
96
|
-
|
|
97
|
-
if (isInside && !overItem.isGroup) {
|
|
98
|
-
return false; // we can't drop inside an item that isn't a group
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
if (restrictDragAndDrop) {
|
|
102
|
-
if (isInside) return false; // in this mode we can't drop inside another element
|
|
103
|
-
|
|
104
|
-
const sameParent = itemsShareSameParent([draggedItem, overItem]);
|
|
105
|
-
if (overItem.node.model.isExpanded && isAfter) return false;
|
|
106
|
-
if (!sameParent) return false;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
return true;
|
|
110
|
-
};
|
|
111
|
-
const inferKeyboardKinshipDrop = _ref4 => {
|
|
112
|
-
let {
|
|
113
|
-
items,
|
|
114
|
-
newIndex
|
|
115
|
-
} = _ref4;
|
|
116
|
-
const kinship = {};
|
|
117
|
-
const itemBefore = items[newIndex];
|
|
118
|
-
const itemBeforeModel = itemBefore.node.model;
|
|
119
|
-
const isGroupAndIsExpanded = itemBeforeModel.isExpanded && itemBeforeModel.children.length > 0;
|
|
120
|
-
|
|
121
|
-
if (isGroupAndIsExpanded) {
|
|
122
|
-
kinship.newParentNode = itemBefore.node;
|
|
123
|
-
kinship.newNestedIndex = 0;
|
|
124
|
-
} else {
|
|
125
|
-
kinship.newParentNode = getItemsParentNode([itemBefore], true);
|
|
126
|
-
kinship.newNestedIndex = itemBefore.node.getIndex();
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
return kinship;
|
|
130
|
-
};
|
|
131
|
-
|
|
132
|
-
export { inferHoverItemKinshipDrop, inferKeyboardKinshipDrop, isDropValid, keyCodes, sameParentAsHoverItemDrop };
|
|
@@ -1,216 +0,0 @@
|
|
|
1
|
-
import 'core-js/modules/esnext.async-iterator.constructor.js';
|
|
2
|
-
import 'core-js/modules/esnext.async-iterator.drop.js';
|
|
3
|
-
import 'core-js/modules/esnext.iterator.constructor.js';
|
|
4
|
-
import 'core-js/modules/esnext.iterator.drop.js';
|
|
5
|
-
import 'core-js/modules/web.dom-collections.iterator.js';
|
|
6
|
-
import { useContext, useCallback } from 'react';
|
|
7
|
-
import { cloneDeep } from 'lodash';
|
|
8
|
-
import TreeViewContext, { defaultRelativeMouseCoord } from '../TreeViewContext.js';
|
|
9
|
-
import { getNodeById, focusItem } from './tree-helpers.js';
|
|
10
|
-
import { inferKeyboardKinshipDrop, inferHoverItemKinshipDrop, isDropValid } from './dnd-helpers.js';
|
|
11
|
-
|
|
12
|
-
const useDnDHelpers = () => {
|
|
13
|
-
const ctx = useContext(TreeViewContext);
|
|
14
|
-
const {
|
|
15
|
-
props: {
|
|
16
|
-
data,
|
|
17
|
-
onOrderChange,
|
|
18
|
-
restrictDragAndDrop
|
|
19
|
-
},
|
|
20
|
-
relativeMouseCord,
|
|
21
|
-
setRelativeMouseCord,
|
|
22
|
-
visibleItems,
|
|
23
|
-
isDragging,
|
|
24
|
-
setIsDragging,
|
|
25
|
-
isKeyboardDragging,
|
|
26
|
-
setIsKeyboardDragging,
|
|
27
|
-
setDraggedItem,
|
|
28
|
-
setFocusedItem,
|
|
29
|
-
triggerTreeRerender,
|
|
30
|
-
tree,
|
|
31
|
-
treeRoot,
|
|
32
|
-
draggedItem
|
|
33
|
-
} = ctx;
|
|
34
|
-
const onSortEnd = useCallback(_ref => {
|
|
35
|
-
let {
|
|
36
|
-
oldIndex,
|
|
37
|
-
newIndex,
|
|
38
|
-
isKeySorting
|
|
39
|
-
} = _ref;
|
|
40
|
-
const {
|
|
41
|
-
isBefore,
|
|
42
|
-
isAfter,
|
|
43
|
-
item: overItem,
|
|
44
|
-
isValid
|
|
45
|
-
} = relativeMouseCord;
|
|
46
|
-
|
|
47
|
-
if (draggedItem && tree && treeRoot && overItem) {
|
|
48
|
-
let newItems = cloneDeep(data); // if dropping in same position do nothing
|
|
49
|
-
// if the drop is not allowed do nothing
|
|
50
|
-
|
|
51
|
-
if (oldIndex === newIndex || !isValid) {
|
|
52
|
-
// onOrderChange(newItems, data);
|
|
53
|
-
setIsDragging(false);
|
|
54
|
-
setDraggedItem(null);
|
|
55
|
-
triggerTreeRerender();
|
|
56
|
-
return;
|
|
57
|
-
} // if we are moving from topToBottom the offset changes
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
const movementDirection = newIndex > oldIndex ? 'topToBottom' : 'bottomToTop';
|
|
61
|
-
let newNestedIndex;
|
|
62
|
-
let newParentNode;
|
|
63
|
-
|
|
64
|
-
if (isKeySorting) {
|
|
65
|
-
const kinship = inferKeyboardKinshipDrop({
|
|
66
|
-
items: visibleItems,
|
|
67
|
-
newIndex
|
|
68
|
-
});
|
|
69
|
-
newNestedIndex = kinship.newNestedIndex;
|
|
70
|
-
newParentNode = kinship.newParentNode;
|
|
71
|
-
} else {
|
|
72
|
-
const kinship = inferHoverItemKinshipDrop({
|
|
73
|
-
isBefore,
|
|
74
|
-
isAfter,
|
|
75
|
-
overItem,
|
|
76
|
-
movementDirection,
|
|
77
|
-
draggedItem
|
|
78
|
-
});
|
|
79
|
-
newNestedIndex = kinship.newNestedIndex;
|
|
80
|
-
newParentNode = kinship.newParentNode;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
const newMovedItemNode = tree.parse(draggedItem.node.model);
|
|
84
|
-
getNodeById(treeRoot, draggedItem.id).drop();
|
|
85
|
-
|
|
86
|
-
if (newParentNode && typeof newNestedIndex === 'number') {
|
|
87
|
-
newParentNode.addChildAtIndex(newMovedItemNode, newNestedIndex);
|
|
88
|
-
|
|
89
|
-
if (newParentNode.isRoot()) {
|
|
90
|
-
newItems = [...newParentNode.model.children];
|
|
91
|
-
} else {
|
|
92
|
-
newItems = [...treeRoot.model.children];
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
onOrderChange(newItems, data, draggedItem);
|
|
97
|
-
setIsDragging(false);
|
|
98
|
-
setDraggedItem(null);
|
|
99
|
-
triggerTreeRerender();
|
|
100
|
-
}
|
|
101
|
-
}, [data, draggedItem, relativeMouseCord, visibleItems, tree, treeRoot, onOrderChange, triggerTreeRerender, setIsDragging, setDraggedItem]);
|
|
102
|
-
const onSortStart = useCallback(() => {}, // ({ node, index, collection, isKeySorting }, event) => {
|
|
103
|
-
// console.log('node :>> ', node);
|
|
104
|
-
// console.log('isKeySorting :>> ', isKeySorting);
|
|
105
|
-
// console.log('event :>> ', event);
|
|
106
|
-
// const item = collection?.[index] || visibleItems[index];
|
|
107
|
-
// setIsDragging(true);
|
|
108
|
-
// setDraggedItem(item);
|
|
109
|
-
// },
|
|
110
|
-
[]);
|
|
111
|
-
const updateBeforeSortStart = useCallback(beforeStartArgs => new Promise(resolve => {
|
|
112
|
-
const {
|
|
113
|
-
index,
|
|
114
|
-
isKeySorting
|
|
115
|
-
} = beforeStartArgs;
|
|
116
|
-
const item = visibleItems[index];
|
|
117
|
-
const {
|
|
118
|
-
isExpanded
|
|
119
|
-
} = item.node.model;
|
|
120
|
-
|
|
121
|
-
if (isExpanded) {
|
|
122
|
-
item.node.model.isExpanded = false;
|
|
123
|
-
triggerTreeRerender();
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
setRelativeMouseCord(defaultRelativeMouseCoord);
|
|
127
|
-
setIsKeyboardDragging(isKeySorting);
|
|
128
|
-
setIsDragging(true);
|
|
129
|
-
setDraggedItem(item);
|
|
130
|
-
focusItem(null);
|
|
131
|
-
setFocusedItem(null);
|
|
132
|
-
if (document.activeElement && typeof document.activeElement.blur === 'function') document.activeElement.blur();
|
|
133
|
-
resolve(true);
|
|
134
|
-
}), [visibleItems, setRelativeMouseCord, setIsKeyboardDragging, setIsDragging, setDraggedItem, setFocusedItem, triggerTreeRerender]); // tracks mouse coords relative to an element to check if the drop happens
|
|
135
|
-
// at the top/center/bottom of an element to choose where to move the element
|
|
136
|
-
// requested in the specs
|
|
137
|
-
|
|
138
|
-
const onMouseDragOverItem = useCallback(_ref2 => {
|
|
139
|
-
let {
|
|
140
|
-
event,
|
|
141
|
-
item,
|
|
142
|
-
itemIndex,
|
|
143
|
-
setIsDraggingOverThis,
|
|
144
|
-
openFolderOnHoverTimeout
|
|
145
|
-
} = _ref2;
|
|
146
|
-
const {
|
|
147
|
-
node
|
|
148
|
-
} = item;
|
|
149
|
-
const {
|
|
150
|
-
nodeItemRef
|
|
151
|
-
} = node.model;
|
|
152
|
-
|
|
153
|
-
if (isDragging && !isKeyboardDragging && draggedItem) {
|
|
154
|
-
var _nodeItemRef$current;
|
|
155
|
-
|
|
156
|
-
const rect = nodeItemRef === null || nodeItemRef === void 0 ? void 0 : (_nodeItemRef$current = nodeItemRef.current) === null || _nodeItemRef$current === void 0 ? void 0 : _nodeItemRef$current.getBoundingClientRect();
|
|
157
|
-
|
|
158
|
-
if (rect) {
|
|
159
|
-
const x = event.clientX - rect.left; // x position within the element.
|
|
160
|
-
|
|
161
|
-
const y = event.clientY - rect.top; // y position within the element.
|
|
162
|
-
// by spec we need to track where the drop will happens
|
|
163
|
-
// if drop happens on top 25% drop before
|
|
164
|
-
// if drop happens on bottom of 25% drop after
|
|
165
|
-
// if drop happens in the middle 50% either invalid or drop into children
|
|
166
|
-
|
|
167
|
-
const {
|
|
168
|
-
height: elementHeight
|
|
169
|
-
} = rect;
|
|
170
|
-
const dropBeforeMaxY = elementHeight * 0.25;
|
|
171
|
-
const dropAfterMinY = elementHeight - elementHeight * 0.25;
|
|
172
|
-
const isBefore = y < dropBeforeMaxY;
|
|
173
|
-
const isAfter = y > dropAfterMinY;
|
|
174
|
-
const isValid = isDropValid({
|
|
175
|
-
isBefore,
|
|
176
|
-
isAfter,
|
|
177
|
-
draggedItem,
|
|
178
|
-
overItem: item,
|
|
179
|
-
restrictDragAndDrop
|
|
180
|
-
});
|
|
181
|
-
setRelativeMouseCord({
|
|
182
|
-
isBefore,
|
|
183
|
-
isAfter,
|
|
184
|
-
isValid,
|
|
185
|
-
item,
|
|
186
|
-
x,
|
|
187
|
-
y,
|
|
188
|
-
relativeElementDOMRect: rect,
|
|
189
|
-
relativeElementIndex: itemIndex
|
|
190
|
-
});
|
|
191
|
-
setIsDraggingOverThis(true);
|
|
192
|
-
|
|
193
|
-
if (!(openFolderOnHoverTimeout !== null && openFolderOnHoverTimeout !== void 0 && openFolderOnHoverTimeout.current) && // only set the interval if it wasn't set already once
|
|
194
|
-
(draggedItem === null || draggedItem === void 0 ? void 0 : draggedItem.id) !== (item === null || item === void 0 ? void 0 : item.id) && ( // don't open ghost element
|
|
195
|
-
item.isGroup || item.children.length > 0) && // only open groups
|
|
196
|
-
!restrictDragAndDrop) {
|
|
197
|
-
openFolderOnHoverTimeout.current = setTimeout(() => {
|
|
198
|
-
item.node.model.isExpanded = true;
|
|
199
|
-
openFolderOnHoverTimeout.current = null;
|
|
200
|
-
triggerTreeRerender();
|
|
201
|
-
}, 1000);
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
} else {
|
|
205
|
-
setRelativeMouseCord(defaultRelativeMouseCoord);
|
|
206
|
-
}
|
|
207
|
-
}, [isDragging, isKeyboardDragging, draggedItem, restrictDragAndDrop, setRelativeMouseCord, triggerTreeRerender]);
|
|
208
|
-
return {
|
|
209
|
-
updateBeforeSortStart,
|
|
210
|
-
onSortStart,
|
|
211
|
-
onSortEnd,
|
|
212
|
-
onMouseDragOverItem
|
|
213
|
-
};
|
|
214
|
-
};
|
|
215
|
-
|
|
216
|
-
export { useDnDHelpers };
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import type { DSTreeviewT } from '../react-desc-prop-types';
|
|
2
|
-
import type { DSTreeviewInternalsT } from '../sharedTypes';
|
|
3
|
-
interface MetaInfoT {
|
|
4
|
-
isBefore: boolean;
|
|
5
|
-
isAfter: boolean;
|
|
6
|
-
draggedItem: DSTreeviewT.Item;
|
|
7
|
-
overItem: DSTreeviewT.Item;
|
|
8
|
-
}
|
|
9
|
-
interface KinshipT {
|
|
10
|
-
newParentNode: DSTreeviewT.Item['node'];
|
|
11
|
-
newNestedIndex: number;
|
|
12
|
-
}
|
|
13
|
-
export declare const keyCodes: {
|
|
14
|
-
lift: number[];
|
|
15
|
-
drop: number[];
|
|
16
|
-
cancel: number[];
|
|
17
|
-
up: number[];
|
|
18
|
-
down: number[];
|
|
19
|
-
};
|
|
20
|
-
export declare const sameParentAsHoverItemDrop: ({ isBefore, isAfter, draggedItem, overItem, movementDirection, }: MetaInfoT & {
|
|
21
|
-
movementDirection: DSTreeviewInternalsT.DnDMovementDirectionT;
|
|
22
|
-
}) => {
|
|
23
|
-
newNestedIndex: number;
|
|
24
|
-
newParentNode: import("tree-model/types").Node<DSTreeviewT.Item>;
|
|
25
|
-
};
|
|
26
|
-
export declare const inferHoverItemKinshipDrop: ({ isBefore, isAfter, draggedItem, overItem, movementDirection, }: MetaInfoT & {
|
|
27
|
-
movementDirection: DSTreeviewInternalsT.DnDMovementDirectionT;
|
|
28
|
-
}) => {
|
|
29
|
-
newNestedIndex: number;
|
|
30
|
-
newParentNode: import("tree-model/types").Node<DSTreeviewT.Item>;
|
|
31
|
-
};
|
|
32
|
-
export declare const isDropValid: ({ isBefore, isAfter, draggedItem, overItem, restrictDragAndDrop, }: MetaInfoT & {
|
|
33
|
-
restrictDragAndDrop: boolean;
|
|
34
|
-
}) => boolean;
|
|
35
|
-
export declare const inferKeyboardKinshipDrop: ({ items, newIndex, }: {
|
|
36
|
-
items: DSTreeviewT.Item[];
|
|
37
|
-
newIndex: number;
|
|
38
|
-
}) => Partial<KinshipT>;
|
|
39
|
-
export {};
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
/// <reference types="mocha" />
|
|
3
|
-
/// <reference types="webpack-env" />
|
|
4
|
-
/// <reference types="styled-components" />
|
|
5
|
-
import React from 'react';
|
|
6
|
-
import type { DSTreeviewT } from '../react-desc-prop-types';
|
|
7
|
-
import type { DSTreeviewInternalsT } from '../sharedTypes';
|
|
8
|
-
export declare const useDnDHelpers: () => {
|
|
9
|
-
updateBeforeSortStart: (beforeStartArgs: {
|
|
10
|
-
index: number;
|
|
11
|
-
isKeySorting: boolean;
|
|
12
|
-
}) => Promise<unknown>;
|
|
13
|
-
onSortStart: () => void;
|
|
14
|
-
onSortEnd: ({ oldIndex, newIndex, isKeySorting }: {
|
|
15
|
-
oldIndex: number;
|
|
16
|
-
newIndex: number;
|
|
17
|
-
isKeySorting: boolean;
|
|
18
|
-
}) => void;
|
|
19
|
-
onMouseDragOverItem: ({ event, item, itemIndex, setIsDraggingOverThis, openFolderOnHoverTimeout, }: {
|
|
20
|
-
event: React.MouseEvent<HTMLLIElement>;
|
|
21
|
-
item: DSTreeviewT.Item;
|
|
22
|
-
itemIndex: number;
|
|
23
|
-
setIsDraggingOverThis: DSTreeviewInternalsT.StateSetter<boolean>;
|
|
24
|
-
openFolderOnHoverTimeout: React.MutableRefObject<NodeJS.Timeout | null>;
|
|
25
|
-
}) => void;
|
|
26
|
-
};
|