A frontend Framework for building admin applications on top of REST services, using ES6, React and Material UI
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
React Admin provides a comprehensive layout system with navigation components, application structure, and customizable UI elements. The layout system includes the app bar, sidebar navigation, menu system, and responsive design capabilities.
The main <Layout> component defines the overall application structure and shell.
import { Layout } from 'react-admin';
interface LayoutProps {
appBar?: React.ComponentType<AppBarProps>;
sidebar?: React.ComponentType<SidebarProps>;
menu?: React.ComponentType<MenuProps>;
error?: React.ComponentType;
className?: string;
sx?: any;
children: React.ReactNode;
}
const Layout: React.FC<LayoutProps>;import { Layout, CheckForApplicationUpdate } from 'react-admin';
import { MyAppBar } from './MyAppBar';
import { MySidebar } from './MySidebar';
const MyLayout = ({ children, ...props }) => (
<>
<Layout
{...props}
appBar={MyAppBar}
sidebar={MySidebar}
>
{children}
</Layout>
<CheckForApplicationUpdate />
</>
);
// Usage in Admin
<Admin layout={MyLayout} dataProvider={dataProvider}>
<Resource name="posts" list={PostList} />
</Admin>The application bar provides the top navigation area with title, user menu, and actions.
import { AppBar } from 'react-admin';
interface AppBarProps {
alwaysOn?: boolean;
className?: string;
color?: 'default' | 'inherit' | 'primary' | 'secondary' | 'transparent';
elevation?: number;
position?: 'fixed' | 'absolute' | 'sticky' | 'static' | 'relative';
title?: string | React.ReactElement;
titleComponent?: React.ComponentType;
toolbar?: React.ReactElement;
userMenu?: React.ReactElement | false;
sx?: any;
children?: React.ReactNode;
}
const AppBar: React.FC<AppBarProps>;import { AppBar, TitlePortal, RefreshIconButton, ToggleThemeButton } from 'react-admin';
import { Box, Typography } from '@mui/material';
const MyAppBar = () => (
<AppBar
sx={{
'& .RaAppBar-title': {
flex: 1,
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
overflow: 'hidden',
},
}}
>
<TitlePortal />
<Box flex="1" />
<RefreshIconButton />
<ToggleThemeButton />
</AppBar>
);The sidebar contains navigation menus and can be collapsed/expanded.
import { Sidebar } from 'react-admin';
interface SidebarProps {
children?: React.ReactNode;
className?: string;
closedSize?: number;
size?: number;
sx?: any;
}
const Sidebar: React.FC<SidebarProps>;import { Sidebar, Menu, MenuItemLink, DashboardMenuItem } from 'react-admin';
import { Card, CardContent } from '@mui/material';
import LabelIcon from '@mui/icons-material/Label';
const MySidebar = () => (
<Sidebar>
<Menu>
<DashboardMenuItem />
<MenuItemLink
to="/posts"
state={{ _scrollToTop: true }}
primaryText="Posts"
leftIcon={<LabelIcon />}
/>
<MenuItemLink
to="/users"
state={{ _scrollToTop: true }}
primaryText="Users"
leftIcon={<LabelIcon />}
/>
</Menu>
<Card sx={{ margin: 1 }}>
<CardContent>
<h4>Quick Stats</h4>
<p>Posts: 142</p>
<p>Users: 23</p>
</CardContent>
</Card>
</Sidebar>
);The main navigation menu component.
import { Menu } from 'react-admin';
interface MenuProps {
className?: string;
dense?: boolean;
hasDashboard?: boolean;
children?: React.ReactNode;
sx?: any;
}
const Menu: React.FC<MenuProps>;Individual menu item for navigation.
import { MenuItemLink } from 'react-admin';
interface MenuItemLinkProps {
to: string;
primaryText?: string;
leftIcon?: React.ReactElement;
rightIcon?: React.ReactElement;
onClick?: () => void;
sidebarIsOpen?: boolean;
dense?: boolean;
className?: string;
sx?: any;
state?: any;
}
const MenuItemLink: React.FC<MenuItemLinkProps>;Pre-configured menu item for the dashboard.
import { DashboardMenuItem } from 'react-admin';
interface DashboardMenuItemProps {
className?: string;
leftIcon?: React.ReactElement;
primaryText?: string;
sidebarIsOpen?: boolean;
sx?: any;
to?: string;
}
const DashboardMenuItem: React.FC<DashboardMenuItemProps>;Menu items for resources.
import { ResourceMenuItem, ResourceMenuItems } from 'react-admin';
interface ResourceMenuItemProps {
name: string;
className?: string;
leftIcon?: React.ReactElement;
primaryText?: string;
sidebarIsOpen?: boolean;
sx?: any;
}
const ResourceMenuItem: React.FC<ResourceMenuItemProps>;
const ResourceMenuItems: React.FC<{ className?: string; sx?: any }>;import { Menu, MenuItemLink, DashboardMenuItem, ResourceMenuItems } from 'react-admin';
import { Dashboard, People, Article, Settings, Analytics } from '@mui/icons-material';
const CustomMenu = () => (
<Menu>
<DashboardMenuItem leftIcon={<Dashboard />} />
<ResourceMenuItems />
<MenuItemLink
to="/analytics"
primaryText="Analytics"
leftIcon={<Analytics />}
/>
<MenuItemLink
to="/settings"
primaryText="Settings"
leftIcon={<Settings />}
/>
</Menu>
);Manages page titles and breadcrumbs.
import { Title } from 'react-admin';
interface TitleProps {
defaultTitle?: string;
record?: RaRecord;
title?: string | React.ReactElement;
className?: string;
sx?: any;
}
const Title: React.FC<TitleProps>;Portal for rendering dynamic titles in the AppBar.
import { TitlePortal } from 'react-admin';
const TitlePortal: React.FC;Configurable page title component.
import { PageTitleConfigurable } from 'react-admin';
const PageTitleConfigurable: React.FC<{ preferenceKey?: string }>;Manage sidebar open/closed state.
import { useSidebarState } from 'react-admin';
const useSidebarState: () => [boolean, () => void];import { useSidebarState } from 'react-admin';
import { IconButton } from '@mui/material';
import { Menu as MenuIcon } from '@mui/icons-material';
const SidebarToggle = () => {
const [sidebarIsOpen, setSidebarVisibility] = useSidebarState();
return (
<IconButton onClick={() => setSidebarVisibility()}>
<MenuIcon />
</IconButton>
);
};Access the application's base URL.
import { useBasename } from 'react-admin';
const useBasename: () => string;Create navigation paths for resources.
import { useCreatePath } from 'react-admin';
const useCreatePath: () => (params: CreatePathParams) => string;
interface CreatePathParams {
type: 'list' | 'create' | 'edit' | 'show';
resource: string;
id?: Identifier;
}Programmatic navigation and redirection.
import { useRedirect } from 'react-admin';
type RedirectFunction = (
page: string,
resource?: string,
id?: Identifier,
data?: any,
state?: any
) => void;
const useRedirect: () => RedirectFunction;import { useRedirect } from 'react-admin';
const MyComponent = () => {
const redirect = useRedirect();
const handleSuccess = (data) => {
// Redirect to show page
redirect('show', 'posts', data.id);
// Redirect to list
redirect('list', 'posts');
// Redirect to external URL
redirect('/dashboard');
};
return <button onClick={handleSuccess}>Save and View</button>;
};Container for action buttons at the top of views.
import { TopToolbar } from 'react-admin';
interface TopToolbarProps {
className?: string;
sx?: any;
children?: React.ReactNode;
}
const TopToolbar: React.FC<TopToolbarProps>;import { TopToolbar, CreateButton, ExportButton, FilterButton } from 'react-admin';
const ListActions = () => (
<TopToolbar>
<FilterButton />
<CreateButton />
<ExportButton />
</TopToolbar>
);
const PostList = () => (
<List actions={<ListActions />}>
<Datagrid>
<TextField source="title" />
</Datagrid>
</List>
);Dropdown menu for user-related actions.
import { UserMenu } from 'react-admin';
interface UserMenuProps {
children?: React.ReactNode;
className?: string;
label?: string;
icon?: React.ReactElement;
sx?: any;
}
const UserMenu: React.FC<UserMenuProps>;Hook for accessing user menu functionality.
import { useUserMenu } from 'react-admin';
const useUserMenu: () => {
isOpen: boolean;
open: (event: React.MouseEvent) => void;
close: () => void;
anchorEl: HTMLElement | null;
};import { UserMenu, MenuItemLink, Logout } from 'react-admin';
import { MenuItem } from '@mui/material';
import { Settings, Person } from '@mui/icons-material';
const CustomUserMenu = () => (
<UserMenu>
<MenuItemLink
to="/profile"
primaryText="Profile"
leftIcon={<Person />}
/>
<MenuItemLink
to="/settings"
primaryText="Settings"
leftIcon={<Settings />}
/>
<Logout />
</UserMenu>
);Loading indicator component.
import { Loading } from 'react-admin';
interface LoadingProps {
className?: string;
sx?: any;
loadingPrimary?: string;
loadingSecondary?: string;
}
const Loading: React.FC<LoadingProps>;Global loading indicator.
import { LoadingIndicator } from 'react-admin';
const LoadingIndicator: React.FC<{ className?: string; sx?: any }>;Error handling and display.
import { Error } from 'react-admin';
interface ErrorProps {
error?: any;
errorInfo?: any;
title?: string;
className?: string;
sx?: any;
}
const Error: React.FC<ErrorProps>;404 error page component.
import { NotFound } from 'react-admin';
interface NotFoundProps {
className?: string;
sx?: any;
title?: string;
}
const NotFound: React.FC<NotFoundProps>;Component for testing responsive behavior.
import { DeviceTestWrapper } from 'react-admin';
interface DeviceTestWrapperProps {
width?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
children: React.ReactNode;
}
const DeviceTestWrapper: React.FC<DeviceTestWrapperProps>;Hook for responsive design (from Material-UI).
import { useMediaQuery, useTheme } from '@mui/material';
const MyResponsiveComponent = () => {
const theme = useTheme();
const isSmall = useMediaQuery(theme.breakpoints.down('sm'));
return (
<div>
{isSmall ? (
<SimplifiedView />
) : (
<FullView />
)}
</div>
);
};import { Menu, MenuItemLink, Collapse, List, ListItem } from 'react-admin';
import { useState } from 'react';
import { ExpandLess, ExpandMore, Dashboard, Article, People } from '@mui/icons-material';
const MultiLevelMenu = () => {
const [contentOpen, setContentOpen] = useState(false);
return (
<Menu>
<DashboardMenuItem leftIcon={<Dashboard />} />
<ListItem button onClick={() => setContentOpen(!contentOpen)}>
<ListItemIcon><Article /></ListItemIcon>
<ListItemText primary="Content" />
{contentOpen ? <ExpandLess /> : <ExpandMore />}
</ListItem>
<Collapse in={contentOpen}>
<List component="div" disablePadding>
<MenuItemLink
to="/posts"
primaryText="Posts"
sx={{ pl: 4 }}
/>
<MenuItemLink
to="/pages"
primaryText="Pages"
sx={{ pl: 4 }}
/>
</List>
</Collapse>
<MenuItemLink
to="/users"
primaryText="Users"
leftIcon={<People />}
/>
</Menu>
);
};import { Layout, Breadcrumbs } from 'react-admin';
import { useLocation, useParams } from 'react-router-dom';
const BreadcrumbLayout = ({ children, ...props }) => {
const location = useLocation();
const params = useParams();
return (
<Layout {...props}>
<Breadcrumbs location={location} params={params} />
{children}
</Layout>
);
};import { Sidebar, useResourceContext, useGetOne } from 'react-admin';
import { Card, CardContent, List, ListItem } from '@mui/material';
const ContextualSidebar = () => {
const resource = useResourceContext();
if (resource === 'posts') {
return <PostSidebar />;
}
if (resource === 'users') {
return <UserSidebar />;
}
return <DefaultSidebar />;
};
const PostSidebar = () => (
<Sidebar>
<Card>
<CardContent>
<h3>Post Management</h3>
<List>
<ListItem>Drafts: 15</ListItem>
<ListItem>Published: 142</ListItem>
<ListItem>Archived: 8</ListItem>
</List>
</CardContent>
</Card>
</Sidebar>
);import { Layout, useMediaQuery } from 'react-admin';
import { useTheme } from '@mui/material';
const ResponsiveLayout = ({ children, ...props }) => {
const theme = useTheme();
const isSmall = useMediaQuery(theme.breakpoints.down('sm'));
return (
<Layout
{...props}
sidebar={isSmall ? undefined : props.sidebar}
appBar={isSmall ? MobileAppBar : props.appBar}
>
{children}
</Layout>
);
};
const MobileAppBar = ({ ...props }) => (
<AppBar {...props}>
<SidebarToggleButton />
<TitlePortal />
<UserMenu />
</AppBar>
);import { Admin, Resource, CustomRoutes } from 'react-admin';
import { Route } from 'react-router-dom';
const Dashboard = () => (
<div>
<h1>Welcome to Admin Dashboard</h1>
<div style={{ display: 'flex', gap: 20 }}>
<Card>
<CardContent>
<h3>Recent Posts</h3>
<RecentPosts />
</CardContent>
</Card>
<Card>
<CardContent>
<h3>User Activity</h3>
<UserActivity />
</CardContent>
</Card>
</div>
</div>
);
const App = () => (
<Admin
dataProvider={dataProvider}
dashboard={Dashboard}
layout={MyLayout}
>
<Resource name="posts" list={PostList} />
<Resource name="users" list={UserList} />
<CustomRoutes>
<Route path="/analytics" element={<AnalyticsPage />} />
</CustomRoutes>
</Admin>
);React Admin's layout and navigation system provides a flexible foundation for creating sophisticated admin interfaces with customizable navigation, responsive design, and comprehensive user experience features.
Install with Tessl CLI
npx tessl i tessl/npm-react-admin