cuz
Version:
Front-end modular development kit.
276 lines (253 loc) • 7.33 kB
JavaScript
import React from 'react';
import classNames from 'classnames';
import { utils, SafeAnchor } from 'react-bootstrap';
import PaginationButton from 'react-bootstrap/lib/PaginationButton';
const Pagination = React.createClass({
propTypes: {
activePage: React.PropTypes.number,
items: React.PropTypes.number,
maxButtons: React.PropTypes.number,
noPageButton: React.PropTypes.bool,
/**
* When `true`, will display the default node value ('...').
* Otherwise, will display provided node (when specified).
*/
ellipsis: React.PropTypes.oneOfType([
React.PropTypes.bool,
React.PropTypes.node
]),
/**
* When `true`, will display the default node value ('«').
* Otherwise, will display provided node (when specified).
*/
first: React.PropTypes.oneOfType([
React.PropTypes.bool,
React.PropTypes.node
]),
/**
* When `true`, will display the default node value ('»').
* Otherwise, will display provided node (when specified).
*/
last: React.PropTypes.oneOfType([
React.PropTypes.bool,
React.PropTypes.node
]),
/**
* When `true`, will display the default node value ('‹').
* Otherwise, will display provided node (when specified).
*/
prev: React.PropTypes.oneOfType([
React.PropTypes.bool,
React.PropTypes.node
]),
/**
* When `true`, will display the default node value ('›').
* Otherwise, will display provided node (when specified).
*/
next: React.PropTypes.oneOfType([
React.PropTypes.bool,
React.PropTypes.node
]),
onSelect: React.PropTypes.func,
/**
* You can use a custom element for the buttons
*/
buttonComponentClass: React.PropTypes.any,
className: React.PropTypes.string
},
getDefaultProps() {
return {
activePage: 1,
items: 1,
maxButtons: 5,
first: false,
last: false,
prev: false,
next: false,
noPageButton: false,
ellipsis: true,
buttonComponentClass: SafeAnchor,
bsClass: 'pagination'
};
},
renderPageButtons() {
const pageButtons = [];
let startPage;
let endPage;
let hasHiddenPagesAfter;
const {
maxButtons,
activePage,
items,
onSelect,
ellipsis,
buttonComponentClass
} = this.props;
let hiddenPagesBefore = activePage - parseInt(maxButtons / 2, 10);
startPage = hiddenPagesBefore > 1 ? hiddenPagesBefore : 1;
hasHiddenPagesAfter = startPage + maxButtons < items;
if (!hasHiddenPagesAfter) {
endPage = items;
startPage = items - maxButtons + 1;
if (startPage < 1) {
startPage = 1;
}
hiddenPagesBefore = startPage;
} else {
endPage = startPage + maxButtons - 1;
}
if (hiddenPagesBefore > 1) {
pageButtons.push(
<PaginationButton
key={1}
eventKey={1}
active={activePage === 1}
onSelect={onSelect}
buttonComponentClass={buttonComponentClass}>
{1}
</PaginationButton>
);
}
if (hiddenPagesBefore > 2) {
pageButtons.push(
<PaginationButton
key="preEllipsis"
disabled
className="no-border"
buttonComponentClass={buttonComponentClass}>
<span aria-label="More1">
{this.props.ellipsis === true ? '...' : this.props.ellipsis}
</span>
</PaginationButton>
);
}
for (let pagenumber = startPage; pagenumber <= endPage; pagenumber++) {
pageButtons.push(
<PaginationButton
key={pagenumber}
eventKey={pagenumber}
active={pagenumber === activePage}
onSelect={onSelect}
buttonComponentClass={buttonComponentClass}>
{pagenumber}
</PaginationButton>
);
}
if (maxButtons && hasHiddenPagesAfter && ellipsis) {
pageButtons.push(
<PaginationButton
key="afterEllipsis"
disabled
className="no-border"
buttonComponentClass={buttonComponentClass}>
<span aria-label="More">
{this.props.ellipsis === true ? '...' : this.props.ellipsis}
</span>
</PaginationButton>
);
pageButtons.push(
<PaginationButton
key={items}
eventKey={items}
active={items === activePage}
onSelect={onSelect}
buttonComponentClass={buttonComponentClass}>
{items}
</PaginationButton>
);
}
return pageButtons;
},
renderNumber() {
const { items, activePage } = this.props;
return (
<span className="number-page">
{activePage}/{items}
</span>
);
},
renderPrev() {
if (!this.props.prev) {
return null;
}
return (
<PaginationButton
key="prev"
eventKey={this.props.activePage - 1}
disabled={this.props.activePage === 1}
onSelect={this.props.onSelect}
buttonComponentClass={this.props.buttonComponentClass}>
<span aria-label="Previous">
{this.props.prev === true ? <i className="fa fa-angle-left"></i> : this.props.prev}
</span>
</PaginationButton>
);
},
renderNext() {
if (!this.props.next) {
return null;
}
return (
<PaginationButton
key="next"
eventKey={this.props.activePage + 1}
disabled={this.props.activePage >= this.props.items}
onSelect={this.props.onSelect}
buttonComponentClass={this.props.buttonComponentClass}>
<span aria-label="Next">
{this.props.next === true ? <i className="fa fa-angle-right"></i> : this.props.next}
</span>
</PaginationButton>
);
},
renderFirst() {
if (!this.props.first) {
return null;
}
return (
<PaginationButton
key="first"
eventKey={1}
disabled={this.props.activePage === 1 }
onSelect={this.props.onSelect}
buttonComponentClass={this.props.buttonComponentClass}>
<span aria-label="First">
{this.props.first === true ? <i className="fa fa-angle-double-left"></i> : this.props.first}
</span>
</PaginationButton>
);
},
renderLast() {
if (!this.props.last) {
return null;
}
return (
<PaginationButton
key="last"
eventKey={this.props.items}
disabled={this.props.activePage >= this.props.items}
onSelect={this.props.onSelect}
buttonComponentClass={this.props.buttonComponentClass}>
<span aria-label="Last">
{this.props.last === true ? <i className="fa fa-angle-double-right"></i> : this.props.last}
</span>
</PaginationButton>
);
},
render() {
const {noPageButton} = this.props;
return (
<ul
{...this.props}
className={classNames(this.props.className, utils.bootstrapUtils.getClassSet(this.props))}>
{this.renderFirst()}
{this.renderPrev()}
{noPageButton === false && this.renderPageButtons()}
{this.renderNext()}
{this.renderLast()}
{noPageButton && this.renderNumber()}
</ul>
);
}
});
export default Pagination;