From 0b0ac36d6dfc050a54e5001f0b44bb8e0f349819 Mon Sep 17 00:00:00 2001 From: Michal Dziekonski Date: Sun, 4 Oct 2015 01:04:16 +0200 Subject: [PATCH 1/3] [added] Custom labels for Pagination's special element (ellipsis, first, last, prev & next) --- src/Pagination.js | 20 +++++++++++++++----- test/PaginationSpec.js | 30 +++++++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/src/Pagination.js b/src/Pagination.js index 8157914115..293c2cda69 100644 --- a/src/Pagination.js +++ b/src/Pagination.js @@ -17,6 +17,11 @@ const Pagination = React.createClass({ last: React.PropTypes.bool, prev: React.PropTypes.bool, next: React.PropTypes.bool, + firstLabel: React.PropTypes.node, + lastLabel: React.PropTypes.node, + prevLabel: React.PropTypes.node, + nextLabel: React.PropTypes.node, + ellipsisLabel: React.PropTypes.node, onSelect: React.PropTypes.func, /** * You can use a custom element for the buttons @@ -34,6 +39,11 @@ const Pagination = React.createClass({ prev: false, next: false, ellipsis: true, + firstLabel: '\u00ab', + lastLabel: '\u00bb', + prevLabel: '\u2039', + nextLabel: '\u203a', + ellipsisLabel: '...', buttonComponentClass: SafeAnchor, bsClass: 'pagination' }; @@ -89,7 +99,7 @@ const Pagination = React.createClass({ key="ellipsis" disabled buttonComponentClass={buttonComponentClass}> - ... + {this.props.ellipsisLabel} ); } @@ -109,7 +119,7 @@ const Pagination = React.createClass({ disabled={this.props.activePage === 1} onSelect={this.props.onSelect} buttonComponentClass={this.props.buttonComponentClass}> - + {this.props.prevLabel} ); }, @@ -126,7 +136,7 @@ const Pagination = React.createClass({ disabled={this.props.activePage >= this.props.items} onSelect={this.props.onSelect} buttonComponentClass={this.props.buttonComponentClass}> - + {this.props.nextLabel} ); }, @@ -143,7 +153,7 @@ const Pagination = React.createClass({ disabled={this.props.activePage === 1 } onSelect={this.props.onSelect} buttonComponentClass={this.props.buttonComponentClass}> - « + {this.props.firstLabel} ); }, @@ -160,7 +170,7 @@ const Pagination = React.createClass({ disabled={this.props.activePage >= this.props.items} onSelect={this.props.onSelect} buttonComponentClass={this.props.buttonComponentClass}> - » + {this.props.lastLabel} ); }, diff --git a/test/PaginationSpec.js b/test/PaginationSpec.js index 6b88fd1b20..e08f4e3142 100644 --- a/test/PaginationSpec.js +++ b/test/PaginationSpec.js @@ -52,7 +52,7 @@ describe('Pagination', () => { React.findDOMNode(pageButtons[4]).className.should.match(/\bactive\b/); }); - it('Should show the ellipsis, first, last, prev and next button', () => { + it('Should show the ellipsis, first, last, prev and next button with default labels', () => { let instance = ReactTestUtils.renderIntoDocument( { }); + it('Should show the ellipsis, first, last, prev and next button with custom labels', () => { + let instance = ReactTestUtils.renderIntoDocument( + + ); + let pageButtons = ReactTestUtils.scryRenderedDOMComponentsWithTag(instance, 'li'); + // add first, last, prev, next and ellipsis button + assert.equal(pageButtons.length, 8); + + assert.equal(React.findDOMNode(pageButtons[0]).innerText, 'first'); + assert.equal(React.findDOMNode(pageButtons[1]).innerText, 'prev'); + assert.equal(React.findDOMNode(pageButtons[5]).innerText, 'more'); + assert.equal(React.findDOMNode(pageButtons[6]).innerText, 'next'); + assert.equal(React.findDOMNode(pageButtons[7]).innerText, 'last'); + + }); + it('Should enumerate pagenums correctly when ellipsis=true', () => { const instance = ReactTestUtils.renderIntoDocument( Date: Wed, 7 Oct 2015 00:32:48 +0200 Subject: [PATCH 2/3] Simplify ellipsis, first, last, prev & next labels API --- src/Pagination.js | 90 ++++++++++++++++++++++++++++++------------ test/PaginationSpec.js | 15 +++---- 2 files changed, 71 insertions(+), 34 deletions(-) diff --git a/src/Pagination.js b/src/Pagination.js index 293c2cda69..97b316bb17 100644 --- a/src/Pagination.js +++ b/src/Pagination.js @@ -12,16 +12,51 @@ const Pagination = React.createClass({ activePage: React.PropTypes.number, items: React.PropTypes.number, maxButtons: React.PropTypes.number, - ellipsis: React.PropTypes.bool, - first: React.PropTypes.bool, - last: React.PropTypes.bool, - prev: React.PropTypes.bool, - next: React.PropTypes.bool, - firstLabel: React.PropTypes.node, - lastLabel: React.PropTypes.node, - prevLabel: React.PropTypes.node, - nextLabel: React.PropTypes.node, - ellipsisLabel: React.PropTypes.node, + /** + * When `true`, will display the default node value ('...'). + * When exactly `false`, will not display the element at all. + * Every other value (`truthy` or `null`) will be passed "as is". + */ + ellipsis: React.PropTypes.oneOfType([ + React.PropTypes.bool, + React.PropTypes.node + ]), + /** + * When `true`, will display the default node value ('«'). + * When exactly `false`, will not display the element at all. + * Every other value (`truthy` or `null`) will be passed "as is". + */ + first: React.PropTypes.oneOfType([ + React.PropTypes.bool, + React.PropTypes.node + ]), + /** + * When `true`, will display the default node value ('»'). + * When exactly `false`, will not display the element at all. + * Every other value (`truthy` or `null`) will be passed "as is". + */ + last: React.PropTypes.oneOfType([ + React.PropTypes.bool, + React.PropTypes.node + ]), + /** + * When `true`, will display the default node value ('‹'). + * When exactly `false`, will not display the element at all. + * Every other value (`truthy` or `null`) will be passed "as is". + */ + prev: React.PropTypes.oneOfType([ + React.PropTypes.bool, + React.PropTypes.node + ]), + /** + * When `true`, will display the default node value ('›'). + * When exactly `false`, will not display the element at all. + * Every other value (`truthy` or `null`) will be passed "as is". + */ + next: React.PropTypes.oneOfType([ + React.PropTypes.bool, + React.PropTypes.node + ]), onSelect: React.PropTypes.func, /** * You can use a custom element for the buttons @@ -39,11 +74,6 @@ const Pagination = React.createClass({ prev: false, next: false, ellipsis: true, - firstLabel: '\u00ab', - lastLabel: '\u00bb', - prevLabel: '\u2039', - nextLabel: '\u203a', - ellipsisLabel: '...', buttonComponentClass: SafeAnchor, bsClass: 'pagination' }; @@ -93,13 +123,15 @@ const Pagination = React.createClass({ ); } - if (maxButtons && hasHiddenPagesAfter && ellipsis) { + if (maxButtons && hasHiddenPagesAfter && ellipsis !== false) { pageButtons.push( - {this.props.ellipsisLabel} + + {this.props.ellipsis === true ? '...' : this.props.ellipsis} + ); } @@ -108,7 +140,7 @@ const Pagination = React.createClass({ }, renderPrev() { - if (!this.props.prev) { + if (this.props.prev === false) { return null; } @@ -119,13 +151,15 @@ const Pagination = React.createClass({ disabled={this.props.activePage === 1} onSelect={this.props.onSelect} buttonComponentClass={this.props.buttonComponentClass}> - {this.props.prevLabel} + + {this.props.prev === true ? '\u2039' : this.props.prev} + ); }, renderNext() { - if (!this.props.next) { + if (this.props.next === false) { return null; } @@ -136,13 +170,15 @@ const Pagination = React.createClass({ disabled={this.props.activePage >= this.props.items} onSelect={this.props.onSelect} buttonComponentClass={this.props.buttonComponentClass}> - {this.props.nextLabel} + + {this.props.next === true ? '\u203a' : this.props.next} + ); }, renderFirst() { - if (!this.props.first) { + if (this.props.first === false) { return null; } @@ -153,13 +189,15 @@ const Pagination = React.createClass({ disabled={this.props.activePage === 1 } onSelect={this.props.onSelect} buttonComponentClass={this.props.buttonComponentClass}> - {this.props.firstLabel} + + {this.props.first === true ? '\u00ab' : this.props.first} + ); }, renderLast() { - if (!this.props.last) { + if (this.props.last === false) { return null; } @@ -170,7 +208,9 @@ const Pagination = React.createClass({ disabled={this.props.activePage >= this.props.items} onSelect={this.props.onSelect} buttonComponentClass={this.props.buttonComponentClass}> - {this.props.lastLabel} + + {this.props.last === true ? '\u00bb' : this.props.last} + ); }, diff --git a/test/PaginationSpec.js b/test/PaginationSpec.js index e08f4e3142..371ddb59f8 100644 --- a/test/PaginationSpec.js +++ b/test/PaginationSpec.js @@ -59,6 +59,7 @@ describe('Pagination', () => { last={true} prev={true} next={true} + ellipsis={true} maxButtons={3} activePage={10} items={20} /> @@ -78,15 +79,11 @@ describe('Pagination', () => { it('Should show the ellipsis, first, last, prev and next button with custom labels', () => { let instance = ReactTestUtils.renderIntoDocument( From b67bb44a0622198df5a4b8b2fe372eaeaf51bb97 Mon Sep 17 00:00:00 2001 From: Michal Dziekonski Date: Wed, 7 Oct 2015 21:06:00 +0200 Subject: [PATCH 3/3] Don't be so strict about falsiness comparison (match this with the rest of the code) --- src/Pagination.js | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/src/Pagination.js b/src/Pagination.js index 97b316bb17..a09a8117d2 100644 --- a/src/Pagination.js +++ b/src/Pagination.js @@ -14,8 +14,7 @@ const Pagination = React.createClass({ maxButtons: React.PropTypes.number, /** * When `true`, will display the default node value ('...'). - * When exactly `false`, will not display the element at all. - * Every other value (`truthy` or `null`) will be passed "as is". + * Otherwise, will display provided node (when specified). */ ellipsis: React.PropTypes.oneOfType([ React.PropTypes.bool, @@ -23,8 +22,7 @@ const Pagination = React.createClass({ ]), /** * When `true`, will display the default node value ('«'). - * When exactly `false`, will not display the element at all. - * Every other value (`truthy` or `null`) will be passed "as is". + * Otherwise, will display provided node (when specified). */ first: React.PropTypes.oneOfType([ React.PropTypes.bool, @@ -32,8 +30,7 @@ const Pagination = React.createClass({ ]), /** * When `true`, will display the default node value ('»'). - * When exactly `false`, will not display the element at all. - * Every other value (`truthy` or `null`) will be passed "as is". + * Otherwise, will display provided node (when specified). */ last: React.PropTypes.oneOfType([ React.PropTypes.bool, @@ -41,8 +38,7 @@ const Pagination = React.createClass({ ]), /** * When `true`, will display the default node value ('‹'). - * When exactly `false`, will not display the element at all. - * Every other value (`truthy` or `null`) will be passed "as is". + * Otherwise, will display provided node (when specified). */ prev: React.PropTypes.oneOfType([ React.PropTypes.bool, @@ -50,8 +46,7 @@ const Pagination = React.createClass({ ]), /** * When `true`, will display the default node value ('›'). - * When exactly `false`, will not display the element at all. - * Every other value (`truthy` or `null`) will be passed "as is". + * Otherwise, will display provided node (when specified). */ next: React.PropTypes.oneOfType([ React.PropTypes.bool, @@ -123,7 +118,7 @@ const Pagination = React.createClass({ ); } - if (maxButtons && hasHiddenPagesAfter && ellipsis !== false) { + if (maxButtons && hasHiddenPagesAfter && ellipsis) { pageButtons.push(