Files
blog/frontend/shared/utils/pagination.ts
T
davide 1247a2ca07 Add numbered pagination and redesign the IT/EN language switch
Blog and category archives now show a numbered page list (first, last,
current +/-1, collapsing gaps into an ellipsis) instead of only
previous/next — see shared/utils/pagination.ts's paginationRange().

Renders page links via NuxtLink's custom/v-slot API rather than letting
it render its own <a>: RouterLink's built-in active-class/aria-current
detection compares only the route's path, not its query string, so
every ?page=N link was incorrectly marked as the current page.

The language switch now shows both "Italiano / English" at all times,
with the current one as plain non-interactive text and the other as a
link, moved to the header's top-right corner instead of stacked under
the logo.
2026-09-11 14:31:58 +02:00

38 lines
1.3 KiB
TypeScript

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]
}