When I do the following I can navigate with my arrow keys through the tree and the tree gets focus when I tab through the document (only root items, sub branches are broken because they use Branch):
const Item = React.memo(function Item({ item }) { const { onChange } = useContext(DataContext); return (<TreeItem key={item.key} nodeId={item.key} label={item.name}> {Boolean(item?.children) && (<Branch data={item.children} /> )}</TreeItem> );});<TreeView multiSelect selected={NONE}> {data .map((item) => (<Item key={item.key} item={item} nodeId={item.key} /> ))}</TreeView>
But when I do the following the tree doesn't get focussed when tabbing through the document and arrow up and down don't navigate through the tree (only left and right after clicking on an item in the tree):
<TreeView multiSelect selected={NONE}><Branch data={data} /></TreeView>
I think it has something to do with not forwarding a ref I tried with class components (React.PureComponent) but no change. I think a direct child of TreeItem
or TreeView
needs to have a nodeId prop but what will that be for a set of nodes?
One example shows this working but I can't pass nodeId to the Branch as it receives multiple ones. Another example shows using a renderTree function but my items have a checkbox and checking one item causes the whole tree to re paint.
If I need to forward a ref then what is it, no examples of this are given?
update
I got a little further and noticed it is (not) passing nodeId
that will break it:
const Item = React.memo(function Item({ parent }) { const { map } = useContext(DataContext); const parentItem = map.get(parent); const children = !parentItem?.children ? null : parentItem.children.map((key) => (<Item key={key} parent={key} nodeId={key} /> )); //this will not render root but crashes when Tree passes // a nodeId if (!parentItem.parent) { return children; } return (<TreeItem key={parentItem.key} nodeId={parentItem.key} label={parentItem.name || "root"}> {children}</TreeItem> );});const Tree = React.memo(function Tree({ parent }) { return (<TreeView multiSelect selected={NONE} defaultCollapseIcon={<ExpandMoreIcon />} defaultExpandIcon={<ChevronRightIcon />}> {/* if item does not render parent and I pass nodeId it will crash if no nodeId is passed then key navigation is broken again */}<Item parent={parent} nodeId={parent} /></TreeView> );});
If I pass nodeId but not render root the error is:
Uncaught TypeError: Cannot read property 'children' of undefinedat buildVisible (TreeView.js:590)
The above error occurred in the <ForwardRef(TreeView)> component:
Passing nodeId and rendering root will work but root is a dummy to make recursion easier so I don't want to render it.