in src/Pagination/model.tsx [1:120]
export function buildPaginationModel(
pageCount: number,
currentPage: number,
showPages: boolean,
marginPageCount: number,
surroundingPageCount: number
) {
const pages = []
if (showPages) {
const pageNums: Array<number> = []
const addPage = (n: number) => {
if (n >= 1 && n <= pageCount) {
pageNums.push(n)
}
}
// Start by defining the window of pages to show around the current page.
// If the window goes off either edge, shift it until it fits.
let extentLeft = currentPage - surroundingPageCount
let extentRight = currentPage + surroundingPageCount
if (extentLeft < 1 && extentRight > pageCount) {
// Our window is larger than the entire range,
// so simply display every page.
extentLeft = 1
extentRight = pageCount
} else if (extentLeft < 1) {
while (extentLeft < 1) {
extentLeft++
extentRight++
}
} else if (extentRight > pageCount) {
while (extentRight > pageCount) {
extentLeft--
extentRight--
}
}
// Next, include the pages in the margins.
// If a margin page is already covered in the window,
// extend the window to the other direction.
for (let i = 1; i <= marginPageCount; i++) {
const leftPage = i
const rightPage = pageCount - (i - 1)
if (leftPage >= extentLeft) {
extentRight++
} else {
addPage(leftPage)
}
if (rightPage <= extentRight) {
extentLeft--
} else {
addPage(rightPage)
}
}
for (let i = extentLeft; i <= extentRight; i++) {
addPage(i)
}
const sorted = pageNums
.slice()
.sort((a, b) => a - b)
.filter((item, idx, ary) => !idx || item !== ary[idx - 1])
for (let idx = 0; idx < sorted.length; idx++) {
const num = sorted[idx]
const selected = num === currentPage
if (idx === 0) {
if (num !== 1) {
// If the first page isn't page one,
// we need to add a break
pages.push({
type: 'BREAK',
num: 1
})
}
pages.push({
type: 'NUM',
num,
selected
})
} else {
const last = sorted[idx - 1]
const delta = num - last
if (delta === 1) {
pages.push({
type: 'NUM',
num,
selected
})
} else {
// We skipped some, so add a break
pages.push({
type: 'BREAK',
num: num - 1
})
pages.push({
type: 'NUM',
num,
selected
})
}
}
}
const lastPage = pages[pages.length - 1]
if (lastPage.type === 'NUM' && lastPage.num !== pageCount) {
// The last page we rendered wasn't the actual last page,
// so we need an additional break
pages.push({
type: 'BREAK',
num: pageCount
})
}
}
const prev = {type: 'PREV', num: currentPage - 1, disabled: currentPage === 1}
const next = {type: 'NEXT', num: currentPage + 1, disabled: currentPage === pageCount}
return [prev, ...pages, next]
}