@elliemae/ds-treeview 2.0.1 → 2.1.0-rc.0

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 (167) 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 +7 -9
  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 +16 -13
  11. package/cjs/parts/TreeList.js +6 -4
  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/selectable-helper.js +2 -2
  22. package/cjs/utils/tree-helpers.js +42 -27
  23. package/cjs/utils/useDnDHelpers.js +107 -100
  24. package/cjs/utils/useInstanceRefActions.js +3 -2
  25. package/cjs/utils/useTree.js +27 -8
  26. package/esm/TreeView.js +6 -103
  27. package/esm/TreeViewContext.js +44 -47
  28. package/esm/config/useTreeview.js +129 -0
  29. package/esm/index.js +0 -8
  30. package/esm/parts/CheckboxSelectable.js +7 -9
  31. package/esm/parts/ExpandCaret.js +17 -11
  32. package/esm/parts/Icon.js +4 -0
  33. package/esm/parts/NestingSpace.js +15 -21
  34. package/esm/parts/RadioSelectable.js +7 -9
  35. package/esm/parts/TreeItem.js +16 -13
  36. package/esm/parts/TreeList.js +6 -4
  37. package/esm/plugins/dnd/TreeDndPlugin.js +1 -1
  38. package/esm/react-desc-prop-types.js +28 -27
  39. package/esm/related-components/TreeViewSearchBar.js +9 -1
  40. package/esm/{deprecated/plugins/selectable/helper.js → sharedTypes.js} +0 -0
  41. package/esm/utils/dnd-helpers.js +2 -4
  42. package/esm/utils/group-expands-helpers.js +34 -9
  43. package/esm/utils/keyboard-helpers.js +62 -58
  44. package/esm/utils/object-helpers.js +25 -7
  45. package/esm/utils/refs-helpers.js +2 -2
  46. package/esm/utils/selectable-helper.js +2 -2
  47. package/esm/utils/tree-helpers.js +42 -27
  48. package/esm/utils/useDnDHelpers.js +107 -100
  49. package/esm/utils/useInstanceRefActions.js +3 -2
  50. package/esm/utils/useTree.js +27 -8
  51. package/package.json +17 -128
  52. package/types/TreeView.d.ts +4 -148
  53. package/types/TreeViewContext.d.ts +4 -106
  54. package/types/config/useTreeview.d.ts +7 -0
  55. package/types/index.d.ts +0 -1
  56. package/types/parts/CheckboxSelectable.d.ts +5 -6
  57. package/types/parts/ChildrenCountDisplayer.d.ts +6 -6
  58. package/types/parts/ExpandCaret.d.ts +6 -6
  59. package/types/parts/Icon.d.ts +7 -5
  60. package/types/parts/NestingSpace.d.ts +3 -8
  61. package/types/parts/RadioSelectable.d.ts +5 -6
  62. package/types/parts/TreeItem.d.ts +22 -14
  63. package/types/parts/TreeItemText.d.ts +5 -5
  64. package/types/parts/TreeList.d.ts +22 -9
  65. package/types/react-desc-prop-types.d.ts +124 -43
  66. package/types/related-components/TreeViewSearchBar.d.ts +14 -11
  67. package/types/sharedTypes.d.ts +54 -0
  68. package/types/utils/array-helpers.d.ts +2 -2
  69. package/types/utils/dnd-helpers.d.ts +26 -25
  70. package/types/utils/group-expands-helpers.d.ts +13 -10
  71. package/types/utils/keyboard-helpers.d.ts +5 -3
  72. package/types/utils/object-helpers.d.ts +6 -2
  73. package/types/utils/refs-helpers.d.ts +4 -1
  74. package/types/utils/selectable-helper.d.ts +7 -3
  75. package/types/utils/string-helpers.d.ts +1 -1
  76. package/types/utils/tree-helpers.d.ts +25 -11
  77. package/types/utils/useDnDHelpers.d.ts +23 -3
  78. package/types/utils/useInstanceRefActions.d.ts +3 -3
  79. package/types/utils/useTree.d.ts +8 -7
  80. package/cjs/deprecated/TreeView.js +0 -72
  81. package/cjs/deprecated/__testUtils__/utils.js +0 -89
  82. package/cjs/deprecated/index.js +0 -27
  83. package/cjs/deprecated/plugins/dnd/TreeDndPlugin.js +0 -119
  84. package/cjs/deprecated/plugins/dnd/index.js +0 -9
  85. package/cjs/deprecated/plugins/dnd/renderers/DraggableItem.js +0 -67
  86. package/cjs/deprecated/plugins/dnd/renderers/DroppableList.js +0 -181
  87. package/cjs/deprecated/plugins/dnd/utils.js +0 -157
  88. package/cjs/deprecated/plugins/index.js +0 -21
  89. package/cjs/deprecated/plugins/roving/TreeRovingPlugin.js +0 -109
  90. package/cjs/deprecated/plugins/roving/index.js +0 -9
  91. package/cjs/deprecated/plugins/searchable/SearchableTreePlugin.js +0 -109
  92. package/cjs/deprecated/plugins/searchable/index.js +0 -9
  93. package/cjs/deprecated/plugins/searchable/utils.js +0 -7
  94. package/cjs/deprecated/plugins/selectable/SelectablePluginTree.js +0 -290
  95. package/cjs/deprecated/plugins/selectable/index.js +0 -9
  96. package/cjs/deprecated/plugins/selectable/utils.js +0 -19
  97. package/cjs/deprecated/plugins/toolbar/TreeToolbarPlugin.js +0 -128
  98. package/cjs/deprecated/plugins/toolbar/index.js +0 -9
  99. package/cjs/deprecated/plugins/tree/TreeDataPlugin.js +0 -281
  100. package/cjs/deprecated/plugins/tree/index.js +0 -9
  101. package/cjs/deprecated/plugins/tree/useExpandTreeState.js +0 -143
  102. package/cjs/deprecated/plugins/tree/utils.js +0 -43
  103. package/cjs/deprecated/plugins/tree/walkTreeStrategy.js +0 -60
  104. package/cjs/deprecated/plugins/virtualization/TreeVirtualizationPlugin.js +0 -209
  105. package/cjs/deprecated/plugins/virtualization/index.js +0 -9
  106. package/cjs/deprecated/renderers.js +0 -76
  107. package/cjs/prop-types.js +0 -61
  108. package/esm/deprecated/TreeView.js +0 -61
  109. package/esm/deprecated/__testUtils__/utils.js +0 -79
  110. package/esm/deprecated/index.js +0 -14
  111. package/esm/deprecated/plugins/dnd/TreeDndPlugin.js +0 -110
  112. package/esm/deprecated/plugins/dnd/index.js +0 -1
  113. package/esm/deprecated/plugins/dnd/renderers/DraggableItem.js +0 -59
  114. package/esm/deprecated/plugins/dnd/renderers/DroppableList.js +0 -172
  115. package/esm/deprecated/plugins/dnd/utils.js +0 -139
  116. package/esm/deprecated/plugins/index.js +0 -7
  117. package/esm/deprecated/plugins/roving/TreeRovingPlugin.js +0 -96
  118. package/esm/deprecated/plugins/roving/index.js +0 -1
  119. package/esm/deprecated/plugins/searchable/SearchableTreePlugin.js +0 -99
  120. package/esm/deprecated/plugins/searchable/index.js +0 -1
  121. package/esm/deprecated/plugins/searchable/utils.js +0 -3
  122. package/esm/deprecated/plugins/selectable/SelectablePluginTree.js +0 -280
  123. package/esm/deprecated/plugins/selectable/index.js +0 -1
  124. package/esm/deprecated/plugins/selectable/utils.js +0 -15
  125. package/esm/deprecated/plugins/toolbar/TreeToolbarPlugin.js +0 -114
  126. package/esm/deprecated/plugins/toolbar/index.js +0 -1
  127. package/esm/deprecated/plugins/tree/TreeDataPlugin.js +0 -269
  128. package/esm/deprecated/plugins/tree/index.js +0 -1
  129. package/esm/deprecated/plugins/tree/useExpandTreeState.js +0 -135
  130. package/esm/deprecated/plugins/tree/utils.js +0 -28
  131. package/esm/deprecated/plugins/tree/walkTreeStrategy.js +0 -56
  132. package/esm/deprecated/plugins/virtualization/TreeVirtualizationPlugin.js +0 -197
  133. package/esm/deprecated/plugins/virtualization/index.js +0 -1
  134. package/esm/deprecated/renderers.js +0 -59
  135. package/esm/prop-types.js +0 -46
  136. package/types/deprecated/TreeView.d.ts +0 -8
  137. package/types/deprecated/__testUtils__/utils.d.ts +0 -72
  138. package/types/deprecated/index.d.ts +0 -2
  139. package/types/deprecated/plugins/dnd/TreeDndPlugin.d.ts +0 -1
  140. package/types/deprecated/plugins/dnd/index.d.ts +0 -1
  141. package/types/deprecated/plugins/dnd/renderers/DraggableItem.d.ts +0 -3
  142. package/types/deprecated/plugins/dnd/renderers/DroppableList.d.ts +0 -6
  143. package/types/deprecated/plugins/dnd/tests/TreeDndPlugin.test.d.ts +0 -0
  144. package/types/deprecated/plugins/dnd/utils.d.ts +0 -28
  145. package/types/deprecated/plugins/index.d.ts +0 -7
  146. package/types/deprecated/plugins/roving/TreeRovingPlugin.d.ts +0 -1
  147. package/types/deprecated/plugins/roving/index.d.ts +0 -1
  148. package/types/deprecated/plugins/searchable/SearchableTreePlugin.d.ts +0 -1
  149. package/types/deprecated/plugins/searchable/index.d.ts +0 -1
  150. package/types/deprecated/plugins/searchable/utils.d.ts +0 -1
  151. package/types/deprecated/plugins/selectable/SelectablePluginTree.d.ts +0 -1
  152. package/types/deprecated/plugins/selectable/helper.d.ts +0 -0
  153. package/types/deprecated/plugins/selectable/index.d.ts +0 -1
  154. package/types/deprecated/plugins/selectable/tests/SelectablePluginTree.test.d.ts +0 -1
  155. package/types/deprecated/plugins/selectable/utils.d.ts +0 -1
  156. package/types/deprecated/plugins/toolbar/TreeToolbarPlugin.d.ts +0 -1
  157. package/types/deprecated/plugins/toolbar/index.d.ts +0 -1
  158. package/types/deprecated/plugins/tree/TreeDataPlugin.d.ts +0 -1
  159. package/types/deprecated/plugins/tree/index.d.ts +0 -1
  160. package/types/deprecated/plugins/tree/tests/TreeDataPlugin.test.d.ts +0 -1
  161. package/types/deprecated/plugins/tree/useExpandTreeState.d.ts +0 -14
  162. package/types/deprecated/plugins/tree/utils.d.ts +0 -8
  163. package/types/deprecated/plugins/tree/walkTreeStrategy.d.ts +0 -9
  164. package/types/deprecated/plugins/virtualization/TreeVirtualizationPlugin.d.ts +0 -1
  165. package/types/deprecated/plugins/virtualization/index.d.ts +0 -1
  166. package/types/deprecated/renderers.d.ts +0 -19
  167. package/types/prop-types.d.ts +0 -26
@@ -1,15 +1,15 @@
1
1
  import { createRef, createContext } from 'react';
2
2
 
3
3
  /* eslint-disable no-unused-vars */
4
- // import FilePdf from '@elliemae/ds-icons/FilePdf';
4
+
5
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
6
+ function noop() {}
5
7
 
6
8
  const defaultProps = {
7
9
  plugins: [],
8
10
  selection: {},
9
- // { [id]:[state] } -> e.g. {1:true, 2:'mixed'}
10
11
  instanceRef: /*#__PURE__*/createRef(),
11
- disableGroups: false,
12
- disableLeafs: false,
12
+ isItemDisabled: () => false,
13
13
  disableIcons: false,
14
14
  fluid: false,
15
15
  isMultiSelect: false,
@@ -19,30 +19,27 @@ const defaultProps = {
19
19
  sortable: false,
20
20
  isLoading: false,
21
21
  highlightOnlyQuery: false,
22
- onInstanceRefInitialized: istanceRef => {},
23
- onItemClick: (item, e) => {},
24
- onItemFocus: params => {},
25
- // { itemIndex: number, scrollToItem: func }
26
- onVisibleItemsChange: newVisibleItems => {},
27
- onOrderChange: (newData, oldData, draggedItem) => {},
28
- onSelectionChange: (selectionHasmap, item, indexAndScrollTo) => {},
29
- // indexAndScrollTo = { scrollToItem: ()=>{}, itemIndex :number }
30
- onExpandChange: (expandedHashmap, itemToggled) => {},
31
- // expandedHashmap -> {[id]:true, ...[id]:true} itemToggled -> item that caused the change for being toggled
22
+ onItemClick: noop,
23
+ onItemFocus: noop,
24
+ onVisibleItemsChange: noop,
25
+ onOrderChange: noop,
26
+ onSelectionChange: noop,
27
+ onExpandChange: noop,
28
+ onInstanceRefInitialized: noop,
32
29
  rowSize: 'normal',
33
- // ['normal', 'compact']
34
30
  labelOverflow: 'wrap',
35
- // ['wrap', 'wrap-all', 'truncate']
36
31
  noItemsPlaceholder: 'No items found',
37
32
  nameKey: 'name',
38
- // use to retrieve the label text inside ever data item
39
33
  width: '100%',
40
34
  height: '100%',
41
35
  groupIcon: null,
42
- // <Folder />,
43
36
  itemIcon: null,
44
- // <FilePdf />,
45
- searchQuery: ''
37
+ searchQuery: '' // workaround on the typings over the fact that
38
+ // when we instantiate the context we can't have all the props
39
+ // we only have a part of them but the final typings will include missing props
40
+ // this is safe to do because
41
+ // we will "mergeWithDefaults" + "validatePropTypes" when we do instantiate the context
42
+
46
43
  };
47
44
  const defaultRelativeMouseCoord = {
48
45
  isBefore: false,
@@ -54,48 +51,48 @@ const defaultRelativeMouseCoord = {
54
51
  relativeElementDOMRect: null,
55
52
  relativeElementIndex: null
56
53
  };
57
- /** Context for cross component communication */
58
-
59
- const TreeViewContext = /*#__PURE__*/createContext({
54
+ const defaultContext = {
60
55
  props: defaultProps,
61
56
  visibleItems: [],
62
57
  withRadioChecks: false,
63
58
  withCheckboxChecks: false,
64
59
  withDragAndDrop: false,
65
60
  relativeMouseCord: defaultRelativeMouseCoord,
66
- setRelativeMouseCord: () => {},
67
- labelRenderer: value => value,
68
- triggerTreeRerender: () => {},
69
- tree: {},
70
- virtualListHelpers: {},
71
- virtualListRef: {},
72
- treeRoot: {},
61
+ setRelativeMouseCord: noop,
62
+ triggerTreeRerender: noop,
63
+ tree: undefined,
64
+ treeRoot: undefined,
65
+ virtualListHelpers: {
66
+ virtualItems: [],
67
+ totalSize: 0,
68
+ scrollToOffset: noop,
69
+ scrollToIndex: noop
70
+ },
71
+ virtualListRef: undefined,
73
72
  isDragging: false,
74
- setIsDragging: () => {},
73
+ setIsDragging: noop,
75
74
  isKeyboardDragging: false,
76
- setIsKeyboardDragging: () => {},
75
+ setIsKeyboardDragging: noop,
77
76
  draggedItem: null,
78
- // item
79
- setDraggedItem: () => {},
77
+ setDraggedItem: noop,
80
78
  uniqueTreeViewUUID: '',
81
79
  selectedItem: null,
82
- // item
83
- setSelectedItem: () => {},
80
+ setSelectedItem: noop,
84
81
  focusedItem: null,
85
- // item
86
- setFocusedItem: () => {},
82
+ setFocusedItem: noop,
87
83
  selectedCheckboxes: {},
88
- // { [id]:[state] } -> e.g. {1:true, 2:'mixed'}
89
- setSelectedCheckboxes: () => {},
84
+ setSelectedCheckboxes: noop,
90
85
  expandedGroups: {},
91
- // { [id]:true } -> e.g. {1:true, 2:true} // false are not listed
92
- setExpandedGroups: () => {},
86
+ setExpandedGroups: noop,
93
87
  latestToggledItem: null,
94
- // item -> if toggle all -> should be undefined
95
- setLatestToggledItem: () => {},
88
+ setLatestToggledItem: noop,
96
89
  hoverItem: null,
97
- // item
98
- setHoverItem: () => {}
99
- });
90
+ setHoverItem: noop,
91
+ handleExpandGroup: noop,
92
+ updateUserExpandedState: noop
93
+ };
94
+ /** Context for cross component communication */
95
+
96
+ const TreeViewContext = /*#__PURE__*/createContext(defaultContext);
100
97
 
101
98
  export { TreeViewContext as default, defaultProps, defaultRelativeMouseCoord };
@@ -0,0 +1,129 @@
1
+ import 'core-js/modules/esnext.async-iterator.filter.js';
2
+ import 'core-js/modules/esnext.iterator.constructor.js';
3
+ import 'core-js/modules/esnext.iterator.filter.js';
4
+ import 'core-js/modules/esnext.async-iterator.for-each.js';
5
+ import 'core-js/modules/esnext.iterator.for-each.js';
6
+ import _defineProperty from '@babel/runtime/helpers/esm/defineProperty';
7
+ import 'core-js/modules/web.dom-collections.iterator.js';
8
+ import { useRef, useState, useCallback, useMemo, useEffect } from 'react';
9
+ import { useVirtual } from 'react-virtual';
10
+ import { useMemoMergePropsWithDefault, useValidateTypescriptPropTypes } from '@elliemae/ds-props-helpers';
11
+ import { v4 } from 'uuid';
12
+ import { TreeViewPropTypes } from '../react-desc-prop-types.js';
13
+ import { defaultProps, defaultRelativeMouseCoord } from '../TreeViewContext.js';
14
+ import { TreeDndPlugin } from '../plugins/dnd/TreeDndPlugin.js';
15
+ import { useTree } from '../utils/useTree.js';
16
+ import { toggleItemExpand, useNotifyExpandedChange } from '../utils/group-expands-helpers.js';
17
+ import { useInstanceRefActions } from '../utils/useInstanceRefActions.js';
18
+ import { useGlobalToggleAllExpandShortcut } from '../utils/keyboard-helpers.js';
19
+
20
+ 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; }
21
+
22
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
23
+ const useTreeview = props => {
24
+ const propsWithDefault = useMemoMergePropsWithDefault(props, defaultProps);
25
+ useValidateTypescriptPropTypes(propsWithDefault, TreeViewPropTypes);
26
+ const defaultActions = {
27
+ actions: {
28
+ toggleExpandAll: () => {},
29
+ scrollTo: () => {},
30
+ setSelectedItemByVirtualIndex: () => {},
31
+ setFocusedItemByVirtualIndex: () => {}
32
+ }
33
+ };
34
+ const treeRef = useRef(defaultActions);
35
+ const {
36
+ data,
37
+ plugins,
38
+ onOrderChange,
39
+ isMultiSelect,
40
+ isSingleSelect,
41
+ instanceRef,
42
+ selection,
43
+ onInstanceRefInitialized
44
+ } = propsWithDefault;
45
+ const [isDragging, setIsDragging] = useState(false);
46
+ const [isKeyboardDragging, setIsKeyboardDragging] = useState(false);
47
+ const [relativeMouseCord, setRelativeMouseCord] = useState(defaultRelativeMouseCoord);
48
+ const [uniqueTreeViewUUID] = useState(v4());
49
+ const [draggedItem, setDraggedItem] = useState(null);
50
+ const [hoverItem, setHoverItem] = useState(null);
51
+ const [latestToggledItem, setLatestToggledItem] = useState(null);
52
+ const [selectedItem, setSelectedItem] = useState(null);
53
+ const [focusedItem, setFocusedItem] = useState(null);
54
+ const [selectedCheckboxes, setSelectedCheckboxes] = useState(_objectSpread({}, selection));
55
+ const [expandedGroups, setExpandedGroups] = useState({});
56
+ const {
57
+ visibleItems,
58
+ tree,
59
+ treeRoot,
60
+ triggerTreeRerender,
61
+ updateUserExpandedState
62
+ } = useTree(data, propsWithDefault, {
63
+ setExpandedGroups
64
+ });
65
+ const virtualListRef = useRef(); // estimateSize should not be really required given what was stated on
66
+ // https://github.com/tannerlinsley/react-virtual/issues/23
67
+
68
+ const virtualListHelpers = useVirtual({
69
+ size: visibleItems.length,
70
+ parentRef: virtualListRef,
71
+ overscan: 15
72
+ });
73
+ const withDragAndDrop = !!(plugins !== null && plugins !== void 0 && plugins.includes(TreeDndPlugin) && onOrderChange);
74
+ const withRadioChecks = isSingleSelect && !isMultiSelect;
75
+ const withCheckboxChecks = !isSingleSelect && isMultiSelect;
76
+ const handleExpandGroup = useCallback(toggleItemExpand, []);
77
+ const ctx = useMemo(() => ({
78
+ props: propsWithDefault,
79
+ setRelativeMouseCord,
80
+ relativeMouseCord,
81
+ virtualListHelpers,
82
+ virtualListRef,
83
+ tree,
84
+ treeRoot,
85
+ visibleItems,
86
+ triggerTreeRerender,
87
+ isDragging,
88
+ setIsDragging,
89
+ isKeyboardDragging,
90
+ setIsKeyboardDragging,
91
+ draggedItem,
92
+ setDraggedItem,
93
+ withRadioChecks,
94
+ withCheckboxChecks,
95
+ withDragAndDrop,
96
+ uniqueTreeViewUUID,
97
+ selectedCheckboxes,
98
+ setSelectedCheckboxes,
99
+ selectedItem,
100
+ setSelectedItem,
101
+ expandedGroups,
102
+ setExpandedGroups,
103
+ latestToggledItem,
104
+ setLatestToggledItem,
105
+ focusedItem,
106
+ setFocusedItem,
107
+ hoverItem,
108
+ setHoverItem,
109
+ handleExpandGroup,
110
+ updateUserExpandedState
111
+ }), [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
112
+ // as such we manually pass the second parameter as fit
113
+
114
+ if (instanceRef) instanceRef.current = treeRef.current;
115
+ useInstanceRefActions(treeRef.current, ctx);
116
+ useGlobalToggleAllExpandShortcut(treeRoot, triggerTreeRerender, setLatestToggledItem, updateUserExpandedState);
117
+ useNotifyExpandedChange(propsWithDefault, ctx); // this is an horrible hack.
118
+ // this is required because there is no "on rendered" react-way to check if every children has finished rendering
119
+ // this should be working for now, in the future we may want to review this for a better solution
120
+
121
+ useEffect(() => {
122
+ setTimeout(() => onInstanceRefInitialized(treeRef), 100); // eslint-disable-next-line react-hooks/exhaustive-deps
123
+ }, []);
124
+ return useMemo(() => ({
125
+ ctx
126
+ }), [ctx]);
127
+ };
128
+
129
+ export { useTreeview };
package/esm/index.js CHANGED
@@ -7,11 +7,3 @@ export { TreePluginList } from './plugins/tree/TreeDataPlugin.js';
7
7
  export { TreeVirtualizationPlugin } from './plugins/virtualization/TreeVirtualizationPlugin.js';
8
8
  export { SearchableTreePlugin } from './plugins/searchable/SearchableTreePlugin.js';
9
9
  export { TreeViewSearchBar } from './related-components/TreeViewSearchBar.js';
10
- import * as index from './deprecated/index.js';
11
- export { index as DEPRECATED };
12
-
13
- /* eslint-disable global-require */
14
- // Polyfill ResizeObserver for demo
15
- if (typeof ResizeObserver === 'undefined') {
16
- global.ResizeObserver = require('resize-observer-polyfill').default;
17
- }
@@ -12,9 +12,9 @@ import TreeViewContext from '../TreeViewContext.js';
12
12
  import { toggleCheckboxItem } from '../utils/selectable-helper.js';
13
13
  import { filterObject } from '../utils/object-helpers.js';
14
14
 
15
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
15
+ 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; }
16
16
 
17
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
17
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
18
18
  const StyledCheckboxWrapper = /*#__PURE__*/styled.span.withConfig({
19
19
  componentId: "sc-1tyhs3t-0"
20
20
  })(["padding-top:3px;"]);
@@ -30,11 +30,8 @@ function CheckboxSelectable(props) {
30
30
  const ctx = useContext(TreeViewContext);
31
31
  const {
32
32
  props: {
33
- disableGroups,
34
- // radio allows disabling this, checkbox doesnt? check specs
35
- disableLeafs,
36
- // radio allows disabling this, checkbox doesnt? check specs
37
- onSelectionChange
33
+ onSelectionChange,
34
+ isItemDisabled
38
35
  },
39
36
  virtualListHelpers: {
40
37
  scrollToIndex
@@ -50,7 +47,7 @@ function CheckboxSelectable(props) {
50
47
  triggerTreeRerender();
51
48
  const indexAndScrollTo = {
52
49
  scrollToItem: () => {
53
- scrollToIndex(item.virtualIndex);
50
+ if (typeof item.virtualIndex === 'number') scrollToIndex(item.virtualIndex);
54
51
  },
55
52
  itemIndex
56
53
  };
@@ -67,9 +64,10 @@ function CheckboxSelectable(props) {
67
64
 
68
65
  return false;
69
66
  }, [selectedCheckboxes, id]);
67
+ const isDisabled = useMemo(() => isItemDisabled(item), [item, isItemDisabled]);
70
68
  return /*#__PURE__*/_jsx(StyledCheckboxWrapper, {}, void 0, /*#__PURE__*/_jsx(DSCheckbox, {
71
69
  checked: isChecked,
72
- disabled: item.isGroup ? disableGroups : disableLeafs,
70
+ disabled: isDisabled,
73
71
  className: "em-ds-tree-item-checkbox",
74
72
  "data-testid": "tree-item-checkbox",
75
73
  onChange: onCheckboxChange,
@@ -26,6 +26,7 @@ const ExpandCaret = props => {
26
26
  },
27
27
  handleExpandGroup = defaultHandleExpandGroup,
28
28
  triggerTreeRerender,
29
+ updateUserExpandedState,
29
30
  setLatestToggledItem,
30
31
  setFocusedItem,
31
32
  virtualListHelpers: {
@@ -51,18 +52,23 @@ const ExpandCaret = props => {
51
52
  },
52
53
  onClick: e => {
53
54
  e.stopPropagation();
54
- handleExpandGroup(item, triggerTreeRerender, scrollToIndex, e);
55
+ if (e) handleExpandGroup(item, triggerTreeRerender, updateUserExpandedState, scrollToIndex, e);
55
56
  setLatestToggledItem(item);
56
- onItemFocus({
57
- itemIndex: item.virtualIndex,
58
- scrollToItem: function () {
59
- let opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
60
- align: 'start'
61
- };
62
- return scrollToIndex(item.virtualIndex, opts);
63
- },
64
- item
65
- });
57
+ const itemVitualIndex = item.virtualIndex;
58
+
59
+ if (typeof itemVitualIndex === 'number') {
60
+ onItemFocus({
61
+ itemIndex: itemVitualIndex,
62
+ scrollToItem: function () {
63
+ let opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
64
+ align: 'start'
65
+ };
66
+ return scrollToIndex(itemVitualIndex, opts);
67
+ },
68
+ item
69
+ });
70
+ }
71
+
66
72
  setFocusedItem(item);
67
73
  focusItem(item);
68
74
  },
package/esm/parts/Icon.js CHANGED
@@ -18,6 +18,10 @@ const Icon = props => {
18
18
  if (!icon) return null;
19
19
  return /*#__PURE__*/React.cloneElement(icon, {
20
20
  'data-testid': isGroupOrHasChildrens ? 'tree-item-group-icon' : 'tree-item-icon',
21
+ // legacy class-name way of handling things,
22
+ // this will eventually be deprecated in favor of styled components
23
+ // untill then, just eslint-ignore and move on
24
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment
21
25
  className: cx(icon.props.className, 'tree-item-icon')
22
26
  });
23
27
  };
@@ -1,21 +1,10 @@
1
- import 'core-js/modules/esnext.async-iterator.filter.js';
2
- import 'core-js/modules/esnext.iterator.constructor.js';
3
- import 'core-js/modules/esnext.iterator.filter.js';
4
- import 'core-js/modules/esnext.async-iterator.for-each.js';
5
- import 'core-js/modules/esnext.iterator.for-each.js';
6
1
  import _jsx from '@babel/runtime/helpers/esm/jsx';
7
- import _defineProperty from '@babel/runtime/helpers/esm/defineProperty';
8
2
  import 'react';
9
3
 
10
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
11
-
12
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
13
-
14
4
  const getItemNestingLeftPadding = (level, opts) => {
15
5
  const {
16
6
  spaceForNestingLevel = 1.5
17
- } = _objectSpread({}, opts);
18
-
7
+ } = opts;
19
8
  const groupLeftPadding = spaceForNestingLevel * (level - 1);
20
9
  const finalLeftPadding = groupLeftPadding + spaceForNestingLevel - 0.1; // root level left-padding would be negative and would not be applied
21
10
  // if "root-level" nesting, then defaults to 0 left-padding.
@@ -31,15 +20,20 @@ const NestingSpace = props => {
31
20
  const {
32
21
  treeDepth
33
22
  } = item;
34
- const itemNestingLeftPadding = getItemNestingLeftPadding(treeDepth - 1, {
35
- spaceForNestingLevel
36
- });
37
- return /*#__PURE__*/_jsx("div", {
38
- "data-testid": "tree-item-nested-space",
39
- style: {
40
- width: itemNestingLeftPadding
41
- }
42
- });
23
+
24
+ if (treeDepth) {
25
+ const itemNestingLeftPadding = getItemNestingLeftPadding(treeDepth - 1, {
26
+ spaceForNestingLevel
27
+ });
28
+ return /*#__PURE__*/_jsx("div", {
29
+ "data-testid": "tree-item-nested-space",
30
+ style: {
31
+ width: itemNestingLeftPadding
32
+ }
33
+ });
34
+ }
35
+
36
+ return null;
43
37
  };
44
38
 
45
39
  export { NestingSpace };
@@ -11,11 +11,8 @@ function RadioSelectable(props) {
11
11
  const ctx = useContext(TreeViewContext);
12
12
  const {
13
13
  props: {
14
- disableGroups,
15
- // radio allows disabling this, checkbox doesnt? check specs
16
- disableLeafs,
17
- // radio allows disabling this, checkbox doesnt? check specs
18
- onSelectionChange
14
+ onSelectionChange,
15
+ isItemDisabled
19
16
  },
20
17
  virtualListHelpers: {
21
18
  scrollToIndex
@@ -34,21 +31,22 @@ function RadioSelectable(props) {
34
31
  setSelectedCheckboxes(newSelectionHasmap);
35
32
  const indexAndScrollTo = {
36
33
  scrollToItem: () => {
37
- scrollToIndex(item.virtualIndex);
34
+ if (item.virtualIndex) scrollToIndex(item.virtualIndex);
38
35
  },
39
36
  itemIndex
40
37
  };
41
38
  if (onSelectionChange) onSelectionChange(newSelectionHasmap, item, indexAndScrollTo);
42
- }, [item, id, onSelectionChange, scrollToIndex]);
39
+ }, [id, setSelectedCheckboxes, itemIndex, onSelectionChange, item, scrollToIndex]);
43
40
  const radioName = useMemo(() => "radios-".concat(uniqueTreeViewUUID), [uniqueTreeViewUUID]);
41
+ const isDisabled = useMemo(() => isItemDisabled(item), [item, isItemDisabled]);
44
42
  return /*#__PURE__*/_jsx(DSRadio, {
45
43
  checked: selectedCheckboxes[id] === true,
46
44
  name: radioName,
47
- disabled: item.isGroup ? disableGroups : disableLeafs,
45
+ disabled: isDisabled,
48
46
  className: "em-ds-tree-item-radio",
49
47
  "data-testid": "tree-item-radio",
50
48
  onChange: onRadioChange,
51
- tabIndex: "0"
49
+ tabIndex: 0
52
50
  });
53
51
  }
54
52
 
@@ -22,14 +22,16 @@ import { TreeItemText } from './TreeItemText.js';
22
22
  import { treeItemBlockName, DSTreeViewPrefix } from '../config/cssClassesConstants.js';
23
23
  import { jsxs } from 'react/jsx-runtime';
24
24
 
25
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
25
+ 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; }
26
26
 
27
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
27
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
28
28
  const TreeListItem = aggregatedClasses('li', {
29
29
  'data-testid': treeItemBlockName,
30
- role: 'treeitem'
30
+ role: 'treeitem' // temp fix untill we move to styled components
31
+
31
32
  })(treeItemBlockName);
32
- const TreeListItemAddonsWrapper = aggregatedClasses('div')(treeItemBlockName, 'addons');
33
+ const TreeListItemAddonsWrapper = aggregatedClasses('div')(treeItemBlockName, 'addons' // temp fix untill we move to styled components
34
+ );
33
35
  const DnDHandle = SortableHandle(_ref => {
34
36
  let {
35
37
  id
@@ -63,7 +65,7 @@ const TreeItem = props => {
63
65
  const {
64
66
  nodeItemRef
65
67
  } = node.model;
66
- const openFolderOnHoverTimeout = useRef();
68
+ const openFolderOnHoverTimeout = useRef(null);
67
69
  const [isDraggingOverThis, setIsDraggingOverThis] = useState(false);
68
70
  const onItemKeyDown = useOnItemKeyDown(item);
69
71
  const ctx = useContext(TreeViewContext);
@@ -109,8 +111,8 @@ const TreeItem = props => {
109
111
  if (isBefore) className += '-drop-before';else if (isAfter) className += '-drop-after';else className += '-drop-in';
110
112
  return className;
111
113
  }, [withDragAndDrop, relativeMouseCord, isDraggingOverThis]);
112
- const selectedClassName = useMemo(() => (selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.id) === item.id ? 'selected' : '', [selectedItem]);
113
- const hoverClassName = useMemo(() => (hoverItem === null || hoverItem === void 0 ? void 0 : hoverItem.id) !== item.id || withDragAndDrop && isDragging ? '' : 'hover', [hoverItem, withDragAndDrop, isDragging]);
114
+ const selectedClassName = useMemo(() => (selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.id) === item.id ? 'selected' : '', [item.id, selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.id]);
115
+ const hoverClassName = 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]);
114
116
  const fixedHeightClassname = useMemo(() => {
115
117
  if (labelOverflow === 'truncate') {
116
118
  if (rowSize === 'compact') return "".concat(DSTreeViewPrefix, "-").concat(treeItemBlockName, "--fixed-height-compact");
@@ -124,21 +126,22 @@ const TreeItem = props => {
124
126
  onItemClick(item, e);
125
127
  setFocusedItem(item);
126
128
  setSelectedItem(item);
129
+ const itemVirtualIndex = typeof item.virtualIndex === 'number' ? item.virtualIndex : -1;
127
130
  onItemFocus({
128
- itemIndex: item.virtualIndex,
131
+ itemIndex: itemVirtualIndex,
129
132
  scrollToItem: function () {
130
133
  let opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
131
134
  align: 'start'
132
135
  };
133
- return scrollToIndex(item.virtualIndex, opts);
136
+ return scrollToIndex(itemVirtualIndex, opts);
134
137
  },
135
138
  item
136
139
  });
137
140
  }, [item, scrollToIndex, onItemClick, onItemFocus, setSelectedItem, setFocusedItem]);
138
141
  return /*#__PURE__*/jsxs(TreeListItem, {
139
- tabIndex: "0",
142
+ tabIndex: 0,
140
143
  onMouseMove: event => {
141
- if (withDragAndDrop) {
144
+ if (withDragAndDrop && onMouseDragOverItem) {
142
145
  onMouseDragOverItem({
143
146
  event,
144
147
  item,
@@ -165,8 +168,8 @@ const TreeItem = props => {
165
168
  ref: setItemRefs,
166
169
  style: _objectSpread({}, itemWrapperStyle),
167
170
  className: finalClassName,
168
- "aria-expanded": item.isExpanded,
169
- "aria-selected": selectedCheckboxes[item.id],
171
+ "aria-expanded": !!item.isExpanded,
172
+ "aria-selected": !!selectedCheckboxes[item.id],
170
173
  "data-id": item.id,
171
174
  "data-index": item.virtualIndex,
172
175
  onKeyDown: onItemKeyDown,
@@ -12,17 +12,19 @@ import { SortableContainer } from '@elliemae/react-sortable-hoc';
12
12
  import { aggregatedClasses } from '@elliemae/ds-classnames';
13
13
  import { DSCircularProgressIndicator } from '@elliemae/ds-circular-progress-indicator';
14
14
  import TreeViewContext from '../TreeViewContext.js';
15
- import { DragAndDropTreeItem, TreeItem } from './TreeItem.js';
16
15
  import { treeListBlockName, DSTreeViewPrefix } from '../config/cssClassesConstants.js';
16
+ import { DragAndDropTreeItem, TreeItem } from './TreeItem.js';
17
17
  import { jsxs, jsx } from 'react/jsx-runtime';
18
18
 
19
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
19
+ 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; }
20
20
 
21
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
21
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
22
22
  const treeListNoItemsBn = "".concat(treeListBlockName, "-no-items");
23
23
  const TreeListNoItems = aggregatedClasses('div', {
24
24
  'data-testid': treeListNoItemsBn
25
- })(treeListNoItemsBn);
25
+ })(treeListNoItemsBn); // React.ComponentProps<'ul'> uses LegacyRef typings that existed pre-hook era
26
+ // we omit the LegacyRef typings in favor of hook-era typings
27
+
26
28
  const TreeListWrapper = aggregatedClasses('ul', {
27
29
  'data-testid': treeListBlockName,
28
30
  role: 'tree'
@@ -26,7 +26,7 @@ const TreeDnD = () => {
26
26
  onSortStart: onSortStart,
27
27
  onMouseDragOverItem: onMouseDragOverItem,
28
28
  onSortEnd: onSortEnd,
29
- getContainer: () => virtualListRef.current,
29
+ getContainer: () => virtualListRef === null || virtualListRef === void 0 ? void 0 : virtualListRef.current,
30
30
  keyCodes: keyCodes
31
31
  });
32
32
  };