@elliemae/ds-treeview 2.2.0-next.6 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/cjs/TreeView.js +6 -2
  2. package/cjs/TreeViewContext.js +8 -2
  3. package/cjs/config/useTreeview.js +13 -3
  4. package/cjs/index.js +1 -0
  5. package/cjs/parts/TreeItem.js +68 -43
  6. package/cjs/parts/TreeList.js +17 -15
  7. package/cjs/plugins/dnd/TreeDndPlugin.js +37 -0
  8. package/cjs/plugins/dnd/index.js +1 -0
  9. package/cjs/plugins/index.js +1 -0
  10. package/cjs/react-desc-prop-types.js +0 -1
  11. package/cjs/utils/dnd-helpers.js +140 -0
  12. package/cjs/utils/keyboard-helpers.js +5 -6
  13. package/cjs/utils/tree-helpers.js +2 -28
  14. package/cjs/utils/useDnDHelpers.js +220 -0
  15. package/cjs/utils/useTree.js +2 -4
  16. package/esm/TreeView.js +6 -2
  17. package/esm/TreeViewContext.js +8 -2
  18. package/esm/config/useTreeview.js +14 -4
  19. package/esm/index.js +1 -1
  20. package/esm/parts/TreeItem.js +67 -42
  21. package/esm/parts/TreeList.js +17 -16
  22. package/esm/plugins/dnd/TreeDndPlugin.js +33 -1
  23. package/esm/plugins/dnd/index.js +1 -1
  24. package/esm/plugins/index.js +1 -1
  25. package/esm/react-desc-prop-types.js +0 -1
  26. package/esm/utils/dnd-helpers.js +132 -0
  27. package/esm/utils/keyboard-helpers.js +5 -6
  28. package/esm/utils/tree-helpers.js +3 -28
  29. package/esm/utils/useDnDHelpers.js +216 -0
  30. package/esm/utils/useTree.js +3 -5
  31. package/package.json +19 -35
  32. package/types/TreeView.d.ts +1 -1
  33. package/types/parts/TreeItem.d.ts +11 -4
  34. package/types/parts/TreeList.d.ts +4 -0
  35. package/types/plugins/dnd/TreeDndPlugin.d.ts +2 -0
  36. package/types/react-desc-prop-types.d.ts +3 -17
  37. package/types/sharedTypes.d.ts +8 -1
  38. package/types/utils/dnd-helpers.d.ts +39 -0
  39. package/types/utils/keyboard-helpers.d.ts +1 -2
  40. package/types/utils/refs-helpers.d.ts +1 -1
  41. package/types/utils/tree-helpers.d.ts +1 -4
  42. package/types/utils/useDnDHelpers.d.ts +26 -0
  43. package/types/utils/useTree.d.ts +0 -1
  44. package/cjs/hoc/DnDTreeContext.js +0 -18
  45. package/cjs/hoc/SortableItemContext.js +0 -21
  46. package/cjs/hoc/WithConditionalDnDContext.js +0 -138
  47. package/cjs/hoc/WithDnDSortableItemContext.js +0 -70
  48. package/cjs/parts/DnDHandle.js +0 -46
  49. package/cjs/parts/DropIndicator.js +0 -75
  50. package/esm/hoc/DnDTreeContext.js +0 -14
  51. package/esm/hoc/SortableItemContext.js +0 -17
  52. package/esm/hoc/WithConditionalDnDContext.js +0 -128
  53. package/esm/hoc/WithDnDSortableItemContext.js +0 -61
  54. package/esm/parts/DnDHandle.js +0 -38
  55. package/esm/parts/DropIndicator.js +0 -68
  56. package/types/hoc/DnDTreeContext.d.ts +0 -14
  57. package/types/hoc/SortableItemContext.d.ts +0 -19
  58. package/types/hoc/WithConditionalDnDContext.d.ts +0 -4
  59. package/types/hoc/WithDnDSortableItemContext.d.ts +0 -4
  60. package/types/parts/DnDHandle.d.ts +0 -6
  61. package/types/parts/DropIndicator.d.ts +0 -10
package/cjs/TreeView.js CHANGED
@@ -7,6 +7,7 @@ require('react');
7
7
  var reactDesc = require('react-desc');
8
8
  var reactDescPropTypes = require('./react-desc-prop-types.js');
9
9
  var TreeViewContext = require('./TreeViewContext.js');
10
+ var TreeDndPlugin = require('./plugins/dnd/TreeDndPlugin.js');
10
11
  var useTreeview = require('./config/useTreeview.js');
11
12
  var TreeList = require('./parts/TreeList.js');
12
13
 
@@ -14,14 +15,17 @@ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'defau
14
15
 
15
16
  var _jsx__default = /*#__PURE__*/_interopDefaultLegacy(_jsx);
16
17
 
17
- var _TreeList;
18
+ var _TreeDnD, _TreeList;
18
19
  function TreeView(props) {
20
+ const {
21
+ plugins
22
+ } = props;
19
23
  const {
20
24
  ctx
21
25
  } = useTreeview.useTreeview(props);
22
26
  return /*#__PURE__*/_jsx__default["default"](TreeViewContext["default"].Provider, {
23
27
  value: ctx
24
- }, void 0, _TreeList || (_TreeList = /*#__PURE__*/_jsx__default["default"](TreeList.TreeList, {})));
28
+ }, void 0, plugins !== null && plugins !== void 0 && plugins.includes(TreeDndPlugin.TreeDndPlugin) ? _TreeDnD || (_TreeDnD = /*#__PURE__*/_jsx__default["default"](TreeDndPlugin.TreeDnD, {})) : _TreeList || (_TreeList = /*#__PURE__*/_jsx__default["default"](TreeList.TreeList, {})));
25
29
  }
26
30
  const TreeViewWithSchema = reactDesc.describe(TreeView);
27
31
  TreeViewWithSchema.propTypes = reactDescPropTypes.TreeViewPropTypes;
@@ -18,7 +18,6 @@ const defaultProps = {
18
18
  fluid: false,
19
19
  isMultiSelect: false,
20
20
  isSingleSelect: false,
21
- getIsDropValid: () => true,
22
21
  restrictDragAndDrop: false,
23
22
  showChildrenAmount: false,
24
23
  sortable: false,
@@ -59,10 +58,11 @@ const defaultRelativeMouseCoord = {
59
58
  const defaultContext = {
60
59
  props: defaultProps,
61
60
  visibleItems: [],
62
- flattenedItems: [],
63
61
  withRadioChecks: false,
64
62
  withCheckboxChecks: false,
65
63
  withDragAndDrop: false,
64
+ relativeMouseCord: defaultRelativeMouseCoord,
65
+ setRelativeMouseCord: noop,
66
66
  triggerTreeRerender: noop,
67
67
  tree: undefined,
68
68
  treeRoot: undefined,
@@ -73,6 +73,12 @@ const defaultContext = {
73
73
  scrollToIndex: noop
74
74
  },
75
75
  virtualListRef: undefined,
76
+ isDragging: false,
77
+ setIsDragging: noop,
78
+ isKeyboardDragging: false,
79
+ setIsKeyboardDragging: noop,
80
+ draggedItem: null,
81
+ setDraggedItem: noop,
76
82
  uniqueTreeViewUUID: '',
77
83
  selectedItem: null,
78
84
  setSelectedItem: noop,
@@ -50,7 +50,11 @@ const useTreeview = props => {
50
50
  selection,
51
51
  onInstanceRefInitialized
52
52
  } = propsWithDefault;
53
+ const [isDragging, setIsDragging] = React.useState(false);
54
+ const [isKeyboardDragging, setIsKeyboardDragging] = React.useState(false);
55
+ const [relativeMouseCord, setRelativeMouseCord] = React.useState(TreeViewContext.defaultRelativeMouseCoord);
53
56
  const [uniqueTreeViewUUID] = React.useState(uuid.v4());
57
+ const [draggedItem, setDraggedItem] = React.useState(null);
54
58
  const [hoverItem, setHoverItem] = React.useState(null);
55
59
  const [latestToggledItem, setLatestToggledItem] = React.useState(null);
56
60
  const [selectedItem, setSelectedItem] = React.useState(null);
@@ -59,7 +63,6 @@ const useTreeview = props => {
59
63
  const [expandedGroups, setExpandedGroups] = React.useState({});
60
64
  const {
61
65
  visibleItems,
62
- flattenedItems,
63
66
  tree,
64
67
  treeRoot,
65
68
  triggerTreeRerender,
@@ -81,13 +84,20 @@ const useTreeview = props => {
81
84
  const handleExpandGroup = React.useCallback(groupExpandsHelpers.toggleItemExpand, []);
82
85
  const ctx = React.useMemo(() => ({
83
86
  props: propsWithDefault,
87
+ setRelativeMouseCord,
88
+ relativeMouseCord,
84
89
  virtualListHelpers,
85
90
  virtualListRef,
86
91
  tree,
87
92
  treeRoot,
88
93
  visibleItems,
89
- flattenedItems,
90
94
  triggerTreeRerender,
95
+ isDragging,
96
+ setIsDragging,
97
+ isKeyboardDragging,
98
+ setIsKeyboardDragging,
99
+ draggedItem,
100
+ setDraggedItem,
91
101
  withRadioChecks,
92
102
  withCheckboxChecks,
93
103
  withDragAndDrop,
@@ -106,7 +116,7 @@ const useTreeview = props => {
106
116
  setHoverItem,
107
117
  handleExpandGroup,
108
118
  updateUserExpandedState
109
- }), [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
119
+ }), [draggedItem, expandedGroups, focusedItem, handleExpandGroup, hoverItem, isDragging, isKeyboardDragging, latestToggledItem, propsWithDefault, relativeMouseCord, selectedCheckboxes, selectedItem, tree, treeRoot, triggerTreeRerender, uniqueTreeViewUUID, virtualListHelpers, visibleItems, withCheckboxChecks, withDragAndDrop, withRadioChecks, updateUserExpandedState]); // this hooks can't use the context because the context provider doesn't wrap this
110
120
  // as such we manually pass the second parameter as fit
111
121
 
112
122
  if (instanceRef) instanceRef.current = treeRef.current;
package/cjs/index.js CHANGED
@@ -16,6 +16,7 @@ var TreeViewSearchBar = require('./related-components/TreeViewSearchBar.js');
16
16
 
17
17
  exports.TreeView = TreeView.TreeView;
18
18
  exports.TreeViewWithSchema = TreeView.TreeViewWithSchema;
19
+ exports.TreeDnD = TreeDndPlugin.TreeDnD;
19
20
  exports.TreeDndPlugin = TreeDndPlugin.TreeDndPlugin;
20
21
  exports.TreeRovingPlugin = TreeRovingPlugin.TreeRovingPlugin;
21
22
  exports.SelectablePluginTree = SelectablePluginTree.SelectablePluginTree;
@@ -2,15 +2,18 @@
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');
5
8
  require('core-js/modules/esnext.async-iterator.filter.js');
6
9
  require('core-js/modules/esnext.iterator.constructor.js');
7
10
  require('core-js/modules/esnext.iterator.filter.js');
8
11
  require('core-js/modules/esnext.async-iterator.for-each.js');
9
12
  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');
12
13
  var React = require('react');
14
+ var reactSortableHoc = require('@elliemae/react-sortable-hoc');
13
15
  var dsClassnames = require('@elliemae/ds-classnames');
16
+ var dsIcons = require('@elliemae/ds-icons');
14
17
  var RadioSelectable = require('./RadioSelectable.js');
15
18
  var CheckboxSelectable = require('./CheckboxSelectable.js');
16
19
  var TreeViewContext = require('../TreeViewContext.js');
@@ -21,16 +24,12 @@ var Icon = require('./Icon.js');
21
24
  var ExpandCaret = require('./ExpandCaret.js');
22
25
  var TreeItemText = require('./TreeItemText.js');
23
26
  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');
28
27
  var jsxRuntime = require('react/jsx-runtime');
29
28
 
30
29
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
31
30
 
32
- var _jsx__default = /*#__PURE__*/_interopDefaultLegacy(_jsx);
33
31
  var _defineProperty__default = /*#__PURE__*/_interopDefaultLegacy(_defineProperty);
32
+ var _jsx__default = /*#__PURE__*/_interopDefaultLegacy(_jsx);
34
33
 
35
34
  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; }
36
35
 
@@ -42,6 +41,23 @@ const TreeListItem = dsClassnames.aggregatedClasses('li', {
42
41
  })(cssClassesConstants.treeItemBlockName);
43
42
  const TreeListItemAddonsWrapper = dsClassnames.aggregatedClasses('div')(cssClassesConstants.treeItemBlockName, 'addons' // temp fix untill we move to styled components
44
43
  );
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
+ });
45
61
  const TreeItem = props => {
46
62
  const {
47
63
  item,
@@ -49,7 +65,7 @@ const TreeItem = props => {
49
65
  itemWrapperStyle = {},
50
66
  virtualItemRef,
51
67
  spaceForNestingLevel = 1.5,
52
- isDragOverlay = false
68
+ onMouseDragOverItem
53
69
  } = props;
54
70
  const {
55
71
  id,
@@ -58,10 +74,9 @@ const TreeItem = props => {
58
74
  const {
59
75
  nodeItemRef
60
76
  } = node.model;
61
- const {
62
- draggableProps
63
- } = React.useContext(SortableItemContext.SortableItemContext);
64
- const onItemKeyDown = keyboardHelpers.useOnItemKeyDown(item, draggableProps);
77
+ const openFolderOnHoverTimeout = React.useRef(null);
78
+ const [isDraggingOverThis, setIsDraggingOverThis] = React.useState(false);
79
+ const onItemKeyDown = keyboardHelpers.useOnItemKeyDown(item);
65
80
  const ctx = React.useContext(TreeViewContext["default"]);
66
81
  const {
67
82
  props: {
@@ -72,12 +87,14 @@ const TreeItem = props => {
72
87
  rowSize,
73
88
  labelOverflow
74
89
  },
90
+ relativeMouseCord,
75
91
  withRadioChecks,
76
92
  withCheckboxChecks,
77
93
  withDragAndDrop,
78
94
  selectedItem,
79
95
  selectedCheckboxes,
80
96
  hoverItem,
97
+ isDragging,
81
98
  virtualListHelpers: {
82
99
  scrollToIndex
83
100
  },
@@ -87,27 +104,24 @@ const TreeItem = props => {
87
104
  } = ctx; // Sortable Items needs to update
88
105
  // - the virtual list ref (for react-virtual requirement)
89
106
  // - nodeItemRef which is a prop avaiable in the TreeModel nodes
90
- // - the drag and drop node reference
91
107
 
92
108
  const setItemRefs = ref => {
93
- refsHelpers.setMultipleRefs(virtualItemRef, !isDragOverlay && nodeItemRef, !isDragOverlay && draggableProps && draggableProps.setNodeRef)(ref);
109
+ refsHelpers.setMultipleRefs(virtualItemRef, nodeItemRef)(ref);
94
110
  };
95
111
 
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;
100
112
  const dropPreviewClassName = React.useMemo(() => {
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]);
113
+ if (!withDragAndDrop || !relativeMouseCord || !isDraggingOverThis) return '';
114
+ const {
115
+ isBefore,
116
+ isAfter,
117
+ isValid
118
+ } = relativeMouseCord;
119
+ let className = "".concat(cssClassesConstants.DSTreeViewPrefix, "-").concat(cssClassesConstants.treeItemBlockName).concat(isValid ? '--valid' : '--invalid');
120
+ if (isBefore) className += '-drop-before';else if (isAfter) className += '-drop-after';else className += '-drop-in';
121
+ return className;
122
+ }, [withDragAndDrop, relativeMouseCord, isDraggingOverThis]);
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]);
111
125
  const fixedHeightClassname = React.useMemo(() => {
112
126
  if (labelOverflow === 'truncate') {
113
127
  if (rowSize === 'compact') return "".concat(cssClassesConstants.DSTreeViewPrefix, "-").concat(cssClassesConstants.treeItemBlockName, "--fixed-height-compact");
@@ -116,7 +130,7 @@ const TreeItem = props => {
116
130
 
117
131
  return '';
118
132
  }, [labelOverflow, rowSize]);
119
- const finalClassName = React.useMemo(() => "".concat(dropPreviewClassName, " ").concat(fixedHeightClassname, " ").concat(selectedClassName, " ").concat(hoverClassName, " ").concat(dragOverlayClassName), [dropPreviewClassName, selectedClassName, hoverClassName, fixedHeightClassname, dragOverlayClassName]);
133
+ const finalClassName = React.useMemo(() => "".concat(dropPreviewClassName, " ").concat(fixedHeightClassname, " ").concat(selectedClassName, " ").concat(hoverClassName), [dropPreviewClassName, selectedClassName, hoverClassName, fixedHeightClassname]);
120
134
  const handleItemClick = React.useCallback(e => {
121
135
  onItemClick(item, e);
122
136
  setFocusedItem(item);
@@ -135,7 +149,23 @@ const TreeItem = props => {
135
149
  }, [item, scrollToIndex, onItemClick, onItemFocus, setSelectedItem, setFocusedItem]);
136
150
  return /*#__PURE__*/jsxRuntime.jsxs(TreeListItem, {
137
151
  tabIndex: 0,
152
+ onMouseMove: event => {
153
+ if (withDragAndDrop && onMouseDragOverItem) {
154
+ onMouseDragOverItem({
155
+ event,
156
+ item,
157
+ itemIndex,
158
+ setIsDraggingOverThis,
159
+ openFolderOnHoverTimeout
160
+ });
161
+ }
162
+ },
138
163
  onMouseLeave: () => {
164
+ if (withDragAndDrop) {
165
+ setIsDraggingOverThis(false);
166
+ if (openFolderOnHoverTimeout !== null && openFolderOnHoverTimeout !== void 0 && openFolderOnHoverTimeout.current) clearTimeout(openFolderOnHoverTimeout.current);
167
+ }
168
+
139
169
  if ((hoverItem === null || hoverItem === void 0 ? void 0 : hoverItem.id) === item.id) {
140
170
  setHoverItem(null);
141
171
  }
@@ -144,7 +174,6 @@ const TreeItem = props => {
144
174
  setHoverItem(item);
145
175
  },
146
176
  onClick: handleItemClick,
147
- onBlur: () => setFocusedItem(null),
148
177
  ref: setItemRefs,
149
178
  style: _objectSpread({}, itemWrapperStyle),
150
179
  className: finalClassName,
@@ -153,33 +182,29 @@ const TreeItem = props => {
153
182
  "data-id": item.id,
154
183
  "data-index": item.virtualIndex,
155
184
  onKeyDown: onItemKeyDown,
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, {
185
+ children: [/*#__PURE__*/_jsx__default["default"](TreeListItemAddonsWrapper, {}, void 0, withDragAndDrop ? /*#__PURE__*/_jsx__default["default"](DnDHandle, {
186
+ id: id
187
+ }) : null, withRadioChecks ? /*#__PURE__*/_jsx__default["default"](RadioSelectable, {
160
188
  item: item,
161
189
  itemIndex: itemIndex
162
- }) : null, withCheckboxChecks && !isDragOverlay ? /*#__PURE__*/_jsx__default["default"](CheckboxSelectable, {
190
+ }) : null, withCheckboxChecks ? /*#__PURE__*/_jsx__default["default"](CheckboxSelectable, {
163
191
  item: item,
164
192
  itemIndex: itemIndex
165
- }) : null, !isDragOverlay && /*#__PURE__*/_jsx__default["default"](NestingSpace.NestingSpace, {
193
+ }) : null, /*#__PURE__*/_jsx__default["default"](NestingSpace.NestingSpace, {
166
194
  item: item,
167
195
  spaceForNestingLevel: spaceForNestingLevel
168
- }), !isDragOverlay && /*#__PURE__*/_jsx__default["default"](ExpandCaret.ExpandCaret, {
196
+ }), /*#__PURE__*/_jsx__default["default"](ExpandCaret.ExpandCaret, {
169
197
  item: item
170
198
  }), !disableIcons ? /*#__PURE__*/_jsx__default["default"](Icon.Icon, {
171
199
  item: item
172
200
  }) : null), /*#__PURE__*/_jsx__default["default"](TreeItemText.TreeItemText, {
173
201
  item: item
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
- })]
202
+ }), rightAddons && /*#__PURE__*/_jsx__default["default"](TreeListItemAddonsWrapper, {}, void 0, typeof rightAddons === 'function' ? rightAddons(item) : rightAddons)]
178
203
  });
179
204
  };
180
- var TreeItem$1 = WithDnDSortableItemContext.withDnDSortableItemContext(TreeItem);
205
+ const DragAndDropTreeItem = reactSortableHoc.SortableElement(TreeItem);
181
206
 
207
+ exports.DragAndDropTreeItem = DragAndDropTreeItem;
182
208
  exports.TreeItem = TreeItem;
183
209
  exports.TreeListItem = TreeListItem;
184
210
  exports.TreeListItemAddonsWrapper = TreeListItemAddonsWrapper;
185
- exports["default"] = TreeItem$1;
@@ -12,13 +12,12 @@ 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');
15
16
  var dsClassnames = require('@elliemae/ds-classnames');
16
17
  var dsCircularProgressIndicator = require('@elliemae/ds-circular-progress-indicator');
17
18
  var TreeViewContext = require('../TreeViewContext.js');
18
19
  var cssClassesConstants = require('../config/cssClassesConstants.js');
19
20
  var TreeItem = require('./TreeItem.js');
20
- var WithConditionalDnDContext = require('../hoc/WithConditionalDnDContext.js');
21
- var DnDTreeContext = require('../hoc/DnDTreeContext.js');
22
21
  var jsxRuntime = require('react/jsx-runtime');
23
22
 
24
23
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
@@ -48,13 +47,16 @@ const TreeListWrapper = dsClassnames.aggregatedClasses('ul', {
48
47
  });
49
48
  const compactRowClass = "".concat(cssClassesConstants.DSTreeViewPrefix, "-tv-row-size-compact");
50
49
  const normaRowClass = "".concat(cssClassesConstants.DSTreeViewPrefix, "-tv-row-size-normal");
51
-
52
- const TreeListComp = () => {
50
+ const TreeList = props => {
51
+ const {
52
+ onMouseDragOverItem
53
+ } = props;
53
54
  const ctx = React.useContext(TreeViewContext["default"]);
54
55
  const {
55
56
  virtualListRef,
56
57
  virtualListHelpers,
57
- visibleItems: flattenedVisibleItems,
58
+ visibleItems,
59
+ withDragAndDrop,
58
60
  props: {
59
61
  width,
60
62
  height,
@@ -68,9 +70,6 @@ const TreeListComp = () => {
68
70
  virtualItems
69
71
  } = virtualListHelpers;
70
72
  const className = "".concat(rowSize === 'compact' ? "".concat(compactRowClass) : "".concat(normaRowClass));
71
- const {
72
- visibleItems
73
- } = React.useContext(DnDTreeContext.DnDTreeContext);
74
73
  return /*#__PURE__*/jsxRuntime.jsxs(TreeListWrapper, {
75
74
  ref: virtualListRef,
76
75
  className: className,
@@ -105,17 +104,17 @@ const TreeListComp = () => {
105
104
  measureRef,
106
105
  start
107
106
  } = virtualItem;
108
- const item = (visibleItems || flattenedVisibleItems)[index];
109
- if (!item) return null;
107
+ const item = visibleItems[index];
110
108
  item.virtualIndex = index;
111
109
  const {
112
110
  id
113
111
  } = item;
114
112
  const style = {
115
113
  position: 'absolute',
116
- top: "".concat(start, "px"),
114
+ top: 0,
117
115
  left: 0,
118
- width: '100%'
116
+ width: '100%',
117
+ transform: "translateY(".concat(start, "px)")
119
118
  };
120
119
  const listItemProps = {
121
120
  key: "DS-TreeView-List-Item-".concat(id),
@@ -126,13 +125,16 @@ const TreeListComp = () => {
126
125
  item,
127
126
  itemWrapperStyle: style
128
127
  };
129
- return /*#__PURE__*/jsxRuntime.jsx(TreeItem["default"], _objectSpread({}, listItemProps));
128
+ if (withDragAndDrop) return /*#__PURE__*/jsxRuntime.jsx(TreeItem.DragAndDropTreeItem, _objectSpread(_objectSpread({}, listItemProps), {}, {
129
+ onMouseDragOverItem: onMouseDragOverItem
130
+ }));
131
+ return /*#__PURE__*/jsxRuntime.jsx(TreeItem.TreeItem, _objectSpread({}, listItemProps));
130
132
  })) : null]
131
133
  });
132
134
  };
135
+ const DragAndDropTreeList = reactSortableHoc.SortableContainer(TreeList);
133
136
 
134
- const TreeList = WithConditionalDnDContext.withConditionalDnDRowContext(TreeListComp);
135
-
137
+ exports.DragAndDropTreeList = DragAndDropTreeList;
136
138
  exports.TreeList = TreeList;
137
139
  exports.TreeListNoItems = TreeListNoItems;
138
140
  exports.TreeListWrapper = TreeListWrapper;
@@ -2,6 +2,43 @@
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
+ };
5
41
  const TreeDndPlugin = 'tree-dnd';
6
42
 
43
+ exports.TreeDnD = TreeDnD;
7
44
  exports.TreeDndPlugin = TreeDndPlugin;
@@ -6,4 +6,5 @@ var TreeDndPlugin = require('./TreeDndPlugin.js');
6
6
 
7
7
 
8
8
 
9
+ exports.TreeDnD = TreeDndPlugin.TreeDnD;
9
10
  exports.TreeDndPlugin = TreeDndPlugin.TreeDndPlugin;
@@ -12,6 +12,7 @@ var SearchableTreePlugin = require('./searchable/SearchableTreePlugin.js');
12
12
 
13
13
 
14
14
 
15
+ exports.TreeDnD = TreeDndPlugin.TreeDnD;
15
16
  exports.TreeDndPlugin = TreeDndPlugin.TreeDndPlugin;
16
17
  exports.TreeRovingPlugin = TreeRovingPlugin.TreeRovingPlugin;
17
18
  exports.SelectablePluginTree = SelectablePluginTree.SelectablePluginTree;
@@ -30,7 +30,6 @@ 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'),
34
33
  restrictDragAndDrop: reactDesc.PropTypes.bool.description('whether to restrict DnD functionality or not').defaultValue(false),
35
34
  showChildrenAmount: reactDesc.PropTypes.bool.description('whether to show the amount of children or not').defaultValue(false),
36
35
  sortable: reactDesc.PropTypes.bool.description('whether the sortable functionality is active or not').defaultValue(false),
@@ -0,0 +1,140 @@
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;