121 lines
4.1 KiB
JavaScript
121 lines
4.1 KiB
JavaScript
|
"use strict";
|
||
|
'use client';
|
||
|
|
||
|
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
||
|
Object.defineProperty(exports, "__esModule", {
|
||
|
value: true
|
||
|
});
|
||
|
exports.default = usePagination;
|
||
|
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
|
||
|
var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose"));
|
||
|
var _useControlled = _interopRequireDefault(require("@mui/utils/useControlled"));
|
||
|
const _excluded = ["boundaryCount", "componentName", "count", "defaultPage", "disabled", "hideNextButton", "hidePrevButton", "onChange", "page", "showFirstButton", "showLastButton", "siblingCount"];
|
||
|
function usePagination(props = {}) {
|
||
|
// keep default values in sync with @default tags in Pagination.propTypes
|
||
|
const {
|
||
|
boundaryCount = 1,
|
||
|
componentName = 'usePagination',
|
||
|
count = 1,
|
||
|
defaultPage = 1,
|
||
|
disabled = false,
|
||
|
hideNextButton = false,
|
||
|
hidePrevButton = false,
|
||
|
onChange: handleChange,
|
||
|
page: pageProp,
|
||
|
showFirstButton = false,
|
||
|
showLastButton = false,
|
||
|
siblingCount = 1
|
||
|
} = props,
|
||
|
other = (0, _objectWithoutPropertiesLoose2.default)(props, _excluded);
|
||
|
const [page, setPageState] = (0, _useControlled.default)({
|
||
|
controlled: pageProp,
|
||
|
default: defaultPage,
|
||
|
name: componentName,
|
||
|
state: 'page'
|
||
|
});
|
||
|
const handleClick = (event, value) => {
|
||
|
if (!pageProp) {
|
||
|
setPageState(value);
|
||
|
}
|
||
|
if (handleChange) {
|
||
|
handleChange(event, value);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
// https://dev.to/namirsab/comment/2050
|
||
|
const range = (start, end) => {
|
||
|
const length = end - start + 1;
|
||
|
return Array.from({
|
||
|
length
|
||
|
}, (_, i) => start + i);
|
||
|
};
|
||
|
const startPages = range(1, Math.min(boundaryCount, count));
|
||
|
const endPages = range(Math.max(count - boundaryCount + 1, boundaryCount + 1), count);
|
||
|
const siblingsStart = Math.max(Math.min(
|
||
|
// Natural start
|
||
|
page - siblingCount,
|
||
|
// Lower boundary when page is high
|
||
|
count - boundaryCount - siblingCount * 2 - 1),
|
||
|
// Greater than startPages
|
||
|
boundaryCount + 2);
|
||
|
const siblingsEnd = Math.min(Math.max(
|
||
|
// Natural end
|
||
|
page + siblingCount,
|
||
|
// Upper boundary when page is low
|
||
|
boundaryCount + siblingCount * 2 + 2),
|
||
|
// Less than endPages
|
||
|
endPages.length > 0 ? endPages[0] - 2 : count - 1);
|
||
|
|
||
|
// Basic list of items to render
|
||
|
// for example itemList = ['first', 'previous', 1, 'ellipsis', 4, 5, 6, 'ellipsis', 10, 'next', 'last']
|
||
|
const itemList = [...(showFirstButton ? ['first'] : []), ...(hidePrevButton ? [] : ['previous']), ...startPages,
|
||
|
// Start ellipsis
|
||
|
// eslint-disable-next-line no-nested-ternary
|
||
|
...(siblingsStart > boundaryCount + 2 ? ['start-ellipsis'] : boundaryCount + 1 < count - boundaryCount ? [boundaryCount + 1] : []),
|
||
|
// Sibling pages
|
||
|
...range(siblingsStart, siblingsEnd),
|
||
|
// End ellipsis
|
||
|
// eslint-disable-next-line no-nested-ternary
|
||
|
...(siblingsEnd < count - boundaryCount - 1 ? ['end-ellipsis'] : count - boundaryCount > boundaryCount ? [count - boundaryCount] : []), ...endPages, ...(hideNextButton ? [] : ['next']), ...(showLastButton ? ['last'] : [])];
|
||
|
|
||
|
// Map the button type to its page number
|
||
|
const buttonPage = type => {
|
||
|
switch (type) {
|
||
|
case 'first':
|
||
|
return 1;
|
||
|
case 'previous':
|
||
|
return page - 1;
|
||
|
case 'next':
|
||
|
return page + 1;
|
||
|
case 'last':
|
||
|
return count;
|
||
|
default:
|
||
|
return null;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
// Convert the basic item list to PaginationItem props objects
|
||
|
const items = itemList.map(item => {
|
||
|
return typeof item === 'number' ? {
|
||
|
onClick: event => {
|
||
|
handleClick(event, item);
|
||
|
},
|
||
|
type: 'page',
|
||
|
page: item,
|
||
|
selected: item === page,
|
||
|
disabled,
|
||
|
'aria-current': item === page ? 'true' : undefined
|
||
|
} : {
|
||
|
onClick: event => {
|
||
|
handleClick(event, buttonPage(item));
|
||
|
},
|
||
|
type: item,
|
||
|
page: buttonPage(item),
|
||
|
selected: false,
|
||
|
disabled: disabled || item.indexOf('ellipsis') === -1 && (item === 'next' || item === 'last' ? page >= count : page <= 1)
|
||
|
};
|
||
|
});
|
||
|
return (0, _extends2.default)({
|
||
|
items
|
||
|
}, other);
|
||
|
}
|