diff --git a/README.md b/README.md
index 594b3da3..beed22a2 100644
--- a/README.md
+++ b/README.md
@@ -76,7 +76,7 @@ React.render(, container);
| nextIcon | specifict the default previous icon | ReactNode \| (props: PaginationProps) => ReactNode | |
| jumpPrevIcon | specifict the default previous icon | ReactNode \| (props: PaginationProps) => ReactNode | |
| jumpNextIcon | specifict the default previous icon | ReactNode \| (props: PaginationProps) => ReactNode | |
-
+| pagerCount | show number of pagers | Number | 5 |
## License
diff --git a/examples/pagerCount.html b/examples/pagerCount.html
new file mode 100644
index 00000000..48cdce85
--- /dev/null
+++ b/examples/pagerCount.html
@@ -0,0 +1 @@
+placeholder
diff --git a/examples/pagerCount.js b/examples/pagerCount.js
new file mode 100644
index 00000000..68762380
--- /dev/null
+++ b/examples/pagerCount.js
@@ -0,0 +1,50 @@
+import 'rc-pagination/assets/index.less';
+import Pagination from 'rc-pagination';
+import React from 'react';
+import ReactDOM from 'react-dom';
+import Select from 'rc-select';
+import 'rc-select/assets/index.css';
+
+const itemRender = (current, type, element) => {
+ const hideItems = ['jump-last', 'jump-first'];
+
+ if (hideItems.includes(type)) {
+ return null;
+ }
+
+ return element;
+};
+
+function onShowSizeChange(current, pageSize) {
+ console.log(current, pageSize);
+}
+
+ReactDOM.render(
+
+
pageCount = 10, hide prev and next jumpers
+
+
+
Has `showSizeChanger` and `showQuickJumper`
+
+
+
pagerCount less than 3
+
+
+
Has `showLessItems` and `pagerCount`
+
+
+
The pagerCount is odd
+
+
+
The pagerCount is even
+
+
+, document.getElementById('__react-content'));
diff --git a/src/Pager.jsx b/src/Pager.jsx
index 421f9c9e..067aed90 100644
--- a/src/Pager.jsx
+++ b/src/Pager.jsx
@@ -25,7 +25,18 @@ const Pager = (props) => {
props.onKeyPress(e, props.onClick, props.page);
};
+ let pageType = 'page';
+ if (props.last) {
+ pageType = 'jump-last';
+ }
+ if (props.first) {
+ pageType = 'jump-first';
+ }
+
+ const itemNode = props.itemRender(props.page, pageType, {props.page});
+
return (
+ itemNode === null ? null :
{
onKeyPress={handleKeyPress}
tabIndex="0"
>
- {props.itemRender(props.page, 'page', {props.page})}
+ {itemNode}
);
};
diff --git a/src/Pagination.jsx b/src/Pagination.jsx
index 35e7e4eb..e8765114 100644
--- a/src/Pagination.jsx
+++ b/src/Pagination.jsx
@@ -53,6 +53,7 @@ class Pagination extends React.Component {
nextIcon: PropTypes.oneOfType([PropTypes.func, PropTypes.node]),
jumpPrevIcon: PropTypes.oneOfType([PropTypes.func, PropTypes.node]),
jumpNextIcon: PropTypes.oneOfType([PropTypes.func, PropTypes.node]),
+ pagerCount: PropTypes.number,
};
static defaultProps = {
@@ -74,6 +75,7 @@ class Pagination extends React.Component {
locale: LOCALE,
style: {},
itemRender: defaultItemRender,
+ pagerCount: 5,
};
constructor(props) {
@@ -81,9 +83,15 @@ class Pagination extends React.Component {
const hasOnChange = props.onChange !== noop;
const hasCurrent = ('current' in props);
+ const hasShowLessItems = ('showLessItems' in props);
if (hasCurrent && !hasOnChange) {
console.warn('Warning: You provided a `current` prop to a Pagination component without an `onChange` handler. This will render a read-only component.'); // eslint-disable-line
}
+ if (hasShowLessItems && props.showLessItems) {
+ console.warn(
+ 'Warning: `showLessItems` is deprecated since 1.18.0. Please use pagerCount instead.'
+ ) // eslint-disable-line
+ }
let current = props.defaultCurrent;
if ('current' in props) {
@@ -143,13 +151,17 @@ class Pagination extends React.Component {
}
getJumpPrevPage = () => {
- return Math.max(1, this.state.current - (this.props.showLessItems ? 3 : 5));
+ const { showLessItems } = this.props;
+ const hasPagerCount = this.hasPagerCount();
+ return Math.max(1, this.state.current - (showLessItems && !hasPagerCount ? 3 : 5));
}
getJumpNextPage = () => {
+ const { showLessItems } = this.props;
+ const hasPagerCount = this.hasPagerCount();
return Math.min(
calculatePage(undefined, this.state, this.props),
- this.state.current + (this.props.showLessItems ? 3 : 5)
+ this.state.current + (showLessItems && !hasPagerCount ? 3 : 5)
);
}
@@ -316,6 +328,8 @@ class Pagination extends React.Component {
}
}
+ hasPagerCount = () => !(this.props.pagerCount === 5)
+
render() {
// When hideOnSinglePage is true and there is only 1 page, hide the pager
if (this.props.hideOnSinglePage === true && this.props.total <= this.state.pageSize) {
@@ -334,8 +348,17 @@ class Pagination extends React.Component {
let lastPager = null;
let gotoButton = null;
+ const { pagerCount, showLessItems } = props;
+ // `pagerCount` priority is greater than `showLessItems`.
+ const hasPagerCount = this.hasPagerCount();
+ const boundary = pagerCount === 0 ? 0 : 1;
+ const pagerCountBoundary = pagerCount % 2 !== 0 ? 0 : boundary;
+ const boundaryRemainder = hasPagerCount ? pagerCountBoundary : 0;
+ const halfPagerCount = Math.max(0, Math.floor((pagerCount - 1) / 2));
+ const halfHasLessItemsCount = showLessItems ? 1 : halfPagerCount;
+ const pageBufferSize = hasPagerCount ? halfPagerCount : halfHasLessItemsCount;
+
const goButton = (props.showQuickJumper && props.showQuickJumper.goButton);
- const pageBufferSize = props.showLessItems ? 1 : 2;
const { current, pageSize } = this.state;
const prevPage = current - 1 > 0 ? current - 1 : 0;
@@ -425,7 +448,7 @@ class Pagination extends React.Component {
);
}
- if (allPages <= 5 + pageBufferSize * 2) {
+ if (allPages <= pageBufferSize * 2 + boundaryRemainder + 1) {
const pagerProps = {
locale,
rootPrefixCls: prefixCls,
@@ -456,8 +479,8 @@ class Pagination extends React.Component {
);
}
} else {
- const prevItemTitle = props.showLessItems ? locale.prev_3 : locale.prev_5;
- const nextItemTitle = props.showLessItems ? locale.next_3 : locale.next_5;
+ const prevItemTitle = showLessItems && !hasPagerCount ? locale.prev_3 : locale.prev_5;
+ const nextItemTitle = showLessItems && !hasPagerCount ? locale.next_3 : locale.next_5;
if (props.showPrevNextJumpers) {
let jumpPrevClassString = `${prefixCls}-jump-prev`;
if (props.jumpPrevIcon) {
@@ -500,6 +523,7 @@ class Pagination extends React.Component {
);
}
+
lastPager = (
);
- let left = Math.max(1, current - pageBufferSize);
+ let left = Math.max(1, current - pageBufferSize - boundaryRemainder);
let right = Math.min(current + pageBufferSize, allPages);
if (current - 1 <= pageBufferSize) {
- right = 1 + pageBufferSize * 2;
+ right = 1 + pageBufferSize * 2 + boundaryRemainder;
}
- if (allPages - current <= pageBufferSize) {
- left = allPages - pageBufferSize * 2;
+ if (allPages - current < pageBufferSize) {
+ left = allPages - pageBufferSize * 2 - boundaryRemainder;
}
for (let i = left; i <= right; i++) {
@@ -556,13 +581,13 @@ class Pagination extends React.Component {
);
}
- if (current - 1 >= pageBufferSize * 2 && current !== 1 + 2) {
+ if (current - boundaryRemainder - 2 > pageBufferSize) {
pagerList[0] = React.cloneElement(pagerList[0], {
className: `${prefixCls}-item-after-jump-prev`,
});
pagerList.unshift(jumpPrev);
}
- if (allPages - current >= pageBufferSize * 2 && current !== allPages - 2) {
+ if (allPages - current > pageBufferSize && current !== allPages - pageBufferSize - 1) {
pagerList[pagerList.length - 1] = React.cloneElement(pagerList[pagerList.length - 1], {
className: `${prefixCls}-item-before-jump-next`,
});
diff --git a/tests/Pagination.spec.js b/tests/Pagination.spec.js
index 25623d3e..7cd613a3 100644
--- a/tests/Pagination.spec.js
+++ b/tests/Pagination.spec.js
@@ -813,3 +813,142 @@ describe('data and aria props', () => {
});
});
});
+
+describe('pagerCount props', () => {
+ describe('with pagerCount, when hide first, last', () => {
+ const container = document.createElement('div');
+ document.body.appendChild(container);
+
+ const itemRender = (current, type, element) => {
+ if (type === 'jump-first' || type === 'jump-last') {
+ return null;
+ }
+ return element;
+ };
+
+ it('pageCount is 2, total is 10, show 1 pager', (done) => {
+ ReactDOM.render(
+ ,
+ container,
+ function () {
+ const pagers = TestUtils.scryRenderedDOMComponentsWithClass(
+ this,
+ 'rc-pagination-item'
+ );
+ expect(pagers.length).to.be(1);
+ done();
+ }
+ );
+ });
+
+ it('pageCount is 2, total is 11, show 2 pager', (done) => {
+ ReactDOM.render(
+ ,
+ container,
+ function () {
+ const pagers = TestUtils.scryRenderedDOMComponentsWithClass(
+ this,
+ 'rc-pagination-item'
+ );
+ expect(pagers.length).to.be(2);
+ done();
+ }
+ );
+ });
+
+ it('should show 10 pagers if pageCount equals 10', (done) => {
+ ReactDOM.render(
+ ,
+ container,
+ function () {
+ const pagers = TestUtils.scryRenderedDOMComponentsWithClass(
+ this,
+ 'rc-pagination-item'
+ );
+ expect(pagers.length).to.be(10);
+
+ const eighthPager = TestUtils.findRenderedDOMComponentWithClass(
+ this,
+ 'rc-pagination-item-8'
+ );
+ expect(TestUtils.isDOMComponent(eighthPager)).to.be(true);
+ Simulate.click(eighthPager);
+ setTimeout(() => {
+ const afterPagers = TestUtils.scryRenderedDOMComponentsWithClass(
+ this,
+ 'rc-pagination-item'
+ );
+ expect(afterPagers.length).to.be(10);
+ done();
+ }, 10);
+ }
+ );
+ });
+ });
+
+ describe('pagerCount is even', () => {
+ it('pageCount is even', (done) => {
+ const container = document.createElement('div');
+ document.body.appendChild(container);
+ ReactDOM.render(
+ ,
+ container,
+ function () {
+ const pagers = TestUtils.scryRenderedDOMComponentsWithClass(
+ this,
+ 'rc-pagination-item'
+ );
+ expect(pagers.length).to.be(9);
+
+ const sixthPager = TestUtils.findRenderedDOMComponentWithClass(
+ this,
+ 'rc-pagination-item-6'
+ );
+ expect(TestUtils.isDOMComponent(sixthPager)).to.be(true);
+ Simulate.click(sixthPager);
+ setTimeout(() => {
+ const afterPagers = TestUtils.scryRenderedDOMComponentsWithClass(
+ this,
+ 'rc-pagination-item'
+ );
+ expect(afterPagers.length).to.be(10);
+ done();
+ }, 10);
+ }
+ );
+ });
+
+ it('defaultCurrent is last page', (done) => {
+ const container = document.createElement('div');
+ document.body.appendChild(container);
+ ReactDOM.render(
+ ,
+ container,
+ function () {
+ setTimeout(() => {
+ const pagers = TestUtils.scryRenderedDOMComponentsWithClass(
+ this,
+ 'rc-pagination-item'
+ );
+ expect(pagers.length).to.be(8);
+
+ const pager46 = TestUtils.findRenderedDOMComponentWithClass(
+ this,
+ 'rc-pagination-item-46'
+ );
+ expect(TestUtils.isDOMComponent(pager46)).to.be(true);
+ Simulate.click(pager46);
+ setTimeout(() => {
+ const afterPagers = TestUtils.scryRenderedDOMComponentsWithClass(
+ this,
+ 'rc-pagination-item'
+ );
+ expect(afterPagers.length).to.be(9);
+ done();
+ }, 10);
+ }, 10);
+ }
+ );
+ });
+ });
+});