How to create nested Menu components from material-ui 🎉
In this post, I would like to share my work on nested menu component which is used to power Settings menu at Axon. This is done by composing material-ui's Popper component provided out of the box with major inspiration from Chakra-ui's Popover component. Stay tuned and read on guys 😎
Design system has become a normal thing to have at any company regardless of sizes. At Axon, we started working actively on our own component library several years ago. Given the fact we are not at the scale like Apple or Google to come up with our own component library from scratch. We decided to extensively use material-ui's components and customize on demand as per our requirements. As of writing, I am working on a media team where we provide media experience across Axon products. There are several components that material-ui's components could not fulfill our need. Slider component from material-ui is not flexible enough for us to wire our Youtube-like Volume and Scrubber components. Hence, I had to build these components from scratch. This time, I ran into a much bigger problem which is nested menu component which is again Youtube's like experience except that our menus at different levels can be opened at once (no two or more menus at the same levels can be opened)
Material-ui's menu component again could not fulfill our unique case. This is where I had to do a bunch of research on how UI libraries build it. I have come across several well-known state-of-the art libraries such as Ant Design's Menu, Quasar's Menu and Chakra UI's Menu. Different libraries has been using fairly distinguishable techniques which leads to different API usage. Understandably, these libraries are trying to solve as many cases as possible since they are open source projects. Given our use case is much simple at media team, we only requires our menu to work very much like Youtube's setting menu. My very first solution was a port from Quasar's Menu component which has a very nice API compared to other two IMO 😄. Unfortunately, the library took advantage of Vue's flexibility which React does not have - Vue allows developers to access Vue's component runtime and even traversing the virtual dom. Despise this is impressive but failed my use case of porting the component to my React code.
One day I came across this set of components from Chakra-ui so-called Popover. This is where I started to think about how API will look like for ur media's menu component. It typically looks similar to what Chakra-ui's Popover has except behaving like a menu component with nested behavior. Behind the scene, Chakra-ui makes extensive use of popper.js library which is very battle tested and common use by many libraries including material-ui. This is the exact moment when I knew what I would do with our current situation at Axon's FE codebase. Bundle size is something I have taken really seriously at our media package, having seen that Popper component from material-ui has been included -> all I need to is to make up a set of menu components which reused the Popper component. Since it's just a port from Chakra-ui's Popover components with extensive help from material-ui's work. I will give you guys a link to play with in Code sandbox instead of showing the step by step code as other posts. I highly recommend checking the source code to learn more about it since it's such a wonderful library 😎
Composability is the key to success, I love the battles I have had whenever I need to fight for the right balance between these three -> under / balanced / over abstractions 🤗
❤️ ❤️ ❤️ Be well Be happy ❤️ ❤️ ❤️