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;