@mui/x-tree-view 7.1.1 → 7.2.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 (77) hide show
  1. package/CHANGELOG.md +86 -0
  2. package/RichTreeView/RichTreeView.types.d.ts +3 -3
  3. package/TreeItem/TreeItem.js +1 -1
  4. package/TreeItem2/TreeItem2.d.ts +5 -1
  5. package/TreeItem2/TreeItem2.js +0 -1
  6. package/index.js +1 -1
  7. package/internals/TreeViewProvider/TreeViewChildrenItemProvider.d.ts +16 -0
  8. package/internals/TreeViewProvider/TreeViewChildrenItemProvider.js +57 -0
  9. package/internals/TreeViewProvider/TreeViewContext.d.ts +2 -0
  10. package/internals/TreeViewProvider/TreeViewProvider.js +2 -3
  11. package/internals/TreeViewProvider/TreeViewProvider.types.d.ts +3 -1
  12. package/internals/corePlugins/useTreeViewInstanceEvents/useTreeViewInstanceEvents.js +7 -8
  13. package/internals/models/plugin.d.ts +13 -5
  14. package/internals/models/treeView.d.ts +1 -2
  15. package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +15 -15
  16. package/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +25 -26
  17. package/internals/plugins/useTreeViewId/useTreeViewId.js +5 -7
  18. package/internals/plugins/useTreeViewId/useTreeViewId.types.d.ts +1 -1
  19. package/internals/plugins/useTreeViewItems/useTreeViewItems.js +60 -50
  20. package/internals/plugins/useTreeViewItems/useTreeViewItems.types.d.ts +19 -15
  21. package/internals/plugins/useTreeViewItems/useTreeViewItems.utils.d.ts +4 -0
  22. package/internals/plugins/useTreeViewItems/useTreeViewItems.utils.js +8 -0
  23. package/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.js +66 -41
  24. package/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.types.d.ts +3 -2
  25. package/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +20 -18
  26. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +11 -22
  27. package/internals/useTreeView/useTreeView.js +21 -3
  28. package/internals/utils/tree.d.ts +8 -0
  29. package/internals/utils/tree.js +137 -0
  30. package/modern/TreeItem/TreeItem.js +1 -1
  31. package/modern/TreeItem2/TreeItem2.js +0 -1
  32. package/modern/index.js +1 -1
  33. package/modern/internals/TreeViewProvider/TreeViewChildrenItemProvider.js +57 -0
  34. package/modern/internals/TreeViewProvider/TreeViewProvider.js +2 -3
  35. package/modern/internals/corePlugins/useTreeViewInstanceEvents/useTreeViewInstanceEvents.js +7 -8
  36. package/modern/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +15 -15
  37. package/modern/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +25 -26
  38. package/modern/internals/plugins/useTreeViewId/useTreeViewId.js +5 -7
  39. package/modern/internals/plugins/useTreeViewItems/useTreeViewItems.js +60 -50
  40. package/modern/internals/plugins/useTreeViewItems/useTreeViewItems.utils.js +8 -0
  41. package/modern/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.js +66 -41
  42. package/modern/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +20 -18
  43. package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +11 -22
  44. package/modern/internals/useTreeView/useTreeView.js +21 -3
  45. package/modern/internals/utils/tree.js +137 -0
  46. package/modern/useTreeItem2/useTreeItem2.js +1 -1
  47. package/node/TreeItem/TreeItem.js +1 -1
  48. package/node/TreeItem2/TreeItem2.js +0 -1
  49. package/node/index.js +1 -1
  50. package/node/internals/TreeViewProvider/TreeViewChildrenItemProvider.js +67 -0
  51. package/node/internals/TreeViewProvider/TreeViewProvider.js +2 -3
  52. package/node/internals/corePlugins/useTreeViewInstanceEvents/useTreeViewInstanceEvents.js +7 -8
  53. package/node/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +15 -15
  54. package/node/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +25 -26
  55. package/node/internals/plugins/useTreeViewId/useTreeViewId.js +5 -7
  56. package/node/internals/plugins/useTreeViewItems/useTreeViewItems.js +60 -50
  57. package/node/internals/plugins/useTreeViewItems/useTreeViewItems.utils.js +15 -0
  58. package/node/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.js +66 -41
  59. package/node/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +20 -18
  60. package/node/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +11 -22
  61. package/node/internals/useTreeView/useTreeView.js +21 -3
  62. package/node/internals/utils/tree.js +148 -0
  63. package/node/useTreeItem2/useTreeItem2.js +1 -1
  64. package/package.json +1 -1
  65. package/useTreeItem2/useTreeItem2.js +1 -1
  66. package/internals/TreeViewProvider/DescendantProvider.d.ts +0 -38
  67. package/internals/TreeViewProvider/DescendantProvider.js +0 -176
  68. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.d.ts +0 -17
  69. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.js +0 -55
  70. package/internals/useTreeView/useTreeView.utils.d.ts +0 -9
  71. package/internals/useTreeView/useTreeView.utils.js +0 -46
  72. package/modern/internals/TreeViewProvider/DescendantProvider.js +0 -176
  73. package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.js +0 -55
  74. package/modern/internals/useTreeView/useTreeView.utils.js +0 -46
  75. package/node/internals/TreeViewProvider/DescendantProvider.js +0 -185
  76. package/node/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.js +0 -62
  77. package/node/internals/useTreeView/useTreeView.utils.js +0 -58
@@ -1,176 +0,0 @@
1
- import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
2
- import _extends from "@babel/runtime/helpers/esm/extends";
3
- const _excluded = ["element"];
4
- import * as React from 'react';
5
- import PropTypes from 'prop-types';
6
- import useEnhancedEffect from '@mui/utils/useEnhancedEffect';
7
-
8
- /** Credit: https://github.com/reach/reach-ui/blob/86a046f54d53b6420e392b3fa56dd991d9d4e458/packages/descendants/README.md
9
- * Modified slightly to suit our purposes.
10
- */
11
- import { jsx as _jsx } from "react/jsx-runtime";
12
- function binaryFindElement(array, element) {
13
- let start = 0;
14
- let end = array.length - 1;
15
- while (start <= end) {
16
- const middle = Math.floor((start + end) / 2);
17
- if (array[middle].element === element) {
18
- return middle;
19
- }
20
-
21
- // eslint-disable-next-line no-bitwise
22
- if (array[middle].element.compareDocumentPosition(element) & Node.DOCUMENT_POSITION_PRECEDING) {
23
- end = middle - 1;
24
- } else {
25
- start = middle + 1;
26
- }
27
- }
28
- return start;
29
- }
30
- const DescendantContext = /*#__PURE__*/React.createContext({});
31
- if (process.env.NODE_ENV !== 'production') {
32
- DescendantContext.displayName = 'DescendantContext';
33
- }
34
- function usePrevious(value) {
35
- const ref = React.useRef(null);
36
- React.useEffect(() => {
37
- ref.current = value;
38
- }, [value]);
39
- return ref.current;
40
- }
41
- const noop = () => {};
42
-
43
- /**
44
- * This hook registers our descendant by passing it into an array. We can then
45
- * search that array by to find its index when registering it in the component.
46
- * We use this for focus management, keyboard navigation, and typeahead
47
- * functionality for some components.
48
- *
49
- * The hook accepts the element item
50
- *
51
- * Our main goals with this are:
52
- * 1) maximum composability,
53
- * 2) minimal API friction
54
- * 3) SSR compatibility*
55
- * 4) concurrent safe
56
- * 5) index always up-to-date with the tree despite changes
57
- * 6) works with memoization of any component in the tree (hopefully)
58
- *
59
- * * As for SSR, the good news is that we don't actually need the index on the
60
- * server for most use-cases, as we are only using it to determine the order of
61
- * composed descendants for keyboard navigation.
62
- */
63
- export function useDescendant(descendant) {
64
- const [, forceUpdate] = React.useState();
65
- const {
66
- registerDescendant = noop,
67
- unregisterDescendant = noop,
68
- descendants = [],
69
- parentId = null
70
- } = React.useContext(DescendantContext);
71
-
72
- // This will initially return -1 because we haven't registered the descendant
73
- // on the first render. After we register, this will then return the correct
74
- // index on the following render, and we will re-register descendants
75
- // so that everything is up-to-date before the user interacts with a
76
- // collection.
77
- const index = descendants.findIndex(item => item.element === descendant.element);
78
- const previousDescendants = usePrevious(descendants);
79
-
80
- // We also need to re-register descendants any time ANY of the other
81
- // descendants have changed. My brain was melting when I wrote this and it
82
- // feels a little off, but checking in render and using the result in the
83
- // effect's dependency array works well enough.
84
- const someDescendantsHaveChanged = descendants.some((newDescendant, position) => {
85
- return previousDescendants && previousDescendants[position] && previousDescendants[position].element !== newDescendant.element;
86
- });
87
-
88
- // Prevent any flashing
89
- useEnhancedEffect(() => {
90
- if (descendant.element) {
91
- registerDescendant(_extends({}, descendant, {
92
- index
93
- }));
94
- return () => {
95
- unregisterDescendant(descendant.element);
96
- };
97
- }
98
- forceUpdate({});
99
- return undefined;
100
- }, [registerDescendant, unregisterDescendant, index, someDescendantsHaveChanged, descendant]);
101
- return {
102
- parentId,
103
- index
104
- };
105
- }
106
- export function DescendantProvider(props) {
107
- const {
108
- children,
109
- id
110
- } = props;
111
- const [items, set] = React.useState([]);
112
- const registerDescendant = React.useCallback(_ref => {
113
- let {
114
- element
115
- } = _ref,
116
- other = _objectWithoutPropertiesLoose(_ref, _excluded);
117
- set(oldItems => {
118
- if (oldItems.length === 0) {
119
- // If there are no items, register at index 0 and bail.
120
- return [_extends({}, other, {
121
- element,
122
- index: 0
123
- })];
124
- }
125
- const index = binaryFindElement(oldItems, element);
126
- let newItems;
127
- if (oldItems[index] && oldItems[index].element === element) {
128
- // If the element is already registered, just use the same array
129
- newItems = oldItems;
130
- } else {
131
- // When registering a descendant, we need to make sure we insert in
132
- // into the array in the same order that it appears in the DOM. So as
133
- // new descendants are added or maybe some are removed, we always know
134
- // that the array is up-to-date and correct.
135
- //
136
- // So here we look at our registered descendants and see if the new
137
- // element we are adding appears earlier than an existing descendant's
138
- // DOM node via `node.compareDocumentPosition`. If it does, we insert
139
- // the new element at this index. Because `registerDescendant` will be
140
- // called in an effect every time the descendants state value changes,
141
- // we should be sure that this index is accurate when descendent
142
- // elements come or go from our component.
143
-
144
- const newItem = _extends({}, other, {
145
- element,
146
- index
147
- });
148
-
149
- // If an index is not found we will push the element to the end.
150
- newItems = oldItems.slice();
151
- newItems.splice(index, 0, newItem);
152
- }
153
- newItems.forEach((item, position) => {
154
- item.index = position;
155
- });
156
- return newItems;
157
- });
158
- }, []);
159
- const unregisterDescendant = React.useCallback(element => {
160
- set(oldItems => oldItems.filter(item => element !== item.element));
161
- }, []);
162
- const value = React.useMemo(() => ({
163
- descendants: items,
164
- registerDescendant,
165
- unregisterDescendant,
166
- parentId: id
167
- }), [items, registerDescendant, unregisterDescendant, id]);
168
- return /*#__PURE__*/_jsx(DescendantContext.Provider, {
169
- value: value,
170
- children: children
171
- });
172
- }
173
- process.env.NODE_ENV !== "production" ? DescendantProvider.propTypes = {
174
- children: PropTypes.node,
175
- id: PropTypes.string
176
- } : void 0;
@@ -1,55 +0,0 @@
1
- /**
2
- * This is used to determine the start and end of a selection range so
3
- * we can get the items between the two border items.
4
- *
5
- * It finds the items' common ancestor using
6
- * a naive implementation of a lowest common ancestor algorithm
7
- * (https://en.wikipedia.org/wiki/Lowest_common_ancestor).
8
- * Then compares the ancestor's 2 children that are ancestors of itemA and ItemB
9
- * so we can compare their indexes to work out which item comes first in a depth first search.
10
- * (https://en.wikipedia.org/wiki/Depth-first_search)
11
- *
12
- * Another way to put it is which item is shallower in a trémaux tree
13
- * https://en.wikipedia.org/wiki/Tr%C3%A9maux_tree
14
- */
15
- export const findOrderInTremauxTree = (instance, nodeAId, nodeBId) => {
16
- if (nodeAId === nodeBId) {
17
- return [nodeAId, nodeBId];
18
- }
19
- const nodeA = instance.getNode(nodeAId);
20
- const nodeB = instance.getNode(nodeBId);
21
- if (nodeA.parentId === nodeB.id || nodeB.parentId === nodeA.id) {
22
- return nodeB.parentId === nodeA.id ? [nodeA.id, nodeB.id] : [nodeB.id, nodeA.id];
23
- }
24
- const aFamily = [nodeA.id];
25
- const bFamily = [nodeB.id];
26
- let aAncestor = nodeA.parentId;
27
- let bAncestor = nodeB.parentId;
28
- let aAncestorIsCommon = bFamily.indexOf(aAncestor) !== -1;
29
- let bAncestorIsCommon = aFamily.indexOf(bAncestor) !== -1;
30
- let continueA = true;
31
- let continueB = true;
32
- while (!bAncestorIsCommon && !aAncestorIsCommon) {
33
- if (continueA) {
34
- aFamily.push(aAncestor);
35
- aAncestorIsCommon = bFamily.indexOf(aAncestor) !== -1;
36
- continueA = aAncestor !== null;
37
- if (!aAncestorIsCommon && continueA) {
38
- aAncestor = instance.getNode(aAncestor).parentId;
39
- }
40
- }
41
- if (continueB && !aAncestorIsCommon) {
42
- bFamily.push(bAncestor);
43
- bAncestorIsCommon = aFamily.indexOf(bAncestor) !== -1;
44
- continueB = bAncestor !== null;
45
- if (!bAncestorIsCommon && continueB) {
46
- bAncestor = instance.getNode(bAncestor).parentId;
47
- }
48
- }
49
- }
50
- const commonAncestor = aAncestorIsCommon ? aAncestor : bAncestor;
51
- const ancestorFamily = instance.getChildrenIds(commonAncestor);
52
- const aSide = aFamily[aFamily.indexOf(commonAncestor) - 1];
53
- const bSide = bFamily[bFamily.indexOf(commonAncestor) - 1];
54
- return ancestorFamily.indexOf(aSide) < ancestorFamily.indexOf(bSide) ? [nodeAId, nodeBId] : [nodeBId, nodeAId];
55
- };
@@ -1,46 +0,0 @@
1
- export const getPreviousItem = (instance, itemId) => {
2
- const node = instance.getNode(itemId);
3
- const siblings = instance.getNavigableChildrenIds(node.parentId);
4
- const itemIndex = siblings.indexOf(itemId);
5
- if (itemIndex === 0) {
6
- return node.parentId;
7
- }
8
- let currentItem = siblings[itemIndex - 1];
9
- while (instance.isItemExpanded(currentItem) && instance.getNavigableChildrenIds(currentItem).length > 0) {
10
- currentItem = instance.getNavigableChildrenIds(currentItem).pop();
11
- }
12
- return currentItem;
13
- };
14
- export const getNextItem = (instance, itemId) => {
15
- // If expanded get first child
16
- if (instance.isItemExpanded(itemId) && instance.getNavigableChildrenIds(itemId).length > 0) {
17
- return instance.getNavigableChildrenIds(itemId)[0];
18
- }
19
- let node = instance.getNode(itemId);
20
- while (node != null) {
21
- // Try to get next sibling
22
- const siblings = instance.getNavigableChildrenIds(node.parentId);
23
- const nextSibling = siblings[siblings.indexOf(node.id) + 1];
24
- if (nextSibling) {
25
- return nextSibling;
26
- }
27
-
28
- // If the sibling does not exist, go up a level to the parent and try again.
29
- node = instance.getNode(node.parentId);
30
- }
31
- return null;
32
- };
33
- export const getLastItem = instance => {
34
- let lastItem = instance.getNavigableChildrenIds(null).pop();
35
- while (instance.isItemExpanded(lastItem)) {
36
- lastItem = instance.getNavigableChildrenIds(lastItem).pop();
37
- }
38
- return lastItem;
39
- };
40
- export const getFirstItem = instance => instance.getNavigableChildrenIds(null)[0];
41
- export const populateInstance = (instance, methods) => {
42
- Object.assign(instance, methods);
43
- };
44
- export const populatePublicAPI = (publicAPI, methods) => {
45
- Object.assign(publicAPI, methods);
46
- };
@@ -1,185 +0,0 @@
1
- "use strict";
2
-
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
- Object.defineProperty(exports, "__esModule", {
5
- value: true
6
- });
7
- exports.DescendantProvider = DescendantProvider;
8
- exports.useDescendant = useDescendant;
9
- var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose"));
10
- var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
11
- var React = _interopRequireWildcard(require("react"));
12
- var _propTypes = _interopRequireDefault(require("prop-types"));
13
- var _useEnhancedEffect = _interopRequireDefault(require("@mui/utils/useEnhancedEffect"));
14
- var _jsxRuntime = require("react/jsx-runtime");
15
- const _excluded = ["element"];
16
- /** Credit: https://github.com/reach/reach-ui/blob/86a046f54d53b6420e392b3fa56dd991d9d4e458/packages/descendants/README.md
17
- * Modified slightly to suit our purposes.
18
- */
19
- function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
20
- function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
21
- function binaryFindElement(array, element) {
22
- let start = 0;
23
- let end = array.length - 1;
24
- while (start <= end) {
25
- const middle = Math.floor((start + end) / 2);
26
- if (array[middle].element === element) {
27
- return middle;
28
- }
29
-
30
- // eslint-disable-next-line no-bitwise
31
- if (array[middle].element.compareDocumentPosition(element) & Node.DOCUMENT_POSITION_PRECEDING) {
32
- end = middle - 1;
33
- } else {
34
- start = middle + 1;
35
- }
36
- }
37
- return start;
38
- }
39
- const DescendantContext = /*#__PURE__*/React.createContext({});
40
- if (process.env.NODE_ENV !== 'production') {
41
- DescendantContext.displayName = 'DescendantContext';
42
- }
43
- function usePrevious(value) {
44
- const ref = React.useRef(null);
45
- React.useEffect(() => {
46
- ref.current = value;
47
- }, [value]);
48
- return ref.current;
49
- }
50
- const noop = () => {};
51
-
52
- /**
53
- * This hook registers our descendant by passing it into an array. We can then
54
- * search that array by to find its index when registering it in the component.
55
- * We use this for focus management, keyboard navigation, and typeahead
56
- * functionality for some components.
57
- *
58
- * The hook accepts the element item
59
- *
60
- * Our main goals with this are:
61
- * 1) maximum composability,
62
- * 2) minimal API friction
63
- * 3) SSR compatibility*
64
- * 4) concurrent safe
65
- * 5) index always up-to-date with the tree despite changes
66
- * 6) works with memoization of any component in the tree (hopefully)
67
- *
68
- * * As for SSR, the good news is that we don't actually need the index on the
69
- * server for most use-cases, as we are only using it to determine the order of
70
- * composed descendants for keyboard navigation.
71
- */
72
- function useDescendant(descendant) {
73
- const [, forceUpdate] = React.useState();
74
- const {
75
- registerDescendant = noop,
76
- unregisterDescendant = noop,
77
- descendants = [],
78
- parentId = null
79
- } = React.useContext(DescendantContext);
80
-
81
- // This will initially return -1 because we haven't registered the descendant
82
- // on the first render. After we register, this will then return the correct
83
- // index on the following render, and we will re-register descendants
84
- // so that everything is up-to-date before the user interacts with a
85
- // collection.
86
- const index = descendants.findIndex(item => item.element === descendant.element);
87
- const previousDescendants = usePrevious(descendants);
88
-
89
- // We also need to re-register descendants any time ANY of the other
90
- // descendants have changed. My brain was melting when I wrote this and it
91
- // feels a little off, but checking in render and using the result in the
92
- // effect's dependency array works well enough.
93
- const someDescendantsHaveChanged = descendants.some((newDescendant, position) => {
94
- return previousDescendants && previousDescendants[position] && previousDescendants[position].element !== newDescendant.element;
95
- });
96
-
97
- // Prevent any flashing
98
- (0, _useEnhancedEffect.default)(() => {
99
- if (descendant.element) {
100
- registerDescendant((0, _extends2.default)({}, descendant, {
101
- index
102
- }));
103
- return () => {
104
- unregisterDescendant(descendant.element);
105
- };
106
- }
107
- forceUpdate({});
108
- return undefined;
109
- }, [registerDescendant, unregisterDescendant, index, someDescendantsHaveChanged, descendant]);
110
- return {
111
- parentId,
112
- index
113
- };
114
- }
115
- function DescendantProvider(props) {
116
- const {
117
- children,
118
- id
119
- } = props;
120
- const [items, set] = React.useState([]);
121
- const registerDescendant = React.useCallback(_ref => {
122
- let {
123
- element
124
- } = _ref,
125
- other = (0, _objectWithoutPropertiesLoose2.default)(_ref, _excluded);
126
- set(oldItems => {
127
- if (oldItems.length === 0) {
128
- // If there are no items, register at index 0 and bail.
129
- return [(0, _extends2.default)({}, other, {
130
- element,
131
- index: 0
132
- })];
133
- }
134
- const index = binaryFindElement(oldItems, element);
135
- let newItems;
136
- if (oldItems[index] && oldItems[index].element === element) {
137
- // If the element is already registered, just use the same array
138
- newItems = oldItems;
139
- } else {
140
- // When registering a descendant, we need to make sure we insert in
141
- // into the array in the same order that it appears in the DOM. So as
142
- // new descendants are added or maybe some are removed, we always know
143
- // that the array is up-to-date and correct.
144
- //
145
- // So here we look at our registered descendants and see if the new
146
- // element we are adding appears earlier than an existing descendant's
147
- // DOM node via `node.compareDocumentPosition`. If it does, we insert
148
- // the new element at this index. Because `registerDescendant` will be
149
- // called in an effect every time the descendants state value changes,
150
- // we should be sure that this index is accurate when descendent
151
- // elements come or go from our component.
152
-
153
- const newItem = (0, _extends2.default)({}, other, {
154
- element,
155
- index
156
- });
157
-
158
- // If an index is not found we will push the element to the end.
159
- newItems = oldItems.slice();
160
- newItems.splice(index, 0, newItem);
161
- }
162
- newItems.forEach((item, position) => {
163
- item.index = position;
164
- });
165
- return newItems;
166
- });
167
- }, []);
168
- const unregisterDescendant = React.useCallback(element => {
169
- set(oldItems => oldItems.filter(item => element !== item.element));
170
- }, []);
171
- const value = React.useMemo(() => ({
172
- descendants: items,
173
- registerDescendant,
174
- unregisterDescendant,
175
- parentId: id
176
- }), [items, registerDescendant, unregisterDescendant, id]);
177
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(DescendantContext.Provider, {
178
- value: value,
179
- children: children
180
- });
181
- }
182
- process.env.NODE_ENV !== "production" ? DescendantProvider.propTypes = {
183
- children: _propTypes.default.node,
184
- id: _propTypes.default.string
185
- } : void 0;
@@ -1,62 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.findOrderInTremauxTree = void 0;
7
- /**
8
- * This is used to determine the start and end of a selection range so
9
- * we can get the items between the two border items.
10
- *
11
- * It finds the items' common ancestor using
12
- * a naive implementation of a lowest common ancestor algorithm
13
- * (https://en.wikipedia.org/wiki/Lowest_common_ancestor).
14
- * Then compares the ancestor's 2 children that are ancestors of itemA and ItemB
15
- * so we can compare their indexes to work out which item comes first in a depth first search.
16
- * (https://en.wikipedia.org/wiki/Depth-first_search)
17
- *
18
- * Another way to put it is which item is shallower in a trémaux tree
19
- * https://en.wikipedia.org/wiki/Tr%C3%A9maux_tree
20
- */
21
- const findOrderInTremauxTree = (instance, nodeAId, nodeBId) => {
22
- if (nodeAId === nodeBId) {
23
- return [nodeAId, nodeBId];
24
- }
25
- const nodeA = instance.getNode(nodeAId);
26
- const nodeB = instance.getNode(nodeBId);
27
- if (nodeA.parentId === nodeB.id || nodeB.parentId === nodeA.id) {
28
- return nodeB.parentId === nodeA.id ? [nodeA.id, nodeB.id] : [nodeB.id, nodeA.id];
29
- }
30
- const aFamily = [nodeA.id];
31
- const bFamily = [nodeB.id];
32
- let aAncestor = nodeA.parentId;
33
- let bAncestor = nodeB.parentId;
34
- let aAncestorIsCommon = bFamily.indexOf(aAncestor) !== -1;
35
- let bAncestorIsCommon = aFamily.indexOf(bAncestor) !== -1;
36
- let continueA = true;
37
- let continueB = true;
38
- while (!bAncestorIsCommon && !aAncestorIsCommon) {
39
- if (continueA) {
40
- aFamily.push(aAncestor);
41
- aAncestorIsCommon = bFamily.indexOf(aAncestor) !== -1;
42
- continueA = aAncestor !== null;
43
- if (!aAncestorIsCommon && continueA) {
44
- aAncestor = instance.getNode(aAncestor).parentId;
45
- }
46
- }
47
- if (continueB && !aAncestorIsCommon) {
48
- bFamily.push(bAncestor);
49
- bAncestorIsCommon = aFamily.indexOf(bAncestor) !== -1;
50
- continueB = bAncestor !== null;
51
- if (!bAncestorIsCommon && continueB) {
52
- bAncestor = instance.getNode(bAncestor).parentId;
53
- }
54
- }
55
- }
56
- const commonAncestor = aAncestorIsCommon ? aAncestor : bAncestor;
57
- const ancestorFamily = instance.getChildrenIds(commonAncestor);
58
- const aSide = aFamily[aFamily.indexOf(commonAncestor) - 1];
59
- const bSide = bFamily[bFamily.indexOf(commonAncestor) - 1];
60
- return ancestorFamily.indexOf(aSide) < ancestorFamily.indexOf(bSide) ? [nodeAId, nodeBId] : [nodeBId, nodeAId];
61
- };
62
- exports.findOrderInTremauxTree = findOrderInTremauxTree;
@@ -1,58 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.populatePublicAPI = exports.populateInstance = exports.getPreviousItem = exports.getNextItem = exports.getLastItem = exports.getFirstItem = void 0;
7
- const getPreviousItem = (instance, itemId) => {
8
- const node = instance.getNode(itemId);
9
- const siblings = instance.getNavigableChildrenIds(node.parentId);
10
- const itemIndex = siblings.indexOf(itemId);
11
- if (itemIndex === 0) {
12
- return node.parentId;
13
- }
14
- let currentItem = siblings[itemIndex - 1];
15
- while (instance.isItemExpanded(currentItem) && instance.getNavigableChildrenIds(currentItem).length > 0) {
16
- currentItem = instance.getNavigableChildrenIds(currentItem).pop();
17
- }
18
- return currentItem;
19
- };
20
- exports.getPreviousItem = getPreviousItem;
21
- const getNextItem = (instance, itemId) => {
22
- // If expanded get first child
23
- if (instance.isItemExpanded(itemId) && instance.getNavigableChildrenIds(itemId).length > 0) {
24
- return instance.getNavigableChildrenIds(itemId)[0];
25
- }
26
- let node = instance.getNode(itemId);
27
- while (node != null) {
28
- // Try to get next sibling
29
- const siblings = instance.getNavigableChildrenIds(node.parentId);
30
- const nextSibling = siblings[siblings.indexOf(node.id) + 1];
31
- if (nextSibling) {
32
- return nextSibling;
33
- }
34
-
35
- // If the sibling does not exist, go up a level to the parent and try again.
36
- node = instance.getNode(node.parentId);
37
- }
38
- return null;
39
- };
40
- exports.getNextItem = getNextItem;
41
- const getLastItem = instance => {
42
- let lastItem = instance.getNavigableChildrenIds(null).pop();
43
- while (instance.isItemExpanded(lastItem)) {
44
- lastItem = instance.getNavigableChildrenIds(lastItem).pop();
45
- }
46
- return lastItem;
47
- };
48
- exports.getLastItem = getLastItem;
49
- const getFirstItem = instance => instance.getNavigableChildrenIds(null)[0];
50
- exports.getFirstItem = getFirstItem;
51
- const populateInstance = (instance, methods) => {
52
- Object.assign(instance, methods);
53
- };
54
- exports.populateInstance = populateInstance;
55
- const populatePublicAPI = (publicAPI, methods) => {
56
- Object.assign(publicAPI, methods);
57
- };
58
- exports.populatePublicAPI = populatePublicAPI;