0
# UI Components
1
2
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.
3
4
## Button Components
5
6
### Button
7
8
Base button component with React Admin styling and functionality.
9
10
```typescript { .api }
11
import { Button } from 'react-admin';
12
13
interface ButtonProps {
14
label?: string;
15
children?: React.ReactNode;
16
color?: 'inherit' | 'primary' | 'secondary' | 'success' | 'error' | 'info' | 'warning';
17
disabled?: boolean;
18
size?: 'small' | 'medium' | 'large';
19
variant?: 'text' | 'outlined' | 'contained';
20
startIcon?: React.ReactNode;
21
endIcon?: React.ReactNode;
22
onClick?: (event: React.MouseEvent) => void;
23
href?: string;
24
to?: string;
25
className?: string;
26
sx?: any;
27
}
28
29
const Button: React.FC<ButtonProps>;
30
```
31
32
### SaveButton
33
34
Button for saving forms with loading states and validation.
35
36
```typescript { .api }
37
import { SaveButton } from 'react-admin';
38
39
interface SaveButtonProps extends ButtonProps {
40
alwaysEnable?: boolean;
41
icon?: React.ReactElement;
42
invalid?: boolean;
43
mutationOptions?: UseMutationOptions;
44
pristine?: boolean;
45
saving?: boolean;
46
submitOnEnter?: boolean;
47
transform?: TransformData;
48
type?: 'button' | 'submit';
49
}
50
51
const SaveButton: React.FC<SaveButtonProps>;
52
```
53
54
### DeleteButton & DeleteWithConfirmButton
55
56
Buttons for deleting records with confirmation dialogs.
57
58
```typescript { .api }
59
import { DeleteButton, DeleteWithConfirmButton } from 'react-admin';
60
61
interface DeleteButtonProps extends ButtonProps {
62
confirmTitle?: string;
63
confirmContent?: string | React.ReactElement;
64
icon?: React.ReactElement;
65
mutationMode?: 'pessimistic' | 'optimistic' | 'undoable';
66
mutationOptions?: UseMutationOptions;
67
record?: RaRecord;
68
redirect?: string | false | RedirectToFunction;
69
resource?: string;
70
translateOptions?: any;
71
}
72
73
const DeleteButton: React.FC<DeleteButtonProps>;
74
const DeleteWithConfirmButton: React.FC<DeleteButtonProps>;
75
```
76
77
### Navigation Buttons
78
79
Buttons for navigating between views.
80
81
```typescript { .api }
82
import {
83
CreateButton,
84
EditButton,
85
ShowButton,
86
ListButton,
87
CloneButton
88
} from 'react-admin';
89
90
interface CreateButtonProps extends ButtonProps {
91
icon?: React.ReactElement;
92
record?: RaRecord;
93
resource?: string;
94
scrollToTop?: boolean;
95
}
96
97
interface EditButtonProps extends ButtonProps {
98
icon?: React.ReactElement;
99
record?: RaRecord;
100
resource?: string;
101
scrollToTop?: boolean;
102
}
103
104
interface ShowButtonProps extends EditButtonProps {}
105
interface ListButtonProps extends EditButtonProps {}
106
interface CloneButtonProps extends EditButtonProps {}
107
108
const CreateButton: React.FC<CreateButtonProps>;
109
const EditButton: React.FC<EditButtonProps>;
110
const ShowButton: React.FC<ShowButtonProps>;
111
const ListButton: React.FC<ListButtonProps>;
112
const CloneButton: React.FC<CloneButtonProps>;
113
```
114
115
### Action Button Examples
116
117
```typescript
118
import {
119
TopToolbar,
120
CreateButton,
121
ExportButton,
122
EditButton,
123
DeleteButton,
124
ShowButton,
125
SaveButton
126
} from 'react-admin';
127
128
// List actions
129
const PostListActions = () => (
130
<TopToolbar>
131
<CreateButton />
132
<ExportButton />
133
</TopToolbar>
134
);
135
136
// Show actions
137
const PostShowActions = () => (
138
<TopToolbar>
139
<EditButton />
140
<DeleteButton />
141
</TopToolbar>
142
);
143
144
// Custom button with navigation
145
const CustomButton = () => {
146
const redirect = useRedirect();
147
148
return (
149
<Button
150
label="Custom Action"
151
onClick={() => redirect('list', 'posts')}
152
color="primary"
153
variant="contained"
154
/>
155
);
156
};
157
```
158
159
### Bulk Action Buttons
160
161
Buttons for performing actions on multiple selected records.
162
163
```typescript { .api }
164
import {
165
BulkDeleteButton,
166
BulkDeleteWithConfirmButton,
167
BulkExportButton,
168
BulkUpdateButton
169
} from 'react-admin';
170
171
interface BulkActionProps {
172
label?: string;
173
icon?: React.ReactElement;
174
selectedIds?: Identifier[];
175
className?: string;
176
sx?: any;
177
}
178
179
interface BulkDeleteButtonProps extends BulkActionProps {
180
mutationMode?: 'pessimistic' | 'optimistic' | 'undoable';
181
mutationOptions?: UseMutationOptions;
182
}
183
184
interface BulkUpdateButtonProps extends BulkActionProps {
185
data: any;
186
mutationMode?: 'pessimistic' | 'optimistic' | 'undoable';
187
mutationOptions?: UseMutationOptions;
188
}
189
190
const BulkDeleteButton: React.FC<BulkDeleteButtonProps>;
191
const BulkDeleteWithConfirmButton: React.FC<BulkDeleteButtonProps>;
192
const BulkExportButton: React.FC<BulkActionProps>;
193
const BulkUpdateButton: React.FC<BulkUpdateButtonProps>;
194
```
195
196
#### Bulk Actions Example
197
198
```typescript
199
import { BulkDeleteButton, BulkUpdateButton, BulkExportButton } from 'react-admin';
200
201
const PostBulkActions = () => (
202
<>
203
<BulkUpdateButton
204
label="Publish Selected"
205
data={{ status: 'published' }}
206
mutationMode="optimistic"
207
/>
208
<BulkExportButton />
209
<BulkDeleteButton mutationMode="pessimistic" />
210
</>
211
);
212
213
const PostList = () => (
214
<List>
215
<Datagrid bulkActionButtons={<PostBulkActions />}>
216
<TextField source="title" />
217
<SelectField source="status" choices={statusChoices} />
218
</Datagrid>
219
</List>
220
);
221
```
222
223
## Notification System
224
225
### useNotify Hook
226
227
Hook for displaying notifications to users.
228
229
```typescript { .api }
230
import { useNotify } from 'react-admin';
231
232
type NotificationType = 'info' | 'success' | 'warning' | 'error';
233
234
interface NotifyOptions {
235
type?: NotificationType;
236
messageArgs?: any;
237
undoable?: boolean;
238
autoHideDuration?: number;
239
multiline?: boolean;
240
anchorOrigin?: {
241
vertical: 'top' | 'bottom';
242
horizontal: 'left' | 'center' | 'right';
243
};
244
}
245
246
type NotifyFunction = (
247
message: string,
248
options?: NotifyOptions
249
) => void;
250
251
const useNotify: () => NotifyFunction;
252
```
253
254
#### Notification Examples
255
256
```typescript
257
import { useNotify } from 'react-admin';
258
259
const MyComponent = () => {
260
const notify = useNotify();
261
262
const handleSuccess = () => {
263
notify('Record saved successfully', { type: 'success' });
264
};
265
266
const handleError = () => {
267
notify('An error occurred', {
268
type: 'error',
269
autoHideDuration: 6000
270
});
271
};
272
273
const handleWarning = () => {
274
notify('This action cannot be undone', {
275
type: 'warning',
276
multiline: true
277
});
278
};
279
280
const handleUndoable = () => {
281
notify('Post deleted', {
282
type: 'info',
283
undoable: true
284
});
285
};
286
287
return (
288
<div>
289
<button onClick={handleSuccess}>Success</button>
290
<button onClick={handleError}>Error</button>
291
<button onClick={handleWarning}>Warning</button>
292
<button onClick={handleUndoable}>Undoable</button>
293
</div>
294
);
295
};
296
```
297
298
### Notification Component
299
300
Component for displaying notification messages.
301
302
```typescript { .api }
303
import { Notification } from 'react-admin';
304
305
interface NotificationProps {
306
className?: string;
307
sx?: any;
308
}
309
310
const Notification: React.FC<NotificationProps>;
311
```
312
313
## Theming System
314
315
### Theme Provider and Hooks
316
317
React Admin uses Material-UI's theming system with additional customizations.
318
319
```typescript { .api }
320
import { useTheme } from 'react-admin';
321
322
const useTheme: () => [Theme, (theme: Theme) => void];
323
324
interface Theme {
325
palette: {
326
mode: 'light' | 'dark';
327
primary: PaletteColor;
328
secondary: PaletteColor;
329
error: PaletteColor;
330
warning: PaletteColor;
331
info: PaletteColor;
332
success: PaletteColor;
333
background: {
334
default: string;
335
paper: string;
336
};
337
text: {
338
primary: string;
339
secondary: string;
340
};
341
};
342
typography: Typography;
343
spacing: (factor: number) => number;
344
breakpoints: Breakpoints;
345
components?: ComponentsOverrides;
346
}
347
```
348
349
### Predefined Themes
350
351
React Admin includes several built-in themes.
352
353
```typescript { .api }
354
import {
355
defaultTheme,
356
nanoTheme,
357
radiantTheme,
358
houseTheme
359
} from 'react-admin';
360
361
const defaultTheme: Theme;
362
const nanoTheme: Theme;
363
const radiantTheme: Theme;
364
const houseTheme: Theme;
365
```
366
367
### Theme Usage Examples
368
369
```typescript
370
import { Admin, defaultTheme, radiantTheme } from 'react-admin';
371
import { createTheme } from '@mui/material/styles';
372
373
// Using predefined themes
374
const App = () => (
375
<Admin theme={radiantTheme} dataProvider={dataProvider}>
376
<Resource name="posts" list={PostList} />
377
</Admin>
378
);
379
380
// Custom theme
381
const customTheme = createTheme({
382
palette: {
383
mode: 'dark',
384
primary: {
385
main: '#1976d2',
386
},
387
secondary: {
388
main: '#dc004e',
389
},
390
background: {
391
default: '#121212',
392
paper: '#1e1e1e',
393
},
394
},
395
typography: {
396
fontFamily: 'Inter, sans-serif',
397
},
398
components: {
399
MuiButton: {
400
styleOverrides: {
401
root: {
402
borderRadius: 8,
403
},
404
},
405
},
406
},
407
});
408
409
const AppWithCustomTheme = () => (
410
<Admin theme={customTheme} dataProvider={dataProvider}>
411
<Resource name="posts" list={PostList} />
412
</Admin>
413
);
414
```
415
416
### ToggleThemeButton
417
418
Button for switching between light and dark themes.
419
420
```typescript { .api }
421
import { ToggleThemeButton } from 'react-admin';
422
423
interface ToggleThemeButtonProps {
424
className?: string;
425
sx?: any;
426
}
427
428
const ToggleThemeButton: React.FC<ToggleThemeButtonProps>;
429
```
430
431
### ThemeProvider
432
433
Provider for theme context in custom layouts.
434
435
```typescript { .api }
436
import { ThemeProvider } from 'react-admin';
437
438
interface ThemeProviderProps {
439
theme?: Theme;
440
children: React.ReactNode;
441
}
442
443
const ThemeProvider: React.FC<ThemeProviderProps>;
444
```
445
446
## Utility Components
447
448
### Confirm Dialog
449
450
Component for confirmation dialogs.
451
452
```typescript { .api }
453
import { Confirm } from 'react-admin';
454
455
interface ConfirmProps {
456
isOpen: boolean;
457
title: string;
458
content?: string | React.ReactElement;
459
onConfirm: () => void;
460
onClose: () => void;
461
confirmColor?: 'primary' | 'secondary' | 'error' | 'warning' | 'info' | 'success';
462
ConfirmIcon?: React.ComponentType;
463
CancelIcon?: React.ComponentType;
464
className?: string;
465
sx?: any;
466
}
467
468
const Confirm: React.FC<ConfirmProps>;
469
```
470
471
### LinearProgress
472
473
Progress indicator component.
474
475
```typescript { .api }
476
import { LinearProgress } from 'react-admin';
477
478
interface LinearProgressProps {
479
className?: string;
480
sx?: any;
481
}
482
483
const LinearProgress: React.FC<LinearProgressProps>;
484
```
485
486
### Loading Components
487
488
Various loading state indicators.
489
490
```typescript { .api }
491
import { Loading, LoadingIndicator, LoadingPage } from 'react-admin';
492
493
const Loading: React.FC<{ className?: string; sx?: any }>;
494
const LoadingIndicator: React.FC<{ className?: string; sx?: any }>;
495
const LoadingPage: React.FC<{ className?: string; sx?: any }>;
496
```
497
498
### Link Component
499
500
Enhanced link component with React Router integration.
501
502
```typescript { .api }
503
import { Link } from 'react-admin';
504
505
interface LinkProps {
506
to: string;
507
children: React.ReactNode;
508
className?: string;
509
sx?: any;
510
color?: 'inherit' | 'primary' | 'secondary' | 'textPrimary' | 'textSecondary' | 'error';
511
underline?: 'none' | 'hover' | 'always';
512
variant?: string;
513
}
514
515
const Link: React.FC<LinkProps>;
516
```
517
518
## Icon and Visual Components
519
520
### RefreshIconButton
521
522
Icon button for refreshing data.
523
524
```typescript { .api }
525
import { RefreshIconButton } from 'react-admin';
526
527
const RefreshIconButton: React.FC<{ className?: string; sx?: any }>;
528
```
529
530
### Skip Navigation Button
531
532
Accessibility component for keyboard navigation.
533
534
```typescript { .api }
535
import { SkipNavigationButton } from 'react-admin';
536
537
const SkipNavigationButton: React.FC<{ className?: string; sx?: any }>;
538
```
539
540
### LocalesMenuButton
541
542
Button for language selection.
543
544
```typescript { .api }
545
import { LocalesMenuButton } from 'react-admin';
546
547
interface LocalesMenuButtonProps {
548
className?: string;
549
sx?: any;
550
languages?: { locale: string; name: string }[];
551
}
552
553
const LocalesMenuButton: React.FC<LocalesMenuButtonProps>;
554
```
555
556
## Advanced UI Examples
557
558
### Custom Confirm Dialog
559
560
```typescript
561
import { useState } from 'react';
562
import { Confirm, useDelete, useNotify, useRedirect } from 'react-admin';
563
564
const CustomDeleteButton = ({ record }) => {
565
const [open, setOpen] = useState(false);
566
const [deleteOne, { isLoading }] = useDelete();
567
const notify = useNotify();
568
const redirect = useRedirect();
569
570
const handleDelete = () => {
571
deleteOne('posts', { id: record.id, previousData: record })
572
.then(() => {
573
notify('Post deleted successfully');
574
redirect('list', 'posts');
575
})
576
.catch(() => {
577
notify('Error deleting post', { type: 'error' });
578
});
579
setOpen(false);
580
};
581
582
return (
583
<>
584
<Button
585
label="Delete"
586
onClick={() => setOpen(true)}
587
color="error"
588
/>
589
<Confirm
590
isOpen={open}
591
title="Delete Post"
592
content="Are you sure you want to delete this post? This action cannot be undone."
593
onConfirm={handleDelete}
594
onClose={() => setOpen(false)}
595
confirmColor="error"
596
/>
597
</>
598
);
599
};
600
```
601
602
### Status Indicator Component
603
604
```typescript
605
import { Chip } from '@mui/material';
606
import { useTheme } from '@mui/material/styles';
607
608
const StatusIndicator = ({ status }) => {
609
const theme = useTheme();
610
611
const getStatusColor = (status) => {
612
switch (status) {
613
case 'published': return theme.palette.success.main;
614
case 'draft': return theme.palette.warning.main;
615
case 'archived': return theme.palette.text.disabled;
616
default: return theme.palette.text.secondary;
617
}
618
};
619
620
return (
621
<Chip
622
label={status.toUpperCase()}
623
size="small"
624
sx={{
625
backgroundColor: getStatusColor(status),
626
color: 'white',
627
fontWeight: 'bold'
628
}}
629
/>
630
);
631
};
632
```
633
634
### Custom Toolbar with Actions
635
636
```typescript
637
import { Toolbar, SaveButton, Button } from 'react-admin';
638
import { useFormContext } from 'react-hook-form';
639
import { useNotify } from 'react-admin';
640
641
const CustomFormToolbar = () => {
642
const { reset, getValues } = useFormContext();
643
const notify = useNotify();
644
645
const handleSaveAndContinue = () => {
646
// Custom save logic
647
notify('Saved and continuing...');
648
};
649
650
const handleReset = () => {
651
reset();
652
notify('Form reset');
653
};
654
655
return (
656
<Toolbar>
657
<SaveButton />
658
<Button
659
label="Save & Continue"
660
onClick={handleSaveAndContinue}
661
variant="outlined"
662
sx={{ marginLeft: 1 }}
663
/>
664
<Button
665
label="Reset"
666
onClick={handleReset}
667
variant="text"
668
sx={{ marginLeft: 1 }}
669
/>
670
</Toolbar>
671
);
672
};
673
```
674
675
### Responsive Button Group
676
677
```typescript
678
import { useMediaQuery, useTheme } from '@mui/material';
679
import { TopToolbar, CreateButton, ExportButton, Button } from 'react-admin';
680
681
const ResponsiveActions = () => {
682
const theme = useTheme();
683
const isSmall = useMediaQuery(theme.breakpoints.down('sm'));
684
685
return (
686
<TopToolbar>
687
<CreateButton />
688
{!isSmall && <ExportButton />}
689
{!isSmall && (
690
<Button label="Advanced" onClick={() => {}} />
691
)}
692
</TopToolbar>
693
);
694
};
695
```
696
697
### Theme Switcher Component
698
699
```typescript
700
import { useState } from 'react';
701
import { ToggleThemeButton, useTheme } from 'react-admin';
702
import { Menu, MenuItem, IconButton } from '@mui/material';
703
import { Palette as PaletteIcon } from '@mui/icons-material';
704
705
const ThemeSwitcher = () => {
706
const [theme, setTheme] = useTheme();
707
const [anchorEl, setAnchorEl] = useState(null);
708
709
const themes = [
710
{ name: 'Default', value: defaultTheme },
711
{ name: 'Nano', value: nanoTheme },
712
{ name: 'Radiant', value: radiantTheme },
713
{ name: 'House', value: houseTheme }
714
];
715
716
const handleClose = () => setAnchorEl(null);
717
718
const handleThemeSelect = (selectedTheme) => {
719
setTheme(selectedTheme);
720
handleClose();
721
};
722
723
return (
724
<>
725
<IconButton onClick={(e) => setAnchorEl(e.currentTarget)}>
726
<PaletteIcon />
727
</IconButton>
728
<Menu
729
anchorEl={anchorEl}
730
open={Boolean(anchorEl)}
731
onClose={handleClose}
732
>
733
{themes.map((themeOption) => (
734
<MenuItem
735
key={themeOption.name}
736
onClick={() => handleThemeSelect(themeOption.value)}
737
>
738
{themeOption.name}
739
</MenuItem>
740
))}
741
</Menu>
742
</>
743
);
744
};
745
```
746
747
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.