@elliemae/ds-treeview 2.0.2 → 2.1.0-rc.4

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 (165) hide show
  1. package/cjs/TreeView.js +5 -103
  2. package/cjs/TreeViewContext.js +44 -47
  3. package/cjs/config/useTreeview.js +137 -0
  4. package/cjs/index.js +1 -7
  5. package/cjs/parts/CheckboxSelectable.js +5 -7
  6. package/cjs/parts/ExpandCaret.js +17 -11
  7. package/cjs/parts/Icon.js +4 -0
  8. package/cjs/parts/NestingSpace.js +15 -22
  9. package/cjs/parts/RadioSelectable.js +7 -9
  10. package/cjs/parts/TreeItem.js +14 -11
  11. package/cjs/parts/TreeList.js +4 -2
  12. package/cjs/plugins/dnd/TreeDndPlugin.js +1 -1
  13. package/cjs/react-desc-prop-types.js +28 -27
  14. package/cjs/related-components/TreeViewSearchBar.js +9 -1
  15. package/cjs/{deprecated/plugins/selectable/helper.js → sharedTypes.js} +0 -0
  16. package/cjs/utils/dnd-helpers.js +2 -4
  17. package/cjs/utils/group-expands-helpers.js +34 -8
  18. package/cjs/utils/keyboard-helpers.js +64 -60
  19. package/cjs/utils/object-helpers.js +25 -7
  20. package/cjs/utils/refs-helpers.js +2 -2
  21. package/cjs/utils/tree-helpers.js +42 -27
  22. package/cjs/utils/useDnDHelpers.js +107 -100
  23. package/cjs/utils/useInstanceRefActions.js +3 -2
  24. package/cjs/utils/useTree.js +25 -6
  25. package/esm/TreeView.js +6 -103
  26. package/esm/TreeViewContext.js +44 -47
  27. package/esm/config/useTreeview.js +129 -0
  28. package/esm/index.js +0 -8
  29. package/esm/parts/CheckboxSelectable.js +5 -7
  30. package/esm/parts/ExpandCaret.js +17 -11
  31. package/esm/parts/Icon.js +4 -0
  32. package/esm/parts/NestingSpace.js +15 -21
  33. package/esm/parts/RadioSelectable.js +7 -9
  34. package/esm/parts/TreeItem.js +14 -11
  35. package/esm/parts/TreeList.js +4 -2
  36. package/esm/plugins/dnd/TreeDndPlugin.js +1 -1
  37. package/esm/react-desc-prop-types.js +28 -27
  38. package/esm/related-components/TreeViewSearchBar.js +9 -1
  39. package/esm/{deprecated/plugins/selectable/helper.js → sharedTypes.js} +0 -0
  40. package/esm/utils/dnd-helpers.js +2 -4
  41. package/esm/utils/group-expands-helpers.js +34 -9
  42. package/esm/utils/keyboard-helpers.js +62 -58
  43. package/esm/utils/object-helpers.js +25 -7
  44. package/esm/utils/refs-helpers.js +2 -2
  45. package/esm/utils/tree-helpers.js +42 -27
  46. package/esm/utils/useDnDHelpers.js +107 -100
  47. package/esm/utils/useInstanceRefActions.js +3 -2
  48. package/esm/utils/useTree.js +25 -6
  49. package/package.json +17 -128
  50. package/types/TreeView.d.ts +4 -148
  51. package/types/TreeViewContext.d.ts +4 -106
  52. package/types/config/useTreeview.d.ts +7 -0
  53. package/types/index.d.ts +0 -1
  54. package/types/parts/CheckboxSelectable.d.ts +5 -6
  55. package/types/parts/ChildrenCountDisplayer.d.ts +6 -6
  56. package/types/parts/ExpandCaret.d.ts +6 -6
  57. package/types/parts/Icon.d.ts +7 -5
  58. package/types/parts/NestingSpace.d.ts +3 -8
  59. package/types/parts/RadioSelectable.d.ts +5 -6
  60. package/types/parts/TreeItem.d.ts +22 -14
  61. package/types/parts/TreeItemText.d.ts +5 -5
  62. package/types/parts/TreeList.d.ts +22 -9
  63. package/types/react-desc-prop-types.d.ts +124 -43
  64. package/types/related-components/TreeViewSearchBar.d.ts +14 -11
  65. package/types/sharedTypes.d.ts +54 -0
  66. package/types/utils/array-helpers.d.ts +2 -2
  67. package/types/utils/dnd-helpers.d.ts +26 -25
  68. package/types/utils/group-expands-helpers.d.ts +13 -10
  69. package/types/utils/keyboard-helpers.d.ts +5 -3
  70. package/types/utils/object-helpers.d.ts +6 -2
  71. package/types/utils/refs-helpers.d.ts +4 -1
  72. package/types/utils/selectable-helper.d.ts +7 -3
  73. package/types/utils/string-helpers.d.ts +1 -1
  74. package/types/utils/tree-helpers.d.ts +25 -11
  75. package/types/utils/useDnDHelpers.d.ts +23 -3
  76. package/types/utils/useInstanceRefActions.d.ts +3 -3
  77. package/types/utils/useTree.d.ts +8 -7
  78. package/cjs/deprecated/TreeView.js +0 -72
  79. package/cjs/deprecated/__testUtils__/utils.js +0 -89
  80. package/cjs/deprecated/index.js +0 -27
  81. package/cjs/deprecated/plugins/dnd/TreeDndPlugin.js +0 -119
  82. package/cjs/deprecated/plugins/dnd/index.js +0 -9
  83. package/cjs/deprecated/plugins/dnd/renderers/DraggableItem.js +0 -67
  84. package/cjs/deprecated/plugins/dnd/renderers/DroppableList.js +0 -181
  85. package/cjs/deprecated/plugins/dnd/utils.js +0 -157
  86. package/cjs/deprecated/plugins/index.js +0 -21
  87. package/cjs/deprecated/plugins/roving/TreeRovingPlugin.js +0 -109
  88. package/cjs/deprecated/plugins/roving/index.js +0 -9
  89. package/cjs/deprecated/plugins/searchable/SearchableTreePlugin.js +0 -109
  90. package/cjs/deprecated/plugins/searchable/index.js +0 -9
  91. package/cjs/deprecated/plugins/searchable/utils.js +0 -7
  92. package/cjs/deprecated/plugins/selectable/SelectablePluginTree.js +0 -290
  93. package/cjs/deprecated/plugins/selectable/index.js +0 -9
  94. package/cjs/deprecated/plugins/selectable/utils.js +0 -19
  95. package/cjs/deprecated/plugins/toolbar/TreeToolbarPlugin.js +0 -128
  96. package/cjs/deprecated/plugins/toolbar/index.js +0 -9
  97. package/cjs/deprecated/plugins/tree/TreeDataPlugin.js +0 -281
  98. package/cjs/deprecated/plugins/tree/index.js +0 -9
  99. package/cjs/deprecated/plugins/tree/useExpandTreeState.js +0 -143
  100. package/cjs/deprecated/plugins/tree/utils.js +0 -43
  101. package/cjs/deprecated/plugins/tree/walkTreeStrategy.js +0 -60
  102. package/cjs/deprecated/plugins/virtualization/TreeVirtualizationPlugin.js +0 -209
  103. package/cjs/deprecated/plugins/virtualization/index.js +0 -9
  104. package/cjs/deprecated/renderers.js +0 -76
  105. package/cjs/prop-types.js +0 -61
  106. package/esm/deprecated/TreeView.js +0 -61
  107. package/esm/deprecated/__testUtils__/utils.js +0 -79
  108. package/esm/deprecated/index.js +0 -14
  109. package/esm/deprecated/plugins/dnd/TreeDndPlugin.js +0 -110
  110. package/esm/deprecated/plugins/dnd/index.js +0 -1
  111. package/esm/deprecated/plugins/dnd/renderers/DraggableItem.js +0 -59
  112. package/esm/deprecated/plugins/dnd/renderers/DroppableList.js +0 -172
  113. package/esm/deprecated/plugins/dnd/utils.js +0 -139
  114. package/esm/deprecated/plugins/index.js +0 -7
  115. package/esm/deprecated/plugins/roving/TreeRovingPlugin.js +0 -96
  116. package/esm/deprecated/plugins/roving/index.js +0 -1
  117. package/esm/deprecated/plugins/searchable/SearchableTreePlugin.js +0 -99
  118. package/esm/deprecated/plugins/searchable/index.js +0 -1
  119. package/esm/deprecated/plugins/searchable/utils.js +0 -3
  120. package/esm/deprecated/plugins/selectable/SelectablePluginTree.js +0 -280
  121. package/esm/deprecated/plugins/selectable/index.js +0 -1
  122. package/esm/deprecated/plugins/selectable/utils.js +0 -15
  123. package/esm/deprecated/plugins/toolbar/TreeToolbarPlugin.js +0 -114
  124. package/esm/deprecated/plugins/toolbar/index.js +0 -1
  125. package/esm/deprecated/plugins/tree/TreeDataPlugin.js +0 -269
  126. package/esm/deprecated/plugins/tree/index.js +0 -1
  127. package/esm/deprecated/plugins/tree/useExpandTreeState.js +0 -135
  128. package/esm/deprecated/plugins/tree/utils.js +0 -28
  129. package/esm/deprecated/plugins/tree/walkTreeStrategy.js +0 -56
  130. package/esm/deprecated/plugins/virtualization/TreeVirtualizationPlugin.js +0 -197
  131. package/esm/deprecated/plugins/virtualization/index.js +0 -1
  132. package/esm/deprecated/renderers.js +0 -59
  133. package/esm/prop-types.js +0 -46
  134. package/types/deprecated/TreeView.d.ts +0 -8
  135. package/types/deprecated/__testUtils__/utils.d.ts +0 -72
  136. package/types/deprecated/index.d.ts +0 -2
  137. package/types/deprecated/plugins/dnd/TreeDndPlugin.d.ts +0 -1
  138. package/types/deprecated/plugins/dnd/index.d.ts +0 -1
  139. package/types/deprecated/plugins/dnd/renderers/DraggableItem.d.ts +0 -3
  140. package/types/deprecated/plugins/dnd/renderers/DroppableList.d.ts +0 -6
  141. package/types/deprecated/plugins/dnd/tests/TreeDndPlugin.test.d.ts +0 -0
  142. package/types/deprecated/plugins/dnd/utils.d.ts +0 -28
  143. package/types/deprecated/plugins/index.d.ts +0 -7
  144. package/types/deprecated/plugins/roving/TreeRovingPlugin.d.ts +0 -1
  145. package/types/deprecated/plugins/roving/index.d.ts +0 -1
  146. package/types/deprecated/plugins/searchable/SearchableTreePlugin.d.ts +0 -1
  147. package/types/deprecated/plugins/searchable/index.d.ts +0 -1
  148. package/types/deprecated/plugins/searchable/utils.d.ts +0 -1
  149. package/types/deprecated/plugins/selectable/SelectablePluginTree.d.ts +0 -1
  150. package/types/deprecated/plugins/selectable/helper.d.ts +0 -0
  151. package/types/deprecated/plugins/selectable/index.d.ts +0 -1
  152. package/types/deprecated/plugins/selectable/tests/SelectablePluginTree.test.d.ts +0 -1
  153. package/types/deprecated/plugins/selectable/utils.d.ts +0 -1
  154. package/types/deprecated/plugins/toolbar/TreeToolbarPlugin.d.ts +0 -1
  155. package/types/deprecated/plugins/toolbar/index.d.ts +0 -1
  156. package/types/deprecated/plugins/tree/TreeDataPlugin.d.ts +0 -1
  157. package/types/deprecated/plugins/tree/index.d.ts +0 -1
  158. package/types/deprecated/plugins/tree/tests/TreeDataPlugin.test.d.ts +0 -1
  159. package/types/deprecated/plugins/tree/useExpandTreeState.d.ts +0 -14
  160. package/types/deprecated/plugins/tree/utils.d.ts +0 -8
  161. package/types/deprecated/plugins/tree/walkTreeStrategy.d.ts +0 -9
  162. package/types/deprecated/plugins/virtualization/TreeVirtualizationPlugin.d.ts +0 -1
  163. package/types/deprecated/plugins/virtualization/index.d.ts +0 -1
  164. package/types/deprecated/renderers.d.ts +0 -19
  165. package/types/prop-types.d.ts +0 -26
@@ -37,63 +37,68 @@ const useDnDHelpers = () => {
37
37
  newIndex,
38
38
  isKeySorting
39
39
  } = _ref;
40
- let newItems = cloneDeep(data);
41
40
  const {
42
41
  isBefore,
43
42
  isAfter,
44
43
  item: overItem,
45
44
  isValid
46
- } = relativeMouseCord; // if dropping in same position do nothing
47
- // if the drop is not allowed do nothing
45
+ } = relativeMouseCord;
46
+
47
+ if (draggedItem && tree && treeRoot && overItem) {
48
+ let newItems = cloneDeep(data); // if dropping in same position do nothing
49
+ // if the drop is not allowed do nothing
50
+
51
+ if (oldIndex === newIndex || !isValid) {
52
+ // onOrderChange(newItems, data);
53
+ setIsDragging(false);
54
+ setDraggedItem(null);
55
+ triggerTreeRerender();
56
+ return;
57
+ } // if we are moving from topToBottom the offset changes
58
+
59
+
60
+ const movementDirection = newIndex > oldIndex ? 'topToBottom' : 'bottomToTop';
61
+ let newNestedIndex;
62
+ let newParentNode;
63
+
64
+ if (isKeySorting) {
65
+ const kinship = inferKeyboardKinshipDrop({
66
+ items: visibleItems,
67
+ newIndex
68
+ });
69
+ newNestedIndex = kinship.newNestedIndex;
70
+ newParentNode = kinship.newParentNode;
71
+ } else {
72
+ const kinship = inferHoverItemKinshipDrop({
73
+ isBefore,
74
+ isAfter,
75
+ overItem,
76
+ movementDirection,
77
+ draggedItem
78
+ });
79
+ newNestedIndex = kinship.newNestedIndex;
80
+ newParentNode = kinship.newParentNode;
81
+ }
82
+
83
+ const newMovedItemNode = tree.parse(draggedItem.node.model);
84
+ getNodeById(treeRoot, draggedItem.id).drop();
85
+
86
+ if (newParentNode && typeof newNestedIndex === 'number') {
87
+ newParentNode.addChildAtIndex(newMovedItemNode, newNestedIndex);
48
88
 
49
- if (oldIndex === newIndex || !isValid) {
50
- // onOrderChange(newItems, data);
89
+ if (newParentNode.isRoot()) {
90
+ newItems = [...newParentNode.model.children];
91
+ } else {
92
+ newItems = [...treeRoot.model.children];
93
+ }
94
+ }
95
+
96
+ onOrderChange(newItems, data, draggedItem);
51
97
  setIsDragging(false);
52
98
  setDraggedItem(null);
53
99
  triggerTreeRerender();
54
- return;
55
- } // if we are moving from topToBottom the offset changes
56
-
57
-
58
- const movementDirection = newIndex > oldIndex ? 'topToBottom' : 'bottomToTop';
59
- let newNestedIndex;
60
- let newParentNode;
61
-
62
- if (isKeySorting) {
63
- const kinship = inferKeyboardKinshipDrop({
64
- items: visibleItems,
65
- newIndex,
66
- movementDirection
67
- });
68
- newNestedIndex = kinship.newNestedIndex;
69
- newParentNode = kinship.newParentNode;
70
- } else {
71
- const kinship = inferHoverItemKinshipDrop({
72
- isBefore,
73
- isAfter,
74
- overItem,
75
- movementDirection,
76
- draggedItem
77
- });
78
- newNestedIndex = kinship.newNestedIndex;
79
- newParentNode = kinship.newParentNode;
80
100
  }
81
-
82
- const newMovedItemNode = tree.parse(draggedItem.node.model);
83
- getNodeById(treeRoot, draggedItem.id).drop();
84
- newParentNode.addChildAtIndex(newMovedItemNode, newNestedIndex);
85
-
86
- if (newParentNode.isRoot()) {
87
- newItems = [...newParentNode.model.children];
88
- } else {
89
- newItems = [...treeRoot.model.children];
90
- }
91
-
92
- onOrderChange(newItems, data, draggedItem);
93
- setIsDragging(false);
94
- setDraggedItem(null);
95
- triggerTreeRerender();
96
- }, [data, draggedItem, relativeMouseCord, visibleItems, tree, treeRoot, onOrderChange, triggerTreeRerender, setIsDragging, setDraggedItem, setRelativeMouseCord]);
101
+ }, [data, draggedItem, relativeMouseCord, visibleItems, tree, treeRoot, onOrderChange, triggerTreeRerender, setIsDragging, setDraggedItem]);
97
102
  const onSortStart = useCallback(() => {}, // ({ node, index, collection, isKeySorting }, event) => {
98
103
  // console.log('node :>> ', node);
99
104
  // console.log('isKeySorting :>> ', isKeySorting);
@@ -106,10 +111,9 @@ const useDnDHelpers = () => {
106
111
  const updateBeforeSortStart = useCallback(beforeStartArgs => new Promise(resolve => {
107
112
  const {
108
113
  index,
109
- collection,
110
114
  isKeySorting
111
115
  } = beforeStartArgs;
112
- const item = (collection === null || collection === void 0 ? void 0 : collection[index]) || visibleItems[index];
116
+ const item = visibleItems[index];
113
117
  const {
114
118
  isExpanded
115
119
  } = item.node.model;
@@ -125,9 +129,9 @@ const useDnDHelpers = () => {
125
129
  setDraggedItem(item);
126
130
  focusItem(null);
127
131
  setFocusedItem(null);
128
- document.activeElement.blur();
129
- resolve();
130
- }), [visibleItems, isKeyboardDragging, setFocusedItem, setIsKeyboardDragging, setRelativeMouseCord]); // tracks mouse coords relative to an element to check if the drop happens
132
+ if (document.activeElement && typeof document.activeElement.blur === 'function') document.activeElement.blur();
133
+ resolve(true);
134
+ }), [visibleItems, setRelativeMouseCord, setIsKeyboardDragging, setIsDragging, setDraggedItem, setFocusedItem, triggerTreeRerender]); // tracks mouse coords relative to an element to check if the drop happens
131
135
  // at the top/center/bottom of an element to choose where to move the element
132
136
  // requested in the specs
133
137
 
@@ -146,58 +150,61 @@ const useDnDHelpers = () => {
146
150
  nodeItemRef
147
151
  } = node.model;
148
152
 
149
- if (isDragging && !isKeyboardDragging) {
150
- const rect = nodeItemRef.current.getBoundingClientRect();
151
- const x = event.clientX - rect.left; // x position within the element.
152
-
153
- const y = event.clientY - rect.top; // y position within the element.
154
- // by spec we need to track where the drop will happens
155
- // if drop happens on top 25% drop before
156
- // if drop happens on bottom of 25% drop after
157
- // if drop happens in the middle 50% either invalid or drop into children
158
-
159
- const {
160
- height: elementHeight
161
- } = rect;
162
- const dropBeforeMaxY = elementHeight * 0.25;
163
- const dropAfterMinY = elementHeight - elementHeight * 0.25;
164
- const isBefore = y < dropBeforeMaxY;
165
- const isAfter = y > dropAfterMinY;
166
- const isInside = !isBefore && !isAfter;
167
- const isValid = isDropValid({
168
- isBefore,
169
- isAfter,
170
- draggedItem,
171
- overItem: item,
172
- restrictDragAndDrop
173
- });
174
- setRelativeMouseCord({
175
- isBefore,
176
- isAfter,
177
- isInside,
178
- isValid,
179
- item,
180
- x,
181
- y,
182
- relativeElementDOMRect: rect,
183
- relativeElementIndex: itemIndex
184
- });
185
- setIsDraggingOverThis(true);
186
-
187
- if (!(openFolderOnHoverTimeout !== null && openFolderOnHoverTimeout !== void 0 && openFolderOnHoverTimeout.current) && // only set the interval if it wasn't set already once
188
- (draggedItem === null || draggedItem === void 0 ? void 0 : draggedItem.id) !== (item === null || item === void 0 ? void 0 : item.id) && ( // don't open ghost element
189
- item.isGroup || item.children.length > 0) && // only open groups
190
- !restrictDragAndDrop) {
191
- openFolderOnHoverTimeout.current = setTimeout(() => {
192
- item.node.model.isExpanded = true;
193
- openFolderOnHoverTimeout.current = null;
194
- triggerTreeRerender();
195
- }, 1000);
153
+ if (isDragging && !isKeyboardDragging && draggedItem) {
154
+ var _nodeItemRef$current;
155
+
156
+ const rect = nodeItemRef === null || nodeItemRef === void 0 ? void 0 : (_nodeItemRef$current = nodeItemRef.current) === null || _nodeItemRef$current === void 0 ? void 0 : _nodeItemRef$current.getBoundingClientRect();
157
+
158
+ if (rect) {
159
+ const x = event.clientX - rect.left; // x position within the element.
160
+
161
+ const y = event.clientY - rect.top; // y position within the element.
162
+ // by spec we need to track where the drop will happens
163
+ // if drop happens on top 25% drop before
164
+ // if drop happens on bottom of 25% drop after
165
+ // if drop happens in the middle 50% either invalid or drop into children
166
+
167
+ const {
168
+ height: elementHeight
169
+ } = rect;
170
+ const dropBeforeMaxY = elementHeight * 0.25;
171
+ const dropAfterMinY = elementHeight - elementHeight * 0.25;
172
+ const isBefore = y < dropBeforeMaxY;
173
+ const isAfter = y > dropAfterMinY;
174
+ const isValid = isDropValid({
175
+ isBefore,
176
+ isAfter,
177
+ draggedItem,
178
+ overItem: item,
179
+ restrictDragAndDrop
180
+ });
181
+ setRelativeMouseCord({
182
+ isBefore,
183
+ isAfter,
184
+ isValid,
185
+ item,
186
+ x,
187
+ y,
188
+ relativeElementDOMRect: rect,
189
+ relativeElementIndex: itemIndex
190
+ });
191
+ setIsDraggingOverThis(true);
192
+
193
+ if (!(openFolderOnHoverTimeout !== null && openFolderOnHoverTimeout !== void 0 && openFolderOnHoverTimeout.current) && // only set the interval if it wasn't set already once
194
+ (draggedItem === null || draggedItem === void 0 ? void 0 : draggedItem.id) !== (item === null || item === void 0 ? void 0 : item.id) && ( // don't open ghost element
195
+ item.isGroup || item.children.length > 0) && // only open groups
196
+ !restrictDragAndDrop) {
197
+ openFolderOnHoverTimeout.current = setTimeout(() => {
198
+ item.node.model.isExpanded = true;
199
+ openFolderOnHoverTimeout.current = null;
200
+ triggerTreeRerender();
201
+ }, 1000);
202
+ }
196
203
  }
197
204
  } else {
198
205
  setRelativeMouseCord(defaultRelativeMouseCoord);
199
206
  }
200
- }, [isDragging, setRelativeMouseCord, draggedItem, restrictDragAndDrop, isKeyboardDragging]);
207
+ }, [isDragging, isKeyboardDragging, draggedItem, restrictDragAndDrop, setRelativeMouseCord, triggerTreeRerender]);
201
208
  return {
202
209
  updateBeforeSortStart,
203
210
  onSortStart,
@@ -15,6 +15,7 @@ const useInstanceRefActions = (_ref, ctx) => {
15
15
  treeRoot,
16
16
  visibleItems,
17
17
  triggerTreeRerender,
18
+ updateUserExpandedState,
18
19
  setSelectedItem,
19
20
  setFocusedItem,
20
21
  setLatestToggledItem
@@ -36,11 +37,11 @@ const useInstanceRefActions = (_ref, ctx) => {
36
37
  actions.toggleExpandAll = useCallback(isExpand => {
37
38
  const p = new Promise(resolve => {
38
39
  promises.expandResolve = resolve;
39
- toggleExpandAllHelper(isExpand, treeRoot, triggerTreeRerender, setLatestToggledItem);
40
+ if (treeRoot) toggleExpandAllHelper(isExpand, treeRoot, triggerTreeRerender, setLatestToggledItem, updateUserExpandedState);
40
41
  });
41
42
  setPromise(p);
42
43
  return p;
43
- }, [promises, treeRoot, triggerTreeRerender, setLatestToggledItem]);
44
+ }, [promises, treeRoot, triggerTreeRerender, setLatestToggledItem, updateUserExpandedState]);
44
45
  actions.scrollTo = useCallback(function (indx) {
45
46
  let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
46
47
  align: 'start'
@@ -9,6 +9,7 @@ import { useMemo, useState, useEffect, useCallback } from 'react';
9
9
  import TreeModel from 'tree-model';
10
10
  import { cloneDeep } from 'lodash';
11
11
  import { enrichNodeModelInPlace, walkVisibles } from './tree-helpers.js';
12
+ import { updateExpandedState } from './group-expands-helpers.js';
12
13
 
13
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; }
14
15
 
@@ -18,15 +19,19 @@ const useTree = (data, props, states) => {
18
19
  setExpandedGroups
19
20
  } = states;
20
21
  const unfrozenData = useMemo(() => cloneDeep(data), [data]); // convert data into a TreeModel with extra isExpanded prop
22
+ // root element type is an exception, children model is based on what the dev passed on
23
+ // since root is an excepcion we must typecast
21
24
 
22
25
  const tree = useMemo(() => new TreeModel(), []);
23
26
  const [treeData, setTreeData] = useState({
27
+ id: '__ds_tree_root',
24
28
  name: '__root',
25
29
  isExpanded: true,
26
30
  children: unfrozenData
27
31
  });
28
32
  useEffect(() => {
29
33
  setTreeData({
34
+ id: '__ds_tree_root',
30
35
  name: '__root',
31
36
  isExpanded: true,
32
37
  children: unfrozenData
@@ -42,20 +47,32 @@ const useTree = (data, props, states) => {
42
47
  const [treeRoot, setTreeRoot] = useState(tree.parse(treeData));
43
48
  useEffect(() => {
44
49
  setTreeRoot(tree.parse(treeData));
45
- }, [treeData, rerenderItems]);
50
+ }, [treeData, rerenderItems, tree]);
46
51
  const [visibleItems, setVisibleItems] = useState([]);
47
52
  const {
48
53
  searchQuery,
49
54
  highlightOnlyQuery,
50
55
  onVisibleItemsChange,
51
- selection
56
+ selection,
57
+ expanded,
58
+ onExpandChange
52
59
  } = props;
60
+ const updateUserExpandedState = useCallback(() => {
61
+ updateExpandedState(treeRoot, onExpandChange);
62
+ }, [treeRoot, onExpandChange]); // we add missing properties to the received Items
63
+ // not the best of the patterns, but it works
64
+ // this is where we convert "SimpleItems" to "Items"
65
+ // this was done to avoid breaking changes back in v1
66
+
53
67
  useEffect(() => {
54
68
  const parsedVisibleItems = [];
55
69
  const newExpandedHashMap = {};
56
70
  treeRoot.walk(node => {
57
- enrichNodeModelInPlace(node, searchQuery, selection);
71
+ const shouldContinueWalking = true; // tree-model ask we return true if we want to continue walking
72
+
73
+ enrichNodeModelInPlace(node, searchQuery, selection, expanded);
58
74
  if (node.model.id && node.model.isGroup && node.model.isExpanded) newExpandedHashMap[node.model.id] = true;
75
+ return shouldContinueWalking;
59
76
  });
60
77
  walkVisibles(treeRoot, node => {
61
78
  parsedVisibleItems.push(_objectSpread(_objectSpread({}, node.model), {}, {
@@ -64,14 +81,16 @@ const useTree = (data, props, states) => {
64
81
  }, true, highlightOnlyQuery);
65
82
  setVisibleItems(parsedVisibleItems);
66
83
  onVisibleItemsChange(parsedVisibleItems);
67
- setExpandedGroups(newExpandedHashMap);
68
- }, [treeRoot, rerenderItems, searchQuery]);
84
+ setExpandedGroups(newExpandedHashMap); // eslint-disable-next-line react-hooks/exhaustive-deps
85
+ }, [treeRoot, rerenderItems, searchQuery, highlightOnlyQuery, selection, expanded, setExpandedGroups // onVisibleItemsChange // evaluate potential performance hit?
86
+ ]);
69
87
  return {
70
88
  visibleItems,
71
89
  tree,
72
90
  treeRoot,
73
91
  rerenderItems,
74
- triggerTreeRerender
92
+ triggerTreeRerender,
93
+ updateUserExpandedState
75
94
  };
76
95
  };
77
96
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elliemae/ds-treeview",
3
- "version": "2.0.2",
3
+ "version": "2.1.0-rc.4",
4
4
  "license": "MIT",
5
5
  "description": "ICE MT - Dimsum - Tree View",
6
6
  "module": "./esm/index.js",
@@ -67,6 +67,10 @@
67
67
  "import": "./esm/TreeView.js",
68
68
  "require": "./cjs/TreeView.js"
69
69
  },
70
+ "./sharedTypes": {
71
+ "import": "./esm/sharedTypes.js",
72
+ "require": "./cjs/sharedTypes.js"
73
+ },
70
74
  "./related-components/TreeViewSearchBar": {
71
75
  "import": "./esm/related-components/TreeViewSearchBar.js",
72
76
  "require": "./cjs/related-components/TreeViewSearchBar.js"
@@ -75,10 +79,6 @@
75
79
  "import": "./esm/react-desc-prop-types.js",
76
80
  "require": "./cjs/react-desc-prop-types.js"
77
81
  },
78
- "./prop-types": {
79
- "import": "./esm/prop-types.js",
80
- "require": "./cjs/prop-types.js"
81
- },
82
82
  "./plugins/virtualization/TreeVirtualizationPlugin": {
83
83
  "import": "./esm/plugins/virtualization/TreeVirtualizationPlugin.js",
84
84
  "require": "./cjs/plugins/virtualization/TreeVirtualizationPlugin.js"
@@ -175,117 +175,9 @@
175
175
  "import": "./esm/parts/CheckboxSelectable.js",
176
176
  "require": "./cjs/parts/CheckboxSelectable.js"
177
177
  },
178
- "./deprecated/TreeView": {
179
- "import": "./esm/deprecated/TreeView.js",
180
- "require": "./cjs/deprecated/TreeView.js"
181
- },
182
- "./deprecated/renderers": {
183
- "import": "./esm/deprecated/renderers.js",
184
- "require": "./cjs/deprecated/renderers.js"
185
- },
186
- "./deprecated/plugins/virtualization/TreeVirtualizationPlugin": {
187
- "import": "./esm/deprecated/plugins/virtualization/TreeVirtualizationPlugin.js",
188
- "require": "./cjs/deprecated/plugins/virtualization/TreeVirtualizationPlugin.js"
189
- },
190
- "./deprecated/plugins/virtualization": {
191
- "import": "./esm/deprecated/plugins/virtualization/index.js",
192
- "require": "./cjs/deprecated/plugins/virtualization/index.js"
193
- },
194
- "./deprecated/plugins/tree/walkTreeStrategy": {
195
- "import": "./esm/deprecated/plugins/tree/walkTreeStrategy.js",
196
- "require": "./cjs/deprecated/plugins/tree/walkTreeStrategy.js"
197
- },
198
- "./deprecated/plugins/tree/utils": {
199
- "import": "./esm/deprecated/plugins/tree/utils.js",
200
- "require": "./cjs/deprecated/plugins/tree/utils.js"
201
- },
202
- "./deprecated/plugins/tree/useExpandTreeState": {
203
- "import": "./esm/deprecated/plugins/tree/useExpandTreeState.js",
204
- "require": "./cjs/deprecated/plugins/tree/useExpandTreeState.js"
205
- },
206
- "./deprecated/plugins/tree/TreeDataPlugin": {
207
- "import": "./esm/deprecated/plugins/tree/TreeDataPlugin.js",
208
- "require": "./cjs/deprecated/plugins/tree/TreeDataPlugin.js"
209
- },
210
- "./deprecated/plugins/tree": {
211
- "import": "./esm/deprecated/plugins/tree/index.js",
212
- "require": "./cjs/deprecated/plugins/tree/index.js"
213
- },
214
- "./deprecated/plugins/toolbar/TreeToolbarPlugin": {
215
- "import": "./esm/deprecated/plugins/toolbar/TreeToolbarPlugin.js",
216
- "require": "./cjs/deprecated/plugins/toolbar/TreeToolbarPlugin.js"
217
- },
218
- "./deprecated/plugins/toolbar": {
219
- "import": "./esm/deprecated/plugins/toolbar/index.js",
220
- "require": "./cjs/deprecated/plugins/toolbar/index.js"
221
- },
222
- "./deprecated/plugins/selectable/utils": {
223
- "import": "./esm/deprecated/plugins/selectable/utils.js",
224
- "require": "./cjs/deprecated/plugins/selectable/utils.js"
225
- },
226
- "./deprecated/plugins/selectable/SelectablePluginTree": {
227
- "import": "./esm/deprecated/plugins/selectable/SelectablePluginTree.js",
228
- "require": "./cjs/deprecated/plugins/selectable/SelectablePluginTree.js"
229
- },
230
- "./deprecated/plugins/selectable": {
231
- "import": "./esm/deprecated/plugins/selectable/index.js",
232
- "require": "./cjs/deprecated/plugins/selectable/index.js"
233
- },
234
- "./deprecated/plugins/selectable/helper": {
235
- "import": "./esm/deprecated/plugins/selectable/helper.js",
236
- "require": "./cjs/deprecated/plugins/selectable/helper.js"
237
- },
238
- "./deprecated/plugins/searchable/utils": {
239
- "import": "./esm/deprecated/plugins/searchable/utils.js",
240
- "require": "./cjs/deprecated/plugins/searchable/utils.js"
241
- },
242
- "./deprecated/plugins/searchable/SearchableTreePlugin": {
243
- "import": "./esm/deprecated/plugins/searchable/SearchableTreePlugin.js",
244
- "require": "./cjs/deprecated/plugins/searchable/SearchableTreePlugin.js"
245
- },
246
- "./deprecated/plugins/searchable": {
247
- "import": "./esm/deprecated/plugins/searchable/index.js",
248
- "require": "./cjs/deprecated/plugins/searchable/index.js"
249
- },
250
- "./deprecated/plugins/roving/TreeRovingPlugin": {
251
- "import": "./esm/deprecated/plugins/roving/TreeRovingPlugin.js",
252
- "require": "./cjs/deprecated/plugins/roving/TreeRovingPlugin.js"
253
- },
254
- "./deprecated/plugins/roving": {
255
- "import": "./esm/deprecated/plugins/roving/index.js",
256
- "require": "./cjs/deprecated/plugins/roving/index.js"
257
- },
258
- "./deprecated/plugins": {
259
- "import": "./esm/deprecated/plugins/index.js",
260
- "require": "./cjs/deprecated/plugins/index.js"
261
- },
262
- "./deprecated/plugins/dnd/utils": {
263
- "import": "./esm/deprecated/plugins/dnd/utils.js",
264
- "require": "./cjs/deprecated/plugins/dnd/utils.js"
265
- },
266
- "./deprecated/plugins/dnd/TreeDndPlugin": {
267
- "import": "./esm/deprecated/plugins/dnd/TreeDndPlugin.js",
268
- "require": "./cjs/deprecated/plugins/dnd/TreeDndPlugin.js"
269
- },
270
- "./deprecated/plugins/dnd/renderers/DroppableList": {
271
- "import": "./esm/deprecated/plugins/dnd/renderers/DroppableList.js",
272
- "require": "./cjs/deprecated/plugins/dnd/renderers/DroppableList.js"
273
- },
274
- "./deprecated/plugins/dnd/renderers/DraggableItem": {
275
- "import": "./esm/deprecated/plugins/dnd/renderers/DraggableItem.js",
276
- "require": "./cjs/deprecated/plugins/dnd/renderers/DraggableItem.js"
277
- },
278
- "./deprecated/plugins/dnd": {
279
- "import": "./esm/deprecated/plugins/dnd/index.js",
280
- "require": "./cjs/deprecated/plugins/dnd/index.js"
281
- },
282
- "./deprecated": {
283
- "import": "./esm/deprecated/index.js",
284
- "require": "./cjs/deprecated/index.js"
285
- },
286
- "./deprecated/__testUtils__/utils": {
287
- "import": "./esm/deprecated/__testUtils__/utils.js",
288
- "require": "./cjs/deprecated/__testUtils__/utils.js"
178
+ "./config/useTreeview": {
179
+ "import": "./esm/config/useTreeview.js",
180
+ "require": "./cjs/config/useTreeview.js"
289
181
  },
290
182
  "./config/cssClassesConstants": {
291
183
  "import": "./esm/config/cssClassesConstants.js",
@@ -319,22 +211,19 @@
319
211
  "generateSubmodules": true
320
212
  },
321
213
  "dependencies": {
322
- "@elliemae/ds-button": "2.0.2",
323
- "@elliemae/ds-circular-progress-indicator": "2.0.2",
324
- "@elliemae/ds-classnames": "2.0.2",
325
- "@elliemae/ds-form": "2.0.2",
326
- "@elliemae/ds-icons": "2.0.2",
327
- "@elliemae/ds-shared": "2.0.2",
328
- "@elliemae/ds-truncated-tooltip-text": "2.0.2",
329
- "@elliemae/ds-utilities": "2.0.2",
214
+ "@elliemae/ds-button": "2.1.0-rc.4",
215
+ "@elliemae/ds-circular-progress-indicator": "2.1.0-rc.4",
216
+ "@elliemae/ds-classnames": "2.1.0-rc.4",
217
+ "@elliemae/ds-form": "2.1.0-rc.4",
218
+ "@elliemae/ds-icons": "2.1.0-rc.4",
219
+ "@elliemae/ds-props-helpers": "2.1.0-rc.4",
220
+ "@elliemae/ds-shared": "2.1.0-rc.4",
221
+ "@elliemae/ds-truncated-tooltip-text": "2.1.0-rc.4",
222
+ "@elliemae/ds-utilities": "2.1.0-rc.4",
330
223
  "@elliemae/react-sortable-hoc": "^1.0.0",
331
- "@john-osullivan/react-window-dynamic-fork": "1.9.0-alpha.1",
332
- "prop-types": "~15.7.2",
333
- "react-beautiful-dnd": "~13.0.0",
334
224
  "react-desc": "~4.1.3",
335
225
  "react-highlight-words": "~0.17.0",
336
226
  "react-virtual": "~2.3.2",
337
- "resize-observer-polyfill": "~1.5.1",
338
227
  "tree-model": "~1.0.7",
339
228
  "uuid": "~8.3.2"
340
229
  },