@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
|
@@ -15,14 +15,13 @@ import { toggleItemExpand, toggleExpandAllHelper } from './group-expands-helpers
|
|
|
15
15
|
// 36 home
|
|
16
16
|
// 56 number 8
|
|
17
17
|
// 106 (NumPad) *
|
|
18
|
-
const useOnItemKeyDown = item => {
|
|
18
|
+
const useOnItemKeyDown = (item, draggableProps) => {
|
|
19
19
|
const ctx = useContext(TreeViewContext);
|
|
20
20
|
const {
|
|
21
21
|
props: {
|
|
22
22
|
onItemFocus
|
|
23
23
|
},
|
|
24
24
|
triggerTreeRerender,
|
|
25
|
-
isDragging,
|
|
26
25
|
visibleItems,
|
|
27
26
|
setFocusedItem,
|
|
28
27
|
setSelectedItem,
|
|
@@ -51,10 +50,12 @@ const useOnItemKeyDown = item => {
|
|
|
51
50
|
keyCode
|
|
52
51
|
} = e;
|
|
53
52
|
|
|
54
|
-
if (!
|
|
53
|
+
if (!(draggableProps && draggableProps.active)) {
|
|
55
54
|
if (keyCode !== 9) e.preventDefault(); // allow tab/shift+tab
|
|
56
55
|
|
|
57
|
-
if (keyCode === 13 || keyCode === 32)
|
|
56
|
+
if ((keyCode === 13 || keyCode === 32) && e.target.tagName === 'LI') {
|
|
57
|
+
setSelectedItem(item);
|
|
58
|
+
}
|
|
58
59
|
|
|
59
60
|
if (keyCode === 37) {
|
|
60
61
|
if (isGroup && isExpanded) {
|
|
@@ -142,7 +143,7 @@ const useOnItemKeyDown = item => {
|
|
|
142
143
|
}
|
|
143
144
|
}
|
|
144
145
|
}
|
|
145
|
-
}, [
|
|
146
|
+
}, [draggableProps, setSelectedItem, item, isGroup, isExpanded, triggerTreeRerender, updateUserExpandedState, scrollToIndex, setLatestToggledItem, visibleItems, setFocusedItem, onItemFocusCurry]);
|
|
146
147
|
return onItemKeyDown;
|
|
147
148
|
};
|
|
148
149
|
const useGlobalKeyboardListener = func => {
|
|
@@ -128,7 +128,7 @@ const getChildrenMatchesSearchQuery = function (parentNode) {
|
|
|
128
128
|
*/
|
|
129
129
|
|
|
130
130
|
const enrichNodeModelInPlace = function (node) {
|
|
131
|
-
var _node$model, _node$model$children;
|
|
131
|
+
var _node$model$children$, _node$model, _node$model$children;
|
|
132
132
|
|
|
133
133
|
let searchQuery = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
|
|
134
134
|
let selection = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
|
|
@@ -144,7 +144,7 @@ const enrichNodeModelInPlace = function (node) {
|
|
|
144
144
|
// this is useful to avoid having to always check both the flag and the children.length...
|
|
145
145
|
|
|
146
146
|
|
|
147
|
-
if (typeof node.model.isGroup !== 'boolean' && ((_node$model = node.model) === null || _node$model === void 0 ? void 0 : (_node$model$children = _node$model.children) === null || _node$model$children === void 0 ? void 0 : _node$model$children.length) > 0) {
|
|
147
|
+
if (typeof node.model.isGroup !== 'boolean' && ((_node$model$children$ = (_node$model = node.model) === null || _node$model === void 0 ? void 0 : (_node$model$children = _node$model.children) === null || _node$model$children === void 0 ? void 0 : _node$model$children.length) !== null && _node$model$children$ !== void 0 ? _node$model$children$ : 0) > 0) {
|
|
148
148
|
node.model.isGroup = true;
|
|
149
149
|
}
|
|
150
150
|
|
|
@@ -176,5 +176,30 @@ const focusItem = item => {
|
|
|
176
176
|
|
|
177
177
|
item === null || item === void 0 ? void 0 : (_item$nodeItemRef = item.nodeItemRef) === null || _item$nodeItemRef === void 0 ? void 0 : (_item$nodeItemRef$cur = _item$nodeItemRef.current) === null || _item$nodeItemRef$cur === void 0 ? void 0 : _item$nodeItemRef$cur.focus();
|
|
178
178
|
};
|
|
179
|
+
const flattenTreeForDnD = function (data) {
|
|
180
|
+
let shouldDescend = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : () => true;
|
|
181
|
+
const flattenedTree = [];
|
|
182
|
+
let index = 0;
|
|
183
|
+
|
|
184
|
+
const doit = function (node) {
|
|
185
|
+
var _node$children$length, _node$children, _node$children2;
|
|
186
|
+
|
|
187
|
+
let depth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
|
|
188
|
+
let parentId = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
|
|
189
|
+
flattenedTree.push({
|
|
190
|
+
uid: node.id.toString(),
|
|
191
|
+
depth,
|
|
192
|
+
realIndex: index,
|
|
193
|
+
childrenCount: (_node$children$length = (_node$children = node.children) === null || _node$children === void 0 ? void 0 : _node$children.length) !== null && _node$children$length !== void 0 ? _node$children$length : 0,
|
|
194
|
+
parentId: parentId !== null ? parentId.toString() : null,
|
|
195
|
+
original: node
|
|
196
|
+
});
|
|
197
|
+
index += 1;
|
|
198
|
+
if (shouldDescend(node)) (_node$children2 = node.children) === null || _node$children2 === void 0 ? void 0 : _node$children2.forEach(child => doit(child, depth + 1, node.id.toString()));
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
data.forEach(datum => doit(datum));
|
|
202
|
+
return flattenedTree;
|
|
203
|
+
};
|
|
179
204
|
|
|
180
|
-
export { cloneNode, enrichNodeModelInPlace, focusItem, getChildrenMatchesSearchQuery, getItemsParentNode, getNodeById, getNodeMatchesSearchQuery, itemsShareSameParent, walkAllNodeChildren, walkParents, walkVisibles };
|
|
205
|
+
export { cloneNode, enrichNodeModelInPlace, flattenTreeForDnD, focusItem, getChildrenMatchesSearchQuery, getItemsParentNode, getNodeById, getNodeMatchesSearchQuery, itemsShareSameParent, walkAllNodeChildren, walkParents, walkVisibles };
|
package/esm/utils/useTree.js
CHANGED
|
@@ -8,7 +8,7 @@ import 'core-js/modules/web.dom-collections.iterator.js';
|
|
|
8
8
|
import { useMemo, useState, useEffect, useCallback } from 'react';
|
|
9
9
|
import TreeModel from 'tree-model';
|
|
10
10
|
import { cloneDeep } from 'lodash';
|
|
11
|
-
import { enrichNodeModelInPlace, walkVisibles } from './tree-helpers.js';
|
|
11
|
+
import { enrichNodeModelInPlace, walkVisibles, flattenTreeForDnD } from './tree-helpers.js';
|
|
12
12
|
import { updateExpandedState } from './group-expands-helpers.js';
|
|
13
13
|
|
|
14
14
|
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
@@ -67,9 +67,9 @@ const useTree = (data, props, states) => {
|
|
|
67
67
|
useEffect(() => {
|
|
68
68
|
const parsedVisibleItems = [];
|
|
69
69
|
const newExpandedHashMap = {};
|
|
70
|
-
|
|
71
|
-
const shouldContinueWalking = true; // tree-model ask we return true if we want to continue walking
|
|
70
|
+
const shouldContinueWalking = true; // tree-model ask we return true if we want to continue walking
|
|
72
71
|
|
|
72
|
+
treeRoot.walk(node => {
|
|
73
73
|
enrichNodeModelInPlace(node, searchQuery, selection, expanded);
|
|
74
74
|
if (node.model.id && node.model.isGroup && node.model.isExpanded) newExpandedHashMap[node.model.id] = true;
|
|
75
75
|
return shouldContinueWalking;
|
|
@@ -84,8 +84,10 @@ const useTree = (data, props, states) => {
|
|
|
84
84
|
setExpandedGroups(newExpandedHashMap); // eslint-disable-next-line react-hooks/exhaustive-deps
|
|
85
85
|
}, [treeRoot, rerenderItems, searchQuery, highlightOnlyQuery, selection, expanded, setExpandedGroups // onVisibleItemsChange // evaluate potential performance hit?
|
|
86
86
|
]);
|
|
87
|
+
const flattenedItems = useMemo(() => flattenTreeForDnD(data), [data]);
|
|
87
88
|
return {
|
|
88
89
|
visibleItems,
|
|
90
|
+
flattenedItems,
|
|
89
91
|
tree,
|
|
90
92
|
treeRoot,
|
|
91
93
|
rerenderItems,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elliemae/ds-treeview",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.2",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "ICE MT - Dimsum - Tree View",
|
|
6
6
|
"module": "./esm/index.js",
|
|
@@ -19,10 +19,6 @@
|
|
|
19
19
|
"import": "./esm/utils/useInstanceRefActions.js",
|
|
20
20
|
"require": "./cjs/utils/useInstanceRefActions.js"
|
|
21
21
|
},
|
|
22
|
-
"./utils/useDnDHelpers": {
|
|
23
|
-
"import": "./esm/utils/useDnDHelpers.js",
|
|
24
|
-
"require": "./cjs/utils/useDnDHelpers.js"
|
|
25
|
-
},
|
|
26
22
|
"./utils/tree-helpers": {
|
|
27
23
|
"import": "./esm/utils/tree-helpers.js",
|
|
28
24
|
"require": "./cjs/utils/tree-helpers.js"
|
|
@@ -51,10 +47,6 @@
|
|
|
51
47
|
"import": "./esm/utils/group-expands-helpers.js",
|
|
52
48
|
"require": "./cjs/utils/group-expands-helpers.js"
|
|
53
49
|
},
|
|
54
|
-
"./utils/dnd-helpers": {
|
|
55
|
-
"import": "./esm/utils/dnd-helpers.js",
|
|
56
|
-
"require": "./cjs/utils/dnd-helpers.js"
|
|
57
|
-
},
|
|
58
50
|
"./utils/array-helpers": {
|
|
59
51
|
"import": "./esm/utils/array-helpers.js",
|
|
60
52
|
"require": "./cjs/utils/array-helpers.js"
|
|
@@ -167,6 +159,14 @@
|
|
|
167
159
|
"import": "./esm/parts/ExpandCaret.js",
|
|
168
160
|
"require": "./cjs/parts/ExpandCaret.js"
|
|
169
161
|
},
|
|
162
|
+
"./parts/DropIndicator": {
|
|
163
|
+
"import": "./esm/parts/DropIndicator.js",
|
|
164
|
+
"require": "./cjs/parts/DropIndicator.js"
|
|
165
|
+
},
|
|
166
|
+
"./parts/DnDHandle": {
|
|
167
|
+
"import": "./esm/parts/DnDHandle.js",
|
|
168
|
+
"require": "./cjs/parts/DnDHandle.js"
|
|
169
|
+
},
|
|
170
170
|
"./parts/ChildrenCountDisplayer": {
|
|
171
171
|
"import": "./esm/parts/ChildrenCountDisplayer.js",
|
|
172
172
|
"require": "./cjs/parts/ChildrenCountDisplayer.js"
|
|
@@ -175,6 +175,22 @@
|
|
|
175
175
|
"import": "./esm/parts/CheckboxSelectable.js",
|
|
176
176
|
"require": "./cjs/parts/CheckboxSelectable.js"
|
|
177
177
|
},
|
|
178
|
+
"./hoc/WithDnDSortableItemContext": {
|
|
179
|
+
"import": "./esm/hoc/WithDnDSortableItemContext.js",
|
|
180
|
+
"require": "./cjs/hoc/WithDnDSortableItemContext.js"
|
|
181
|
+
},
|
|
182
|
+
"./hoc/WithConditionalDnDContext": {
|
|
183
|
+
"import": "./esm/hoc/WithConditionalDnDContext.js",
|
|
184
|
+
"require": "./cjs/hoc/WithConditionalDnDContext.js"
|
|
185
|
+
},
|
|
186
|
+
"./hoc/SortableItemContext": {
|
|
187
|
+
"import": "./esm/hoc/SortableItemContext.js",
|
|
188
|
+
"require": "./cjs/hoc/SortableItemContext.js"
|
|
189
|
+
},
|
|
190
|
+
"./hoc/DnDTreeContext": {
|
|
191
|
+
"import": "./esm/hoc/DnDTreeContext.js",
|
|
192
|
+
"require": "./cjs/hoc/DnDTreeContext.js"
|
|
193
|
+
},
|
|
178
194
|
"./config/useTreeview": {
|
|
179
195
|
"import": "./esm/config/useTreeview.js",
|
|
180
196
|
"require": "./cjs/config/useTreeview.js"
|
|
@@ -211,15 +227,15 @@
|
|
|
211
227
|
"generateSubmodules": true
|
|
212
228
|
},
|
|
213
229
|
"dependencies": {
|
|
214
|
-
"@elliemae/ds-button": "2.2.
|
|
215
|
-
"@elliemae/ds-circular-progress-indicator": "2.2.
|
|
216
|
-
"@elliemae/ds-classnames": "2.2.
|
|
217
|
-
"@elliemae/ds-form": "2.2.
|
|
218
|
-
"@elliemae/ds-icons": "2.2.
|
|
219
|
-
"@elliemae/ds-props-helpers": "2.2.
|
|
220
|
-
"@elliemae/ds-shared": "2.2.
|
|
221
|
-
"@elliemae/ds-truncated-tooltip-text": "2.2.
|
|
222
|
-
"@elliemae/ds-utilities": "2.2.
|
|
230
|
+
"@elliemae/ds-button": "2.2.2",
|
|
231
|
+
"@elliemae/ds-circular-progress-indicator": "2.2.2",
|
|
232
|
+
"@elliemae/ds-classnames": "2.2.2",
|
|
233
|
+
"@elliemae/ds-form": "2.2.2",
|
|
234
|
+
"@elliemae/ds-icons": "2.2.2",
|
|
235
|
+
"@elliemae/ds-props-helpers": "2.2.2",
|
|
236
|
+
"@elliemae/ds-shared": "2.2.2",
|
|
237
|
+
"@elliemae/ds-truncated-tooltip-text": "2.2.2",
|
|
238
|
+
"@elliemae/ds-utilities": "2.2.2",
|
|
223
239
|
"@elliemae/react-sortable-hoc": "^1.0.0",
|
|
224
240
|
"react-desc": "~4.1.3",
|
|
225
241
|
"react-highlight-words": "~0.17.0",
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { DSTreeviewT } from '../react-desc-prop-types';
|
|
3
|
+
import { DropIndicatorPosition } from './SortableItemContext';
|
|
4
|
+
declare type DnDTreeContextType = {
|
|
5
|
+
depth: number | undefined;
|
|
6
|
+
activeIndex: number | undefined;
|
|
7
|
+
visibleItems: DSTreeviewT.Item[] | undefined;
|
|
8
|
+
dropIndicatorPosition: DropIndicatorPosition;
|
|
9
|
+
lastActiveId: string | undefined;
|
|
10
|
+
setLastActiveId: React.Dispatch<React.SetStateAction<string>> | undefined;
|
|
11
|
+
isDropValid: boolean;
|
|
12
|
+
};
|
|
13
|
+
export declare const DnDTreeContext: import("react").Context<DnDTreeContextType>;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { useSortable } from '@dnd-kit/sortable';
|
|
3
|
+
export declare enum DropIndicatorPosition {
|
|
4
|
+
None = 0,
|
|
5
|
+
Before = 1,
|
|
6
|
+
After = 2,
|
|
7
|
+
Inside = 3
|
|
8
|
+
}
|
|
9
|
+
export declare type SortableItemContextType = {
|
|
10
|
+
draggableProps: false | (ReturnType<typeof useSortable> & {
|
|
11
|
+
dropIndicatorPosition: DropIndicatorPosition;
|
|
12
|
+
shouldShowDropIndicatorPosition: boolean;
|
|
13
|
+
lastActiveId?: string;
|
|
14
|
+
setLastActiveId?: React.Dispatch<React.SetStateAction<string>>;
|
|
15
|
+
isDropValid: boolean;
|
|
16
|
+
});
|
|
17
|
+
};
|
|
18
|
+
/** Context for cross component communication */
|
|
19
|
+
export declare const SortableItemContext: import("react").Context<SortableItemContextType>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { DropIndicatorPosition } from '../hoc/SortableItemContext';
|
|
3
|
+
interface DropIndicatorProps {
|
|
4
|
+
vertical?: boolean;
|
|
5
|
+
dropIndicatorPosition: DropIndicatorPosition | false;
|
|
6
|
+
isLast?: boolean;
|
|
7
|
+
isDropValid?: boolean;
|
|
8
|
+
}
|
|
9
|
+
declare const DropIndicator: React.ComponentType<DropIndicatorProps>;
|
|
10
|
+
export default DropIndicator;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
1
|
import React from 'react';
|
|
3
2
|
import type { DSTreeviewT } from '../react-desc-prop-types';
|
|
4
3
|
export declare const TreeListItem: React.ComponentType<React.DetailedHTMLProps<React.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>>;
|
|
@@ -6,19 +5,13 @@ export declare const TreeListItemAddonsWrapper: React.ComponentType<{}>;
|
|
|
6
5
|
interface PropsT {
|
|
7
6
|
item: DSTreeviewT.Item;
|
|
8
7
|
itemIndex: number;
|
|
9
|
-
|
|
8
|
+
isDragOverlay?: boolean;
|
|
9
|
+
virtualItemRef?: React.RefObject<HTMLLIElement>;
|
|
10
10
|
itemWrapperStyle?: {
|
|
11
11
|
[key: string]: unknown;
|
|
12
12
|
};
|
|
13
13
|
spaceForNestingLevel?: number;
|
|
14
|
-
onMouseDragOverItem?: (opts: {
|
|
15
|
-
event: React.MouseEvent<HTMLLIElement>;
|
|
16
|
-
item: DSTreeviewT.Item;
|
|
17
|
-
itemIndex: number;
|
|
18
|
-
setIsDraggingOverThis: React.Dispatch<React.SetStateAction<boolean>>;
|
|
19
|
-
openFolderOnHoverTimeout: React.MutableRefObject<NodeJS.Timeout | null>;
|
|
20
|
-
}) => void;
|
|
21
14
|
}
|
|
22
15
|
export declare const TreeItem: (props: PropsT) => JSX.Element;
|
|
23
|
-
|
|
24
|
-
export
|
|
16
|
+
declare const _default: (props: PropsT) => JSX.Element;
|
|
17
|
+
export default _default;
|
|
@@ -17,8 +17,4 @@ interface PropsT {
|
|
|
17
17
|
}) => void;
|
|
18
18
|
}
|
|
19
19
|
export declare const TreeList: (props: PropsT) => JSX.Element;
|
|
20
|
-
export declare const DragAndDropTreeList: React.ComponentClass<PropsT & {
|
|
21
|
-
disableAnimation?: boolean | undefined;
|
|
22
|
-
getContainer: (element: React.ReactElement<unknown>) => HTMLElement | Promise<HTMLElement>;
|
|
23
|
-
} & import("@elliemae/react-sortable-hoc").SortableContainerProps, any>;
|
|
24
20
|
export {};
|
|
@@ -13,7 +13,7 @@ export declare namespace DSTreeviewT {
|
|
|
13
13
|
interface SimpleItem {
|
|
14
14
|
[key: string]: unknown;
|
|
15
15
|
name: string;
|
|
16
|
-
children
|
|
16
|
+
children?: SimpleItem[];
|
|
17
17
|
id: StringOrNum;
|
|
18
18
|
}
|
|
19
19
|
interface Item extends SimpleItem {
|
|
@@ -27,9 +27,19 @@ export declare namespace DSTreeviewT {
|
|
|
27
27
|
matchesSearchQuery?: boolean;
|
|
28
28
|
nodeItemRef?: React.RefObject<HTMLLIElement>;
|
|
29
29
|
model: TreeModel.Node<Item>['model'];
|
|
30
|
-
node: TreeModel.Node<Item
|
|
30
|
+
node: TreeModel.Node<Item> & {
|
|
31
|
+
parent?: TreeModel.Node<Item>;
|
|
32
|
+
};
|
|
31
33
|
nodePath: TreeModel.Node<Item>[];
|
|
32
34
|
}
|
|
35
|
+
interface DndItem {
|
|
36
|
+
uid: string;
|
|
37
|
+
depth: number;
|
|
38
|
+
realIndex: number;
|
|
39
|
+
childrenCount: number;
|
|
40
|
+
parentId: string | null;
|
|
41
|
+
original: SimpleItem;
|
|
42
|
+
}
|
|
33
43
|
interface Actions {
|
|
34
44
|
toggleExpandAll: (isExpand: boolean) => Promise<DSTreeviewT.Item[]>;
|
|
35
45
|
scrollTo: DSTreeviewT.ScrollToFunc;
|
|
@@ -50,6 +60,7 @@ export declare namespace DSTreeviewT {
|
|
|
50
60
|
fluid: boolean;
|
|
51
61
|
isMultiSelect: boolean;
|
|
52
62
|
isSingleSelect: boolean;
|
|
63
|
+
getIsDropValid: (active: DndItem, over: DndItem, dropIndicatorPosition: 'none' | 'before' | 'after' | 'inside') => boolean;
|
|
53
64
|
restrictDragAndDrop: boolean;
|
|
54
65
|
showChildrenAmount: boolean;
|
|
55
66
|
sortable: boolean;
|
|
@@ -62,7 +73,7 @@ export declare namespace DSTreeviewT {
|
|
|
62
73
|
item: Item;
|
|
63
74
|
}) => void;
|
|
64
75
|
onVisibleItemsChange: (newVisibleItems: Item[]) => void;
|
|
65
|
-
onOrderChange: (newData:
|
|
76
|
+
onOrderChange: (newData: SimpleItem[], oldData: SimpleItem[], draggedItem: DndItem) => void;
|
|
66
77
|
onSelectionChange: (selection: SelectionItems, item: Item, meta: {
|
|
67
78
|
scrollToItem: ScrollToItemFunc;
|
|
68
79
|
itemIndex: number;
|
|
@@ -124,6 +135,9 @@ export declare const TreeViewPropTypes: {
|
|
|
124
135
|
isLoading: {
|
|
125
136
|
deprecated: import("react-desc").PropTypesDescValidator;
|
|
126
137
|
};
|
|
138
|
+
getIsDropValid: {
|
|
139
|
+
deprecated: import("react-desc").PropTypesDescValidator;
|
|
140
|
+
};
|
|
127
141
|
restrictDragAndDrop: {
|
|
128
142
|
deprecated: import("react-desc").PropTypesDescValidator;
|
|
129
143
|
};
|
package/types/sharedTypes.d.ts
CHANGED
|
@@ -19,22 +19,15 @@ export declare namespace DSTreeviewInternalsT {
|
|
|
19
19
|
interface CTX {
|
|
20
20
|
props: DSTreeviewT.Props;
|
|
21
21
|
visibleItems: DSTreeviewT.Item[];
|
|
22
|
+
flattenedItems: DSTreeviewT.DndItem[];
|
|
22
23
|
withRadioChecks: boolean;
|
|
23
24
|
withCheckboxChecks: boolean;
|
|
24
25
|
withDragAndDrop: boolean;
|
|
25
|
-
relativeMouseCord: MouseCoord;
|
|
26
|
-
setRelativeMouseCord: StateSetter<MouseCoord>;
|
|
27
26
|
triggerTreeRerender: () => void;
|
|
28
27
|
tree?: TreeModel;
|
|
29
28
|
treeRoot?: TreeModel.Node<DSTreeviewT.Item>;
|
|
30
29
|
virtualListHelpers: ReturnType<typeof useVirtual>;
|
|
31
30
|
virtualListRef?: React.MutableRefObject<HTMLUListElement | undefined>;
|
|
32
|
-
isDragging: boolean;
|
|
33
|
-
setIsDragging: StateSetter<boolean>;
|
|
34
|
-
isKeyboardDragging: boolean;
|
|
35
|
-
setIsKeyboardDragging: StateSetter<boolean>;
|
|
36
|
-
draggedItem: DSTreeviewT.Item | null;
|
|
37
|
-
setDraggedItem: StateSetter<DSTreeviewT.Item | null>;
|
|
38
31
|
uniqueTreeViewUUID: string;
|
|
39
32
|
selectedItem: DSTreeviewT.Item | null;
|
|
40
33
|
setSelectedItem: StateSetter<DSTreeviewT.Item | null>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { DSTreeviewT } from '../react-desc-prop-types';
|
|
2
2
|
import type { DSTreeviewInternalsT } from '../sharedTypes';
|
|
3
|
-
|
|
3
|
+
import { SortableItemContextType } from '../hoc/SortableItemContext';
|
|
4
|
+
export declare const useOnItemKeyDown: (item: DSTreeviewT.Item, draggableProps: SortableItemContextType['draggableProps']) => (e: React.KeyboardEvent<HTMLLIElement>) => void;
|
|
4
5
|
export declare const useGlobalKeyboardListener: (func: (e: KeyboardEvent) => void) => void;
|
|
5
6
|
export declare const useGlobalToggleAllExpandShortcut: (treeRoot: DSTreeviewT.Item['node'], triggerTreeRerender: () => void, setLatestToggledItem: DSTreeviewInternalsT.CTX['setLatestToggledItem'], updateUserExpandedState: DSTreeviewInternalsT.CTX['updateUserExpandedState']) => void;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
declare type GenericMergeableRef = null | undefined | React.MutableRefObject<unknown> | ((ref: HTMLElement) => void);
|
|
2
|
+
declare type GenericMergeableRef = null | undefined | React.MutableRefObject<unknown> | ((ref: HTMLElement) => void) | false;
|
|
3
3
|
export declare const setMultipleRefs: (...refs: GenericMergeableRef[]) => (ref: HTMLElement) => void;
|
|
4
4
|
export {};
|
|
@@ -7,7 +7,9 @@ export declare const walkAllNodeChildren: (node: DSTreeviewT.Item['node'], callb
|
|
|
7
7
|
export declare const getNodeById: (treeRoot: DSTreeviewT.Item['node'], id: DSTreeviewT.StringOrNum) => TreeModel.Node<DSTreeviewT.Item>;
|
|
8
8
|
export declare const cloneNode: (tree: TreeModel, node: DSTreeviewT.Item) => TreeModel.Node<DSTreeviewT.Item>;
|
|
9
9
|
export declare const itemsShareSameParent: (items?: DSTreeviewT.Item[]) => boolean;
|
|
10
|
-
export declare const getItemsParentNode: (items?: DSTreeviewT.Item[], skipSameParentCheck?: boolean) => TreeModel.Node<DSTreeviewT.Item
|
|
10
|
+
export declare const getItemsParentNode: (items?: DSTreeviewT.Item[], skipSameParentCheck?: boolean) => TreeModel.Node<DSTreeviewT.Item> & {
|
|
11
|
+
parent?: TreeModel.Node<DSTreeviewT.Item> | undefined;
|
|
12
|
+
};
|
|
11
13
|
export declare const getNodeMatchesSearchQuery: (node: DSTreeviewT.Item['node'], searchQuery?: string) => boolean;
|
|
12
14
|
export declare const getChildrenMatchesSearchQuery: (parentNode: DSTreeviewT.Item['node'], searchQuery?: string) => boolean;
|
|
13
15
|
/**
|
|
@@ -22,4 +24,5 @@ export declare const getChildrenMatchesSearchQuery: (parentNode: DSTreeviewT.Ite
|
|
|
22
24
|
*/
|
|
23
25
|
export declare const enrichNodeModelInPlace: (node: TreeModel.Node<DSTreeviewT.SimpleItem>, searchQuery?: string, selection?: DSTreeviewT.SelectionItems | null, expanded?: DSTreeviewT.ExpandedItems | null) => void;
|
|
24
26
|
export declare const focusItem: (item: DSTreeviewT.Item | null) => void;
|
|
27
|
+
export declare const flattenTreeForDnD: (data: DSTreeviewT.SimpleItem[], shouldDescend?: (datum: DSTreeviewT.SimpleItem) => boolean) => DSTreeviewT.DndItem[];
|
|
25
28
|
export {};
|
package/types/utils/useTree.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export declare const useTree: (data: DSTreeviewT.SimpleItem[], props: DSTreeview
|
|
|
5
5
|
setExpandedGroups: DSTreeviewInternalsT.StateSetter<DSTreeviewT.ExpandedItems>;
|
|
6
6
|
}) => {
|
|
7
7
|
visibleItems: DSTreeviewT.Item[];
|
|
8
|
+
flattenedItems: DSTreeviewT.DndItem[];
|
|
8
9
|
tree: TreeModel;
|
|
9
10
|
treeRoot: TreeModel.Node<DSTreeviewT.Item>;
|
|
10
11
|
rerenderItems: {};
|
package/cjs/utils/dnd-helpers.js
DELETED
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
-
|
|
5
|
-
var treeHelpers = require('./tree-helpers.js');
|
|
6
|
-
|
|
7
|
-
/* eslint-disable max-lines */
|
|
8
|
-
const keyCodes = {
|
|
9
|
-
lift: [32, 13],
|
|
10
|
-
drop: [32, 13],
|
|
11
|
-
cancel: [27],
|
|
12
|
-
up: [38, 37],
|
|
13
|
-
down: [40, 39]
|
|
14
|
-
};
|
|
15
|
-
const sameParentAsHoverItemDrop = _ref => {
|
|
16
|
-
let {
|
|
17
|
-
isBefore,
|
|
18
|
-
isAfter,
|
|
19
|
-
draggedItem,
|
|
20
|
-
overItem,
|
|
21
|
-
movementDirection
|
|
22
|
-
} = _ref;
|
|
23
|
-
const hoveredItemNodeNestedIndex = overItem.node.getIndex();
|
|
24
|
-
let newParentNode = treeHelpers.getItemsParentNode([overItem], true);
|
|
25
|
-
const {
|
|
26
|
-
treeDepth: draggedItemTreeDepth
|
|
27
|
-
} = draggedItem;
|
|
28
|
-
const {
|
|
29
|
-
treeDepth: overItemTreeDepth
|
|
30
|
-
} = overItem;
|
|
31
|
-
const directionOffset = // we don't apply the offset for direction
|
|
32
|
-
// if moving from less nested to more nested
|
|
33
|
-
// or moving bottom to top
|
|
34
|
-
// the offset is required when moving elemnts down in their nest level
|
|
35
|
-
draggedItemTreeDepth <= overItemTreeDepth && movementDirection === 'topToBottom' ? -1 : 0;
|
|
36
|
-
let newNestedIndex;
|
|
37
|
-
if (isBefore) newNestedIndex = hoveredItemNodeNestedIndex + directionOffset;else if (isAfter) newNestedIndex = hoveredItemNodeNestedIndex + 1 + directionOffset;else {
|
|
38
|
-
newNestedIndex = overItem.children.length; // append as last child of the group
|
|
39
|
-
|
|
40
|
-
newParentNode = overItem.node;
|
|
41
|
-
}
|
|
42
|
-
if (newNestedIndex < 0) newNestedIndex = 0;
|
|
43
|
-
return {
|
|
44
|
-
newNestedIndex,
|
|
45
|
-
newParentNode
|
|
46
|
-
};
|
|
47
|
-
};
|
|
48
|
-
const inferHoverItemKinshipDrop = _ref2 => {
|
|
49
|
-
let {
|
|
50
|
-
isBefore,
|
|
51
|
-
isAfter,
|
|
52
|
-
draggedItem,
|
|
53
|
-
overItem,
|
|
54
|
-
movementDirection
|
|
55
|
-
} = _ref2;
|
|
56
|
-
const hoverItemModel = overItem.node.model;
|
|
57
|
-
const isGroupAndIsExpanded = hoverItemModel.isExpanded && hoverItemModel.children.length > 0;
|
|
58
|
-
|
|
59
|
-
if (isAfter && isGroupAndIsExpanded) {
|
|
60
|
-
return {
|
|
61
|
-
newNestedIndex: 0,
|
|
62
|
-
// append after the group, so basically as first child
|
|
63
|
-
newParentNode: overItem.node
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
if (isBefore || isAfter && !isGroupAndIsExpanded) {
|
|
68
|
-
return sameParentAsHoverItemDrop({
|
|
69
|
-
isBefore,
|
|
70
|
-
isAfter,
|
|
71
|
-
draggedItem,
|
|
72
|
-
overItem,
|
|
73
|
-
movementDirection
|
|
74
|
-
});
|
|
75
|
-
} // drop inside
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
return {
|
|
79
|
-
newNestedIndex: overItem.children.length,
|
|
80
|
-
// append as last child of the group
|
|
81
|
-
newParentNode: overItem.node
|
|
82
|
-
};
|
|
83
|
-
};
|
|
84
|
-
const isDropValid = _ref3 => {
|
|
85
|
-
let {
|
|
86
|
-
isBefore,
|
|
87
|
-
isAfter,
|
|
88
|
-
draggedItem,
|
|
89
|
-
overItem,
|
|
90
|
-
restrictDragAndDrop
|
|
91
|
-
} = _ref3;
|
|
92
|
-
const {
|
|
93
|
-
id: movedId
|
|
94
|
-
} = draggedItem;
|
|
95
|
-
const {
|
|
96
|
-
id: hoverId
|
|
97
|
-
} = overItem;
|
|
98
|
-
const isInside = !isBefore && !isAfter;
|
|
99
|
-
if (movedId === hoverId) return false;
|
|
100
|
-
|
|
101
|
-
if (isInside && !overItem.isGroup) {
|
|
102
|
-
return false; // we can't drop inside an item that isn't a group
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
if (restrictDragAndDrop) {
|
|
106
|
-
if (isInside) return false; // in this mode we can't drop inside another element
|
|
107
|
-
|
|
108
|
-
const sameParent = treeHelpers.itemsShareSameParent([draggedItem, overItem]);
|
|
109
|
-
if (overItem.node.model.isExpanded && isAfter) return false;
|
|
110
|
-
if (!sameParent) return false;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
return true;
|
|
114
|
-
};
|
|
115
|
-
const inferKeyboardKinshipDrop = _ref4 => {
|
|
116
|
-
let {
|
|
117
|
-
items,
|
|
118
|
-
newIndex
|
|
119
|
-
} = _ref4;
|
|
120
|
-
const kinship = {};
|
|
121
|
-
const itemBefore = items[newIndex];
|
|
122
|
-
const itemBeforeModel = itemBefore.node.model;
|
|
123
|
-
const isGroupAndIsExpanded = itemBeforeModel.isExpanded && itemBeforeModel.children.length > 0;
|
|
124
|
-
|
|
125
|
-
if (isGroupAndIsExpanded) {
|
|
126
|
-
kinship.newParentNode = itemBefore.node;
|
|
127
|
-
kinship.newNestedIndex = 0;
|
|
128
|
-
} else {
|
|
129
|
-
kinship.newParentNode = treeHelpers.getItemsParentNode([itemBefore], true);
|
|
130
|
-
kinship.newNestedIndex = itemBefore.node.getIndex();
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
return kinship;
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
exports.inferHoverItemKinshipDrop = inferHoverItemKinshipDrop;
|
|
137
|
-
exports.inferKeyboardKinshipDrop = inferKeyboardKinshipDrop;
|
|
138
|
-
exports.isDropValid = isDropValid;
|
|
139
|
-
exports.keyCodes = keyCodes;
|
|
140
|
-
exports.sameParentAsHoverItemDrop = sameParentAsHoverItemDrop;
|