<Menu>
This component renders a menu, with one menu item per resource by default. You can also set menu items by hand.
Usage
Create a custom menu component using react-admin’s <Menu>
as the root component, and a combination of <Menu.DashboardItem>
, <Menu.ResourceItems>
, <Menu.ResourceItem>
, and <Menu.Item>
as children:
// in src/MyMenu.js
import { Menu } from 'react-admin';
import LabelIcon from '@mui/icons-material/Label';
export const MyMenu = () => (
<Menu>
<Menu.DashboardItem />
<Menu.ResourceItem name="posts" />
<Menu.ResourceItem name="comments" />
<Menu.ResourceItem name="users" />
<Menu.Item to="/custom-route" primaryText="Miscellaneous" leftIcon={<LabelIcon />} />
</Menu>
);
Then, create a custom layout using the <Layout>
component and pass your custom menu component to it:
// in src/MyLayout.js
import { Layout } from 'react-admin';
import { MyMenu } from './MyMenu';
export const MyLayout = ({ children }) => (
<Layout menu={MyMenu}>
{children}
</Layout>
);
Finally, pass this custom layout to the <Admin>
component:
// in src/App.js
import { MyLayout } from './MyLayout';
const App = () => (
<Admin layout={MyLayout} dataProvider={...}>
// ...
</Admin>
);
Tip: <Menu.DashboardItem>
is a shortcut for <DashboardMenuItem>
, and <Menu.Item>
is a shortcut for <MenuItemLink>
.
Props
Prop | Required | Type | Default | Description |
---|---|---|---|---|
children |
Optional | ReactNode |
- | The Menu Item Links to be rendered. If not provided, defaults to the Resource names. |
sx |
Optional | SxProps |
- | Style overrides, powered by MUI System |
Additional props are passed down to the root component (the Material UI <MenuList>
component)
children
<Menu>
without children renders one menu item per resource, in the same order as they are declared in <Admin>
, using the <Resource icon>
prop as menu icon. The menu target is the list
route of the resource. If you define a <Admin dashboard>
component, react-admin adds a dashboard menu item at the top of the menu.
So the following example of <Menu>
used without children:
import { Admin, Resource, Layout, Menu } from 'react-admin';
import BookIcon from '@mui/icons-material/Book';
import ChatBubbleIcon from '@mui/icons-material/ChatBubble';
import PeopleIcon from '@mui/icons-material/People';
import { dataProvider } from './dataProvider';
const MyMenu = () => <Menu />;
const MyLayout = ({ children }) => (
<Layout menu={MyMenu}>
{children}
</Layout>
);
const App = () => (
<Admin dataProvider={dataProvider} layout={MyLayout} dashboard={MyDashboard}>
<Resource name="posts" list={PostList} icon={BookIcon} />
<Resource name="comments" list={CommentList} icon={ChatBubbleIcon} />
<Resource name="tags" list={TagList} />
<Resource name="users" list={UserList} icon={PeopleIcon} />
</Admin>
);
Renders the following menu:
If you pass children to <Menu>
, they will override the default menu items. The children should be a combination of:
<Menu.DashboardItem>
to add a menu item for the dashboard,<Menu.ResourceItems>
to add menu items for the list views of all resources,<Menu.ResourceItem>
to add menu items for the list view of one resource,<Menu.Item>
to add custom menu items.
<Menu>
will render its children in the order they are declared.
So the following example of <Menu>
used with children:
// in src/MyMenu.js
import { Menu } from 'react-admin';
import LabelIcon from '@mui/icons-material/Label';
export const MyMenu = () => (
<Menu>
<Menu.DashboardItem />
<Menu.ResourceItem name="posts" />
<Menu.ResourceItem name="comments" />
<Menu.ResourceItem name="users" />
<Menu.Item to="/custom-route" primaryText="Miscellaneous" leftIcon={<LabelIcon />} />
</Menu>
);
Renders the following menu:
Check the <Menu.Item>
section for more information.
sx
: CSS API
Pass an sx
prop to customize the style of the main component and the underlying elements.
export const MyMenu = () => (
<Menu sx={{
marginTop: 0,
'&.RaMenu-closed': {
opacity: 0.8,
},
}} />
);
This property accepts the following subclasses:
Rule name | Description |
---|---|
&.RaMenu-open |
Applied the menu when it’s open |
&.RaMenu-closed |
Applied to the menu when it’s closed |
To override the style of <Menu>
using the application-wide style overrides, use the RaMenu
key.
<Menu.Item>
The <Menu.Item>
component displays a menu item with a label and an icon - or only the icon with a tooltip when the sidebar is minimized. It also handles the automatic closing of the menu on tap on mobile.
// in src/MyMenu.js
import { Menu } from 'react-admin';
export const MyMenu = () => (
<Menu>
...
<Menu.Item to="/custom-route" primaryText="Miscellaneous" />
</Menu>
);
The primaryText
prop accepts a string, that react-admin passes through the translation utility. Alternately, you can set the menu item content using the children
, e.g. to display a badge on top of the menu item:
import Badge from '@mui/material/Badge';
import { Menu } from 'react-admin';
export const MyMenu = () => (
<Menu>
...
<Menu.Item to="/custom-route" primaryText="Notifications">
<Badge badgeContent={4} color="primary">
Notifications
</Badge>
</Menu.Item>
</Menu>
);
Note that if you use the children
prop, you’ll have to translate the menu item content yourself using useTranslate
. You’ll also need to provide a primaryText
either way, because it will be rendered in the tooltip when the side menu is collapsed.
The letfIcon
prop allows setting the menu left icon.
// in src/MyMenu.js
import { Menu } from 'react-admin';
import LabelIcon from '@mui/icons-material/Label';
export const MyMenu = () => (
<Menu>
...
<Menu.Item
to="/custom-route"
primaryText="Miscellaneous"
leftIcon={<LabelIcon />}
/>
</Menu>
);
Additional props are passed down to the underling Material UI <MenuItem>
component.
Tip: The <Menu.Item>
component makes use of the React Router NavLink component, hence allowing to customize the active menu style. For instance, here is how to use a custom theme to show a left border for the active menu:
export const theme = {
palette: {
// ...
},
components: {
// ...
RaMenuItemLink: {
styleOverrides: {
root: {
// invisible border when not active, to avoid position flashs
borderLeft: '3px solid transparent',
'&.RaMenuItemLink-active': {
borderLeft: '10px solid #4f3cc9',
},
'& .RaMenuItemLink-icon': {
color: '#EFC44F',
},
},
},
},
},
};
<Menu.DashboardItem>
The <Menu.DashboardItem>
component displays a menu item for the dashboard.
// in src/MyMenu.js
import { Menu } from 'react-admin';
export const MyMenu = () => (
<Menu>
<Menu.DashboardItem />
...
</Menu>
);
Clicking on the dashboard menu item leads to the /
route and renders the component defined in the <Admin dashboard>
prop.
You can customize this menu item label by using the primaryText
or children
prop (see the <Menu.Item>
section for more information).
<Menu.ResourceItems>
The <Menu.ResourceItems>
component displays one menu item for each resource, using the resource label and icon defined in the <Resource>
components, and in the order in which they were declared in <Admin>
.
import { Menu } from 'react-admin';
export const MyMenu = () => (
<Menu>
...
<Menu.ResourceItems />
...
</Menu>
);
So with the following <Admin>
component:
const App = () => (
<Admin dataProvider={dataProvider} layout={MyLayout} dashboard={MyDashboard}>
<Resource name="posts" list={PostList} icon={BookIcon} />
<Resource name="comments" list={CommentList} icon={ChatBubbleIcon} />
<Resource name="tags" list={TagList} />
<Resource name="users" list={UserList} icon={PeopleIcon} />
</Admin>
);
<Menu.ResourceItems>
renders the following menu items:
<Menu.ResourceItem name="posts" />
<Menu.ResourceItem name="comments" />
<Menu.ResourceItem name="tags" />
<Menu.ResourceItem name="users" />
<Menu.ResourceItem>
The <Menu.ResourceItem>
component displays a menu item for the list page of a resource, based on the resource name.
import { Menu } from 'react-admin';
export const MyMenu = () => (
<Menu>
<Menu.ResourceItem name="posts" />
<Menu.ResourceItem name="comments" />
<Menu.ResourceItem name="tags" />
<Menu.ResourceItem name="users" />
</Menu>
);
<Menu.ResourceItem>
renders a menu item for a resource based on its name, using the resource label and icon defined in the corresponding <Resource>
component.
So using the following resource definition:
<Resource name="posts" list={PostList} icon={BookIcon} />
the following code:
<Menu.ResourceItem name="posts" />
translates to:
<Menu.Item to="/posts" primaryText="Posts" leftIcon={<BookIcon />} />
You can customize this menu item label by using the primaryText
or children
prop (see the <Menu.Item>
section for more information).
Creating Menu Items For Resources
If you want to reorder the default menu, create a new Menu and use <Menu.ResourceItem>
components as children.
// in src/MyMenu.js
import { Menu } from 'react-admin';
export const MyMenu = () => (
<Menu>
<Menu.ResourceItem name="posts" />
<Menu.ResourceItem name="comments" />
<Menu.ResourceItem name="tags" />
<Menu.ResourceItem name="users" />
</Menu>
);
Passing children
to <Menu>
actually replaces the default menu items. If you want to render a custom menu item in addition to the default resource menu items, use the <Menu.ResourceItems>
component to render one menu item per resource.
// in src/MyMenu.js
import { Menu } from 'react-admin';
import LabelIcon from '@mui/icons-material/Label';
export const MyMenu = () => (
<Menu>
<Menu.ResourceItems />
<Menu.Item to="/custom-route" primaryText="Miscellaneous" leftIcon={<LabelIcon />} />
</Menu>
);
Adding A Menu To A Filtered List
As the filter values are taken from the URL, you can link to a pre-filtered list by setting the filter
query parameter.
For instance, to include a menu to a list of published posts:
<Menu.Item
to={{
pathname: '/posts',
search: `filter=${JSON.stringify({ is_published: true })}`,
}}
primaryText="Published Posts"
leftIcon={<BookIcon />}
/>
Resetting Filters On Menu Click
By default, a click on <Menu.Item >
for a list page opens the list with the same filters as they were applied the last time the user saw them. This is usually the expected behavior, but your users may prefer that clicking on a menu item resets the list filters.
Just use an empty filter
query parameter to force empty filters:
<Menu.Item
to="/posts?filter=%7B%7D" // %7B%7D is JSON.stringify({})
primaryText="Posts"
leftIcon={<BookIcon />}
/>
Nested Menu Items
If you need to display a menu item with a submenu, you should use the <MultiLevelMenu>
component instead of <Menu>
.
Live Updates
You can display a badge on the menu item to indicate that new data is available. Use the <MenuLive>
component instead of <Menu>
to enable this feature.
import type { ReactNode } from 'react';
import { Admin, Layout, Resource } from 'react-admin';
import { MenuLive } from '@react-admin/ra-realtime';
import { PostList, PostShow, PostEdit, realTimeDataProvider } from '.';
const CustomLayout = ({ children}: { children: ReactNode }) => (
<Layout menu={MenuLive}>
{children}
</Layout>
);
const MyReactAdmin = () => (
<Admin dataProvider={realTimeDataProvider} layout={CustomLayout}>
<Resource name="posts" list={PostList} show={PostShow} edit={PostEdit} />
</Admin>
);