Search code examples
reactjstypescriptmaterial-uitreeviewreact-dnd

React MUI TreeView / React DnD: How to use a draggable component?


In my React web app, I would like to

  1. drag items from the MUI TreeView on the left to one of the drop targets on the right
  2. drag and drop items between the drop targets

UI mockup:

MUI TreeView UI mockup

The second part already works.

As for the first part, I did manage to make them draggable (following the React DnD Basic Example) and I can drag them from the tree view into the drop targets:

const DraggableTreeItem = (props: TreeItemProps) => {
  const [{ isDragging }, drag] = useDrag({
    collect: (monitor: DragSourceMonitor) => ({
      isDragging: monitor.isDragging()
    }),
    item: props,
    type: MyDnDItemType
  })
  return (
    <TreeItem ref={drag} {...props}/>
  )
}

export default DraggableTreeItem;

My problem: I would like the items in the tree view to look the same as in the drop targets to maintain some "UI coherence", i.e. make it visually immediately obvious that those are the same items: Instead of just the MUI "built-in" simple string, I'd like the same item box with a colored icon (and a string): Seems to me I should ideally use the same component throughout.

I've messed around with the ContentComponent prop example in the MUI TreeView docs, but it seems to me that when I take that approach, I need to re-implement (i.e. duplicate) a lot of the built-in tree functionality (expanding nodes, collapsing, selecting, etc.).

I've also tried to make sense of the MUI TreeView docs Gmail clone example, but there seems to be so much unrelated stuff in there that I don't see the forest for all the trees. Also, I am not sure if this MUI styled(TreeItem)(({ theme }) concept is intended for what I want to achieve.

My question: How can I use my own (draggable) component as tree view item ?


Solution

  • Found the solution: The MUI TreeView API docs don't seem to mention that, but the TreeItem label prop can be a simple string (as it often is) - or an entire component, for example my custom component:

    <TreeView >
      <TreeItem label={ <MyComponent/> } nodeId="1"/>
    </TreeView>
    

    Well, technically, the docs do state node as type for the TreeView label prop, but that really seems like the kind of info you only see once you already know it - and The tree node label. as description really sounds like a string and not like a component.

    The UI now looks like this:

    MUI TreeView UI mockup