use-pagination
Version:
React hook for data pagination
134 lines (125 loc) • 5.52 kB
JavaScript
Object.defineProperty(exports, '__esModule', { value: true });
var React = require('react');
/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
var __assign = function() {
__assign = Object.assign || function __assign(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var getInitialState = function (props) {
var items = props.items, _a = props.initialPage, initialPage = _a === void 0 ? 1 : _a, itemsPerPage = props.itemsPerPage;
if (itemsPerPage <= 0) {
throw new Error('itemsPerPage must be > 0');
}
var maxPages = Math.ceil(items.length / itemsPerPage);
var currentPage = clamp(initialPage, 1, maxPages);
var currentItems = getCurrentItems(items, currentPage, itemsPerPage);
var _b = getBoundingPages(currentPage, maxPages), previousPage = _b[0], nextPage = _b[1];
var hasNextPage = nextPage <= maxPages && currentPage !== maxPages;
var hasPreviousPage = previousPage >= 1 && currentPage !== 1;
return {
currentItems: currentItems,
currentPage: currentPage,
hasNextPage: hasNextPage,
hasPreviousPage: hasPreviousPage,
items: items,
itemsPerPage: itemsPerPage,
maxPages: maxPages,
nextPage: nextPage,
previousPage: previousPage,
};
};
/**
* Prevents a number from going out of bounds
*/
var clamp = function (num, min, max) {
return Math.min(Math.max(num, min), max);
};
var getBoundingPages = function (currentPage, maxPages) {
var previousPage = Math.max(1, currentPage - 1);
var nextPage = Math.min(currentPage + 1, maxPages);
return [previousPage, nextPage];
};
var getCurrentItems = function (items, currentPage, itemsPerPage) {
return items.slice().splice((currentPage - 1) * itemsPerPage, itemsPerPage);
};
var reducer = function (state, action) {
var items = state.items, itemsPerPage = state.itemsPerPage, maxPages = state.maxPages;
var currentPage = state.currentPage;
switch (action.type) {
case 'next': {
currentPage = clamp(state.currentPage + 1, 1, maxPages);
break;
}
case 'previous': {
currentPage = clamp(state.currentPage - 1, 1, maxPages);
break;
}
case 'set': {
currentPage = clamp(action.currentPage, 1, maxPages);
break;
}
case 'update': {
return Object.assign({}, state, {
items: action.items,
});
}
case 'reset': {
return Object.assign({}, state, getInitialState(action.initialState));
}
default: {
throw new Error("Unknown action type: " + action.type);
}
}
var _a = getBoundingPages(currentPage, maxPages), previousPage = _a[0], nextPage = _a[1];
var currentItems = getCurrentItems(items, currentPage, itemsPerPage);
var hasNextPage = nextPage <= maxPages && currentPage !== maxPages;
var hasPreviousPage = previousPage >= 1 && currentPage !== 1;
return Object.assign({}, state, {
currentItems: currentItems,
currentPage: currentPage,
hasNextPage: hasNextPage,
hasPreviousPage: hasPreviousPage,
nextPage: nextPage,
previousPage: previousPage
});
};
var usePagination = function (props) {
var initialState = React.useMemo(function () { return getInitialState(props); }, [
props.items
]);
var _a = React.useReducer(reducer, initialState), state = _a[0], dispatch = _a[1];
var onNextPage = React.useCallback(function () { return dispatch({ type: 'next' }); }, []);
var onPreviousPage = React.useCallback(function () { return dispatch({ type: 'previous' }); }, []);
var onResetPage = React.useCallback(function () { return dispatch({ type: 'reset', initialState: props }); }, [props]);
var setCurrentPage = React.useCallback(function (currentPage) { return dispatch({ type: 'set', currentPage: currentPage }); }, []);
React.useEffect(function () {
dispatch({ type: 'update', items: props.items });
}, [props.items]);
return __assign({ onNextPage: onNextPage,
onPreviousPage: onPreviousPage,
dispatch: dispatch,
onResetPage: onResetPage,
setCurrentPage: setCurrentPage }, state);
};
exports.getInitialState = getInitialState;
exports.reducer = reducer;
exports.default = usePagination;
//# sourceMappingURL=index.js.map
;