@utahdts/utah-design-system
Version:
Utah Design System React Library
145 lines (128 loc) • 4.58 kB
JavaScript
/**
* @param {object} param
* @param {number} param.currentPageIndex
* @param {number} param.numberOfPages
* @returns {{ isEllipsis: boolean, title?: string, label: string | null, pageIndex: number }[]}
*/
export function determinePaginationLinks({ currentPageIndex, numberOfPages }) {
const numberOfPagesAtLeastOne = Math.max(numberOfPages, 1);
let currentPageIndexUse = currentPageIndex || 0;
if (currentPageIndex < 0 || currentPageIndex >= numberOfPagesAtLeastOne) {
// eslint-disable-next-line no-console
console.warn(`determinePaginationLinks: currentPageIndex out of range ${currentPageIndex}:${numberOfPages}`);
currentPageIndexUse = 0;
}
if (!Number(currentPageIndex) && currentPageIndex !== 0) {
// eslint-disable-next-line no-console
console.warn(`determinePaginationLinks: bad currentPageIndex number ${currentPageIndex}:${numberOfPages}`);
currentPageIndexUse = 0;
}
let slotsConsumed = 0;
// keep 1st, last, currentPage and one less and one more than the current page
const pageIndexKeepers = Array.from({ length: numberOfPagesAtLeastOne }).fill(false);
pageIndexKeepers[0] = true;
pageIndexKeepers[numberOfPagesAtLeastOne - 1] = true;
// if one page then there's only one slot, so can't consume 2 slots (⌐⊙_⊙)
slotsConsumed += numberOfPagesAtLeastOne === 1 ? 1 : 2;
// if not last/first page, then mark current as a keeper
if (currentPageIndexUse !== 0 && currentPageIndexUse !== numberOfPagesAtLeastOne - 1) {
pageIndexKeepers[currentPageIndexUse] = true;
slotsConsumed += 1;
}
const totalSlots = Math.min(7, numberOfPagesAtLeastOne);
let currentPageLeft = currentPageIndexUse - 1;
let currentPageRight = currentPageIndexUse + 1;
while (true) {
let slotsLeft = totalSlots - slotsConsumed;
// ellipses will consume 2 slots
// - left ellipsis (will be checked below if it will disappear)
if (currentPageLeft > 0) {
slotsLeft -= 1;
}
// - right ellipsis (will be checked below if it will disappear)
if (currentPageRight < numberOfPagesAtLeastOne - 1) {
slotsLeft -= 1;
}
// try to consume a number to the left of center
if (slotsLeft && currentPageLeft > 0) {
slotsConsumed += 1;
pageIndexKeepers[currentPageLeft] = true;
currentPageLeft -= 1;
// if reached an edge, then the ellipsis slot was consumed, so don't change slotsLeft
if (currentPageLeft > 0) {
slotsLeft -= 1;
}
}
// try to consume a number to the right of center
if (slotsLeft && currentPageRight < numberOfPagesAtLeastOne - 1) {
slotsConsumed += 1;
pageIndexKeepers[currentPageRight] = true;
currentPageRight += 1;
// if reached an edge, then the ellipsis slot was consumed, so don't change slotsLeft
if (currentPageRight < numberOfPagesAtLeastOne - 1) {
slotsLeft -= 1;
}
}
if (!slotsLeft) {
break;
}
}
// formulate links
const paginationLinks = [];
// push first index
paginationLinks.push({
isEllipsis: false,
label: '1',
pageIndex: 0,
});
// replace ellipsis left
if (currentPageLeft === 1) {
// only one page# being replaced, so just show the page# instead of ellipsis
paginationLinks.push({
isEllipsis: false,
pageIndex: currentPageLeft,
label: `${currentPageLeft + 1}`,
});
} else if (currentPageLeft > 0) {
// push ellipsis
paginationLinks.push({
isEllipsis: true,
label: null,
pageIndex: NaN,
});
}
// push all 'true' keepers (not start/end)
for (let pageIndexKeepersIndex = 1; pageIndexKeepersIndex < pageIndexKeepers.length - 1; pageIndexKeepersIndex += 1) {
if (pageIndexKeepers[pageIndexKeepersIndex]) {
paginationLinks.push({
isEllipsis: false,
label: `${pageIndexKeepersIndex + 1}`,
pageIndex: pageIndexKeepersIndex,
});
}
}
if (numberOfPagesAtLeastOne - currentPageRight === 2) {
// push currentPageRight
paginationLinks.push({
isEllipsis: false,
label: `${currentPageRight + 1}`,
pageIndex: currentPageRight,
});
} else if (currentPageRight < numberOfPagesAtLeastOne - 1) {
// push ellipsis
paginationLinks.push({
isEllipsis: true,
label: null,
pageIndex: NaN,
});
}
// push last index
if (numberOfPagesAtLeastOne > 1) {
paginationLinks.push({
isEllipsis: false,
label: `${numberOfPagesAtLeastOne}`,
pageIndex: numberOfPagesAtLeastOne - 1,
});
}
return paginationLinks;
}