@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
package/cjs/parts/TreeItem.js
CHANGED
|
@@ -2,18 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
var _defineProperty = require('@babel/runtime/helpers/defineProperty');
|
|
6
|
-
var _jsx = require('@babel/runtime/helpers/jsx');
|
|
7
|
-
require('core-js/modules/web.dom-collections.iterator.js');
|
|
8
5
|
require('core-js/modules/esnext.async-iterator.filter.js');
|
|
9
6
|
require('core-js/modules/esnext.iterator.constructor.js');
|
|
10
7
|
require('core-js/modules/esnext.iterator.filter.js');
|
|
11
8
|
require('core-js/modules/esnext.async-iterator.for-each.js');
|
|
12
9
|
require('core-js/modules/esnext.iterator.for-each.js');
|
|
10
|
+
var _jsx = require('@babel/runtime/helpers/jsx');
|
|
11
|
+
var _defineProperty = require('@babel/runtime/helpers/defineProperty');
|
|
13
12
|
var React = require('react');
|
|
14
|
-
var reactSortableHoc = require('@elliemae/react-sortable-hoc');
|
|
15
13
|
var dsClassnames = require('@elliemae/ds-classnames');
|
|
16
|
-
var dsIcons = require('@elliemae/ds-icons');
|
|
17
14
|
var RadioSelectable = require('./RadioSelectable.js');
|
|
18
15
|
var CheckboxSelectable = require('./CheckboxSelectable.js');
|
|
19
16
|
var TreeViewContext = require('../TreeViewContext.js');
|
|
@@ -24,12 +21,16 @@ var Icon = require('./Icon.js');
|
|
|
24
21
|
var ExpandCaret = require('./ExpandCaret.js');
|
|
25
22
|
var TreeItemText = require('./TreeItemText.js');
|
|
26
23
|
var cssClassesConstants = require('../config/cssClassesConstants.js');
|
|
24
|
+
var DnDHandle = require('./DnDHandle.js');
|
|
25
|
+
var WithDnDSortableItemContext = require('../hoc/WithDnDSortableItemContext.js');
|
|
26
|
+
var SortableItemContext = require('../hoc/SortableItemContext.js');
|
|
27
|
+
var DropIndicator = require('./DropIndicator.js');
|
|
27
28
|
var jsxRuntime = require('react/jsx-runtime');
|
|
28
29
|
|
|
29
30
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
30
31
|
|
|
31
|
-
var _defineProperty__default = /*#__PURE__*/_interopDefaultLegacy(_defineProperty);
|
|
32
32
|
var _jsx__default = /*#__PURE__*/_interopDefaultLegacy(_jsx);
|
|
33
|
+
var _defineProperty__default = /*#__PURE__*/_interopDefaultLegacy(_defineProperty);
|
|
33
34
|
|
|
34
35
|
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; }
|
|
35
36
|
|
|
@@ -41,23 +42,6 @@ const TreeListItem = dsClassnames.aggregatedClasses('li', {
|
|
|
41
42
|
})(cssClassesConstants.treeItemBlockName);
|
|
42
43
|
const TreeListItemAddonsWrapper = dsClassnames.aggregatedClasses('div')(cssClassesConstants.treeItemBlockName, 'addons' // temp fix untill we move to styled components
|
|
43
44
|
);
|
|
44
|
-
const DnDHandle = reactSortableHoc.SortableHandle(_ref => {
|
|
45
|
-
let {
|
|
46
|
-
id
|
|
47
|
-
} = _ref;
|
|
48
|
-
return /*#__PURE__*/_jsx__default["default"](dsIcons.GripperVertical, {
|
|
49
|
-
"data-testid": "drag-handle",
|
|
50
|
-
className: "drag-handle",
|
|
51
|
-
size: "s",
|
|
52
|
-
onMouseDown: e => {
|
|
53
|
-
// prevent focusing the drag-handle to avoid borders
|
|
54
|
-
if (e) {
|
|
55
|
-
e.preventDefault();
|
|
56
|
-
}
|
|
57
|
-
},
|
|
58
|
-
tabIndex: "0"
|
|
59
|
-
}, "".concat(id, "-drag-handle"));
|
|
60
|
-
});
|
|
61
45
|
const TreeItem = props => {
|
|
62
46
|
const {
|
|
63
47
|
item,
|
|
@@ -65,7 +49,7 @@ const TreeItem = props => {
|
|
|
65
49
|
itemWrapperStyle = {},
|
|
66
50
|
virtualItemRef,
|
|
67
51
|
spaceForNestingLevel = 1.5,
|
|
68
|
-
|
|
52
|
+
isDragOverlay = false
|
|
69
53
|
} = props;
|
|
70
54
|
const {
|
|
71
55
|
id,
|
|
@@ -74,9 +58,10 @@ const TreeItem = props => {
|
|
|
74
58
|
const {
|
|
75
59
|
nodeItemRef
|
|
76
60
|
} = node.model;
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
61
|
+
const {
|
|
62
|
+
draggableProps
|
|
63
|
+
} = React.useContext(SortableItemContext.SortableItemContext);
|
|
64
|
+
const onItemKeyDown = keyboardHelpers.useOnItemKeyDown(item, draggableProps);
|
|
80
65
|
const ctx = React.useContext(TreeViewContext["default"]);
|
|
81
66
|
const {
|
|
82
67
|
props: {
|
|
@@ -87,14 +72,12 @@ const TreeItem = props => {
|
|
|
87
72
|
rowSize,
|
|
88
73
|
labelOverflow
|
|
89
74
|
},
|
|
90
|
-
relativeMouseCord,
|
|
91
75
|
withRadioChecks,
|
|
92
76
|
withCheckboxChecks,
|
|
93
77
|
withDragAndDrop,
|
|
94
78
|
selectedItem,
|
|
95
79
|
selectedCheckboxes,
|
|
96
80
|
hoverItem,
|
|
97
|
-
isDragging,
|
|
98
81
|
virtualListHelpers: {
|
|
99
82
|
scrollToIndex
|
|
100
83
|
},
|
|
@@ -104,24 +87,27 @@ const TreeItem = props => {
|
|
|
104
87
|
} = ctx; // Sortable Items needs to update
|
|
105
88
|
// - the virtual list ref (for react-virtual requirement)
|
|
106
89
|
// - nodeItemRef which is a prop avaiable in the TreeModel nodes
|
|
90
|
+
// - the drag and drop node reference
|
|
107
91
|
|
|
108
92
|
const setItemRefs = ref => {
|
|
109
|
-
refsHelpers.setMultipleRefs(virtualItemRef, nodeItemRef)(ref);
|
|
93
|
+
refsHelpers.setMultipleRefs(virtualItemRef, !isDragOverlay && nodeItemRef, !isDragOverlay && draggableProps && draggableProps.setNodeRef)(ref);
|
|
110
94
|
};
|
|
111
95
|
|
|
96
|
+
const dropIndicatorPosition = draggableProps && draggableProps.shouldShowDropIndicatorPosition && draggableProps.dropIndicatorPosition;
|
|
97
|
+
const isDropIndicatorPositionInside = dropIndicatorPosition === SortableItemContext.DropIndicatorPosition.Inside;
|
|
98
|
+
const isDragging = draggableProps && draggableProps.isDragging;
|
|
99
|
+
const isDropValid = draggableProps && draggableProps.isDropValid;
|
|
112
100
|
const dropPreviewClassName = React.useMemo(() => {
|
|
113
|
-
if (
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
const selectedClassName = React.useMemo(() => (selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.id) === item.id ? 'selected' : '', [item.id, selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.id]);
|
|
124
|
-
const hoverClassName = React.useMemo(() => (hoverItem === null || hoverItem === void 0 ? void 0 : hoverItem.id) !== item.id || withDragAndDrop && isDragging ? '' : 'hover', [hoverItem === null || hoverItem === void 0 ? void 0 : hoverItem.id, item.id, withDragAndDrop, isDragging]);
|
|
101
|
+
if (isDropIndicatorPositionInside) {
|
|
102
|
+
const className = "".concat(cssClassesConstants.DSTreeViewPrefix, "-").concat(cssClassesConstants.treeItemBlockName).concat(isDropValid ? '--valid' : '--invalid', "-drop-in");
|
|
103
|
+
return className;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return '';
|
|
107
|
+
}, [isDropIndicatorPositionInside, isDropValid]);
|
|
108
|
+
const dragOverlayClassName = React.useMemo(() => isDragOverlay ? 'drag-overlay' : '', [isDragOverlay]);
|
|
109
|
+
const selectedClassName = React.useMemo(() => (selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.id) === item.id && !isDragOverlay ? 'selected' : '', [isDragOverlay, item.id, selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.id]);
|
|
110
|
+
const hoverClassName = React.useMemo(() => !isDragOverlay && ((hoverItem === null || hoverItem === void 0 ? void 0 : hoverItem.id) === item.id || isDragging) ? 'hover' : '', [isDragOverlay, hoverItem === null || hoverItem === void 0 ? void 0 : hoverItem.id, item.id, isDragging]);
|
|
125
111
|
const fixedHeightClassname = React.useMemo(() => {
|
|
126
112
|
if (labelOverflow === 'truncate') {
|
|
127
113
|
if (rowSize === 'compact') return "".concat(cssClassesConstants.DSTreeViewPrefix, "-").concat(cssClassesConstants.treeItemBlockName, "--fixed-height-compact");
|
|
@@ -130,7 +116,7 @@ const TreeItem = props => {
|
|
|
130
116
|
|
|
131
117
|
return '';
|
|
132
118
|
}, [labelOverflow, rowSize]);
|
|
133
|
-
const finalClassName = React.useMemo(() => "".concat(dropPreviewClassName, " ").concat(fixedHeightClassname, " ").concat(selectedClassName, " ").concat(hoverClassName), [dropPreviewClassName, selectedClassName, hoverClassName, fixedHeightClassname]);
|
|
119
|
+
const finalClassName = React.useMemo(() => "".concat(dropPreviewClassName, " ").concat(fixedHeightClassname, " ").concat(selectedClassName, " ").concat(hoverClassName, " ").concat(dragOverlayClassName), [dropPreviewClassName, selectedClassName, hoverClassName, fixedHeightClassname, dragOverlayClassName]);
|
|
134
120
|
const handleItemClick = React.useCallback(e => {
|
|
135
121
|
onItemClick(item, e);
|
|
136
122
|
setFocusedItem(item);
|
|
@@ -149,23 +135,7 @@ const TreeItem = props => {
|
|
|
149
135
|
}, [item, scrollToIndex, onItemClick, onItemFocus, setSelectedItem, setFocusedItem]);
|
|
150
136
|
return /*#__PURE__*/jsxRuntime.jsxs(TreeListItem, {
|
|
151
137
|
tabIndex: 0,
|
|
152
|
-
onMouseMove: event => {
|
|
153
|
-
if (withDragAndDrop && onMouseDragOverItem) {
|
|
154
|
-
onMouseDragOverItem({
|
|
155
|
-
event,
|
|
156
|
-
item,
|
|
157
|
-
itemIndex,
|
|
158
|
-
setIsDraggingOverThis,
|
|
159
|
-
openFolderOnHoverTimeout
|
|
160
|
-
});
|
|
161
|
-
}
|
|
162
|
-
},
|
|
163
138
|
onMouseLeave: () => {
|
|
164
|
-
if (withDragAndDrop) {
|
|
165
|
-
setIsDraggingOverThis(false);
|
|
166
|
-
if (openFolderOnHoverTimeout !== null && openFolderOnHoverTimeout !== void 0 && openFolderOnHoverTimeout.current) clearTimeout(openFolderOnHoverTimeout.current);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
139
|
if ((hoverItem === null || hoverItem === void 0 ? void 0 : hoverItem.id) === item.id) {
|
|
170
140
|
setHoverItem(null);
|
|
171
141
|
}
|
|
@@ -174,6 +144,7 @@ const TreeItem = props => {
|
|
|
174
144
|
setHoverItem(item);
|
|
175
145
|
},
|
|
176
146
|
onClick: handleItemClick,
|
|
147
|
+
onBlur: () => setFocusedItem(null),
|
|
177
148
|
ref: setItemRefs,
|
|
178
149
|
style: _objectSpread({}, itemWrapperStyle),
|
|
179
150
|
className: finalClassName,
|
|
@@ -182,29 +153,33 @@ const TreeItem = props => {
|
|
|
182
153
|
"data-id": item.id,
|
|
183
154
|
"data-index": item.virtualIndex,
|
|
184
155
|
onKeyDown: onItemKeyDown,
|
|
185
|
-
children: [/*#__PURE__*/_jsx__default["default"](TreeListItemAddonsWrapper, {}, void 0, withDragAndDrop ? /*#__PURE__*/_jsx__default["default"](DnDHandle, {
|
|
186
|
-
id: id
|
|
187
|
-
|
|
156
|
+
children: [/*#__PURE__*/_jsx__default["default"](TreeListItemAddonsWrapper, {}, void 0, withDragAndDrop ? /*#__PURE__*/_jsx__default["default"](DnDHandle.DnDHandle, {
|
|
157
|
+
id: id,
|
|
158
|
+
isDragOverlay: isDragOverlay
|
|
159
|
+
}) : null, withRadioChecks && !isDragOverlay ? /*#__PURE__*/_jsx__default["default"](RadioSelectable, {
|
|
188
160
|
item: item,
|
|
189
161
|
itemIndex: itemIndex
|
|
190
|
-
}) : null, withCheckboxChecks ? /*#__PURE__*/_jsx__default["default"](CheckboxSelectable, {
|
|
162
|
+
}) : null, withCheckboxChecks && !isDragOverlay ? /*#__PURE__*/_jsx__default["default"](CheckboxSelectable, {
|
|
191
163
|
item: item,
|
|
192
164
|
itemIndex: itemIndex
|
|
193
|
-
}) : null, /*#__PURE__*/_jsx__default["default"](NestingSpace.NestingSpace, {
|
|
165
|
+
}) : null, !isDragOverlay && /*#__PURE__*/_jsx__default["default"](NestingSpace.NestingSpace, {
|
|
194
166
|
item: item,
|
|
195
167
|
spaceForNestingLevel: spaceForNestingLevel
|
|
196
|
-
}), /*#__PURE__*/_jsx__default["default"](ExpandCaret.ExpandCaret, {
|
|
168
|
+
}), !isDragOverlay && /*#__PURE__*/_jsx__default["default"](ExpandCaret.ExpandCaret, {
|
|
197
169
|
item: item
|
|
198
170
|
}), !disableIcons ? /*#__PURE__*/_jsx__default["default"](Icon.Icon, {
|
|
199
171
|
item: item
|
|
200
172
|
}) : null), /*#__PURE__*/_jsx__default["default"](TreeItemText.TreeItemText, {
|
|
201
173
|
item: item
|
|
202
|
-
}), rightAddons && /*#__PURE__*/_jsx__default["default"](TreeListItemAddonsWrapper, {}, void 0, typeof rightAddons === 'function' ? rightAddons(item) : rightAddons)]
|
|
174
|
+
}), rightAddons && /*#__PURE__*/_jsx__default["default"](TreeListItemAddonsWrapper, {}, void 0, typeof rightAddons === 'function' ? rightAddons(item) : rightAddons), /*#__PURE__*/_jsx__default["default"](DropIndicator, {
|
|
175
|
+
dropIndicatorPosition: dropIndicatorPosition,
|
|
176
|
+
isDropValid: isDropValid
|
|
177
|
+
})]
|
|
203
178
|
});
|
|
204
179
|
};
|
|
205
|
-
|
|
180
|
+
var TreeItem$1 = WithDnDSortableItemContext.withDnDSortableItemContext(TreeItem);
|
|
206
181
|
|
|
207
|
-
exports.DragAndDropTreeItem = DragAndDropTreeItem;
|
|
208
182
|
exports.TreeItem = TreeItem;
|
|
209
183
|
exports.TreeListItem = TreeListItem;
|
|
210
184
|
exports.TreeListItemAddonsWrapper = TreeListItemAddonsWrapper;
|
|
185
|
+
exports["default"] = TreeItem$1;
|
package/cjs/parts/TreeList.js
CHANGED
|
@@ -12,12 +12,13 @@ require('core-js/modules/esnext.iterator.filter.js');
|
|
|
12
12
|
require('core-js/modules/esnext.async-iterator.for-each.js');
|
|
13
13
|
require('core-js/modules/esnext.iterator.for-each.js');
|
|
14
14
|
var React = require('react');
|
|
15
|
-
var reactSortableHoc = require('@elliemae/react-sortable-hoc');
|
|
16
15
|
var dsClassnames = require('@elliemae/ds-classnames');
|
|
17
16
|
var dsCircularProgressIndicator = require('@elliemae/ds-circular-progress-indicator');
|
|
18
17
|
var TreeViewContext = require('../TreeViewContext.js');
|
|
19
18
|
var cssClassesConstants = require('../config/cssClassesConstants.js');
|
|
20
19
|
var TreeItem = require('./TreeItem.js');
|
|
20
|
+
var WithConditionalDnDContext = require('../hoc/WithConditionalDnDContext.js');
|
|
21
|
+
var DnDTreeContext = require('../hoc/DnDTreeContext.js');
|
|
21
22
|
var jsxRuntime = require('react/jsx-runtime');
|
|
22
23
|
|
|
23
24
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
@@ -47,16 +48,13 @@ const TreeListWrapper = dsClassnames.aggregatedClasses('ul', {
|
|
|
47
48
|
});
|
|
48
49
|
const compactRowClass = "".concat(cssClassesConstants.DSTreeViewPrefix, "-tv-row-size-compact");
|
|
49
50
|
const normaRowClass = "".concat(cssClassesConstants.DSTreeViewPrefix, "-tv-row-size-normal");
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
onMouseDragOverItem
|
|
53
|
-
} = props;
|
|
51
|
+
|
|
52
|
+
const TreeListComp = () => {
|
|
54
53
|
const ctx = React.useContext(TreeViewContext["default"]);
|
|
55
54
|
const {
|
|
56
55
|
virtualListRef,
|
|
57
56
|
virtualListHelpers,
|
|
58
|
-
visibleItems,
|
|
59
|
-
withDragAndDrop,
|
|
57
|
+
visibleItems: flattenedVisibleItems,
|
|
60
58
|
props: {
|
|
61
59
|
width,
|
|
62
60
|
height,
|
|
@@ -70,6 +68,9 @@ const TreeList = props => {
|
|
|
70
68
|
virtualItems
|
|
71
69
|
} = virtualListHelpers;
|
|
72
70
|
const className = "".concat(rowSize === 'compact' ? "".concat(compactRowClass) : "".concat(normaRowClass));
|
|
71
|
+
const {
|
|
72
|
+
visibleItems
|
|
73
|
+
} = React.useContext(DnDTreeContext.DnDTreeContext);
|
|
73
74
|
return /*#__PURE__*/jsxRuntime.jsxs(TreeListWrapper, {
|
|
74
75
|
ref: virtualListRef,
|
|
75
76
|
className: className,
|
|
@@ -104,17 +105,17 @@ const TreeList = props => {
|
|
|
104
105
|
measureRef,
|
|
105
106
|
start
|
|
106
107
|
} = virtualItem;
|
|
107
|
-
const item = visibleItems[index];
|
|
108
|
+
const item = (visibleItems || flattenedVisibleItems)[index];
|
|
109
|
+
if (!item) return null;
|
|
108
110
|
item.virtualIndex = index;
|
|
109
111
|
const {
|
|
110
112
|
id
|
|
111
113
|
} = item;
|
|
112
114
|
const style = {
|
|
113
115
|
position: 'absolute',
|
|
114
|
-
top:
|
|
116
|
+
top: "".concat(start, "px"),
|
|
115
117
|
left: 0,
|
|
116
|
-
width: '100%'
|
|
117
|
-
transform: "translateY(".concat(start, "px)")
|
|
118
|
+
width: '100%'
|
|
118
119
|
};
|
|
119
120
|
const listItemProps = {
|
|
120
121
|
key: "DS-TreeView-List-Item-".concat(id),
|
|
@@ -125,16 +126,13 @@ const TreeList = props => {
|
|
|
125
126
|
item,
|
|
126
127
|
itemWrapperStyle: style
|
|
127
128
|
};
|
|
128
|
-
|
|
129
|
-
onMouseDragOverItem: onMouseDragOverItem
|
|
130
|
-
}));
|
|
131
|
-
return /*#__PURE__*/jsxRuntime.jsx(TreeItem.TreeItem, _objectSpread({}, listItemProps));
|
|
129
|
+
return /*#__PURE__*/jsxRuntime.jsx(TreeItem["default"], _objectSpread({}, listItemProps));
|
|
132
130
|
})) : null]
|
|
133
131
|
});
|
|
134
132
|
};
|
|
135
|
-
const DragAndDropTreeList = reactSortableHoc.SortableContainer(TreeList);
|
|
136
133
|
|
|
137
|
-
|
|
134
|
+
const TreeList = WithConditionalDnDContext.withConditionalDnDRowContext(TreeListComp);
|
|
135
|
+
|
|
138
136
|
exports.TreeList = TreeList;
|
|
139
137
|
exports.TreeListNoItems = TreeListNoItems;
|
|
140
138
|
exports.TreeListWrapper = TreeListWrapper;
|
|
@@ -2,43 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
var _jsx = require('@babel/runtime/helpers/jsx');
|
|
6
|
-
var React = require('react');
|
|
7
|
-
var TreeList = require('../../parts/TreeList.js');
|
|
8
|
-
var useDnDHelpers = require('../../utils/useDnDHelpers.js');
|
|
9
|
-
var dndHelpers = require('../../utils/dnd-helpers.js');
|
|
10
|
-
var TreeViewContext = require('../../TreeViewContext.js');
|
|
11
|
-
|
|
12
|
-
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
13
|
-
|
|
14
|
-
var _jsx__default = /*#__PURE__*/_interopDefaultLegacy(_jsx);
|
|
15
|
-
|
|
16
|
-
const TreeDnD = () => {
|
|
17
|
-
const {
|
|
18
|
-
updateBeforeSortStart,
|
|
19
|
-
onSortStart,
|
|
20
|
-
onMouseDragOverItem,
|
|
21
|
-
onSortEnd
|
|
22
|
-
} = useDnDHelpers.useDnDHelpers();
|
|
23
|
-
const ctx = React.useContext(TreeViewContext["default"]);
|
|
24
|
-
const {
|
|
25
|
-
virtualListRef
|
|
26
|
-
} = ctx;
|
|
27
|
-
return /*#__PURE__*/_jsx__default["default"](TreeList.DragAndDropTreeList, {
|
|
28
|
-
useDragHandle: true,
|
|
29
|
-
transitionDuration: 0,
|
|
30
|
-
keyboardSortingTransitionDuration: 0,
|
|
31
|
-
hideSortableGhost: false,
|
|
32
|
-
disableAnimation: true,
|
|
33
|
-
updateBeforeSortStart: updateBeforeSortStart,
|
|
34
|
-
onSortStart: onSortStart,
|
|
35
|
-
onMouseDragOverItem: onMouseDragOverItem,
|
|
36
|
-
onSortEnd: onSortEnd,
|
|
37
|
-
getContainer: () => virtualListRef === null || virtualListRef === void 0 ? void 0 : virtualListRef.current,
|
|
38
|
-
keyCodes: dndHelpers.keyCodes
|
|
39
|
-
});
|
|
40
|
-
};
|
|
41
5
|
const TreeDndPlugin = 'tree-dnd';
|
|
42
6
|
|
|
43
|
-
exports.TreeDnD = TreeDnD;
|
|
44
7
|
exports.TreeDndPlugin = TreeDndPlugin;
|
package/cjs/plugins/dnd/index.js
CHANGED
package/cjs/plugins/index.js
CHANGED
|
@@ -12,7 +12,6 @@ var SearchableTreePlugin = require('./searchable/SearchableTreePlugin.js');
|
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
|
|
15
|
-
exports.TreeDnD = TreeDndPlugin.TreeDnD;
|
|
16
15
|
exports.TreeDndPlugin = TreeDndPlugin.TreeDndPlugin;
|
|
17
16
|
exports.TreeRovingPlugin = TreeRovingPlugin.TreeRovingPlugin;
|
|
18
17
|
exports.SelectablePluginTree = SelectablePluginTree.SelectablePluginTree;
|
|
@@ -30,6 +30,7 @@ const TreeViewPropTypes = {
|
|
|
30
30
|
isMultiSelect: reactDesc.PropTypes.bool.description('whether the tree view is multi select or not').defaultValue(false),
|
|
31
31
|
isSingleSelect: reactDesc.PropTypes.bool.description('wheter the tree view is single select or not').defaultValue(false),
|
|
32
32
|
isLoading: reactDesc.PropTypes.bool.description('wheter the tree should show the loading state or not').defaultValue(false),
|
|
33
|
+
getIsDropValid: reactDesc.PropTypes.func.description("Function that returns true if the drop is valid and false if it's not").defaultValue('() => true'),
|
|
33
34
|
restrictDragAndDrop: reactDesc.PropTypes.bool.description('whether to restrict DnD functionality or not').defaultValue(false),
|
|
34
35
|
showChildrenAmount: reactDesc.PropTypes.bool.description('whether to show the amount of children or not').defaultValue(false),
|
|
35
36
|
sortable: reactDesc.PropTypes.bool.description('whether the sortable functionality is active or not').defaultValue(false),
|
|
@@ -19,14 +19,13 @@ var groupExpandsHelpers = require('./group-expands-helpers.js');
|
|
|
19
19
|
// 36 home
|
|
20
20
|
// 56 number 8
|
|
21
21
|
// 106 (NumPad) *
|
|
22
|
-
const useOnItemKeyDown = item => {
|
|
22
|
+
const useOnItemKeyDown = (item, draggableProps) => {
|
|
23
23
|
const ctx = React.useContext(TreeViewContext["default"]);
|
|
24
24
|
const {
|
|
25
25
|
props: {
|
|
26
26
|
onItemFocus
|
|
27
27
|
},
|
|
28
28
|
triggerTreeRerender,
|
|
29
|
-
isDragging,
|
|
30
29
|
visibleItems,
|
|
31
30
|
setFocusedItem,
|
|
32
31
|
setSelectedItem,
|
|
@@ -55,10 +54,12 @@ const useOnItemKeyDown = item => {
|
|
|
55
54
|
keyCode
|
|
56
55
|
} = e;
|
|
57
56
|
|
|
58
|
-
if (!
|
|
57
|
+
if (!(draggableProps && draggableProps.active)) {
|
|
59
58
|
if (keyCode !== 9) e.preventDefault(); // allow tab/shift+tab
|
|
60
59
|
|
|
61
|
-
if (keyCode === 13 || keyCode === 32)
|
|
60
|
+
if ((keyCode === 13 || keyCode === 32) && e.target.tagName === 'LI') {
|
|
61
|
+
setSelectedItem(item);
|
|
62
|
+
}
|
|
62
63
|
|
|
63
64
|
if (keyCode === 37) {
|
|
64
65
|
if (isGroup && isExpanded) {
|
|
@@ -146,7 +147,7 @@ const useOnItemKeyDown = item => {
|
|
|
146
147
|
}
|
|
147
148
|
}
|
|
148
149
|
}
|
|
149
|
-
}, [
|
|
150
|
+
}, [draggableProps, setSelectedItem, item, isGroup, isExpanded, triggerTreeRerender, updateUserExpandedState, scrollToIndex, setLatestToggledItem, visibleItems, setFocusedItem, onItemFocusCurry]);
|
|
150
151
|
return onItemKeyDown;
|
|
151
152
|
};
|
|
152
153
|
const useGlobalKeyboardListener = func => {
|
|
@@ -132,7 +132,7 @@ const getChildrenMatchesSearchQuery = function (parentNode) {
|
|
|
132
132
|
*/
|
|
133
133
|
|
|
134
134
|
const enrichNodeModelInPlace = function (node) {
|
|
135
|
-
var _node$model, _node$model$children;
|
|
135
|
+
var _node$model$children$, _node$model, _node$model$children;
|
|
136
136
|
|
|
137
137
|
let searchQuery = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
|
|
138
138
|
let selection = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
|
|
@@ -148,7 +148,7 @@ const enrichNodeModelInPlace = function (node) {
|
|
|
148
148
|
// this is useful to avoid having to always check both the flag and the children.length...
|
|
149
149
|
|
|
150
150
|
|
|
151
|
-
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) {
|
|
151
|
+
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) {
|
|
152
152
|
node.model.isGroup = true;
|
|
153
153
|
}
|
|
154
154
|
|
|
@@ -180,9 +180,35 @@ const focusItem = item => {
|
|
|
180
180
|
|
|
181
181
|
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();
|
|
182
182
|
};
|
|
183
|
+
const flattenTreeForDnD = function (data) {
|
|
184
|
+
let shouldDescend = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : () => true;
|
|
185
|
+
const flattenedTree = [];
|
|
186
|
+
let index = 0;
|
|
187
|
+
|
|
188
|
+
const doit = function (node) {
|
|
189
|
+
var _node$children$length, _node$children, _node$children2;
|
|
190
|
+
|
|
191
|
+
let depth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
|
|
192
|
+
let parentId = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
|
|
193
|
+
flattenedTree.push({
|
|
194
|
+
uid: node.id.toString(),
|
|
195
|
+
depth,
|
|
196
|
+
realIndex: index,
|
|
197
|
+
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,
|
|
198
|
+
parentId: parentId !== null ? parentId.toString() : null,
|
|
199
|
+
original: node
|
|
200
|
+
});
|
|
201
|
+
index += 1;
|
|
202
|
+
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()));
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
data.forEach(datum => doit(datum));
|
|
206
|
+
return flattenedTree;
|
|
207
|
+
};
|
|
183
208
|
|
|
184
209
|
exports.cloneNode = cloneNode;
|
|
185
210
|
exports.enrichNodeModelInPlace = enrichNodeModelInPlace;
|
|
211
|
+
exports.flattenTreeForDnD = flattenTreeForDnD;
|
|
186
212
|
exports.focusItem = focusItem;
|
|
187
213
|
exports.getChildrenMatchesSearchQuery = getChildrenMatchesSearchQuery;
|
|
188
214
|
exports.getItemsParentNode = getItemsParentNode;
|
package/cjs/utils/useTree.js
CHANGED
|
@@ -76,9 +76,9 @@ const useTree = (data, props, states) => {
|
|
|
76
76
|
React.useEffect(() => {
|
|
77
77
|
const parsedVisibleItems = [];
|
|
78
78
|
const newExpandedHashMap = {};
|
|
79
|
-
|
|
80
|
-
const shouldContinueWalking = true; // tree-model ask we return true if we want to continue walking
|
|
79
|
+
const shouldContinueWalking = true; // tree-model ask we return true if we want to continue walking
|
|
81
80
|
|
|
81
|
+
treeRoot.walk(node => {
|
|
82
82
|
treeHelpers.enrichNodeModelInPlace(node, searchQuery, selection, expanded);
|
|
83
83
|
if (node.model.id && node.model.isGroup && node.model.isExpanded) newExpandedHashMap[node.model.id] = true;
|
|
84
84
|
return shouldContinueWalking;
|
|
@@ -93,8 +93,10 @@ const useTree = (data, props, states) => {
|
|
|
93
93
|
setExpandedGroups(newExpandedHashMap); // eslint-disable-next-line react-hooks/exhaustive-deps
|
|
94
94
|
}, [treeRoot, rerenderItems, searchQuery, highlightOnlyQuery, selection, expanded, setExpandedGroups // onVisibleItemsChange // evaluate potential performance hit?
|
|
95
95
|
]);
|
|
96
|
+
const flattenedItems = React.useMemo(() => treeHelpers.flattenTreeForDnD(data), [data]);
|
|
96
97
|
return {
|
|
97
98
|
visibleItems,
|
|
99
|
+
flattenedItems,
|
|
98
100
|
tree,
|
|
99
101
|
treeRoot,
|
|
100
102
|
rerenderItems,
|
package/esm/TreeView.js
CHANGED
|
@@ -3,21 +3,17 @@ import 'react';
|
|
|
3
3
|
import { describe } from 'react-desc';
|
|
4
4
|
import { TreeViewPropTypes } from './react-desc-prop-types.js';
|
|
5
5
|
import TreeViewContext from './TreeViewContext.js';
|
|
6
|
-
import { TreeDndPlugin, TreeDnD } from './plugins/dnd/TreeDndPlugin.js';
|
|
7
6
|
import { useTreeview } from './config/useTreeview.js';
|
|
8
7
|
import { TreeList } from './parts/TreeList.js';
|
|
9
8
|
|
|
10
|
-
var
|
|
9
|
+
var _TreeList;
|
|
11
10
|
function TreeView(props) {
|
|
12
|
-
const {
|
|
13
|
-
plugins
|
|
14
|
-
} = props;
|
|
15
11
|
const {
|
|
16
12
|
ctx
|
|
17
13
|
} = useTreeview(props);
|
|
18
14
|
return /*#__PURE__*/_jsx(TreeViewContext.Provider, {
|
|
19
15
|
value: ctx
|
|
20
|
-
}, void 0,
|
|
16
|
+
}, void 0, _TreeList || (_TreeList = /*#__PURE__*/_jsx(TreeList, {})));
|
|
21
17
|
}
|
|
22
18
|
const TreeViewWithSchema = describe(TreeView);
|
|
23
19
|
TreeViewWithSchema.propTypes = TreeViewPropTypes;
|
package/esm/TreeViewContext.js
CHANGED
|
@@ -14,6 +14,7 @@ const defaultProps = {
|
|
|
14
14
|
fluid: false,
|
|
15
15
|
isMultiSelect: false,
|
|
16
16
|
isSingleSelect: false,
|
|
17
|
+
getIsDropValid: () => true,
|
|
17
18
|
restrictDragAndDrop: false,
|
|
18
19
|
showChildrenAmount: false,
|
|
19
20
|
sortable: false,
|
|
@@ -54,11 +55,10 @@ const defaultRelativeMouseCoord = {
|
|
|
54
55
|
const defaultContext = {
|
|
55
56
|
props: defaultProps,
|
|
56
57
|
visibleItems: [],
|
|
58
|
+
flattenedItems: [],
|
|
57
59
|
withRadioChecks: false,
|
|
58
60
|
withCheckboxChecks: false,
|
|
59
61
|
withDragAndDrop: false,
|
|
60
|
-
relativeMouseCord: defaultRelativeMouseCoord,
|
|
61
|
-
setRelativeMouseCord: noop,
|
|
62
62
|
triggerTreeRerender: noop,
|
|
63
63
|
tree: undefined,
|
|
64
64
|
treeRoot: undefined,
|
|
@@ -69,12 +69,6 @@ const defaultContext = {
|
|
|
69
69
|
scrollToIndex: noop
|
|
70
70
|
},
|
|
71
71
|
virtualListRef: undefined,
|
|
72
|
-
isDragging: false,
|
|
73
|
-
setIsDragging: noop,
|
|
74
|
-
isKeyboardDragging: false,
|
|
75
|
-
setIsKeyboardDragging: noop,
|
|
76
|
-
draggedItem: null,
|
|
77
|
-
setDraggedItem: noop,
|
|
78
72
|
uniqueTreeViewUUID: '',
|
|
79
73
|
selectedItem: null,
|
|
80
74
|
setSelectedItem: noop,
|
|
@@ -10,7 +10,7 @@ import { useVirtual } from 'react-virtual';
|
|
|
10
10
|
import { useMemoMergePropsWithDefault, useValidateTypescriptPropTypes } from '@elliemae/ds-props-helpers';
|
|
11
11
|
import { v4 } from 'uuid';
|
|
12
12
|
import { TreeViewPropTypes } from '../react-desc-prop-types.js';
|
|
13
|
-
import { defaultProps
|
|
13
|
+
import { defaultProps } from '../TreeViewContext.js';
|
|
14
14
|
import { TreeDndPlugin } from '../plugins/dnd/TreeDndPlugin.js';
|
|
15
15
|
import { useTree } from '../utils/useTree.js';
|
|
16
16
|
import { toggleItemExpand, useNotifyExpandedChange } from '../utils/group-expands-helpers.js';
|
|
@@ -42,11 +42,7 @@ const useTreeview = props => {
|
|
|
42
42
|
selection,
|
|
43
43
|
onInstanceRefInitialized
|
|
44
44
|
} = propsWithDefault;
|
|
45
|
-
const [isDragging, setIsDragging] = useState(false);
|
|
46
|
-
const [isKeyboardDragging, setIsKeyboardDragging] = useState(false);
|
|
47
|
-
const [relativeMouseCord, setRelativeMouseCord] = useState(defaultRelativeMouseCoord);
|
|
48
45
|
const [uniqueTreeViewUUID] = useState(v4());
|
|
49
|
-
const [draggedItem, setDraggedItem] = useState(null);
|
|
50
46
|
const [hoverItem, setHoverItem] = useState(null);
|
|
51
47
|
const [latestToggledItem, setLatestToggledItem] = useState(null);
|
|
52
48
|
const [selectedItem, setSelectedItem] = useState(null);
|
|
@@ -55,6 +51,7 @@ const useTreeview = props => {
|
|
|
55
51
|
const [expandedGroups, setExpandedGroups] = useState({});
|
|
56
52
|
const {
|
|
57
53
|
visibleItems,
|
|
54
|
+
flattenedItems,
|
|
58
55
|
tree,
|
|
59
56
|
treeRoot,
|
|
60
57
|
triggerTreeRerender,
|
|
@@ -76,20 +73,13 @@ const useTreeview = props => {
|
|
|
76
73
|
const handleExpandGroup = useCallback(toggleItemExpand, []);
|
|
77
74
|
const ctx = useMemo(() => ({
|
|
78
75
|
props: propsWithDefault,
|
|
79
|
-
setRelativeMouseCord,
|
|
80
|
-
relativeMouseCord,
|
|
81
76
|
virtualListHelpers,
|
|
82
77
|
virtualListRef,
|
|
83
78
|
tree,
|
|
84
79
|
treeRoot,
|
|
85
80
|
visibleItems,
|
|
81
|
+
flattenedItems,
|
|
86
82
|
triggerTreeRerender,
|
|
87
|
-
isDragging,
|
|
88
|
-
setIsDragging,
|
|
89
|
-
isKeyboardDragging,
|
|
90
|
-
setIsKeyboardDragging,
|
|
91
|
-
draggedItem,
|
|
92
|
-
setDraggedItem,
|
|
93
83
|
withRadioChecks,
|
|
94
84
|
withCheckboxChecks,
|
|
95
85
|
withDragAndDrop,
|
|
@@ -108,7 +98,7 @@ const useTreeview = props => {
|
|
|
108
98
|
setHoverItem,
|
|
109
99
|
handleExpandGroup,
|
|
110
100
|
updateUserExpandedState
|
|
111
|
-
}), [
|
|
101
|
+
}), [propsWithDefault, virtualListHelpers, tree, treeRoot, visibleItems, flattenedItems, triggerTreeRerender, withRadioChecks, withCheckboxChecks, withDragAndDrop, uniqueTreeViewUUID, selectedCheckboxes, selectedItem, expandedGroups, latestToggledItem, focusedItem, hoverItem, handleExpandGroup, updateUserExpandedState]); // this hooks can't use the context because the context provider doesn't wrap this
|
|
112
102
|
// as such we manually pass the second parameter as fit
|
|
113
103
|
|
|
114
104
|
if (instanceRef) instanceRef.current = treeRef.current;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { createContext } from 'react';
|
|
2
|
+
import { DropIndicatorPosition } from './SortableItemContext.js';
|
|
3
|
+
|
|
4
|
+
const DnDTreeContext = /*#__PURE__*/createContext({
|
|
5
|
+
depth: undefined,
|
|
6
|
+
activeIndex: undefined,
|
|
7
|
+
visibleItems: undefined,
|
|
8
|
+
dropIndicatorPosition: DropIndicatorPosition.None,
|
|
9
|
+
lastActiveId: undefined,
|
|
10
|
+
setLastActiveId: undefined,
|
|
11
|
+
isDropValid: false
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
export { DnDTreeContext };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { createContext } from 'react';
|
|
2
|
+
|
|
3
|
+
let DropIndicatorPosition;
|
|
4
|
+
|
|
5
|
+
(function (DropIndicatorPosition) {
|
|
6
|
+
DropIndicatorPosition[DropIndicatorPosition["None"] = 0] = "None";
|
|
7
|
+
DropIndicatorPosition[DropIndicatorPosition["Before"] = 1] = "Before";
|
|
8
|
+
DropIndicatorPosition[DropIndicatorPosition["After"] = 2] = "After";
|
|
9
|
+
DropIndicatorPosition[DropIndicatorPosition["Inside"] = 3] = "Inside";
|
|
10
|
+
})(DropIndicatorPosition || (DropIndicatorPosition = {}));
|
|
11
|
+
|
|
12
|
+
/** Context for cross component communication */
|
|
13
|
+
const SortableItemContext = /*#__PURE__*/createContext({
|
|
14
|
+
draggableProps: false
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
export { DropIndicatorPosition, SortableItemContext };
|