skip to Main Content

I have the following data structure:

const bullets = [
"Top Sports are:",
"hockey",
"soccer",
"football",
"Top Names are:",
"liam",
"noah",
"jordan"
]

I am able to make a bulleted list using MUI’s typography comoponent like so:

import { Typography } from 'components/Typography'
//...

<div >
  {bullets.map((bullet: string, index: any) => (
    <Typography key={index} component='li' variant='body2'>
      {bullet}
    </Typography>
     )
)}
</div>

However, I would like to change the data structure to have arrays for the nested/indented lists like so:

const nestedBullets = [
"Top Sports are:",
["hockey","soccer","football"],
"Top Names are:",
["liam","noah","jordan"]
]

But I don’t know how to adapt the original code to deal with the nested lists so they appear like this rather than a flat bulleted list:

 - Top Sports are:
    - hockey
    - soccer
    - football
 - Top Names are:
    - liam
    - noah
    - jordan

2

Answers


  1. one solution I can think of is to create a component that accepts an array of items as props and then display it with the map() method, for each iteration checks if the item is an array so it recursively calls itself otherwise directly display it:

    const ParentComponent = () => {
      const nestedBullets = [
        "Top Sports are:",
        ["hockey", "soccer", "football"],
        "Top Names are:",
        ["liam", "noah", "jordan"],
      ];
    
      return <NestedList items={nestedBullets} />;
    };
    
    
    const NestedList = ({ items }) => (
      <>
        {items.map((item, index) => (
          <div key={index}>
            {Array.isArray(item) ? (
              <ul>
                <NestedList items={item} />
              </ul>
            ) : (
              <li>
                <Typography component="li" variant="body2">
                  {item}
                </Typography>
              </li>
            )}
          </div>
        ))}
      </>
    );
    
    
    Login or Signup to reply.
  2. I think the problem with @Ahmed Sbai’s answer is that it does not include the usage of Mui Typography as per the question but it’s on the right path.

    Here is my solution… I’ve written in typescript so replace it with JS if required. This also accounts for nesting multiple levels dictated by the data structure passed in for "infinite" nesting.

    import { Typography } from '@mui/material';
    
    function App() {
      const nestedBullets = [
        "Top Sports are:",
          ["hockey", "soccer", "football"],
        "Top Names are:",
          ["liam", "noah", "jordan", ["stacy", "becky", ["miah", "julie", "tracy"]]]
    
      ]
      return (<ListComponent items={nestedBullets} />)
    }
    
    
    type DataTree<T> = T | Array<DataTree<T>>
    type Data = DataTree<string>
    type ListComponentProps = { items: Data[] }
    
    const ListComponent = ({ items }: ListComponentProps) => (
      <Typography component="ul" >
        {
          items.map((item, index) =>
            (typeof item === "string") ?
              <Typography key={index} component="li">{item}</Typography> :
              <ListComponent key={index} items={item} />)
        }
      </Typography>
    )
    
    export default App;
    
    

    Displays as like the following, apply your own styles 🙂.

    Renders:

    What you are asking

    "Infinite" nesting levels:

      const nestedBullets = [
        "Top Sports are:",
          ["hockey", "soccer", "football"],
        "Top Names are:",
        ["liam", "noah", "jordan",
          ["stacy", "becky",
            ["miah", "julie", "tracy"]
          ]
        ]
      ]
    

    Infinite nesting levels

    Note: The ListCoponent expects an Array to be passed for the items prop.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search