Vertical lines to show connection between nodes
Hi. Is it possible to make a tree which contains vertical lines connected between nodes with the current implementation?
F.e. add some flag to toggle the structure of items from renderProps to the "nested tree" type. Every item will have a childNodes property ?
[
{
"index": 0,
"parent": "",
"level": 0,
"key": "1",
....otherInjectedProps
},
{
"index": 1,
"parent": "",
"level": 0,
"key": "2",
....otherInjectedProps
},
{
"index": 1,
"parent": "2",
"level": 1,
"key": "2/7",
....otherInjectedProps
},
{
"index": 2,
"parent": "",
"level": 0,
"key": "4",
}
]
to
[
{
"index": 0,
"parent": "",
"level": 0,
"key": "1",
....otherInjectedProps
},
{
"index": 1,
"parent": "",
"level": 0,
"key": "2",
childNodes: [
{
"index": 1,
"parent": "2",
"level": 1,
"key": "2/7",
....otherInjectedProps
}
],
....otherInjectedProps
},
{
"index": 2,
"parent": "",
"level": 0,
"key": "4",
}
]
And than use some sort of component recursion
const TreeItem = ({data}) => (
<ul>
{data && data.map(item => (
<li>
{item.label}
{item.childNodes && <TreeItem data={item.childNodes} />}
</li>
))}
</ul>
);
Hello, I'm not sure if I understand your question. This library flattens your data into one-level array, and provide props like level and parent for you to know how to style the component. You can add your custom styling to show the relationship among all the nodes with all the given props.
Are you suggesting keeping the nesting structure and get rid of the flattening?
@iannbing Hi. F.e. my case. I would like to have something like:
<ul>
<li>item</li>
<li>
Item 2
<ul> // horizontal line with setting border here
<li>item 3</li>
<li>item 4</li>
</ul
<li>
</ul>
instead of calculating padding/margins for every separate node:
<ul><li></li>.......more elements</ul>
With the current implementation I have to convert flattened data to treeData one more time:
<TreeMenu data={treeData} debounceTime={125}>
{({ items }) => {
const treeList = arrayToTree(items, { id: 'key', parentId: 'parent', dataField: null, childrenField: 'childNodes' });
return <TreeView.Items data={treeList} />;
}}
</TreeMenu>
@iannbing And another problem is difficulties with collapse/expand animations. Flattened items from render-props doesn't include child nodes of parent elements that is not opened. Their appearance in items is controlled by calling 'toggleNode' func that produces changing of children property ,f.e., in some custom TreeViewItem component. If TreeViewItem component renders child nodes in animated container it will cause a problem: how to determine the range of height to animate ?, animation is started running on changing of isOpen property(need to call toggleNode func), but in the same time 'children' is disappeared/appeared even if animation is already started. It produces a flash effect .
Is it possible to to keep even not opened nodes in 'items' ? I can't see any disadvantages of this.
What you have said about the flattened ul structure is correct. That's the trade-off I made when I designed this component. What I wanted to achieve is simplicity and flexibility. User of this library can manipulate items as much as they want, just like what you've achieved there.
With regards to hiding the collapsed children instead of removing them, I prefer clean DOM structure over hiding elements using CSS. A possible solution is to provide a customToggleNode prop that allows you to customize the behavior, e.g. add a delay.
Something like this:
<TreeMenu
data={treeData}
customToggleNode={toggleNode => {
triggerAnimation();
setTimeout(toggleNode, 250);
}}
/>
What do you think?
@iannbing It will not force users to hide childNodes using css. U can print childNodes in DOM only if parent is opened. It is just an implementation. My suggestion is to inject in item a boolean property which will mean: "this item must not be visible for this time". Call of 'toggleNode' on the parent component will not cause unmounting of childNodes, because their creation is depends ONLY on the fact their data representation is included into items array. I can create a sandbox with a problem related to this. sandbox. Try to collapse an opened node. And this sandbox to compare.
Duration will be useful for delay-based animations. But ,f.e., react-spring use 'spring physics' . As I understood, time of collapsing/expanding is depends on the count on nodes => the occupied height. F.e." expanding" of 3 nodes and 40 nodes can not take the same time. So, there is no way to calculate delay.