Tree Menu List component in React
- julienmesser
- 31 déc. 2024
- 2 min de lecture
In this post we will show how to create a Tree Menu List component in less than 200 lines of code:

Resources:
The TreeMenuList component provides a hierarchical list of options for selection. Each option may include a nested list of sub-options, allowing for flexible, multi-level structures.
Approach
The TreeMenuList is made of 3 simple components:
The "TreeMenuList" itself: it manages the interactions with the calling app and wraps and renders the options
The "SingleSelectItem" represents one option which is capable of being selected. It also contains the "SingleSelectItem" subOptions if applicable
The "ToggleButton" shows different arrows depending of the collapsed/expanded state
To implement the options we decided to define a structure, maybe an alternative could have been to support react components as children.
Definition of the options
Each option is characterized by:
key: A unique identifier
label: The text to be displayed
subOptions (optional): A list of nested options
Example:
const options = [
{ index: "1", label: "Option 1"},
{ index: "2", label: "Option 2", subOptions: [
{ index: "2.1", label: "Suboption 2.1"},
{ index: "2.2", label: "Suboption 2.2"},
]},
{ index: "3", label: "Option 3", subOptions: [
{ index: "3.1", label: "Suboption 3.1"},
{ index: "3.2", label: "Suboption 3.2"},
]},
];
Behavior
Expand/Collapse Sub-Options: Sub-options can be expanded or collapsed using a ToggleButton. The button displays an arrow pointing to the right when collapsed or downward when expanded.
Default State: By default, only the sub-options required to display the selected option are expanded. All other options are collapsed.
Expected Props
The TreeMenuList expects the following props:
options: The list of available options.
selectedOption: The currently selected option (identified by its index).
onChange: A callback invoked when a new option is selected. The selected option is passed as an argument.
Remarks
Centralized State Management:The expandedOptions are managed centrally in the component’s state. This ensures that any levels expanded or collapsed by the user remain in memory.
All the options and subOptions are implemented as siblings, not as descendents, why? The reason is that the component should behave as a list, getting highlighted on the whole width on hover. The correct indentation is obtained with a calculation based on the option's depth and applied with a padding.
Limitations:
Keyboard support is not yet implemented.
Mouse and touch interactions could be improved.
The component could be extended to support custom render functions or additional features.
Tests are not developped yet.
Thank you for visiting this page! I hope you found the information helpful.
Comments