From 9dbb674cd07f9168c088cbc04ff2771d416fb5d8 Mon Sep 17 00:00:00 2001
From: Kmaschta <kevin@marmelab.com>
Date: Tue, 10 Dec 2019 10:56:23 +0100
Subject: [PATCH 1/4] Make pagination more extendable

---
 .../ra-ui-materialui/src/list/Pagination.js   | 16 ++++++++---
 .../src/list/PaginationActions.js             | 27 ++++++++++++++-----
 2 files changed, 32 insertions(+), 11 deletions(-)

diff --git a/packages/ra-ui-materialui/src/list/Pagination.js b/packages/ra-ui-materialui/src/list/Pagination.js
index 8c107e735b9..d19bc2a32dc 100644
--- a/packages/ra-ui-materialui/src/list/Pagination.js
+++ b/packages/ra-ui-materialui/src/list/Pagination.js
@@ -3,8 +3,8 @@ import PropTypes from 'prop-types';
 import { TablePagination, Toolbar, useMediaQuery } from '@material-ui/core';
 import { useTranslate, sanitizeListRestProps } from 'ra-core';
 
-import PaginationActions from './PaginationActions';
-import PaginationLimit from './PaginationLimit';
+import DefaultPaginationActions from './PaginationActions';
+import DefaultPaginationLimit from './PaginationLimit';
 
 const emptyArray = [];
 
@@ -16,6 +16,8 @@ const Pagination = ({
     total,
     setPage,
     setPerPage,
+    ActionsComponent,
+    limit,
     ...rest
 }) => {
     useEffect(() => {
@@ -64,8 +66,9 @@ const Pagination = ({
     );
 
     if (total === 0) {
-        return loading ? <Toolbar variant="dense" /> : <PaginationLimit />;
+        return loading ? <Toolbar variant="dense" /> : limit;
     }
+
     if (isSmall) {
         return (
             <TablePagination
@@ -80,6 +83,7 @@ const Pagination = ({
             />
         );
     }
+
     return (
         <TablePagination
             count={total}
@@ -87,7 +91,7 @@ const Pagination = ({
             page={page - 1}
             onChangePage={handlePageChange}
             onChangeRowsPerPage={handlePerPageChange}
-            ActionsComponent={PaginationActions}
+            ActionsComponent={ActionsComponent}
             component="span"
             labelRowsPerPage={translate('ra.navigation.page_rows_per_page')}
             labelDisplayedRows={labelDisplayedRows}
@@ -106,10 +110,14 @@ Pagination.propTypes = {
     setPage: PropTypes.func,
     setPerPage: PropTypes.func,
     total: PropTypes.number,
+    ActionsComponent: PropTypes.node,
+    limit: PropTypes.element,
 };
 
 Pagination.defaultProps = {
     rowsPerPageOptions: [5, 10, 25],
+    ActionsComponent: DefaultPaginationActions,
+    limit: <DefaultPaginationLimit />,
 };
 
 export default React.memo(Pagination);
diff --git a/packages/ra-ui-materialui/src/list/PaginationActions.js b/packages/ra-ui-materialui/src/list/PaginationActions.js
index a89a44c8288..03fa90b15f4 100644
--- a/packages/ra-ui-materialui/src/list/PaginationActions.js
+++ b/packages/ra-ui-materialui/src/list/PaginationActions.js
@@ -24,6 +24,8 @@ function PaginationActions({
     rowsPerPage,
     count,
     onChangePage,
+    color,
+    size,
 }) {
     const classes = useStyles({ classes: classesOverride });
     const translate = useTranslate();
@@ -102,12 +104,12 @@ function PaginationActions({
                 </span>
             ) : (
                 <Button
+                    size={size}
                     className="page-number"
-                    color={pageNum === page + 1 ? 'default' : 'primary'}
+                    color={pageNum === page + 1 ? 'default' : color}
                     key={pageNum}
                     data-page={pageNum - 1}
                     onClick={gotoPage}
-                    size="small"
                 >
                     {pageNum}
                 </Button>
@@ -116,16 +118,20 @@ function PaginationActions({
     };
 
     const nbPages = getNbPages();
-    if (nbPages === 1) return <div className={classes.actions} />;
+
+    if (nbPages === 1) {
+        return <div className={classes.actions} />;
+    }
+
     return (
         <div className={classes.actions}>
             {page > 0 && (
                 <Button
-                    color="primary"
+                    color={color}
+                    size={size}
                     key="prev"
                     onClick={prevPage}
                     className="previous-page"
-                    size="small"
                 >
                     <ChevronLeft />
                     {translate('ra.navigation.prev')}
@@ -134,11 +140,11 @@ function PaginationActions({
             {renderPageNums()}
             {page !== nbPages - 1 && (
                 <Button
-                    color="primary"
+                    color={color}
+                    size={size}
                     key="next"
                     onClick={nextPage}
                     className="next-page"
-                    size="small"
                 >
                     {translate('ra.navigation.next')}
                     <ChevronRight />
@@ -162,6 +168,13 @@ PaginationActions.propTypes = {
     onChangePage: PropTypes.func.isRequired,
     page: PropTypes.number.isRequired,
     rowsPerPage: PropTypes.number.isRequired,
+    color: PropTypes.oneOf(['primary', 'secondary']),
+    size: PropTypes.oneOf(['small', 'medium', 'large']),
+};
+
+PaginationActions.defaultProps = {
+    color: 'primary',
+    size: 'small',
 };
 
 export default React.memo(PaginationActions);

From 6bdcb006d698e5734d27a59c7445be1b190c7258 Mon Sep 17 00:00:00 2001
From: Kmaschta <kevin@marmelab.com>
Date: Tue, 10 Dec 2019 14:35:04 +0100
Subject: [PATCH 2/4] Document pagination

---
 docs/List.md | 145 +++++++++++++++++++++++++++++----------------------
 1 file changed, 83 insertions(+), 62 deletions(-)

diff --git a/docs/List.md b/docs/List.md
index f24ed33d5c4..ab84201726c 100644
--- a/docs/List.md
+++ b/docs/List.md
@@ -573,68 +573,6 @@ export const PostList = (props) => (
 const filterSentToDataProvider = { ...filterDefaultValues, ...filterChosenByUser, ...filters };
 ```
 
-### Pagination
-
-Here are all the props required by the <Pagination> component:
-
-* `page`: The current page number (integer). First page is `1`.
-* `perPage`: The number of records per page.
-* `setPage`: `function(page: number) => void`. A function that set the current page number.
-* `total`: The total number of records.
-
-You don't need to fill these props when you pass the `Pagination` component to the `List` component through the `pagination` prop: `<List pagination={<Pagination />}>`.
-
-You can also replace the default pagination element by your own. For instance, you can modify the default pagination by adjusting the "rows per page" selector.
-
-```jsx
-// in src/MyPagination.js
-import { Pagination, List } from 'react-admin';
-
-const PostPagination = props => <Pagination rowsPerPageOptions={[10, 25, 50, 100]} {...props} />;
-
-export const PostList = (props) => (
-    <List {...props} pagination={<PostPagination />}>
-        ...
-    </List>
-);
-```
-
-**Tip**: Pass an empty array to `rowsPerPageOptions` to disable the rows per page selection.
-
-Alternately, if you want to replace the default pagination by a "<previous - next>" pagination, create a pagination component like the following:
-
-```jsx
-import Button from '@material-ui/core/Button';
-import ChevronLeft from '@material-ui/icons/ChevronLeft';
-import ChevronRight from '@material-ui/icons/ChevronRight';
-import Toolbar from '@material-ui/core/Toolbar';
-
-const PostPagination = ({ page, perPage, total, setPage }) => {
-    const nbPages = Math.ceil(total / perPage) || 1;
-    return (
-        nbPages > 1 &&
-            <Toolbar>
-                {page > 1 &&
-                    <Button color="primary" key="prev" icon={ChevronLeft} onClick={() => setPage(page - 1)}>
-                        Prev
-                    </Button>
-                }
-                {page !== nbPages &&
-                    <Button color="primary" key="next" icon={ChevronRight} onClick={() => setPage(page + 1)} labelPosition="before">
-                        Next
-                    </Button>
-                }
-            </Toolbar>
-    );
-}
-
-export const PostList = (props) => (
-    <List {...props} pagination={<PostPagination />}>
-        ...
-    </List>
-);
-```
-
 ### Aside component
 
 You may want to display additional information on the side of the list. Use the `aside` prop for that, passing the component of your choice:
@@ -1388,3 +1326,86 @@ export const UserList = ({ permissions, ...props }) => {
 {% endraw %}
 
 **Tip**: Note how the `permissions` prop is passed down to the custom `filters` component.
+
+## Pagination
+
+Here are all the props required by the <Pagination> component:
+
+* `page`: The current page number (integer). First page is `1`.
+* `perPage`: The number of records per page.
+* `setPage`: `function(page: number) => void`. A function that set the current page number.
+* `total`: The total number of records.
+* `ActionsComponent`: A composant that displays the pagination buttons (default: `PaginationActions`)
+* `limit`: An element that is displayed if there is no data to shpw (default: `<PaginationLimit>`)
+
+You don't need to fill these props when you pass the `Pagination` component to the `List` component through the `pagination` prop: `<List pagination={<Pagination />}>`.
+
+You can also replace the default pagination element by your own. For instance, you can modify the default pagination by adjusting the "rows per page" selector.
+
+```jsx
+// in src/MyPagination.js
+import { Pagination, List } from 'react-admin';
+
+const PostPagination = props => <Pagination rowsPerPageOptions={[10, 25, 50, 100]} {...props} />;
+
+export const PostList = (props) => (
+    <List {...props} pagination={<PostPagination />}>
+        ...
+    </List>
+);
+```
+
+**Tip**: Pass an empty array to `rowsPerPageOptions` to disable the rows per page selection.
+
+Alternately, if you want to replace the default pagination by a "<previous - next>" pagination, create a pagination component like the following:
+
+```jsx
+import Button from '@material-ui/core/Button';
+import ChevronLeft from '@material-ui/icons/ChevronLeft';
+import ChevronRight from '@material-ui/icons/ChevronRight';
+import Toolbar from '@material-ui/core/Toolbar';
+
+const PostPagination = ({ page, perPage, total, setPage }) => {
+    const nbPages = Math.ceil(total / perPage) || 1;
+    return (
+        nbPages > 1 &&
+            <Toolbar>
+                {page > 1 &&
+                    <Button color="primary" key="prev" icon={ChevronLeft} onClick={() => setPage(page - 1)}>
+                        Prev
+                    </Button>
+                }
+                {page !== nbPages &&
+                    <Button color="primary" key="next" icon={ChevronRight} onClick={() => setPage(page + 1)} labelPosition="before">
+                        Next
+                    </Button>
+                }
+            </Toolbar>
+    );
+}
+
+export const PostList = (props) => (
+    <List {...props} pagination={<PostPagination />}>
+        ...
+    </List>
+);
+```
+
+But if you just want to change the color property of the pagination button, you can extend the existing components:
+
+```jsx
+import {
+    List,
+    Pagination as RaPagination,
+    PaginationActions as RaPaginationActions,
+} from 'react-admin';
+
+export const PaginationActions = props => <RaPaginationActions {...props} color="secondary" />;
+
+export const Pagination = props => <RaPagination {...props} ActionsComponent={PaginationActions} />;
+
+export const UserList = props => (
+    <List {...props} pagination={<Pagination />}>
+    </List>
+);
+```

From 0af09488e3ae9719482faaf1511bfb11b0ed15ab Mon Sep 17 00:00:00 2001
From: Kmaschta <kevin@marmelab.com>
Date: Tue, 10 Dec 2019 15:00:26 +0100
Subject: [PATCH 3/4] Code Review

---
 docs/List.md                                     | 2 +-
 packages/ra-ui-materialui/src/list/Pagination.js | 8 ++++----
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/docs/List.md b/docs/List.md
index ab84201726c..bca83339962 100644
--- a/docs/List.md
+++ b/docs/List.md
@@ -1335,7 +1335,7 @@ Here are all the props required by the <Pagination> component:
 * `perPage`: The number of records per page.
 * `setPage`: `function(page: number) => void`. A function that set the current page number.
 * `total`: The total number of records.
-* `ActionsComponent`: A composant that displays the pagination buttons (default: `PaginationActions`)
+* `actions`: A component that displays the pagination buttons (default: `PaginationActions`)
 * `limit`: An element that is displayed if there is no data to shpw (default: `<PaginationLimit>`)
 
 You don't need to fill these props when you pass the `Pagination` component to the `List` component through the `pagination` prop: `<List pagination={<Pagination />}>`.
diff --git a/packages/ra-ui-materialui/src/list/Pagination.js b/packages/ra-ui-materialui/src/list/Pagination.js
index d19bc2a32dc..92cad22e594 100644
--- a/packages/ra-ui-materialui/src/list/Pagination.js
+++ b/packages/ra-ui-materialui/src/list/Pagination.js
@@ -16,7 +16,7 @@ const Pagination = ({
     total,
     setPage,
     setPerPage,
-    ActionsComponent,
+    actions,
     limit,
     ...rest
 }) => {
@@ -91,7 +91,7 @@ const Pagination = ({
             page={page - 1}
             onChangePage={handlePageChange}
             onChangeRowsPerPage={handlePerPageChange}
-            ActionsComponent={ActionsComponent}
+            ActionsComponent={actions}
             component="span"
             labelRowsPerPage={translate('ra.navigation.page_rows_per_page')}
             labelDisplayedRows={labelDisplayedRows}
@@ -110,13 +110,13 @@ Pagination.propTypes = {
     setPage: PropTypes.func,
     setPerPage: PropTypes.func,
     total: PropTypes.number,
-    ActionsComponent: PropTypes.node,
+    actions: PropTypes.node,
     limit: PropTypes.element,
 };
 
 Pagination.defaultProps = {
     rowsPerPageOptions: [5, 10, 25],
-    ActionsComponent: DefaultPaginationActions,
+    actions: DefaultPaginationActions,
     limit: <DefaultPaginationLimit />,
 };
 

From e9937eb79b3f3d89b79c076ed5a7afae2480d462 Mon Sep 17 00:00:00 2001
From: Francois Zaninotto <francois@marmelab.com>
Date: Wed, 11 Dec 2019 08:56:12 +0100
Subject: [PATCH 4/4] fix typo

---
 docs/List.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/docs/List.md b/docs/List.md
index bca83339962..c7b083103b7 100644
--- a/docs/List.md
+++ b/docs/List.md
@@ -1336,7 +1336,7 @@ Here are all the props required by the <Pagination> component:
 * `setPage`: `function(page: number) => void`. A function that set the current page number.
 * `total`: The total number of records.
 * `actions`: A component that displays the pagination buttons (default: `PaginationActions`)
-* `limit`: An element that is displayed if there is no data to shpw (default: `<PaginationLimit>`)
+* `limit`: An element that is displayed if there is no data to show (default: `<PaginationLimit>`)
 
 You don't need to fill these props when you pass the `Pagination` component to the `List` component through the `pagination` prop: `<List pagination={<Pagination />}>`.