They have great example how to do that https://codesandbox.io/s/material-demo-ui4dx

Also be careful with TreeView component as it is still in Lab and can be with some issues and not finished implementation.

Answer from Eugene Chybisov on Stack Overflow
🌐
Material UI
v4.mui.com › api › tree-item
TreeItem API - Material-UI - MUI
import TreeItem from '@material-ui/lab/TreeItem'; // or import { TreeItem } from '@material-ui/lab';
🌐
MUI
mui.com › x › api › tree-view › tree-item
TreeItem API - MUI X
API reference docs for the React TreeItem component. Learn about the props, CSS, and other APIs of this exported module.
🌐
Stack Overflow
stackoverflow.com › questions › 64359383 › how-to-use-material-ui-treeview-with-recursive-treeitem-component-with-added-sta
reactjs - How to use Material UI TreeView with Recursive TreeItem Component with added state - Stack Overflow
@priyankaUkirde, Yes, but I just downloaded the source for the TreeItem component and put customizations in there ... const data: RenderTree = { id: 'root', name: 'Parent', extra: 'xxxx', <--- add extra data like this children: [ { id: '1', name: 'Child - 1', extra: 'xxxx', <--- add extra data like this }, { id: '3', name: 'Child - 3', children: [ { id: '4', name: 'Child - 4', }, ], }, ], }; Another choice is using this library: https://github.com/helfi92/material-ui-treeview#readme
🌐
johnnyreilly
johnnyreilly.com › home › blog › mui react tree view: pass data to treeitem
MUI React Tree View: pass data to TreeItem | johnnyreilly
July 1, 2024 - function OurComponent() { // ... return ( <RichTreeView defaultExpandedItems={initialExpandedItems} multiSelect={true} checkboxSelection={true} selectedItems={selectedIds} onSelectedItemsChange={handleSelectedItemsChange} items={treeViewNodes} // note that we're using the TreeItemWithLoading component here slots={{ item: TreeItemWithLoading }} slotProps={{ item: { //@ts-expect-error this works but MUI doesn't officially support this prior to v6 - see https://github.com/mui/material-ui/issues/33175#issuecomment-1469725522 'data-still-to-load-ids': data.stillToLoad, }, }} /> ); } function TreeIt
Top answer
1 of 3
10

When you have questions about how to override the default Material-UI styles, the best resource is to look at how the default styles are defined.

Below are the default styles for TreeItemContent:

const StyledTreeItemContent = styled(TreeItemContent, {
  name: 'MuiTreeItem',
  slot: 'Content',
  overridesResolver: (props, styles) => {
    return [
      styles.content,
      styles.iconContainer && {
        [`& .${treeItemClasses.iconContainer}`]: styles.iconContainer,
      },
      styles.label && {
        [`& .${treeItemClasses.label}`]: styles.label,
      },
    ];
  },
})(({ theme }) => ({
  padding: '0 8px',
  width: '100%',
  display: 'flex',
  alignItems: 'center',
  cursor: 'pointer',
  WebkitTapHighlightColor: 'transparent',
  '&:hover': {
    backgroundColor: (theme.vars || theme).palette.action.hover,
    // Reset on touch devices, it doesn't add specificity
    '@media (hover: none)': {
      backgroundColor: 'transparent',
    },
  },
  [`&.${treeItemClasses.disabled}`]: {
    opacity: (theme.vars || theme).palette.action.disabledOpacity,
    backgroundColor: 'transparent',
  },
  [`&.${treeItemClasses.focused}`]: {
    backgroundColor: (theme.vars || theme).palette.action.focus,
  },
  [`&.${treeItemClasses.selected}`]: {
    backgroundColor: theme.vars
      ? `rgba(${theme.vars.palette.primary.mainChannel} / ${theme.vars.palette.action.selectedOpacity})`
      : alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity),
    '&:hover': {
      backgroundColor: theme.vars
        ? `rgba(${theme.vars.palette.primary.mainChannel} / calc(${theme.vars.palette.action.selectedOpacity} + ${theme.vars.palette.action.hoverOpacity}))`
        : alpha(
            theme.palette.primary.main,
            theme.palette.action.selectedOpacity + theme.palette.action.hoverOpacity,
          ),
      // Reset on touch devices, it doesn't add specificity
      '@media (hover: none)': {
        backgroundColor: theme.vars
          ? `rgba(${theme.vars.palette.primary.mainChannel} / ${theme.vars.palette.action.selectedOpacity})`
          : alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity),
      },
    },
    [`&.${treeItemClasses.focused}`]: {
      backgroundColor: theme.vars
        ? `rgba(${theme.vars.palette.primary.mainChannel} / calc(${theme.vars.palette.action.selectedOpacity} + ${theme.vars.palette.action.focusOpacity}))`
        : alpha(
            theme.palette.primary.main,
            theme.palette.action.selectedOpacity + theme.palette.action.focusOpacity,
          ),
    },
  },
  [`& .${treeItemClasses.iconContainer}`]: {
    marginRight: 4,
    width: 15,
    display: 'flex',
    flexShrink: 0,
    justifyContent: 'center',
    '& svg': {
      fontSize: 18,
    },
  },
  [`& .${treeItemClasses.label}`]: {
    width: '100%',
    // fixes overflow - see https://github.com/mui/material-ui/issues/27372
    minWidth: 0,
    paddingLeft: 4,
    position: 'relative',
    ...theme.typography.body1,
  },
}));

The overall structure of TreeItem can be found by looking at TreeItem and TreeItemContent and is as follows (simplified slightly):

<li className="MuiTreeItem-root">
   <div className="MuiTreeItem-content">
      <div className="MuiTreeItem-iconContainer">
         {icon}
      </div>
      <div className="MuiTreeItem-label">
         {label}
      </div>
   </div>
   {children}
</li>

Additionally, the Mui-selected, Mui-expanded, Mui-focused, and Mui-disabled classes get added to the MuiTreeItem-content div when applicable.

You can target the MuiTreeItem-content div as follows:

const TreeItem = styled(MuiTreeItem)`
  & > .MuiTreeItem-content.Mui-selected {
    color: red;
  }
`;

If you don't want to include the icon in the styling, then you can just target the label within the content:

const TreeItem = styled(MuiTreeItem)`
  & > .MuiTreeItem-content.Mui-selected .MuiTreeItem-label {
    color: red;
  }
`;

If you want to change the background color, you need to pay attention to a few more details in the default styling (since the default styling does a lot with background color) in order to deal appropriately with the hover and focused states.

2 of 3
2

The answers so far use withStyles from MUI v4 because that was the current version when they were posted. I'm pretty sure there is a MUI v5 approach, but I gave up on trying to get that to work.

The technique used doesn't really matter as much, anyway: The problem is getting all the selectors right.

I ended up adding this to index.css which seems to disable any most focused / hover / selected styles (some edge cases seem to persist):

.MuiTreeItem-root:hover {
  background: transparent
}

.MuiTreeItem-root > .MuiTreeItem-content:hover {
  background: transparent
}

.MuiTreeItem-root > .MuiTreeItem-content:hover > .MuiTreeItem-label {
  background: transparent
}

.MuiTreeItem-root > .MuiTreeItem-content.Mui-selected {
  background: transparent
}

.MuiTreeItem-root > .MuiTreeItem-content.Mui-selected:hover {
  background: transparent
}

.MuiTreeItem-root > .MuiTreeItem-content.Mui-selected > .MuiTreeItem-label {
  background: transparent
}

.MuiTreeItem-root > .MuiTreeItem-content.Mui-selected.Mui-focused {
  background: transparent
}

Yes, as far as I can tell, they are all required. Probably still a few more.

NOTE: That's focused (with one s), using e.g. MUI-focussed fails silently.

🌐
MUI
mui.com › x › react-tree-view › tree-item-customization
Tree Item Customization - MUI X
Use the content slot to customize the content of a TreeItem or replace it with a custom component.
🌐
GeeksforGeeks
geeksforgeeks.org › reactjs › react-mui-treeitem-api
React MUI TreeItem API - GeeksforGeeks
July 23, 2025 - Material-UI is a UI library providing predefined robust and customizable components for React for easier web development. The MUI design is based on top of Material Design by Google.
🌐
Material-ui
v4-7-2.material-ui.com › api › tree-item
TreeItem API - Material-UI
import TreeItem from '@material-ui/lab/TreeItem'; // or import { TreeItem } from '@material-ui/lab';
Find elsewhere
🌐
MUI
mui.com › x › react-tree-view › simple-tree-view › customization
Simple Tree View - Customization - MUI X
The demo below is animated using Material UI's Collapse component together with the react-spring library. ... Use treeItemClasses to target internal elements of a TreeItem and change its styles.
Top answer
1 of 3
7

You can achieve that using TreeView expanded prop.
The code below expands the TreeItem with id "1" on mount.

import React, {useEffect, useState} from 'react';
import TreeView from '@material-ui/lab/TreeView';
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
import ChevronRightIcon from '@material-ui/icons/ChevronRight';
import TreeItem from '@material-ui/lab/TreeItem';

export default function FileSystemNavigator() {
  const [expanded, setExpanded] = useState([]);

  useEffect(() => {
    setExpanded(["1"])
  },[])

  return (
    <TreeView
      defaultCollapseIcon={<ExpandMoreIcon />}
      defaultExpandIcon={<ChevronRightIcon />}
      expanded={expanded}
    >
      <TreeItem nodeId="1" label="Applications"    
>
        <TreeItem nodeId="2" label="Calendar" />
        <TreeItem nodeId="3" label="Chrome" />
        <TreeItem nodeId="4" label="Webstorm" />
      </TreeItem>
      <TreeItem nodeId="5" label="Documents"
>
        <TreeItem nodeId="6" label="Material-UI">
          <TreeItem nodeId="7" label="src">
            <TreeItem nodeId="8" label="index.js" />
            <TreeItem nodeId="9" label="tree-view.js" />
          </TreeItem>
        </TreeItem>
      </TreeItem>
    </TreeView>
  );
}

Code Sandbox

2 of 3
4

This answer is for Riham Nour Question in the comment section of this answer (won't be able to reply in comments due to less reputation).

what if I only want the selected parent TreeItem to be selected while collapsing the others? like when I select node 1, then node 6 collapses ?

Just add the nodeId of the selected nodes then you can easily be able to get the desired outcome. You can go through the code Code SandBox.

PS: I hope I understood the question correctly and Sorry I added this in the answer section. Please let me know if there is any better way to communicate the answer to Riham.

🌐
C# Corner
c-sharpcorner.com › article › how-to-add-treeview-component-in-react-application
How To Add TreeView Component In React Application
February 12, 2020 - import ChevronRightIcon from '@material-ui/icons/ChevronRight'; import TreeItem from '@material-ui/lab/TreeItem'; import AppBar from '@material-ui/core/AppBar'; import Toolbar from '@material-ui/core/Toolbar'; Add the following code in Treeview component.
🌐
Material-ui
next.material-ui.com › api › tree-item
TreeItem API - Material UI
API reference docs for the React TreeItem component. Learn about the props, CSS, and other APIs of this exported module.
Top answer
1 of 2
9

Use ContentProps props, it will be merged with the original TreeItemContentProps

<CustomTreeItem
  nodeId="1"
  label="Applications"
  ContentProps={{
    myProps: "my props",
  }}
>
const CustomContent = React.forwardRef(function CustomContent(
  props: TreeItemContentProps,
  ref
) {
  console.log(props.myProps); // "my props"

EDIT: For typescript users, you also need to augment the prop interface of TreeItemContent to remove the error:

declare module "@material-ui/lab/TreeItem" {
  interface TreeItemContentProps {
    myProps: string;
  }
}

The ContentProps itself can't be augmented, this is a shortcoming from the MUI API, a workaround is simply ignore it:

ContentProps={
  {
    myProps: "my props"
  } as any
}
2 of 2
2

As per current document follow these steps

I found the way as mentioned on following document

Code Ref: https://github.com/mui/material-ui/blob/512896973499adbbda057e7f3685d1b23cc02de9/docs/src/components/productX/XTreeViewDemo.tsx

Step1 Add custom property along TreeItemContentProps on custom component create

 const CustomContentChildContent = React.forwardRef(function CustomContent(
        props: TreeItemContentProps & { myCustomData?: string },
        ref,
    )

Step2 Add custom property to with TreeItemProps

const CustomTreeItemChild = (
  props: TreeItemProps & {
    ContentProps?: { myCustomData?: string };
  },
) => <StyledTreeItem ContentComponent={CustomContentChildContent} {...props} />;

Step3

Add property in the component you are calling

<CustomTreeItemChild nodeId="3" label={item.name} ContentProps={{ myCustomData: 'anything-i-can-pass' }} />
🌐
Bayanbennett
bayanbennett.com › posts › help-users-find-things-generate-a-page-tree
Help Users Find Things — Generate a Page Tree
Since I'm using Material UI, it's only natural to look at their existing tree implementation. It consists of a top level <TreeView> component and can have <TreeItem> child components, which themselves can have <TreeItem> children.
🌐
GitHub
github.com › mui › material-ui › issues › 29491
V5 TreeItem onLabelClick and onIconClick missing · Issue #29491 · mui/material-ui
November 3, 2021 - I was using TreeItem onLableClick and onIconClick APIs in MUI V4 for separating the response on the label body clicking and the customized icon click. However, MUI V5 the APIs are removed. How to work around and regain those clicking con...
Author   jingxizhang
Top answer
1 of 1
2

After a little while this is what I got. I tried to match the design of the gif as good as possible.

I used this data which I derived from the question. This example has one disabled node and parent node (my-photo.jpg and zip directory). The data array can be expanded endlessly if it matches TreeData type.

export type TreeData = {
  id: string;
  name: string;
  disabledButton: boolean;
  children?: TreeData[];
};

const data: TreeData[] = [
  {
    id: "1",
    name: "My Web Site",
    disabledButton: false,
    children: [
      {
        id: "2",
        name: "images",
        disabledButton: false,
        children: [
          { id: "3", name: "logo.png", disabledButton: false },
          { id: "4", name: "body-back.png", disabledButton: false },
          { id: "5", name: "my-photo.jpg", disabledButton: true }
        ]
      },
      {
        id: "6",
        name: "resources",
        disabledButton: false,
        children: [
          {
            id: "7",
            name: "pdf",
            disabledButton: false,
            children: [
              { id: "8", name: "brochure.pdf", disabledButton: false },
              { id: "9", name: "prices.pdf", disabledButton: false }
            ]
          },
          {
            id: "10",
            name: "zip",
            disabledButton: true,
            children: [{ id: "11", name: "test.zip", disabledButton: false }]
          }
        ]
      }
    ]
  }
];

The CustomTreeView consists of CustomTreeItem that again makes use of CustomContent. CustomContent is used to handle all events and to display another icon (folder) next to the expandIcon.

In the CustomTreeItem I set the width to fit-content to not select the whole row, but to match the example from the gif:

const CustomTreeItem = (props: TreeItemProps) => (
  <TreeItem
    ContentComponent={CustomContent}
    {...props}
    sx={{
      width: "fit-content",
      ".MuiTreeItem-content": {
        py: "2px",
        width: "fit-content"
      }
    }}
  />
);

The interesting part is the styling of the CustomTreeView and its usage. I have packed the classes into objects, which can be overwritten easily. The theming happens in the styles class which is in styles/Styles.ts.

// Styles.ts
import { createTheme } from "@mui/material";

export const getMuiTheme = () =>
  createTheme({
    palette: {
      primary: {
        main: "#2160dd"
      },
      secondary: {
        main: "#d3d3d3"
      }
    }
  });

// CustomTreeView.tsx
const classes = {
  focused: {
    bgcolor: "transparent",
    py: "1px",
    px: "7px",
    border: `1px solid ${getMuiTheme().palette.secondary.main}`
  },
  selected: {
    bgcolor: getMuiTheme().palette.primary.main,
    color: "white"
  }
};

const CustomTreeView = ({ data }: { data: TreeData[] }) => {
  return (
    <Box mt={2} ml={2} bgcolor="white" width="300px">
      <ThemeProvider theme={getMuiTheme()}>
        <TreeView
          defaultCollapseIcon={<ArrowDropDownIcon />}
          defaultExpandIcon={<ArrowRightIcon />}
          defaultEndIcon={<InsertDriveFile />}
          sx={{
            ".MuiTreeItem-root": {
              ".Mui-focused:not(.Mui-selected)": classes.focused,
              ".Mui-selected, .Mui-focused.Mui-selected, .Mui-selected:hover":
                classes.selected
            }
          }}
        >
          {renderTreeData(data)}
        </TreeView>
      </ThemeProvider>
    </Box>
  );
};

To render arbitrarily nested data we make use of the recursive method renderTreeData. This way the data array can be expanded endlessly as long as it matches TreeData type.

export const renderTreeData = (data: TreeData[]) => {
  return data.map((item) => (
    <React.Fragment key={item.id}>
      {item.children ? (
        <CustomTreeItem
          nodeId={item.id}
          label={item.name}
          disabled={item.disabledButton}
          icon={<FolderOutlined />}
        >
          {renderTreeData(item.children)}
        </CustomTreeItem>
      ) : (
        <CustomTreeItem
          nodeId={item.id}
          label={item.name}
          disabled={item.disabledButton}
          icon={getFileIcon(item.name)}
        />
      )}
    </React.Fragment>
  ));
};

Live Demo