2

I am using Semantic UI React and trying to create a multilevel menu component or a nested menu.

I was able to create a static menu component like below:

 <Menu>
    <Menu.Item>
        <Dropdown text='MCU' pointing className='link item'>
            <Dropdown.Menu>
                <Dropdown.Item>                      
                </Dropdown.Item>
                <Dropdown.Item>                       
                </Dropdown.Item>
            </Dropdown.Menu>
        </Dropdown>
    </Menu.Item>
    <Menu.Item>           
    </Menu.Item>        
    <Menu.Item>
        Dropdown Menu
    </Menu.Item>
</Menu>

Check out the output here

I was trying to create a dynamic component for that menu like below -

export class RecursiveMenu extends Component {
render() {
    const { children, textToShow } = this.props;
    return (
        <Dropdown key={children.wbMenuId} text={textToShow} pointing={children.childMenu ? true : false} className='link item'>
            <Dropdown.Menu>
                {
                    children.map(child => <Dropdown.Item>{child.userMenuName}</Dropdown.Item>)
                }
            </Dropdown.Menu>
        </Dropdown>
    );
}

}

But it's not showing properly. This is example data.

Mushfiq
  • 759
  • 1
  • 8
  • 41

2 Answers2

0

You can do so by creating a recursive component. In my example, I used a side menu instead of dropdown, but the principle is similar, if not the same.

The Menu component (recursive)

export function Menu(props) {
    return(
        <ul className="list-unstyled accordion">
            {props.menus && props.menus.map((menu) => {
                return (
                    <li key={menu.url} className="accordion-item border-0 bg-primary">
                        {menu.menus ? 
                        <h2 className="accordion-header">
                            <button className="accordion-button collapsed ps-1 py-1 bg-primary text-light" 
                                data-bs-toggle="collapse" data-bs-target={`#${menu.url}`} type="button">
                                <strong>{menu.name}</strong>
                            </button>
                        </h2> : 
                        <a className="ps-2 text-decoration-none d-inline-block btn-primary w-100" href={`/${menu.url}`}>
                            {menu.name}
                        </a>
                        }
                        
                        {menu.menus && 
                        <div className="accordion-collapse collapse" id={menu.url}>
                            <div className="accordion-body p-1 ps-2 pe-0">
                                <Menu id={props.id} menus={menu.menus}/>
                            </div>
                        </div>
                        }
                    </li>
                )
            })}
        </ul>
    )
}

So, wherever your main call for the menu is, you need some sort of array with nested items.

My nested items are called menus.

so the json example would be:

[
    {   
        "name": "Home", 
        "url": "" 
    },
    {   
        "name": "About us", 
        "url": "about-us",
        "menus": [
            {
                "name": "Who are we?",
                "url": "who-are-we"
            }
        ]
     }
]
Phillip Zoghbi
  • 512
  • 3
  • 15
-4

You can use Dropdown's options prop to pass your dropdown items instead of creating them yourself.

Here is an example in the Semantic UI docs:

https://react.semantic-ui.com/modules/dropdown#dropdown-example-item-content

morinx
  • 635
  • 7
  • 19