diff --git a/packages/ra-core/src/controller/index.ts b/packages/ra-core/src/controller/index.ts index d2a8f71f597..9d3ec219e9e 100644 --- a/packages/ra-core/src/controller/index.ts +++ b/packages/ra-core/src/controller/index.ts @@ -1,7 +1,9 @@ import ListController from './ListController'; import ListContext from './ListContext'; import ListFilterContext from './ListFilterContext'; -import ListPaginationContext from './ListPaginationContext'; +import ListPaginationContext, { + ListPaginationContextValue, +} from './ListPaginationContext'; import ListSortContext from './ListSortContext'; import ListBase from './ListBase'; import useRecordSelection from './useRecordSelection'; @@ -40,6 +42,7 @@ export { ListContext, ListFilterContext, ListPaginationContext, + ListPaginationContextValue, ListSortContext, ListContextProvider, useCheckMinimumRequiredProps, diff --git a/packages/ra-core/src/controller/useListPaginationContext.ts b/packages/ra-core/src/controller/useListPaginationContext.ts index 94afa300eac..916bfc90fe2 100644 --- a/packages/ra-core/src/controller/useListPaginationContext.ts +++ b/packages/ra-core/src/controller/useListPaginationContext.ts @@ -1,4 +1,5 @@ -import { useContext } from 'react'; +import { useContext, useMemo } from 'react'; +import defaults from 'lodash/defaults'; import ListPaginationContext, { ListPaginationContextValue, @@ -24,25 +25,40 @@ import ListPaginationContext, { */ const useListPaginationContext = (props?: any): ListPaginationContextValue => { const context = useContext(ListPaginationContext); - if (!context.setPage) { - /** - * The element isn't inside a - * - * This may only happen when using Datagrid / SimpleList / SingleFieldList components - * outside of a List / ReferenceManyField / ReferenceArrayField - - * which isn't documented but tolerated. - * To avoid breakage in that case, fallback to props - * - * @deprecated - to be removed in 4.0 - */ - if (process.env.NODE_ENV !== 'production') { - console.log( - "List components must be used inside a . Relying on props rather than context to get List data and callbacks is deprecated and won't be supported in the next major version of react-admin." - ); - } - return props; - } - return context; + return useMemo( + () => + defaults( + {}, + props != null ? extractListPaginationContextProps(props) : {}, + context + ), + [context, props] + ); }; +/** + * Extract only the list controller props + * + * @param {Object} props Props passed to the useListContext hook + * + * @returns {ListControllerResult} List controller props + */ +const extractListPaginationContextProps = ({ + loading, + page, + perPage, + setPage, + setPerPage, + total, + resource, +}) => ({ + loading, + page, + perPage, + setPage, + setPerPage, + total, + resource, +}); + export default useListPaginationContext; diff --git a/packages/ra-ui-materialui/src/list/pagination/Pagination.spec.tsx b/packages/ra-ui-materialui/src/list/pagination/Pagination.spec.tsx index ee8d2442345..17d2a7c823a 100644 --- a/packages/ra-ui-materialui/src/list/pagination/Pagination.spec.tsx +++ b/packages/ra-ui-materialui/src/list/pagination/Pagination.spec.tsx @@ -207,4 +207,21 @@ describe('', () => { ).not.toBeNull(); }); }); + + it('should work outside of a ListContext', () => { + const { queryByText } = render( + + null} + loading={false} + setPerPage={() => {}} + perPage={1} + total={2} + page={1} + /> + + ); + expect(queryByText('ra.navigation.page_rows_per_page')).not.toBeNull(); + }); }); diff --git a/packages/ra-ui-materialui/src/list/pagination/Pagination.tsx b/packages/ra-ui-materialui/src/list/pagination/Pagination.tsx index f79520c6f53..50e3d8df36d 100644 --- a/packages/ra-ui-materialui/src/list/pagination/Pagination.tsx +++ b/packages/ra-ui-materialui/src/list/pagination/Pagination.tsx @@ -13,6 +13,7 @@ import { useListPaginationContext, sanitizeListRestProps, ComponentPropType, + ListPaginationContextValue, } from 'ra-core'; import DefaultPaginationActions from './PaginationActions'; @@ -122,8 +123,9 @@ Pagination.defaultProps = { limit: , rowsPerPageOptions: [5, 10, 25], }; - -export interface PaginationProps extends TablePaginationBaseProps { +export interface PaginationProps + extends TablePaginationBaseProps, + Partial { rowsPerPageOptions?: number[]; actions?: FC; limit?: ReactElement;