in components/RuiPagination/src/RuiPagination.ts [256:313]
private _calculatePageStartEnd(): number[] {
let pageStart = 1;
let pageEnd = this.numberOfPages;
// if the number of pages to show is greater or equal to the number of pages
// then we should just display every page as a pagination item
if (
this.pagesToShow === undefined ||
this.pagesToShow >= this.numberOfPages
) {
return [pageStart, pageEnd];
}
// the number of items that should show to the left of the current page
const leftShown = Math.floor(this.pagesToShow / 2);
// the render logic is slightly different when we are in the
// part of the app where ellipses are not shown
const leftSideThreshold = leftShown + 2;
if (this.currentPage <= leftSideThreshold) {
// the number of pagination items that should show is
// defined by pages to show + 4 where
// the 4 comes from the start and end item which are always present,
// and the two ellipses slots which may or may not be actual ellipses
// e.g | 1 | ... | pages-to-show items | ... | n |
const MAX_ITEMS = Math.min(this.pagesToShow + 4, this.numberOfPages);
pageEnd = this.currentPage + (MAX_ITEMS - 2 - this.currentPage);
} else {
const rightShown = this.pagesToShow - leftShown - 1;
const rightSideThreshold = this.numberOfPages - rightShown - 1;
let rightTruncate = 0;
if (this.currentPage >= rightSideThreshold) {
rightTruncate = rightShown - (this.numberOfPages - this.currentPage) + 2
}
pageStart = Math.max(this.currentPage - leftShown - rightTruncate, 1);
pageEnd = Math.min(this.currentPage + rightShown, this.numberOfPages);
}
// if page start is at 3, then to the left will be 1 and ...
// rather than spend a space on ..., may as well render the 2 instead
// | 1 | ... | 3 | => | 1 | 2 | 3 |
if (pageStart === 3) {
pageStart = 2;
}
// same principal as above but | n - 2 | ... | n | => | n - 2 | n - 1 | n |
if (pageEnd === this.numberOfPages - 2) {
pageEnd = this.numberOfPages - 1;
}
return [
pageStart,
pageEnd
];
}