CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-react-admin

A frontend Framework for building admin applications on top of REST services, using ES6, React and Material UI

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

ui-components.mddocs/

UI Components

React Admin provides a rich set of UI components including buttons, notifications, theming capabilities, and utility components. Built on Material-UI, these components ensure consistent design and excellent user experience across admin interfaces.

Button Components

Button

Base button component with React Admin styling and functionality.

import { Button } from 'react-admin';

interface ButtonProps {
  label?: string;
  children?: React.ReactNode;
  color?: 'inherit' | 'primary' | 'secondary' | 'success' | 'error' | 'info' | 'warning';
  disabled?: boolean;
  size?: 'small' | 'medium' | 'large';
  variant?: 'text' | 'outlined' | 'contained';
  startIcon?: React.ReactNode;
  endIcon?: React.ReactNode;
  onClick?: (event: React.MouseEvent) => void;
  href?: string;
  to?: string;
  className?: string;
  sx?: any;
}

const Button: React.FC<ButtonProps>;

SaveButton

Button for saving forms with loading states and validation.

import { SaveButton } from 'react-admin';

interface SaveButtonProps extends ButtonProps {
  alwaysEnable?: boolean;
  icon?: React.ReactElement;
  invalid?: boolean;
  mutationOptions?: UseMutationOptions;
  pristine?: boolean;
  saving?: boolean;
  submitOnEnter?: boolean;
  transform?: TransformData;
  type?: 'button' | 'submit';
}

const SaveButton: React.FC<SaveButtonProps>;

DeleteButton & DeleteWithConfirmButton

Buttons for deleting records with confirmation dialogs.

import { DeleteButton, DeleteWithConfirmButton } from 'react-admin';

interface DeleteButtonProps extends ButtonProps {
  confirmTitle?: string;
  confirmContent?: string | React.ReactElement;
  icon?: React.ReactElement;
  mutationMode?: 'pessimistic' | 'optimistic' | 'undoable';
  mutationOptions?: UseMutationOptions;
  record?: RaRecord;
  redirect?: string | false | RedirectToFunction;
  resource?: string;
  translateOptions?: any;
}

const DeleteButton: React.FC<DeleteButtonProps>;
const DeleteWithConfirmButton: React.FC<DeleteButtonProps>;

Navigation Buttons

Buttons for navigating between views.

import { 
  CreateButton, 
  EditButton, 
  ShowButton, 
  ListButton,
  CloneButton 
} from 'react-admin';

interface CreateButtonProps extends ButtonProps {
  icon?: React.ReactElement;
  record?: RaRecord;
  resource?: string;
  scrollToTop?: boolean;
}

interface EditButtonProps extends ButtonProps {
  icon?: React.ReactElement;
  record?: RaRecord;
  resource?: string;
  scrollToTop?: boolean;
}

interface ShowButtonProps extends EditButtonProps {}
interface ListButtonProps extends EditButtonProps {}
interface CloneButtonProps extends EditButtonProps {}

const CreateButton: React.FC<CreateButtonProps>;
const EditButton: React.FC<EditButtonProps>;
const ShowButton: React.FC<ShowButtonProps>;
const ListButton: React.FC<ListButtonProps>;
const CloneButton: React.FC<CloneButtonProps>;

Action Button Examples

import { 
  TopToolbar, 
  CreateButton, 
  ExportButton, 
  EditButton, 
  DeleteButton,
  ShowButton,
  SaveButton
} from 'react-admin';

// List actions
const PostListActions = () => (
  <TopToolbar>
    <CreateButton />
    <ExportButton />
  </TopToolbar>
);

// Show actions
const PostShowActions = () => (
  <TopToolbar>
    <EditButton />
    <DeleteButton />
  </TopToolbar>
);

// Custom button with navigation
const CustomButton = () => {
  const redirect = useRedirect();
  
  return (
    <Button
      label="Custom Action"
      onClick={() => redirect('list', 'posts')}
      color="primary"
      variant="contained"
    />
  );
};

Bulk Action Buttons

Buttons for performing actions on multiple selected records.

import { 
  BulkDeleteButton,
  BulkDeleteWithConfirmButton,
  BulkExportButton,
  BulkUpdateButton
} from 'react-admin';

interface BulkActionProps {
  label?: string;
  icon?: React.ReactElement;
  selectedIds?: Identifier[];
  className?: string;
  sx?: any;
}

interface BulkDeleteButtonProps extends BulkActionProps {
  mutationMode?: 'pessimistic' | 'optimistic' | 'undoable';
  mutationOptions?: UseMutationOptions;
}

interface BulkUpdateButtonProps extends BulkActionProps {
  data: any;
  mutationMode?: 'pessimistic' | 'optimistic' | 'undoable';
  mutationOptions?: UseMutationOptions;
}

const BulkDeleteButton: React.FC<BulkDeleteButtonProps>;
const BulkDeleteWithConfirmButton: React.FC<BulkDeleteButtonProps>;
const BulkExportButton: React.FC<BulkActionProps>;
const BulkUpdateButton: React.FC<BulkUpdateButtonProps>;

Bulk Actions Example

import { BulkDeleteButton, BulkUpdateButton, BulkExportButton } from 'react-admin';

const PostBulkActions = () => (
  <>
    <BulkUpdateButton 
      label="Publish Selected"
      data={{ status: 'published' }}
      mutationMode="optimistic"
    />
    <BulkExportButton />
    <BulkDeleteButton mutationMode="pessimistic" />
  </>
);

const PostList = () => (
  <List>
    <Datagrid bulkActionButtons={<PostBulkActions />}>
      <TextField source="title" />
      <SelectField source="status" choices={statusChoices} />
    </Datagrid>
  </List>
);

Notification System

useNotify Hook

Hook for displaying notifications to users.

import { useNotify } from 'react-admin';

type NotificationType = 'info' | 'success' | 'warning' | 'error';

interface NotifyOptions {
  type?: NotificationType;
  messageArgs?: any;
  undoable?: boolean;
  autoHideDuration?: number;
  multiline?: boolean;
  anchorOrigin?: {
    vertical: 'top' | 'bottom';
    horizontal: 'left' | 'center' | 'right';
  };
}

type NotifyFunction = (
  message: string, 
  options?: NotifyOptions
) => void;

const useNotify: () => NotifyFunction;

Notification Examples

import { useNotify } from 'react-admin';

const MyComponent = () => {
  const notify = useNotify();
  
  const handleSuccess = () => {
    notify('Record saved successfully', { type: 'success' });
  };
  
  const handleError = () => {
    notify('An error occurred', { 
      type: 'error',
      autoHideDuration: 6000 
    });
  };
  
  const handleWarning = () => {
    notify('This action cannot be undone', { 
      type: 'warning',
      multiline: true 
    });
  };
  
  const handleUndoable = () => {
    notify('Post deleted', { 
      type: 'info',
      undoable: true 
    });
  };
  
  return (
    <div>
      <button onClick={handleSuccess}>Success</button>
      <button onClick={handleError}>Error</button>
      <button onClick={handleWarning}>Warning</button>
      <button onClick={handleUndoable}>Undoable</button>
    </div>
  );
};

Notification Component

Component for displaying notification messages.

import { Notification } from 'react-admin';

interface NotificationProps {
  className?: string;
  sx?: any;
}

const Notification: React.FC<NotificationProps>;

Theming System

Theme Provider and Hooks

React Admin uses Material-UI's theming system with additional customizations.

import { useTheme } from 'react-admin';

const useTheme: () => [Theme, (theme: Theme) => void];

interface Theme {
  palette: {
    mode: 'light' | 'dark';
    primary: PaletteColor;
    secondary: PaletteColor;
    error: PaletteColor;
    warning: PaletteColor;
    info: PaletteColor;
    success: PaletteColor;
    background: {
      default: string;
      paper: string;
    };
    text: {
      primary: string;
      secondary: string;
    };
  };
  typography: Typography;
  spacing: (factor: number) => number;
  breakpoints: Breakpoints;
  components?: ComponentsOverrides;
}

Predefined Themes

React Admin includes several built-in themes.

import { 
  defaultTheme,
  nanoTheme, 
  radiantTheme,
  houseTheme 
} from 'react-admin';

const defaultTheme: Theme;
const nanoTheme: Theme;
const radiantTheme: Theme;
const houseTheme: Theme;

Theme Usage Examples

import { Admin, defaultTheme, radiantTheme } from 'react-admin';
import { createTheme } from '@mui/material/styles';

// Using predefined themes
const App = () => (
  <Admin theme={radiantTheme} dataProvider={dataProvider}>
    <Resource name="posts" list={PostList} />
  </Admin>
);

// Custom theme
const customTheme = createTheme({
  palette: {
    mode: 'dark',
    primary: {
      main: '#1976d2',
    },
    secondary: {
      main: '#dc004e',
    },
    background: {
      default: '#121212',
      paper: '#1e1e1e',
    },
  },
  typography: {
    fontFamily: 'Inter, sans-serif',
  },
  components: {
    MuiButton: {
      styleOverrides: {
        root: {
          borderRadius: 8,
        },
      },
    },
  },
});

const AppWithCustomTheme = () => (
  <Admin theme={customTheme} dataProvider={dataProvider}>
    <Resource name="posts" list={PostList} />
  </Admin>
);

ToggleThemeButton

Button for switching between light and dark themes.

import { ToggleThemeButton } from 'react-admin';

interface ToggleThemeButtonProps {
  className?: string;
  sx?: any;
}

const ToggleThemeButton: React.FC<ToggleThemeButtonProps>;

ThemeProvider

Provider for theme context in custom layouts.

import { ThemeProvider } from 'react-admin';

interface ThemeProviderProps {
  theme?: Theme;
  children: React.ReactNode;
}

const ThemeProvider: React.FC<ThemeProviderProps>;

Utility Components

Confirm Dialog

Component for confirmation dialogs.

import { Confirm } from 'react-admin';

interface ConfirmProps {
  isOpen: boolean;
  title: string;
  content?: string | React.ReactElement;
  onConfirm: () => void;
  onClose: () => void;
  confirmColor?: 'primary' | 'secondary' | 'error' | 'warning' | 'info' | 'success';
  ConfirmIcon?: React.ComponentType;
  CancelIcon?: React.ComponentType;
  className?: string;
  sx?: any;
}

const Confirm: React.FC<ConfirmProps>;

LinearProgress

Progress indicator component.

import { LinearProgress } from 'react-admin';

interface LinearProgressProps {
  className?: string;
  sx?: any;
}

const LinearProgress: React.FC<LinearProgressProps>;

Loading Components

Various loading state indicators.

import { Loading, LoadingIndicator, LoadingPage } from 'react-admin';

const Loading: React.FC<{ className?: string; sx?: any }>;
const LoadingIndicator: React.FC<{ className?: string; sx?: any }>;
const LoadingPage: React.FC<{ className?: string; sx?: any }>;

Link Component

Enhanced link component with React Router integration.

import { Link } from 'react-admin';

interface LinkProps {
  to: string;
  children: React.ReactNode;
  className?: string;
  sx?: any;
  color?: 'inherit' | 'primary' | 'secondary' | 'textPrimary' | 'textSecondary' | 'error';
  underline?: 'none' | 'hover' | 'always';
  variant?: string;
}

const Link: React.FC<LinkProps>;

Icon and Visual Components

RefreshIconButton

Icon button for refreshing data.

import { RefreshIconButton } from 'react-admin';

const RefreshIconButton: React.FC<{ className?: string; sx?: any }>;

Skip Navigation Button

Accessibility component for keyboard navigation.

import { SkipNavigationButton } from 'react-admin';

const SkipNavigationButton: React.FC<{ className?: string; sx?: any }>;

LocalesMenuButton

Button for language selection.

import { LocalesMenuButton } from 'react-admin';

interface LocalesMenuButtonProps {
  className?: string;
  sx?: any;
  languages?: { locale: string; name: string }[];
}

const LocalesMenuButton: React.FC<LocalesMenuButtonProps>;

Advanced UI Examples

Custom Confirm Dialog

import { useState } from 'react';
import { Confirm, useDelete, useNotify, useRedirect } from 'react-admin';

const CustomDeleteButton = ({ record }) => {
  const [open, setOpen] = useState(false);
  const [deleteOne, { isLoading }] = useDelete();
  const notify = useNotify();
  const redirect = useRedirect();
  
  const handleDelete = () => {
    deleteOne('posts', { id: record.id, previousData: record })
      .then(() => {
        notify('Post deleted successfully');
        redirect('list', 'posts');
      })
      .catch(() => {
        notify('Error deleting post', { type: 'error' });
      });
    setOpen(false);
  };
  
  return (
    <>
      <Button 
        label="Delete" 
        onClick={() => setOpen(true)}
        color="error"
      />
      <Confirm
        isOpen={open}
        title="Delete Post"
        content="Are you sure you want to delete this post? This action cannot be undone."
        onConfirm={handleDelete}
        onClose={() => setOpen(false)}
        confirmColor="error"
      />
    </>
  );
};

Status Indicator Component

import { Chip } from '@mui/material';
import { useTheme } from '@mui/material/styles';

const StatusIndicator = ({ status }) => {
  const theme = useTheme();
  
  const getStatusColor = (status) => {
    switch (status) {
      case 'published': return theme.palette.success.main;
      case 'draft': return theme.palette.warning.main;
      case 'archived': return theme.palette.text.disabled;
      default: return theme.palette.text.secondary;
    }
  };
  
  return (
    <Chip
      label={status.toUpperCase()}
      size="small"
      sx={{
        backgroundColor: getStatusColor(status),
        color: 'white',
        fontWeight: 'bold'
      }}
    />
  );
};

Custom Toolbar with Actions

import { Toolbar, SaveButton, Button } from 'react-admin';
import { useFormContext } from 'react-hook-form';
import { useNotify } from 'react-admin';

const CustomFormToolbar = () => {
  const { reset, getValues } = useFormContext();
  const notify = useNotify();
  
  const handleSaveAndContinue = () => {
    // Custom save logic
    notify('Saved and continuing...');
  };
  
  const handleReset = () => {
    reset();
    notify('Form reset');
  };
  
  return (
    <Toolbar>
      <SaveButton />
      <Button 
        label="Save & Continue"
        onClick={handleSaveAndContinue}
        variant="outlined"
        sx={{ marginLeft: 1 }}
      />
      <Button 
        label="Reset"
        onClick={handleReset}
        variant="text"
        sx={{ marginLeft: 1 }}
      />
    </Toolbar>
  );
};

Responsive Button Group

import { useMediaQuery, useTheme } from '@mui/material';
import { TopToolbar, CreateButton, ExportButton, Button } from 'react-admin';

const ResponsiveActions = () => {
  const theme = useTheme();
  const isSmall = useMediaQuery(theme.breakpoints.down('sm'));
  
  return (
    <TopToolbar>
      <CreateButton />
      {!isSmall && <ExportButton />}
      {!isSmall && (
        <Button label="Advanced" onClick={() => {}} />
      )}
    </TopToolbar>
  );
};

Theme Switcher Component

import { useState } from 'react';
import { ToggleThemeButton, useTheme } from 'react-admin';
import { Menu, MenuItem, IconButton } from '@mui/material';
import { Palette as PaletteIcon } from '@mui/icons-material';

const ThemeSwitcher = () => {
  const [theme, setTheme] = useTheme();
  const [anchorEl, setAnchorEl] = useState(null);
  
  const themes = [
    { name: 'Default', value: defaultTheme },
    { name: 'Nano', value: nanoTheme },
    { name: 'Radiant', value: radiantTheme },
    { name: 'House', value: houseTheme }
  ];
  
  const handleClose = () => setAnchorEl(null);
  
  const handleThemeSelect = (selectedTheme) => {
    setTheme(selectedTheme);
    handleClose();
  };
  
  return (
    <>
      <IconButton onClick={(e) => setAnchorEl(e.currentTarget)}>
        <PaletteIcon />
      </IconButton>
      <Menu
        anchorEl={anchorEl}
        open={Boolean(anchorEl)}
        onClose={handleClose}
      >
        {themes.map((themeOption) => (
          <MenuItem
            key={themeOption.name}
            onClick={() => handleThemeSelect(themeOption.value)}
          >
            {themeOption.name}
          </MenuItem>
        ))}
      </Menu>
    </>
  );
};

React Admin's UI component system provides a comprehensive set of building blocks for creating polished, accessible, and responsive admin interfaces with consistent design patterns and excellent user experience.

Install with Tessl CLI

npx tessl i tessl/npm-react-admin

docs

admin-core.md

advanced.md

auth.md

data-management.md

detail-views.md

forms-inputs.md

i18n.md

index.md

layout-navigation.md

lists-data-display.md

ui-components.md

tile.json