1 | # react-paginate
|
2 |
|
3 | [![NPM](https://nodei.co/npm/react-paginate.png?downloads=true)](https://nodei.co/npm/react-paginate/)
|
4 | [![Build Status](https://travis-ci.org/AdeleD/react-paginate.svg?branch=master)](https://travis-ci.org/AdeleD/react-paginate)
|
5 |
|
6 | **A ReactJS component to render a pagination.**
|
7 |
|
8 | By installing this component and writing only a little bit of CSS you can obtain this:
|
9 | Note: You should write your own css to obtain this UI. This package do not provide any css.
|
10 |
|
11 | <img src="https://cloud.githubusercontent.com/assets/2084833/24840237/7accb75a-1d1e-11e7-9abb-818431398b91.png" alt="Pagination demo 2" />
|
12 |
|
13 | or
|
14 |
|
15 | <img src="https://cloud.githubusercontent.com/assets/2084833/24840230/594e4ea4-1d1e-11e7-8b34-bde943b4793d.png" alt="Pagination demo 1" />
|
16 |
|
17 | ## Installation
|
18 |
|
19 | Install `react-paginate` with [npm](https://www.npmjs.com/):
|
20 |
|
21 | ```
|
22 | npm install react-paginate --save
|
23 | ```
|
24 |
|
25 | ## Usage
|
26 |
|
27 | ```javascript
|
28 | import React, { useEffect, useState } from 'react';
|
29 | import ReactDOM from 'react-dom';
|
30 | import ReactPaginate from 'react-paginate';
|
31 |
|
32 | // Example items, to simulate fetching from another resources.
|
33 | const items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
|
34 |
|
35 | function Items({ currentItems }) {
|
36 | return (
|
37 | <>
|
38 | {currentItems &&
|
39 | currentItems.map((item) => (
|
40 | <div>
|
41 | <h3>Item #{item}</h3>
|
42 | </div>
|
43 | ))}
|
44 | </>
|
45 | );
|
46 | }
|
47 |
|
48 | function PaginatedItems({ itemsPerPage }) {
|
49 | // We start with an empty list of items.
|
50 | const [currentItems, setCurrentItems] = useState(null);
|
51 | const [pageCount, setPageCount] = useState(0);
|
52 | // Here we use item offsets; we could also use page offsets
|
53 | // following the API or data you're working with.
|
54 | const [itemOffset, setItemOffset] = useState(0);
|
55 |
|
56 | useEffect(() => {
|
57 | // Fetch items from another resources.
|
58 | const endOffset = itemOffset + itemsPerPage;
|
59 | console.log(`Loading items from ${itemOffset} to ${endOffset}`);
|
60 | setCurrentItems(items.slice(itemOffset, endOffset));
|
61 | setPageCount(Math.ceil(items.length / itemsPerPage));
|
62 | }, [itemOffset, itemsPerPage]);
|
63 |
|
64 | // Invoke when user click to request another page.
|
65 | const handlePageClick = (event) => {
|
66 | const newOffset = (event.selected * itemsPerPage) % items.length;
|
67 | console.log(
|
68 | `User requested page number ${event.selected}, which is offset ${newOffset}`
|
69 | );
|
70 | setItemOffset(newOffset);
|
71 | };
|
72 |
|
73 | return (
|
74 | <>
|
75 | <Items currentItems={currentItems} />
|
76 | <ReactPaginate
|
77 | breakLabel="..."
|
78 | nextLabel="next >"
|
79 | onPageChange={handlePageClick}
|
80 | pageRangeDisplayed={5}
|
81 | pageCount={pageCount}
|
82 | previousLabel="< previous"
|
83 | renderOnZeroPageCount={null}
|
84 | />
|
85 | </>
|
86 | );
|
87 | }
|
88 |
|
89 | // Add a <div id="container"> to your HTML to see the componend rendered.
|
90 | ReactDOM.render(
|
91 | <PaginatedItems itemsPerPage={4} />,
|
92 | document.getElementById('container')
|
93 | );
|
94 | ```
|
95 |
|
96 | Test it on [CodePen](https://codepen.io/monsieurv/pen/abyJQWQ).
|
97 |
|
98 | You can also read the code of [demo/js/demo.js][1] to quickly understand how to make `react-paginate` work with a list of objects.
|
99 |
|
100 | Finally there is this **[CodePen demo](https://codepen.io/monsieurv/pen/yLoMxYQ)**, with features fetching sample code (using GitHub API) and two synchronized pagination widgets.
|
101 |
|
102 | ## Props
|
103 |
|
104 | | Name | Type | Description |
|
105 | | ------------------------ | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
106 | | `pageCount` | `Number` | **Required.** The total number of pages. |
|
107 | | `pageRangeDisplayed` | `Number` | The range of pages displayed. |
|
108 | | `marginPagesDisplayed` | `Number` | The number of pages to display for margins. |
|
109 | | `previousLabel` | `Node` | Label for the `previous` button. |
|
110 | | `nextLabel` | `Node` | Label for the `next` button. |
|
111 | | `breakLabel` | `Node` | Label for ellipsis. |
|
112 | | `breakClassName` | `String` | The classname on tag `li` of the ellipsis element. |
|
113 | | `breakLinkClassName` | `String` | The classname on tag `a` of the ellipsis element. |
|
114 | | `onPageChange` | `Function` | The method to call when a page is clicked. Exposes the current page object as an argument. |
|
115 | | `onPageActive` | `Function` | The method to call when an active page is clicked. Exposes the active page object as an argument. |
|
116 | | `initialPage` | `Number` | The initial page selected, in [uncontrolled mode](https://reactjs.org/docs/uncontrolled-components.html). Do not use with `forcePage` at the same time. |
|
117 | | `forcePage` | `Number` | To override selected page with parent prop. Use this if you want to [control](https://reactjs.org/docs/forms.html#controlled-components) the page from your app state. |
|
118 | | `disableInitialCallback` | `boolean` | Disable `onPageChange` callback with initial page. Default: `false` |
|
119 | | `containerClassName` | `String` | The classname of the pagination container. |
|
120 | | `className` | `String` | Same as `containerClassName`. For use with [styled-components](https://styled-components.com/) & other CSS-in-JS. |
|
121 | | `pageClassName` | `String` | The classname on tag `li` of each page element. |
|
122 | | `pageLinkClassName` | `String` | The classname on tag `a` of each page element. |
|
123 | | `pageLabelBuilder` | `Function` | Function to set the text on page links. Defaults to `(page) => page` |
|
124 | | `activeClassName` | `String` | The classname for the active page. |
|
125 | | `activeLinkClassName` | `String` | The classname on the active tag `a`. |
|
126 | | `previousClassName` | `String` | The classname on tag `li` of the `previous` button. |
|
127 | | `nextClassName` | `String` | The classname on tag `li` of the `next` button. |
|
128 | | `previousLinkClassName` | `String` | The classname on tag `a` of the `previous` button. |
|
129 | | `nextLinkClassName` | `String` | The classname on tag `a` of the `next` button. |
|
130 | | `disabledClassName` | `String` | The classname for disabled `previous` and `next` buttons. |
|
131 | | `disabledLinkClassName` | `String` | The classname on tag `a` for disabled `previous` and `next` buttons. |
|
132 | | `hrefBuilder` | `Function` | The method is called to generate the `href` attribute value on tag `a` of each page element. |
|
133 | | `hrefAllControls` | `Bool` | By default the `hrefBuilder` add `href` only to active controls. Set this prop to `true` so `href` are generated on all controls ([see](https://github.com/AdeleD/react-paginate/issues/242)). |
|
134 | | `extraAriaContext` | `String` | DEPRECATED: Extra context to add to the `aria-label` HTML attribute. |
|
135 | | `ariaLabelBuilder` | `Function` | The method is called to generate the `aria-label` attribute value on each page link |
|
136 | | `eventListener` | `String` | The event to listen onto before changing the selected page. Default is: `onClick`. |
|
137 | | `renderOnZeroPageCount` | `Function` | A render fonction called when `pageCount` is zero. Let the Previous / Next buttons displayed by default (`undefined`). Display nothing when `null` is provided. |
|
138 | | `prevRel` | `String` | The `rel` property on the `a` tag for the prev page control. Default value `prev`. Set to `null` to disable. |
|
139 | | `nextRel` | `String` | The `rel` propery on the `a` tag for the next page control. Default value `next`. Set to `null` to disable. |
|
140 | | `prevPageRel` | `String` | The `rel` property on the `a` tag just before the selected page. Default value `prev`. Set to `null` to disable. |
|
141 | | `selectedPageRel` | `String` | The `rel` propery on the `a` tag for the selected page. Default value `canonical`. Set to `null` to disable. |
|
142 | | `nextPageRel` | `String` | The `rel` property on the `a` tag just after the selected page. Default value `next`. Set to `null` to disable. |
|
143 |
|
144 | ## Demo
|
145 |
|
146 | To run the demo locally, clone the repository and move into it:
|
147 |
|
148 | ```console
|
149 | git clone git@github.com:AdeleD/react-paginate.git
|
150 | cd react-paginate
|
151 | ```
|
152 |
|
153 | Install dependencies:
|
154 |
|
155 | ```console
|
156 | make install
|
157 | ```
|
158 |
|
159 | Prepare the demo:
|
160 |
|
161 | ```console
|
162 | make demo
|
163 | ```
|
164 |
|
165 | Run the server:
|
166 |
|
167 | ```console
|
168 | make serve
|
169 | ```
|
170 |
|
171 | Open your browser and go to [http://localhost:3000/](http://localhost:3000/)
|
172 |
|
173 | <img src="https://cloud.githubusercontent.com/assets/2084833/24840241/7c95b7b2-1d1e-11e7-97e3-83b9c7a1f832.gif" alt="Pagination demo" />
|
174 |
|
175 | ## Contribute
|
176 |
|
177 | 1. [Submit an issue](https://github.com/AdeleD/react-paginate/issues)
|
178 | 2. Fork the repository
|
179 | 3. Create a dedicated branch (never ever work in `master`)
|
180 | 4. Run `npm start` http://localhost:3000
|
181 | 5. Fix bugs or implement features
|
182 | 6. Always write tests
|
183 | 7. Format with Prettier `npm run format` and check ESLint `npm run lint`
|
184 |
|
185 | Run tests:
|
186 |
|
187 | ```console
|
188 | make test
|
189 | ```
|
190 |
|
191 | [1]: https://github.com/AdeleD/react-paginate/blob/master/demo/js/demo.js
|