diff --git a/src/Pagination.js b/src/Pagination.js index 71909aa694..6548e605cc 100644 --- a/src/Pagination.js +++ b/src/Pagination.js @@ -2,6 +2,8 @@ import React from 'react'; import classNames from 'classnames'; import BootstrapMixin from './BootstrapMixin'; import PaginationButton from './PaginationButton'; +import CustomPropTypes from './utils/CustomPropTypes'; +import SafeAnchor from './SafeAnchor'; const Pagination = React.createClass({ mixins: [BootstrapMixin], @@ -15,7 +17,11 @@ const Pagination = React.createClass({ last: React.PropTypes.bool, prev: React.PropTypes.bool, next: React.PropTypes.bool, - onSelect: React.PropTypes.func + onSelect: React.PropTypes.func, + /** + * You can use a custom element for the buttons + */ + buttonComponentClass: CustomPropTypes.elementType }, getDefaultProps() { @@ -28,6 +34,7 @@ const Pagination = React.createClass({ prev: false, next: false, ellipsis: true, + buttonComponentClass: SafeAnchor, bsClass: 'pagination' }; }, @@ -40,7 +47,8 @@ const Pagination = React.createClass({ activePage, items, onSelect, - ellipsis + ellipsis, + buttonComponentClass } = this.props; if(maxButtons){ @@ -68,7 +76,8 @@ const Pagination = React.createClass({ key={pagenumber} eventKey={pagenumber} active={pagenumber === activePage} - onSelect={onSelect}> + onSelect={onSelect} + buttonComponentClass={buttonComponentClass}> {pagenumber} ); @@ -78,7 +87,8 @@ const Pagination = React.createClass({ pageButtons.push( + disabled + buttonComponentClass={buttonComponentClass}> ... ); @@ -97,7 +107,8 @@ const Pagination = React.createClass({ key='prev' eventKey={this.props.activePage - 1} disabled={this.props.activePage === 1} - onSelect={this.props.onSelect}> + onSelect={this.props.onSelect} + buttonComponentClass={this.props.buttonComponentClass}> ); @@ -113,7 +124,8 @@ const Pagination = React.createClass({ key='next' eventKey={this.props.activePage + 1} disabled={this.props.activePage >= this.props.items} - onSelect={this.props.onSelect}> + onSelect={this.props.onSelect} + buttonComponentClass={this.props.buttonComponentClass}> ); @@ -129,7 +141,8 @@ const Pagination = React.createClass({ key='first' eventKey={1} disabled={this.props.activePage === 1 } - onSelect={this.props.onSelect}> + onSelect={this.props.onSelect} + buttonComponentClass={this.props.buttonComponentClass}> « ); @@ -145,7 +158,8 @@ const Pagination = React.createClass({ key='last' eventKey={this.props.items} disabled={this.props.activePage >= this.props.items} - onSelect={this.props.onSelect}> + onSelect={this.props.onSelect} + buttonComponentClass={this.props.buttonComponentClass}> » ); diff --git a/src/PaginationButton.js b/src/PaginationButton.js index 23177025be..df1f2054f2 100644 --- a/src/PaginationButton.js +++ b/src/PaginationButton.js @@ -2,7 +2,7 @@ import React from 'react'; import classNames from 'classnames'; import BootstrapMixin from './BootstrapMixin'; import createSelectedEvent from './utils/createSelectedEvent'; -import SafeAnchor from './SafeAnchor'; +import CustomPropTypes from './utils/CustomPropTypes'; const PaginationButton = React.createClass({ mixins: [BootstrapMixin], @@ -15,7 +15,11 @@ const PaginationButton = React.createClass({ ]), onSelect: React.PropTypes.func, disabled: React.PropTypes.bool, - active: React.PropTypes.bool + active: React.PropTypes.bool, + /** + * You can use a custom element for this component + */ + buttonComponentClass: CustomPropTypes.elementType }, getDefaultProps() { @@ -44,9 +48,11 @@ const PaginationButton = React.createClass({ ...anchorProps } = this.props; + let ButtonComponentClass = this.props.buttonComponentClass; + return (
  • -
  • diff --git a/test/OverlayTriggerSpec.js b/test/OverlayTriggerSpec.js index 43095d13ad..78b63502b4 100644 --- a/test/OverlayTriggerSpec.js +++ b/test/OverlayTriggerSpec.js @@ -49,7 +49,7 @@ describe('OverlayTrigger', function() { const overlayTrigger = React.findDOMNode(instance); ReactTestUtils.Simulate.click(overlayTrigger); - expect(document.getElementsByClassName('test-overlay').length).to.equal(1) + expect(document.getElementsByClassName('test-overlay').length).to.equal(1); }); it('Should pass transition callbacks to Transition', function (done) { diff --git a/test/PaginationSpec.js b/test/PaginationSpec.js index 6645afb81e..9666a54cc5 100644 --- a/test/PaginationSpec.js +++ b/test/PaginationSpec.js @@ -114,4 +114,65 @@ describe('Pagination', function () { assert.include(React.findDOMNode(pageButtons[0]).className, 'disabled'); assert.include(React.findDOMNode(pageButtons[1]).className, 'disabled'); }); + + it('Should wrap buttons in SafeAnchor when no buttonComponentClass prop is supplied', function () { + let instance = ReactTestUtils.renderIntoDocument( + + ); + let pageButtons = ReactTestUtils.scryRenderedDOMComponentsWithTag(instance, 'li'); + + let tagName = 'A'; + + assert.equal(React.findDOMNode(pageButtons[0]).children[0].tagName, tagName); + assert.equal(React.findDOMNode(pageButtons[1]).children[0].tagName, tagName); + + assert.equal(React.findDOMNode(pageButtons[0]).children[0].getAttribute('href'), ''); + assert.equal(React.findDOMNode(pageButtons[1]).children[0].getAttribute('href'), ''); + }); + + it('Should wrap each button in a buttonComponentClass when it is present', function () { + class DummyElement extends React.Component { + render() { + return
    ; + } + } + + let instance = ReactTestUtils.renderIntoDocument( + + ); + let pageButtons = ReactTestUtils.scryRenderedDOMComponentsWithTag(instance, 'li'); + + let tagName = 'DIV'; + + assert.equal(React.findDOMNode(pageButtons[0]).children[0].tagName, tagName); + assert.equal(React.findDOMNode(pageButtons[1]).children[0].tagName, tagName); + }); + + it('Should call onSelect with custom buttonComponentClass', function (done) { + class DummyElement extends React.Component { + render() { + return
    ; + } + } + + function onSelect(event, selectedEvent) { + assert.equal(selectedEvent.eventKey, 3); + done(); + } + + let instance = ReactTestUtils.renderIntoDocument( + + ); + + ReactTestUtils.Simulate.click( + ReactTestUtils.scryRenderedDOMComponentsWithTag(instance, 'div')[2] + ); + }); });