<ContainerLayout>

This Enterprise Edition component offers an alternative to react-admin’s <Layout> for applications with a limited number of resources. It displays the content in a centered container, has no sidebar, and uses the top bar for navigation.

Container layout

<ContainerLayout> is part of the ra-navigation package.

Usage

Set <ContainerLayout> as the <Admin layout> value:

import { Admin, Resource } from 'react-admin';
import { ContainerLayout } from '@react-admin/ra-navigation';

export const App = () => (
    <Admin dataProvider={dataProvider} layout={ContainerLayout}>
        <Resource name="songs" list={SongList} />
        <Resource name="artists" list={ArtistList} />
    </Admin>
);

Props

<ContainerLayout> accepts the following props, all optional:

  • appBar: The component to use to render the top AppBar. Defaults to <Header>
  • fixed: Whether the content <Container> should be fixed. Defaults to false.
  • maxWidth: The maximum width of the content <Container>. Defaults to md.
  • menu: The menu component to use. Defaults to <HorizontalMenu>.
  • sx: The style of the layout, and the underlying component.
  • toolbar: The buttons to render on the top right of the toolbar.
  • userMenu: The component to use to render the user menu. Defaults to <UserMenu>.

appBar

If you want to use a different color for the AppBar, or to make it sticky, pass a custom appBar element based on <Header>, which is a simple wrapper around Material UI’s <AppBar> component.

import { ContainerLayout, Header } from '@react-admin/ra-navigation';

const myAppBar = <Header color="primary" position="sticky" />;

const MyLayout = ({ children }) => (
    <ContainerLayout appBar={myAppBar}>
        {children}
    </ContainerLayout>
);

fixed

If you prefer to design for a fixed set of sizes instead of trying to accommodate a fully fluid viewport, you can set the fixed prop. The max-width matches the min-width of the current breakpoint.

import { ContainerLayout } from '@react-admin/ra-navigation';

const MyLayout = ({ children }) => (
    <ContainerLayout fixed>
        {children}
    </ContainerLayout>
);

maxWidth

This prop allows to set the maximum width of the content <Container>. It accepts a string, one of xs, sm, md, lg, xl, or false to remove side margins and occupy the full width of the screen.

import { ContainerLayout } from '@react-admin/ra-navigation';

const MyLayout = ({ children }) => (
    <ContainerLayout maxWidth="md">
        {children}
    </ContainerLayout>
);

By default, <ContainerLayout> renders one menu item per resource in the admin. To reorder the menu, omit resources, or add custom pages, pass a custom menu element to the menu prop. This element should be a <HorizontalMenu> component with <HorizontalMenu.Item> children. Each child should have a value corresponding to the application location of the target, and can have a to prop corresponding to the target location if different from the app location.

import {
    Admin,
    Resource,
    CustomRoutes,
    ListGuesser,
    EditGuesser,
} from 'react-admin';
import { Route } from 'react-router-dom';
import {
    ContainerLayout,
    HorizontalMenu,
    useDefineAppLocation,
} from '@react-admin/ra-navigation';

const Menu = () => (
    <HorizontalMenu>
        <HorizontalMenu.Item label="Dashboard" to="/" value="" />
        <HorizontalMenu.Item label="Songs" to="/songs" value="songs" />
        <HorizontalMenu.Item label="Artists" to="/artists" value="artists" />
        <HorizontalMenu.Item label="Custom" to="/custom" value="custom" />
    </HorizontalMenu>
);

const MyLayout = ({ children }) => (
    <ContainerLayout menu={<Menu />}>
        {children}
    </ContainerLayout>
);

const CustomPage = () => {
    useDefineAppLocation('custom');
    return <h1>Custom page</h1>;
};

const Dashboard = () => <h1>Dashboard</h1>;
const CustomPage = () => <h1>Custom page</h1>;

export const App = () => (
    <Admin dataProvider={dataProvider} layout={MyLayout} dashboard={Dashboard}>
        <Resource name="songs" list={ListGuesser} edit={EditGuesser} />
        <Resource name="artists" list={ListGuesser} edit={EditGuesser} />
        <CustomRoutes>
            <Route path="custom" element={<CustomPage />} />
        </CustomRoutes>
    </Admin>
);

sx

The sx prop allows to customize the style of the layout, and the underlying component. It accepts a Material UI sx prop.

import { ContainerLayout } from '@react-admin/ra-navigation';

const MyLayout = ({ children }) => (
    <ContainerLayout
        sx={{
            '& .MuiToolbar-root': { padding: 0 },
        }}
    >
        {children}
    </ContainerLayout>
);

toolbar

The toolbar prop allows to add buttons to the top right of the toolbar. It accepts an element.

import { LocalesMenuButton, LoadingIndicator } from 'react-admin';
import { ContainerLayout } from '@react-admin/ra-navigation';

const toolbar = (
    <>
        <LocalesMenuButton />
        <LoadingIndicator />
    </>
);
const MyLayout = ({ children }) => (
    <ContainerLayout toolbar={toolbar}>
        {children}
    </ContainerLayout>
);

userMenu

By default, the <ContainerLayout> shows a user menu with a single item (logout) when the application has an authProvider. You can customize the user menu by passing a custom element to the userMenu prop.

import * as React from 'react';
import { Logout, UserMenu, useUserMenu } from 'react-admin';
import { MenuList, MenuItem, ListItemIcon, ListItemText } from '@mui/material';
import SettingsIcon from '@mui/icons-material/Settings';
import { ContainerLayout } from '@react-admin/ra-navigation';

// It's important to pass the ref to allow Material UI to manage the keyboard navigation
const ConfigurationMenu = React.forwardRef((props, ref) => {
    const { onClose } = useUserMenu();
    return (
        <MenuItem
            ref={ref}
            // It's important to pass the props to allow Material UI to manage the keyboard navigation
            {...props}
            to="/configuration"
            onClick={onClose}
        >
            <ListItemIcon>
                <SettingsIcon fontSize="small" />
            </ListItemIcon>
            <ListItemText>Configuration</ListItemText>
        </MenuItem>
    );
});

const CustomUserMenu = () => (
    <UserMenu>
        <MenuList>
            <ConfigurationMenu />
            <Logout />
        </MenuList>
    </UserMenu>
);

export const MyLayout = ({ children }) => (
    <ContainerLayout userMenu={<CustomUserMenu />}>
        {children}
    </ContainerLayout>
);

<HorizontalMenu>

This component renders a horizontal menu, to be used in the AppBar of the <ContainerLayout>.

Container layout

This menu automatically detects and highlights the current location.

Usage

Create a menu component based on <HorizontalMenu> and <HorizontalMenu.Item> children. Each child should have a value corresponding to the application location of the target, and can have a to prop corresponding to the target location if different from the app location.

import { HorizontalMenu } from '@react-admin/ra-navigation';

export const Menu = () => (
    <HorizontalMenu>
        <HorizontalMenu.Item label="Dashboard" to="/" value="" />
        <HorizontalMenu.Item label="Songs" to="/songs" value="songs" />
        <HorizontalMenu.Item label="Artists" to="/artists" value="artists" />
    </HorizontalMenu>
);

Then pass this custom menu to the <ContainerLayout menu> prop:

import { Admin, Resource } from 'react-admin';
import { ContainerLayout } from '@react-admin/ra-navigation';

import { Menu } from './Menu';

const MyLayout = ({ children }) => (
    <ContainerLayout menu={<Menu />}>
        {children}
    </ContainerLayout>
);

const App = () => (
    <Admin dataProvider={dataProvider} layout={MyLayout}>
        ...
    </Admin>
);