diff --git a/docs/List.md b/docs/List.md
index 5c0d6cf0f74..5099687f7d3 100644
--- a/docs/List.md
+++ b/docs/List.md
@@ -1981,6 +1981,7 @@ Here are all the props accepted by the component:
* [`isRowExpandable`](#isrowexpandable)
* [`isRowSelectable`](#isrowselectable)
* [`optimized`](#performance)
+* [`empty`](#empty)
Additional props are passed down to [the material-ui `
` element](https://material-ui.com/api/table/).
@@ -2261,6 +2262,10 @@ const PostList = props => (
export default withStyles(styles)(PostList);
```
+### Empty
+
+It's possible that a Datagrid will have no records to display. If the Datagrid's parent component handles the loading state, the Datagrid will return `null` and render nothing.
+Passing through a component to the `empty` prop will cause the Datagrid to render the `empty` component instead of `null`.
### CSS API
The `Datagrid` component accepts the usual `className` prop but you can override many class names injected to the inner components by React-admin thanks to the `classes` property (as most Material UI components, see their [documentation about it](https://material-ui.com/customization/components/#overriding-styles-with-classes)). This property accepts the following keys:
diff --git a/packages/ra-ui-materialui/src/list/datagrid/Datagrid.spec.tsx b/packages/ra-ui-materialui/src/list/datagrid/Datagrid.spec.tsx
index 0e4c514fdef..830142b1c30 100644
--- a/packages/ra-ui-materialui/src/list/datagrid/Datagrid.spec.tsx
+++ b/packages/ra-ui-materialui/src/list/datagrid/Datagrid.spec.tsx
@@ -47,6 +47,26 @@ describe('', () => {
expect(contextValue.onSelect).toHaveBeenCalledTimes(0);
});
+ it('should display the correct empty component', () => {
+ const Empty = () => No records to show
;
+
+ const emptyData = {
+ ...contextValue,
+ data: [],
+ ids: [],
+ };
+
+ const { queryByText } = renderWithRedux(
+
+ } hasBulkActions>
+
+
+
+ );
+
+ expect(queryByText('No records to show')).toBeTruthy();
+ });
+
describe('selecting items with the shift key', () => {
it('should call onSelect with the correct ids when the last selection is after the first', () => {
const Test = ({ selectedIds = [] }) => (
diff --git a/packages/ra-ui-materialui/src/list/datagrid/Datagrid.tsx b/packages/ra-ui-materialui/src/list/datagrid/Datagrid.tsx
index a5b5cf127c6..178f49324fc 100644
--- a/packages/ra-ui-materialui/src/list/datagrid/Datagrid.tsx
+++ b/packages/ra-ui-materialui/src/list/datagrid/Datagrid.tsx
@@ -117,6 +117,7 @@ const Datagrid: FC = React.forwardRef((props, ref) => {
children,
classes: classesOverride,
className,
+ empty,
expand,
hasBulkActions = false,
hover,
@@ -242,9 +243,13 @@ const Datagrid: FC = React.forwardRef((props, ref) => {
/**
* Once loaded, the data for the list may be empty. Instead of
* displaying the table header with zero data rows,
- * the datagrid displays nothing in this case.
+ * the datagrid displays nothing or a custom empty component.
*/
if (loaded && (ids.length === 0 || total === 0)) {
+ if (empty) {
+ return empty;
+ }
+
return null;
}
@@ -353,6 +358,7 @@ Datagrid.propTypes = {
order: PropTypes.string.isRequired,
}),
data: PropTypes.any,
+ empty: PropTypes.element,
// @ts-ignore
expand: PropTypes.oneOfType([PropTypes.element, PropTypes.elementType]),
hasBulkActions: PropTypes.bool,
@@ -387,6 +393,7 @@ export interface DatagridProps
}>;
hasBulkActions?: boolean;
hover?: boolean;
+ empty?: ReactElement;
isRowSelectable?: (record: Record) => boolean;
isRowExpandable?: (record: Record) => boolean;
optimized?: boolean;