React-admin - Create sub menu
Asked Answered
A

2

7

How to create sub menu in react-admin, because in admin-on-rest i can use prop menuItems in MenuItem Component. Does react-admin have same props for this case?

I try create my own component, but with prop primary in ListItemText for give list name my app always show error Uncaught TypeError: Cannot read property '@global'

Thank you

Agrippina answered 16/11, 2018 at 10:54 Comment(0)
E
9

As previously explained by the maintainers/developers of react-admin, this feature is not offered by react-admin.
If you want a sub-menu, you should create a custom menu, following the instructions given in the official react-admin documentation and implement the Material-UI's nested-list logic.
This is a simple example of what your sub-menu could look like, according to the links I provided:

<List component="nav" >
   <ListItem button onClick={this.handleClick}>
      <ListItemIcon>
        <InboxIcon />
      </ListItemIcon>
      <ListItemText inset primary="YOUR-SECTION-TITLE" />
      {this.state.open ? <ExpandLess /> : <ExpandMore />}
   </ListItem>
   <Collapse in={this.state.open} timeout="auto" unmountOnExit>
    <List component="div" disablePadding>
        <MenuItemLink to="/your-api-endpoint-1" primaryText="API-ENDPOINT-1" onClick={this.props.onMenuClick} />
        <MenuItemLink to="/your-api-endpoint-2" primaryText="API-ENDPOINT-2" onClick={this.props.onMenuClick} />
        <MenuItemLink to="/your-api-endpoint-3" primaryText="API-ENDPOINT-3" onClick={this.props.onMenuClick} />
    </List>
  </Collapse>
</List>
Epochal answered 19/11, 2018 at 9:24 Comment(0)
K
6

Simple submenu component compatible with React Admin v4 https://marmelab.com/react-admin/Menu.html

import * as React from 'react';
import { useState } from 'react';
import PropTypes from 'prop-types';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import { List, ListItem, ListItemText, Collapse } from '@mui/material';
import { useTranslate, useSidebarState } from 'react-admin';


export const SubMenu = (props: SubMenuProps) => {
    const { isDropdownOpen = false, primaryText, leftIcon, children, ...rest } = props;
    const translate = useTranslate();
    const [open] = useSidebarState();
    const [isOpen, setIsOpen] = useState(isDropdownOpen);

    const handleToggle = () => {
        setIsOpen(!isOpen);
    };

    return (
        <React.Fragment>
            <ListItem
                dense
                button
                onClick={handleToggle}
                sx={{
                    paddingLeft: '1rem',
                    color: 'rgba(0, 0, 0, 0.54)',
                }}
            >
                {isOpen ? <ExpandMoreIcon /> : leftIcon}
                <ListItemText
                    inset
                    disableTypography
                    primary={translate(primaryText)}
                    sx={{
                        paddingLeft: 2,
                        fontSize: '1rem',
                        color: 'rgba(0, 0, 0, 0.6)',
                    }}
                />
            </ListItem>
            <Collapse in={isOpen} timeout="auto" unmountOnExit>
                <List
                    component="div"
                    disablePadding
                    sx={open ? {
                        paddingLeft: '25px',
                        transition: 'padding-left 195ms cubic-bezier(0.4, 0, 0.6, 1) 0ms',
                    } : {
                        paddingLeft: 0,
                        transition: 'padding-left 195ms cubic-bezier(0.4, 0, 0.6, 1) 0ms',
                    }}
                >
                    {children}
                </List>
            </Collapse>
        </React.Fragment>
    )
}

export type SubMenuProps =  {
    children?: React.ReactNode;
    isDropdownOpen?: boolean;
    leftIcon?: React.ReactElement;
    primaryText?: string;
};

export default SubMenu;

Usage:

import * as React from 'react';
import { Menu } from 'react-admin';

import BookIcon from '@mui/icons-material/Book';
import PeopleIcon from '@mui/icons-material/People';
import LabelIcon from '@mui/icons-material/Label';
import SubMenu from './SubMenu';

export const MainMenu = () => (
    <Menu>
        <Menu.DashboardItem />
        <SubMenu primaryText="CMS" leftIcon={<BookIcon />}>
            <Menu.Item to="/admin/pages" primaryText="Pages" leftIcon={<BookIcon />}/>
            <Menu.Item to="/admin/articles" primaryText="Articles" leftIcon={<PeopleIcon />}/>
        </SubMenu>
        <Menu.Item to="/custom-route" primaryText="Miscellaneous" leftIcon={<LabelIcon />}/>
    </Menu>
);
Khalilahkhalin answered 28/7, 2022 at 13:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.