Provide ability to override the isLeaf calculation
Desired functionality:
I would love to provide the <Tree> class an isLeaf function of something like..
{(node) => !node.children || node.children.length === 0}
This would allow me to negate the 'folder' and 'file' concept and move closer towards something like Confluence spaces - where 'pages' can be also be parents.
As it currently stands, it seems the isLeaf function will only become true on data objects without parents - which makes modifying the original data structure more annoying :)
This is coming in the next major version. Here's a preview from the docs...
It's important to note that tree data can come in many shapes and sizes. However, they do all follow a common pattern. The Tree component that react-arborist exports needs you to convert your data into an array of "Nodes".
There is a utility you can use to turn any data into nodes. It works like this.
const [data, setData] = useState(myRandomData);
const nodes = createNodes(data, {
id: (d) => d.path,
name: (d) => d.name,
children: (d) => d.files,
isLeaf: (d) => !('files' in d),
sort: (a, b) => a.name - b.name,
isVisible: (node) => true // not sure about his yet
});
<Tree
nodes={{
value: nodes,
onChange: (e) => setData(nodes.handleChange(e))
}}
>
This is coming in the next major version. Here's a preview from the docs...
It's important to note that tree data can come in many shapes and sizes. However, they do all follow a common pattern. The
Treecomponent that react-arborist exports needs you to convert your data into an array of "Nodes".There is a utility you can use to turn any data into nodes. It works like this.
const [data, setData] = useState(myRandomData); const nodes = createNodes(data, { id: (d) => d.path, name: (d) => d.name, children: (d) => d.files, isLeaf: (d) => !('files' in d), sort: (a, b) => a.name - b.name, isVisible: (node) => true // not sure about his yet });
<Tree nodes={{ value: nodes, onChange: (e) => setData(nodes.handleChange(e)) }}
Love this! I also directly rely on ordering, so it's nice to see the sort function. Right now this is a little 'wonky' in my system. Currently I have arborist hooked to optimistic updates (Mutations) through Tanstack Query.
It's okay - it's a little slow at times which can kill the UX, but only makes changes on parents/children and not the entire tree. One of the features I offer is on right click you get a ShadCN context menu. On deletion of a folder, I provide the option to persist (default) or remove all children.
Unfortunately, I can't handle the same interactions with a Delete key on the keyboard. Would be pretty sick if you exposed an option to allow users to toggle it on/off or present a modal.
I've considered turning my tree updates offline, perhaps into indexDB as a queue of changes (or storing the tree entirely?) so that I can periodically send the latest tree to the postgres backend... this would mean the tree on the client is always up to date.
What're your thoughts here? Every deal with "yjs" style constraints for tree updates?
The next version will allow keyboard navigation to be overridden very easily.
@jameskerr Hey hey man!
Wanted to ping - hows the updates coming along with v4? :)
I'm re-integrating a sortable tree in a new project, and quite honestly after looking at simple dndkit + pragmatic, this still seems to be my favorite and easiest to integrate.
Thinking you'll have some time to put in some rounds on this project? I'm happy to pony up some beers !:)