@dtrussia/react-pager
Version:
Stateless Pager component
267 lines (218 loc) • 20.9 kB
JavaScript
;
var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; })();
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
Object.defineProperty(exports, "__esModule", {
value: true
});
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _page = require('./page');
var _page2 = _interopRequireDefault(_page);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
* # Stateless Pager component
*
* ## Usage
* ```
* <Pager current={3}
* total={20}
* visiblePages={5}
* onPageChanged={this.handlePageChanged}
* titles={{
* first: "First",
* prev: "Prev",
* prevSet: "<<<",
* nextSet: ">>>",
* next: "Next",
* last: "Last"
* }} />
* ```
*
* ## How it looks like
* ```
* First | Prev | ... | 6 | 7 | 8 | 9 | ... | Next | Last
* ```
*
*/
/**
* ## Constants
*/
var BASE_SHIFT = 0;
var TITLE_SHIFT = 1;
var TITLES = {
first: 'First',
prev: '«',
prevSet: '...',
nextSet: '...',
next: '»',
last: 'Last'
};
function range(start, end) {
var res = [];
for (var i = start; i < end; i++) {
res.push(i);
}
return res;
}
var Pager = (function (_Component) {
_inherits(Pager, _Component);
function Pager(props) {
_classCallCheck(this, Pager);
var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(Pager).call(this, props));
_this.handleFirstPage = function () {
if (_this.isPrevDisabled()) return;
_this.handlePageChanged(BASE_SHIFT);
};
_this.handlePreviousPage = function () {
if (_this.isPrevDisabled()) return;
_this.handlePageChanged(_this.props.current - TITLE_SHIFT);
};
_this.handleNextPage = function () {
if (_this.isNextDisabled()) return;
_this.handlePageChanged(_this.props.current + TITLE_SHIFT);
};
_this.handleLastPage = function () {
if (_this.isNextDisabled()) return;
_this.handlePageChanged(_this.props.total - TITLE_SHIFT);
};
_this.handleMorePrevPages = function () {
var blocks = _this.calcBlocks();
_this.handlePageChanged(blocks.current * blocks.size - TITLE_SHIFT);
};
_this.handleMoreNextPages = function () {
var blocks = _this.calcBlocks();
_this.handlePageChanged((blocks.current + TITLE_SHIFT) * blocks.size);
};
_this.handlePageChanged = function (el) {
var handler = _this.props.onPageChanged;
if (handler) handler(el);
};
_this.calcBlocks = function () {
var _this$props = _this.props;
var total = _this$props.total;
var visiblePages = _this$props.visiblePages;
var current = _this.props.current + TITLE_SHIFT;
var blockSize = visiblePages;
var blocks = Math.ceil(total / blockSize);
var currentBlock = Math.ceil(current / blockSize) - TITLE_SHIFT;
return {
total: blocks,
current: currentBlock,
size: blockSize
};
};
_this.isPrevDisabled = function () {
return _this.props.current <= BASE_SHIFT;
};
_this.isNextDisabled = function () {
return _this.props.current >= _this.props.total - TITLE_SHIFT;
};
_this.isPrevMoreHidden = function () {
var blocks = _this.calcBlocks();
return blocks.total === TITLE_SHIFT || blocks.current === BASE_SHIFT;
};
_this.isNextMoreHidden = function () {
var blocks = _this.calcBlocks();
return blocks.total === TITLE_SHIFT || blocks.current === blocks.total - TITLE_SHIFT;
};
_this.visibleRange = function () {
var blocks = _this.calcBlocks();
var start = blocks.current * blocks.size;
var delta = _this.props.total - start;
var end = start + (delta > blocks.size ? blocks.size : delta);
return [start + TITLE_SHIFT, end + TITLE_SHIFT];
};
_this.getTitles = function (key) {
var _this$props$titles = _this.props.titles;
var titles = _this$props$titles === undefined ? {} : _this$props$titles;
return titles[key] || TITLES[key];
};
_this.renderPages = function (_ref) {
var _ref2 = _slicedToArray(_ref, 2);
var first = _ref2[0];
var second = _ref2[1];
return range(first, second).map(function (el, idx) {
var current = el - TITLE_SHIFT;
var onClick = _this.handlePageChanged.bind(null, current);
var isActive = _this.props.current === current;
return _react2.default.createElement(
_page2.default,
{ key: idx, isActive: isActive, className: 'pagination-btn', onClick: onClick },
el
);
});
};
return _this;
}
_createClass(Pager, [{
key: 'render',
value: function render() {
var titles = this.getTitles;
return _react2.default.createElement(
'nav',
{ className: 'pagination' },
_react2.default.createElement(
_page2.default,
{ className: 'pagination-btn',
key: 'pagination-first-page',
isDisabled: this.isPrevDisabled(),
onClick: this.handleFirstPage },
titles('first')
),
_react2.default.createElement(
_page2.default,
{ className: 'pagination-btn',
key: 'pagination-prev-page',
isDisabled: this.isPrevDisabled(),
onClick: this.handlePreviousPage },
titles('prev')
),
_react2.default.createElement(
_page2.default,
{ className: 'pagination-btn pagination-btn-more',
key: 'pagination-prev-more',
isHidden: this.isPrevMoreHidden(),
onClick: this.handleMorePrevPages },
titles('prevSet')
),
this.renderPages(this.visibleRange()),
_react2.default.createElement(
_page2.default,
{ className: 'pagination-btn pagination-btn-more',
key: 'pagination-next-more',
isHidden: this.isNextMoreHidden(),
onClick: this.handleMoreNextPages },
titles('nextSet')
),
_react2.default.createElement(
_page2.default,
{ className: 'pagination-btn',
key: 'pagination-next-page',
isDisabled: this.isNextDisabled(),
onClick: this.handleNextPage },
titles('next')
),
_react2.default.createElement(
_page2.default,
{ className: 'pagination-btn',
key: 'pagination-last-page',
isDisabled: this.isNextDisabled(),
onClick: this.handleLastPage },
titles('last')
)
);
}
}]);
return Pager;
})(_react.Component);
Pager.propTypes = {
current: _react.PropTypes.number.isRequired,
total: _react.PropTypes.number.isRequired,
visiblePages: _react.PropTypes.number.isRequired,
titles: _react.PropTypes.object,
onPageChanged: _react.PropTypes.func,
onPageSizeChanged: _react.PropTypes.func
};
exports.default = Pager;