@atlaskit/charlie-hierarchy 0.0.5 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/dist/cjs/hooks/use-hierarchy.js +164 -0
- package/dist/es2019/hooks/use-hierarchy.js +148 -0
- package/dist/esm/hooks/use-hierarchy.js +157 -0
- package/dist/types/hooks/use-hierarchy.d.ts +38 -0
- package/dist/types-ts4.5/hooks/use-hierarchy.d.ts +38 -0
- package/package.json +7 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @atlaskit/charlie-hierarchy
|
|
2
2
|
|
|
3
|
+
## 0.0.7
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#198800](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/198800)
|
|
8
|
+
[`060485e2f0561`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/060485e2f0561) -
|
|
9
|
+
Added use-hierarchy hook for interacting with the hierarchy data
|
|
10
|
+
|
|
11
|
+
## 0.0.6
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- Updated dependencies
|
|
16
|
+
|
|
3
17
|
## 0.0.5
|
|
4
18
|
|
|
5
19
|
### Patch Changes
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.useHierarchyData = exports.HierarchyContainer = void 0;
|
|
8
|
+
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
9
|
+
var _reactSweetState = require("react-sweet-state");
|
|
10
|
+
var HierarchyContainer = exports.HierarchyContainer = (0, _reactSweetState.createContainer)();
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* useHierarchyData manages your hierarchal data leveraging
|
|
14
|
+
* the `@visx/hierarchy` library (wrapper for d3).
|
|
15
|
+
*/
|
|
16
|
+
var useHierarchyData = exports.useHierarchyData = function useHierarchyData(_ref) {
|
|
17
|
+
var childrenAccessor = _ref.childrenAccessor,
|
|
18
|
+
updateChildren = _ref.updateChildren,
|
|
19
|
+
identifierAccessor = _ref.identifierAccessor,
|
|
20
|
+
parentIdentifierAccessor = _ref.parentIdentifierAccessor;
|
|
21
|
+
var initialState = {
|
|
22
|
+
rootNode: null,
|
|
23
|
+
addedNodeIdentifiers: new Set(),
|
|
24
|
+
childrenAccessor: childrenAccessor,
|
|
25
|
+
identifierAccessor: identifierAccessor,
|
|
26
|
+
parentIdentifierAccessor: parentIdentifierAccessor,
|
|
27
|
+
updateChildren: updateChildren
|
|
28
|
+
};
|
|
29
|
+
var actions = {
|
|
30
|
+
resetRootNode: function resetRootNode(root) {
|
|
31
|
+
return function (_ref2) {
|
|
32
|
+
var setState = _ref2.setState,
|
|
33
|
+
getState = _ref2.getState;
|
|
34
|
+
setState({
|
|
35
|
+
rootNode: root,
|
|
36
|
+
addedNodeIdentifiers: new Set([getState().identifierAccessor(root)])
|
|
37
|
+
});
|
|
38
|
+
};
|
|
39
|
+
},
|
|
40
|
+
/** for useHierarchyData, when you add a node it must either be:
|
|
41
|
+
* - the new root
|
|
42
|
+
* - parent of the existing root
|
|
43
|
+
* - descendent of the existing root
|
|
44
|
+
*/
|
|
45
|
+
addNode: function addNode(node) {
|
|
46
|
+
return function (_ref3) {
|
|
47
|
+
var setState = _ref3.setState,
|
|
48
|
+
getState = _ref3.getState;
|
|
49
|
+
var childrenAccessor = getState().childrenAccessor;
|
|
50
|
+
var identifierAccessor = getState().identifierAccessor;
|
|
51
|
+
var parentIdentifierAccessor = getState().parentIdentifierAccessor;
|
|
52
|
+
var currentIdentifiers = getState().addedNodeIdentifiers;
|
|
53
|
+
// it's already been added, skip!
|
|
54
|
+
if (currentIdentifiers.has(identifierAccessor(node))) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
var rootNode = getState().rootNode;
|
|
58
|
+
|
|
59
|
+
// if there is no root, the node becomes the root!
|
|
60
|
+
if (rootNode == null) {
|
|
61
|
+
setState({
|
|
62
|
+
rootNode: node,
|
|
63
|
+
addedNodeIdentifiers: new Set([identifierAccessor(node)])
|
|
64
|
+
});
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
var nodeId = identifierAccessor(node);
|
|
68
|
+
var rootId = identifierAccessor(rootNode);
|
|
69
|
+
|
|
70
|
+
// if the node is the parent of the root, then it becomes the new root
|
|
71
|
+
var nodeChildren = childrenAccessor(node);
|
|
72
|
+
var foundChild = false;
|
|
73
|
+
var updatedChildren = (nodeChildren !== null && nodeChildren !== void 0 ? nodeChildren : []).map(function (child) {
|
|
74
|
+
if (identifierAccessor(child) === rootId) {
|
|
75
|
+
foundChild = true;
|
|
76
|
+
return rootNode;
|
|
77
|
+
} else {
|
|
78
|
+
return child;
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
if (foundChild) {
|
|
82
|
+
setState({
|
|
83
|
+
rootNode: updateChildren(node, updatedChildren),
|
|
84
|
+
addedNodeIdentifiers: new Set(currentIdentifiers).add(nodeId)
|
|
85
|
+
});
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
var tempRoot = rootNode;
|
|
89
|
+
var searchingThroughChildren = true;
|
|
90
|
+
var accessedNodes = [];
|
|
91
|
+
var visitedNodes = [];
|
|
92
|
+
var _loop = function _loop() {
|
|
93
|
+
visitedNodes.push(tempRoot);
|
|
94
|
+
var children = childrenAccessor(tempRoot);
|
|
95
|
+
if (children) {
|
|
96
|
+
accessedNodes = [].concat((0, _toConsumableArray2.default)(accessedNodes), (0, _toConsumableArray2.default)(children));
|
|
97
|
+
}
|
|
98
|
+
var foundInTree = false;
|
|
99
|
+
var updatedRootDesc = (children !== null && children !== void 0 ? children : []).map(function (child) {
|
|
100
|
+
if (nodeId === identifierAccessor(child)) {
|
|
101
|
+
foundInTree = true;
|
|
102
|
+
return node;
|
|
103
|
+
} else {
|
|
104
|
+
return child;
|
|
105
|
+
}
|
|
106
|
+
}).filter(Boolean);
|
|
107
|
+
if (foundInTree) {
|
|
108
|
+
// Work our way up the tree to update the parent nodes
|
|
109
|
+
var currentRootNode = updateChildren(tempRoot, updatedRootDesc);
|
|
110
|
+
while (identifierAccessor(currentRootNode) !== rootId) {
|
|
111
|
+
// Find the parent node from our visited nodes
|
|
112
|
+
var parentNode = visitedNodes.find(function (visitedNode) {
|
|
113
|
+
return identifierAccessor(visitedNode) === parentIdentifierAccessor(currentRootNode);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
// No parent found, we must be the root
|
|
117
|
+
if (!parentNode) {
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Get a new version of the children where you replace the old node with the new one
|
|
122
|
+
var currentRootChildrenNodes = childrenAccessor(parentNode);
|
|
123
|
+
var currentDescendingChildren = (currentRootChildrenNodes !== null && currentRootChildrenNodes !== void 0 ? currentRootChildrenNodes : []).map(function (child) {
|
|
124
|
+
if (identifierAccessor(currentRootNode) === identifierAccessor(child)) {
|
|
125
|
+
foundInTree = true;
|
|
126
|
+
return currentRootNode;
|
|
127
|
+
} else {
|
|
128
|
+
return child;
|
|
129
|
+
}
|
|
130
|
+
}).filter(Boolean);
|
|
131
|
+
|
|
132
|
+
// Set the new parent node
|
|
133
|
+
currentRootNode = updateChildren(parentNode, currentDescendingChildren);
|
|
134
|
+
}
|
|
135
|
+
setState({
|
|
136
|
+
rootNode: currentRootNode,
|
|
137
|
+
addedNodeIdentifiers: new Set(currentIdentifiers).add(nodeId)
|
|
138
|
+
});
|
|
139
|
+
return {
|
|
140
|
+
v: void 0
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
if (accessedNodes.length === 0) {
|
|
144
|
+
searchingThroughChildren = false;
|
|
145
|
+
} else {
|
|
146
|
+
tempRoot = accessedNodes.shift();
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
_ret;
|
|
150
|
+
while (searchingThroughChildren && tempRoot != null) {
|
|
151
|
+
_ret = _loop();
|
|
152
|
+
if (_ret) return _ret.v;
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
var Store = (0, _reactSweetState.createStore)({
|
|
158
|
+
containedBy: HierarchyContainer,
|
|
159
|
+
initialState: initialState,
|
|
160
|
+
actions: actions,
|
|
161
|
+
name: 'HierarchyDataStore'
|
|
162
|
+
});
|
|
163
|
+
return (0, _reactSweetState.createHook)(Store)();
|
|
164
|
+
};
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { createContainer, createHook, createStore } from 'react-sweet-state';
|
|
2
|
+
export const HierarchyContainer = createContainer();
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* useHierarchyData manages your hierarchal data leveraging
|
|
6
|
+
* the `@visx/hierarchy` library (wrapper for d3).
|
|
7
|
+
*/
|
|
8
|
+
export const useHierarchyData = ({
|
|
9
|
+
childrenAccessor,
|
|
10
|
+
updateChildren,
|
|
11
|
+
identifierAccessor,
|
|
12
|
+
parentIdentifierAccessor
|
|
13
|
+
}) => {
|
|
14
|
+
const initialState = {
|
|
15
|
+
rootNode: null,
|
|
16
|
+
addedNodeIdentifiers: new Set(),
|
|
17
|
+
childrenAccessor,
|
|
18
|
+
identifierAccessor,
|
|
19
|
+
parentIdentifierAccessor,
|
|
20
|
+
updateChildren
|
|
21
|
+
};
|
|
22
|
+
const actions = {
|
|
23
|
+
resetRootNode: root => ({
|
|
24
|
+
setState,
|
|
25
|
+
getState
|
|
26
|
+
}) => {
|
|
27
|
+
setState({
|
|
28
|
+
rootNode: root,
|
|
29
|
+
addedNodeIdentifiers: new Set([getState().identifierAccessor(root)])
|
|
30
|
+
});
|
|
31
|
+
},
|
|
32
|
+
/** for useHierarchyData, when you add a node it must either be:
|
|
33
|
+
* - the new root
|
|
34
|
+
* - parent of the existing root
|
|
35
|
+
* - descendent of the existing root
|
|
36
|
+
*/
|
|
37
|
+
addNode: node => ({
|
|
38
|
+
setState,
|
|
39
|
+
getState
|
|
40
|
+
}) => {
|
|
41
|
+
const childrenAccessor = getState().childrenAccessor;
|
|
42
|
+
const identifierAccessor = getState().identifierAccessor;
|
|
43
|
+
const parentIdentifierAccessor = getState().parentIdentifierAccessor;
|
|
44
|
+
const currentIdentifiers = getState().addedNodeIdentifiers;
|
|
45
|
+
// it's already been added, skip!
|
|
46
|
+
if (currentIdentifiers.has(identifierAccessor(node))) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
const rootNode = getState().rootNode;
|
|
50
|
+
|
|
51
|
+
// if there is no root, the node becomes the root!
|
|
52
|
+
if (rootNode == null) {
|
|
53
|
+
setState({
|
|
54
|
+
rootNode: node,
|
|
55
|
+
addedNodeIdentifiers: new Set([identifierAccessor(node)])
|
|
56
|
+
});
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const nodeId = identifierAccessor(node);
|
|
60
|
+
const rootId = identifierAccessor(rootNode);
|
|
61
|
+
|
|
62
|
+
// if the node is the parent of the root, then it becomes the new root
|
|
63
|
+
const nodeChildren = childrenAccessor(node);
|
|
64
|
+
let foundChild = false;
|
|
65
|
+
const updatedChildren = (nodeChildren !== null && nodeChildren !== void 0 ? nodeChildren : []).map(child => {
|
|
66
|
+
if (identifierAccessor(child) === rootId) {
|
|
67
|
+
foundChild = true;
|
|
68
|
+
return rootNode;
|
|
69
|
+
} else {
|
|
70
|
+
return child;
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
if (foundChild) {
|
|
74
|
+
setState({
|
|
75
|
+
rootNode: updateChildren(node, updatedChildren),
|
|
76
|
+
addedNodeIdentifiers: new Set(currentIdentifiers).add(nodeId)
|
|
77
|
+
});
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
let tempRoot = rootNode;
|
|
81
|
+
let searchingThroughChildren = true;
|
|
82
|
+
let accessedNodes = [];
|
|
83
|
+
const visitedNodes = [];
|
|
84
|
+
while (searchingThroughChildren && tempRoot != null) {
|
|
85
|
+
visitedNodes.push(tempRoot);
|
|
86
|
+
const children = childrenAccessor(tempRoot);
|
|
87
|
+
if (children) {
|
|
88
|
+
accessedNodes = [...accessedNodes, ...children];
|
|
89
|
+
}
|
|
90
|
+
let foundInTree = false;
|
|
91
|
+
const updatedRootDesc = (children !== null && children !== void 0 ? children : []).map(child => {
|
|
92
|
+
if (nodeId === identifierAccessor(child)) {
|
|
93
|
+
foundInTree = true;
|
|
94
|
+
return node;
|
|
95
|
+
} else {
|
|
96
|
+
return child;
|
|
97
|
+
}
|
|
98
|
+
}).filter(Boolean);
|
|
99
|
+
if (foundInTree) {
|
|
100
|
+
// Work our way up the tree to update the parent nodes
|
|
101
|
+
let currentRootNode = updateChildren(tempRoot, updatedRootDesc);
|
|
102
|
+
while (identifierAccessor(currentRootNode) !== rootId) {
|
|
103
|
+
// Find the parent node from our visited nodes
|
|
104
|
+
const parentNode = visitedNodes.find(visitedNode => {
|
|
105
|
+
return identifierAccessor(visitedNode) === parentIdentifierAccessor(currentRootNode);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
// No parent found, we must be the root
|
|
109
|
+
if (!parentNode) {
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Get a new version of the children where you replace the old node with the new one
|
|
114
|
+
const currentRootChildrenNodes = childrenAccessor(parentNode);
|
|
115
|
+
const currentDescendingChildren = (currentRootChildrenNodes !== null && currentRootChildrenNodes !== void 0 ? currentRootChildrenNodes : []).map(child => {
|
|
116
|
+
if (identifierAccessor(currentRootNode) === identifierAccessor(child)) {
|
|
117
|
+
foundInTree = true;
|
|
118
|
+
return currentRootNode;
|
|
119
|
+
} else {
|
|
120
|
+
return child;
|
|
121
|
+
}
|
|
122
|
+
}).filter(Boolean);
|
|
123
|
+
|
|
124
|
+
// Set the new parent node
|
|
125
|
+
currentRootNode = updateChildren(parentNode, currentDescendingChildren);
|
|
126
|
+
}
|
|
127
|
+
setState({
|
|
128
|
+
rootNode: currentRootNode,
|
|
129
|
+
addedNodeIdentifiers: new Set(currentIdentifiers).add(nodeId)
|
|
130
|
+
});
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
if (accessedNodes.length === 0) {
|
|
134
|
+
searchingThroughChildren = false;
|
|
135
|
+
} else {
|
|
136
|
+
tempRoot = accessedNodes.shift();
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
const Store = createStore({
|
|
142
|
+
containedBy: HierarchyContainer,
|
|
143
|
+
initialState,
|
|
144
|
+
actions: actions,
|
|
145
|
+
name: 'HierarchyDataStore'
|
|
146
|
+
});
|
|
147
|
+
return createHook(Store)();
|
|
148
|
+
};
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
|
|
2
|
+
import { createContainer, createHook, createStore } from 'react-sweet-state';
|
|
3
|
+
export var HierarchyContainer = createContainer();
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* useHierarchyData manages your hierarchal data leveraging
|
|
7
|
+
* the `@visx/hierarchy` library (wrapper for d3).
|
|
8
|
+
*/
|
|
9
|
+
export var useHierarchyData = function useHierarchyData(_ref) {
|
|
10
|
+
var childrenAccessor = _ref.childrenAccessor,
|
|
11
|
+
updateChildren = _ref.updateChildren,
|
|
12
|
+
identifierAccessor = _ref.identifierAccessor,
|
|
13
|
+
parentIdentifierAccessor = _ref.parentIdentifierAccessor;
|
|
14
|
+
var initialState = {
|
|
15
|
+
rootNode: null,
|
|
16
|
+
addedNodeIdentifiers: new Set(),
|
|
17
|
+
childrenAccessor: childrenAccessor,
|
|
18
|
+
identifierAccessor: identifierAccessor,
|
|
19
|
+
parentIdentifierAccessor: parentIdentifierAccessor,
|
|
20
|
+
updateChildren: updateChildren
|
|
21
|
+
};
|
|
22
|
+
var actions = {
|
|
23
|
+
resetRootNode: function resetRootNode(root) {
|
|
24
|
+
return function (_ref2) {
|
|
25
|
+
var setState = _ref2.setState,
|
|
26
|
+
getState = _ref2.getState;
|
|
27
|
+
setState({
|
|
28
|
+
rootNode: root,
|
|
29
|
+
addedNodeIdentifiers: new Set([getState().identifierAccessor(root)])
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
},
|
|
33
|
+
/** for useHierarchyData, when you add a node it must either be:
|
|
34
|
+
* - the new root
|
|
35
|
+
* - parent of the existing root
|
|
36
|
+
* - descendent of the existing root
|
|
37
|
+
*/
|
|
38
|
+
addNode: function addNode(node) {
|
|
39
|
+
return function (_ref3) {
|
|
40
|
+
var setState = _ref3.setState,
|
|
41
|
+
getState = _ref3.getState;
|
|
42
|
+
var childrenAccessor = getState().childrenAccessor;
|
|
43
|
+
var identifierAccessor = getState().identifierAccessor;
|
|
44
|
+
var parentIdentifierAccessor = getState().parentIdentifierAccessor;
|
|
45
|
+
var currentIdentifiers = getState().addedNodeIdentifiers;
|
|
46
|
+
// it's already been added, skip!
|
|
47
|
+
if (currentIdentifiers.has(identifierAccessor(node))) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
var rootNode = getState().rootNode;
|
|
51
|
+
|
|
52
|
+
// if there is no root, the node becomes the root!
|
|
53
|
+
if (rootNode == null) {
|
|
54
|
+
setState({
|
|
55
|
+
rootNode: node,
|
|
56
|
+
addedNodeIdentifiers: new Set([identifierAccessor(node)])
|
|
57
|
+
});
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
var nodeId = identifierAccessor(node);
|
|
61
|
+
var rootId = identifierAccessor(rootNode);
|
|
62
|
+
|
|
63
|
+
// if the node is the parent of the root, then it becomes the new root
|
|
64
|
+
var nodeChildren = childrenAccessor(node);
|
|
65
|
+
var foundChild = false;
|
|
66
|
+
var updatedChildren = (nodeChildren !== null && nodeChildren !== void 0 ? nodeChildren : []).map(function (child) {
|
|
67
|
+
if (identifierAccessor(child) === rootId) {
|
|
68
|
+
foundChild = true;
|
|
69
|
+
return rootNode;
|
|
70
|
+
} else {
|
|
71
|
+
return child;
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
if (foundChild) {
|
|
75
|
+
setState({
|
|
76
|
+
rootNode: updateChildren(node, updatedChildren),
|
|
77
|
+
addedNodeIdentifiers: new Set(currentIdentifiers).add(nodeId)
|
|
78
|
+
});
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
var tempRoot = rootNode;
|
|
82
|
+
var searchingThroughChildren = true;
|
|
83
|
+
var accessedNodes = [];
|
|
84
|
+
var visitedNodes = [];
|
|
85
|
+
var _loop = function _loop() {
|
|
86
|
+
visitedNodes.push(tempRoot);
|
|
87
|
+
var children = childrenAccessor(tempRoot);
|
|
88
|
+
if (children) {
|
|
89
|
+
accessedNodes = [].concat(_toConsumableArray(accessedNodes), _toConsumableArray(children));
|
|
90
|
+
}
|
|
91
|
+
var foundInTree = false;
|
|
92
|
+
var updatedRootDesc = (children !== null && children !== void 0 ? children : []).map(function (child) {
|
|
93
|
+
if (nodeId === identifierAccessor(child)) {
|
|
94
|
+
foundInTree = true;
|
|
95
|
+
return node;
|
|
96
|
+
} else {
|
|
97
|
+
return child;
|
|
98
|
+
}
|
|
99
|
+
}).filter(Boolean);
|
|
100
|
+
if (foundInTree) {
|
|
101
|
+
// Work our way up the tree to update the parent nodes
|
|
102
|
+
var currentRootNode = updateChildren(tempRoot, updatedRootDesc);
|
|
103
|
+
while (identifierAccessor(currentRootNode) !== rootId) {
|
|
104
|
+
// Find the parent node from our visited nodes
|
|
105
|
+
var parentNode = visitedNodes.find(function (visitedNode) {
|
|
106
|
+
return identifierAccessor(visitedNode) === parentIdentifierAccessor(currentRootNode);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
// No parent found, we must be the root
|
|
110
|
+
if (!parentNode) {
|
|
111
|
+
break;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Get a new version of the children where you replace the old node with the new one
|
|
115
|
+
var currentRootChildrenNodes = childrenAccessor(parentNode);
|
|
116
|
+
var currentDescendingChildren = (currentRootChildrenNodes !== null && currentRootChildrenNodes !== void 0 ? currentRootChildrenNodes : []).map(function (child) {
|
|
117
|
+
if (identifierAccessor(currentRootNode) === identifierAccessor(child)) {
|
|
118
|
+
foundInTree = true;
|
|
119
|
+
return currentRootNode;
|
|
120
|
+
} else {
|
|
121
|
+
return child;
|
|
122
|
+
}
|
|
123
|
+
}).filter(Boolean);
|
|
124
|
+
|
|
125
|
+
// Set the new parent node
|
|
126
|
+
currentRootNode = updateChildren(parentNode, currentDescendingChildren);
|
|
127
|
+
}
|
|
128
|
+
setState({
|
|
129
|
+
rootNode: currentRootNode,
|
|
130
|
+
addedNodeIdentifiers: new Set(currentIdentifiers).add(nodeId)
|
|
131
|
+
});
|
|
132
|
+
return {
|
|
133
|
+
v: void 0
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
if (accessedNodes.length === 0) {
|
|
137
|
+
searchingThroughChildren = false;
|
|
138
|
+
} else {
|
|
139
|
+
tempRoot = accessedNodes.shift();
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
_ret;
|
|
143
|
+
while (searchingThroughChildren && tempRoot != null) {
|
|
144
|
+
_ret = _loop();
|
|
145
|
+
if (_ret) return _ret.v;
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
var Store = createStore({
|
|
151
|
+
containedBy: HierarchyContainer,
|
|
152
|
+
initialState: initialState,
|
|
153
|
+
actions: actions,
|
|
154
|
+
name: 'HierarchyDataStore'
|
|
155
|
+
});
|
|
156
|
+
return createHook(Store)();
|
|
157
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { type Action } from 'react-sweet-state';
|
|
2
|
+
type State<NodeType extends object> = {
|
|
3
|
+
addedNodeIdentifiers: Set<string>;
|
|
4
|
+
rootNode: NodeType | null;
|
|
5
|
+
/**
|
|
6
|
+
* used to determine the children of a node
|
|
7
|
+
*/
|
|
8
|
+
childrenAccessor: (node: NodeType) => NodeType[] | undefined | null;
|
|
9
|
+
updateChildren: (node: NodeType, children: NodeType[]) => NodeType;
|
|
10
|
+
/**
|
|
11
|
+
* used to determine the unique identifier of a node for comparison
|
|
12
|
+
*/
|
|
13
|
+
identifierAccessor: (node: NodeType) => string;
|
|
14
|
+
/**
|
|
15
|
+
* used to determine the unique identifier of a nodes parent for comparison
|
|
16
|
+
*/
|
|
17
|
+
parentIdentifierAccessor: (node: NodeType) => string;
|
|
18
|
+
};
|
|
19
|
+
export declare const HierarchyContainer: import("react-sweet-state").GenericContainerComponent<unknown>;
|
|
20
|
+
/**
|
|
21
|
+
* useHierarchyData manages your hierarchal data leveraging
|
|
22
|
+
* the `@visx/hierarchy` library (wrapper for d3).
|
|
23
|
+
*/
|
|
24
|
+
export declare const useHierarchyData: <NodeType extends object>({ childrenAccessor, updateChildren, identifierAccessor, parentIdentifierAccessor, }: {
|
|
25
|
+
childrenAccessor: State<NodeType>['childrenAccessor'];
|
|
26
|
+
updateChildren: State<NodeType>['updateChildren'];
|
|
27
|
+
identifierAccessor: State<NodeType>['identifierAccessor'];
|
|
28
|
+
parentIdentifierAccessor: State<NodeType>['parentIdentifierAccessor'];
|
|
29
|
+
}) => import("react-sweet-state").HookReturnValue<State<NodeType>, import("react-sweet-state").BoundActions<State<NodeType>, {
|
|
30
|
+
resetRootNode: (root: NodeType) => Action<State<NodeType>>;
|
|
31
|
+
/** for useHierarchyData, when you add a node it must either be:
|
|
32
|
+
* - the new root
|
|
33
|
+
* - parent of the existing root
|
|
34
|
+
* - descendent of the existing root
|
|
35
|
+
*/
|
|
36
|
+
addNode: (node: NodeType) => Action<State<NodeType>>;
|
|
37
|
+
}>>;
|
|
38
|
+
export {};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { type Action } from 'react-sweet-state';
|
|
2
|
+
type State<NodeType extends object> = {
|
|
3
|
+
addedNodeIdentifiers: Set<string>;
|
|
4
|
+
rootNode: NodeType | null;
|
|
5
|
+
/**
|
|
6
|
+
* used to determine the children of a node
|
|
7
|
+
*/
|
|
8
|
+
childrenAccessor: (node: NodeType) => NodeType[] | undefined | null;
|
|
9
|
+
updateChildren: (node: NodeType, children: NodeType[]) => NodeType;
|
|
10
|
+
/**
|
|
11
|
+
* used to determine the unique identifier of a node for comparison
|
|
12
|
+
*/
|
|
13
|
+
identifierAccessor: (node: NodeType) => string;
|
|
14
|
+
/**
|
|
15
|
+
* used to determine the unique identifier of a nodes parent for comparison
|
|
16
|
+
*/
|
|
17
|
+
parentIdentifierAccessor: (node: NodeType) => string;
|
|
18
|
+
};
|
|
19
|
+
export declare const HierarchyContainer: import("react-sweet-state").GenericContainerComponent<unknown>;
|
|
20
|
+
/**
|
|
21
|
+
* useHierarchyData manages your hierarchal data leveraging
|
|
22
|
+
* the `@visx/hierarchy` library (wrapper for d3).
|
|
23
|
+
*/
|
|
24
|
+
export declare const useHierarchyData: <NodeType extends object>({ childrenAccessor, updateChildren, identifierAccessor, parentIdentifierAccessor, }: {
|
|
25
|
+
childrenAccessor: State<NodeType>['childrenAccessor'];
|
|
26
|
+
updateChildren: State<NodeType>['updateChildren'];
|
|
27
|
+
identifierAccessor: State<NodeType>['identifierAccessor'];
|
|
28
|
+
parentIdentifierAccessor: State<NodeType>['parentIdentifierAccessor'];
|
|
29
|
+
}) => import("react-sweet-state").HookReturnValue<State<NodeType>, import("react-sweet-state").BoundActions<State<NodeType>, {
|
|
30
|
+
resetRootNode: (root: NodeType) => Action<State<NodeType>>;
|
|
31
|
+
/** for useHierarchyData, when you add a node it must either be:
|
|
32
|
+
* - the new root
|
|
33
|
+
* - parent of the existing root
|
|
34
|
+
* - descendent of the existing root
|
|
35
|
+
*/
|
|
36
|
+
addNode: (node: NodeType) => Action<State<NodeType>>;
|
|
37
|
+
}>>;
|
|
38
|
+
export {};
|
package/package.json
CHANGED
|
@@ -27,15 +27,17 @@
|
|
|
27
27
|
".": "./src/index.ts"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
+
"@atlaskit/button": "^23.3.0",
|
|
30
31
|
"@atlaskit/css": "^0.12.0",
|
|
31
|
-
"@atlaskit/primitives": "^14.
|
|
32
|
-
"@atlaskit/tokens": "^
|
|
32
|
+
"@atlaskit/primitives": "^14.11.0",
|
|
33
|
+
"@atlaskit/tokens": "^6.0.0",
|
|
33
34
|
"@babel/runtime": "^7.0.0",
|
|
34
35
|
"@compiled/react": "^0.18.3",
|
|
35
36
|
"@visx/group": "^1.7.0",
|
|
36
37
|
"@visx/hierarchy": "^1.7.0",
|
|
37
38
|
"@visx/shape": "^1.7.0",
|
|
38
|
-
"@visx/zoom": "^2.10.0"
|
|
39
|
+
"@visx/zoom": "^2.10.0",
|
|
40
|
+
"react-sweet-state": "^2.6.5"
|
|
39
41
|
},
|
|
40
42
|
"peerDependencies": {
|
|
41
43
|
"react": "^18.2.0"
|
|
@@ -46,8 +48,7 @@
|
|
|
46
48
|
"@atlaskit/ssr": "workspace:^",
|
|
47
49
|
"@atlaskit/visual-regression": "workspace:^",
|
|
48
50
|
"@testing-library/react": "^13.4.0",
|
|
49
|
-
"react-dom": "^18.2.0"
|
|
50
|
-
"typescript": "~5.4.2"
|
|
51
|
+
"react-dom": "^18.2.0"
|
|
51
52
|
},
|
|
52
53
|
"techstack": {
|
|
53
54
|
"@atlassian/frontend": {
|
|
@@ -93,7 +94,7 @@
|
|
|
93
94
|
]
|
|
94
95
|
},
|
|
95
96
|
"name": "@atlaskit/charlie-hierarchy",
|
|
96
|
-
"version": "0.0.
|
|
97
|
+
"version": "0.0.7",
|
|
97
98
|
"description": "A component for building SVG-rendered trees, with support for custom node rendering, zooming, and panning.",
|
|
98
99
|
"author": "Atlassian Pty Ltd",
|
|
99
100
|
"license": "Apache-2.0",
|