From 57ec3fd56efcf27d7187bd5dc4c236ae66feea49 Mon Sep 17 00:00:00 2001 From: Nat Budin Date: Fri, 9 Nov 2018 08:24:29 -0800 Subject: [PATCH 1/5] Add ellipsis and ellipsisText to allow showing the first and last page even when they wouldn't ordinarily appear --- README.md | 2 + src/components/Ellipsis.js | 39 +++++++++++++++++++ src/components/Pagination.js | 74 +++++++++++++++++++++++++++++++++--- src/example/App.js | 36 ++++++++++++++++++ 4 files changed, 146 insertions(+), 5 deletions(-) create mode 100644 src/components/Ellipsis.js diff --git a/README.md b/README.md index fd3a140..365040a 100644 --- a/README.md +++ b/README.md @@ -93,3 +93,5 @@ Name | Type | Default | Description `linkClassPrev` | String | | Class of the previous `` tag `linkClassNext` | String | | Class of the next `` tag `linkClassLast` | String | | Class of the last `` tag +`ellipsis` | Boolean | `false` | Put links to the first/last page along with an ellipsis if they are out of the page range +`ellipsisText` | String / ReactElement | `…` | Text of ellipsis element diff --git a/src/components/Ellipsis.js b/src/components/Ellipsis.js new file mode 100644 index 0000000..bab86ba --- /dev/null +++ b/src/components/Ellipsis.js @@ -0,0 +1,39 @@ +import React, { Component } from "react"; +import PropTypes from "prop-types"; +import cx from "classnames"; + +export default class Ellipsis extends Component { + static propTypes = { + ellipsisText: PropTypes.oneOfType([PropTypes.string, PropTypes.element]), + disabledClass: PropTypes.string, + itemClass: PropTypes.string, + linkClass: PropTypes.string + }; + + static defaultProps = { + ellipsisText: "…", + disabledClass: "disabled", + itemClass: undefined, + linkClass: undefined + }; + + render() { + let { + ellipsisText, + itemClass, + disabledClass, + linkClass + } = this.props; + + const css = cx(itemClass, disabledClass); + const linkCss = cx(linkClass); + + return ( +
  • + event.preventDefault()}> + {ellipsisText} + +
  • + ); + } +} diff --git a/src/components/Pagination.js b/src/components/Pagination.js index cd59685..010c30d 100644 --- a/src/components/Pagination.js +++ b/src/components/Pagination.js @@ -2,6 +2,7 @@ import React, { Component } from "react"; import PropTypes from "prop-types"; import paginator from "paginator"; import Page from "./Page"; +import Ellipsis from "./Ellipsis"; import cx from "classnames"; export default class Pagination extends React.Component { @@ -32,7 +33,9 @@ export default class Pagination extends React.Component { linkClassNext: PropTypes.string, linkClassLast: PropTypes.string, hideFirstLastPages: PropTypes.bool, - getPageUrl: PropTypes.func + getPageUrl: PropTypes.func, + ellipsis: PropTypes.bool, + ellipsisText: PropTypes.oneOfType([PropTypes.string, PropTypes.element]) }; static defaultProps = { @@ -48,7 +51,8 @@ export default class Pagination extends React.Component { linkClass: undefined, activeLinkClass: undefined, hideFirstLastPages: false, - getPageUrl: (i) => "#" + getPageUrl: (i) => "#", + ellipsisText: "…" }; isFirstPageVisible(has_previous_page) { @@ -103,7 +107,9 @@ export default class Pagination extends React.Component { linkClassNext, linkClassLast, hideFirstLastPages, - getPageUrl + getPageUrl, + ellipsis, + ellipsisText } = this.props; const paginationInfo = new paginator( @@ -111,6 +117,35 @@ export default class Pagination extends React.Component { pageRangeDisplayed ).build(totalItemsCount, activePage); + if (ellipsis && paginationInfo.first_page > 1) { + pages.push( + + ); + + if (paginationInfo.first_page > 2) { + pages.push( + + ); + } + } + for ( let i = paginationInfo.first_page; i <= paginationInfo.last_page; @@ -132,7 +167,36 @@ export default class Pagination extends React.Component { ); } - this.isPrevPageVisible(paginationInfo.has_previous_page) && + if (ellipsis && paginationInfo.last_page < paginationInfo.total_pages) { + if (paginationInfo.last_page < paginationInfo.total_pages - 1) { + pages.push( + + ); + } + + pages.push( + + ); + } + + this.isPrevPageVisible(paginationInfo.has_previous_page) && pages.unshift( ); - this.isFirstPageVisible(paginationInfo.has_previous_page) && + this.isFirstPageVisible(paginationInfo.has_previous_page) && pages.unshift( + ); +}`; + const overrideText = `render() { return ( + +
    + +
    + {ellipsis} +
    + +
    +
    +
    ); } From c31c05fb4e6a09c39e13a551b77bfe792c5e0c9d Mon Sep 17 00:00:00 2001 From: Nat Budin Date: Fri, 9 Nov 2018 08:24:39 -0800 Subject: [PATCH 2/5] Unrelated capitalization fix --- src/components/Page.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Page.js b/src/components/Page.js index 86d9e09..5597f91 100644 --- a/src/components/Page.js +++ b/src/components/Page.js @@ -22,7 +22,7 @@ export default class Page extends Component { disabledClass: "disabled", itemClass: undefined, linkClass: undefined, - activeLinkCLass: undefined, + activeLinkClass: undefined, isActive: false, isDisabled: false, href: "#" From 21595b09bc063322e4dff3865212be1520a07d4f Mon Sep 17 00:00:00 2001 From: Nat Budin Date: Fri, 9 Nov 2018 08:32:04 -0800 Subject: [PATCH 3/5] Don't bother with the ellipsis if we could just show a single page link --- src/components/Pagination.js | 38 ++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/src/components/Pagination.js b/src/components/Pagination.js index 010c30d..477edb3 100644 --- a/src/components/Pagination.js +++ b/src/components/Pagination.js @@ -133,7 +133,24 @@ export default class Pagination extends React.Component { /> ); - if (paginationInfo.first_page > 2) { + if (paginationInfo.first_page === 3) { + // we might as well show a real link to page 2 since it takes up the same + // space as an ellipsis + pages.push( + + ); + } else if (paginationInfo.first_page > 3) { pages.push( + ); + } else if (paginationInfo.last_page < paginationInfo.total_pages - 1) { pages.push( Date: Fri, 9 Nov 2018 08:43:09 -0800 Subject: [PATCH 4/5] Rebuild --- dist/Page.js | 2 +- dist/Pagination.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/Page.js b/dist/Page.js index 8e2f1e5..56bb0c6 100644 --- a/dist/Page.js +++ b/dist/Page.js @@ -1 +1 @@ -"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var _createClass=function(){function e(e,t){for(var r=0;r1&&(e.push(_react2.default.createElement(_Page2.default,{isActive:1===i,key:1,href:x(1),pageNumber:1,pageText:"1",onClick:o,itemClass:g,linkClass:m,activeClass:_,activeLinkClass:h})),3===N.first_page?e.push(_react2.default.createElement(_Page2.default,{isActive:2===i,key:2,href:x(2),pageNumber:2,pageText:"2",onClick:o,itemClass:g,linkClass:m,activeClass:_,activeLinkClass:h})):N.first_page>3&&e.push(_react2.default.createElement(_Ellipsis2.default,{key:"startEllipsis",itemClass:g,linkClass:m,disabledClass:v,ellipsisText:E})));for(var D=N.first_page;D<=N.last_page;D++)e.push(_react2.default.createElement(_Page2.default,{isActive:D===i,key:D,href:x(D),pageNumber:D,pageText:D+"",onClick:o,itemClass:g,linkClass:m,activeClass:_,activeLinkClass:h}));return T&&N.last_page Date: Fri, 9 Nov 2018 08:44:33 -0800 Subject: [PATCH 5/5] Add Ellipsis component to the build --- build.js | 5 +++++ dist/Ellipsis.js | 1 + 2 files changed, 6 insertions(+) create mode 100644 dist/Ellipsis.js diff --git a/build.js b/build.js index a477efe..2c4c559 100644 --- a/build.js +++ b/build.js @@ -13,4 +13,9 @@ mkdirp("dist", function(err) { "./dist/Page.js", UglifyJS.minify(babel.transformFileSync("src/components/Page.js", {}).code).code ); + + fs.writeFileSync( + "./dist/Ellipsis.js", + UglifyJS.minify(babel.transformFileSync("src/components/Ellipsis.js", {}).code).code + ); }); diff --git a/dist/Ellipsis.js b/dist/Ellipsis.js new file mode 100644 index 0000000..79e5a8c --- /dev/null +++ b/dist/Ellipsis.js @@ -0,0 +1 @@ +"use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _possibleConstructorReturn(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function _inherits(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(exports,"__esModule",{value:!0});var _createClass=function(){function e(e,t){for(var r=0;r