Files
blog/frontend/shared/utils/pagination.ts
T

38 lines
1.3 KiB
TypeScript
Raw Normal View History

export type PaginationItem = number | 'ellipsis'
function range(start: number, end: number): number[] {
const length = end - start + 1
return Array.from({ length }, (_, i) => start + i)
}
/**
* Windowed page list for numbered pagination: always shows the first and
* last page, the current page and its immediate siblings, collapsing any
* gap into a single 'ellipsis' marker. Returns every page when the total
* is small enough that no collapsing is needed.
*/
export function paginationRange(current: number, total: number, siblingCount = 1): PaginationItem[] {
if (total <= 0) return []
const totalVisible = siblingCount * 2 + 5 // first + last + current + 2 siblings + 2 ellipses
if (totalVisible >= total) return range(1, total)
const leftSibling = Math.max(current - siblingCount, 1)
const rightSibling = Math.min(current + siblingCount, total)
const showLeftEllipsis = leftSibling > 2
const showRightEllipsis = rightSibling < total - 1
if (!showLeftEllipsis && showRightEllipsis) {
const leftRange = range(1, 3 + siblingCount * 2)
return [...leftRange, 'ellipsis', total]
}
if (showLeftEllipsis && !showRightEllipsis) {
const rightRange = range(total - (3 + siblingCount * 2) + 1, total)
return [1, 'ellipsis', ...rightRange]
}
return [1, 'ellipsis', ...range(leftSibling, rightSibling), 'ellipsis', total]
}