paginationRange function
Sequência de páginas a exibir, com reticências (null) nas lacunas.
Ex.: paginationRange(currentPage: 6, pageCount: 20) →
[1, null, 5, 6, 7, null, 20]. Uma lacuna de exatamente uma página vira a
própria página (nunca esconde uma só atrás de reticências). Função pura →
testável isoladamente.
Implementation
List<int?> paginationRange({
required int currentPage,
required int pageCount,
int siblingCount = 1,
int boundaryCount = 1,
}) {
if (pageCount <= 0) return const <int?>[];
// Se todas as páginas cabem sem economia de espaço, mostra todas (sem
// reticências).
final int maxWithEllipsis = boundaryCount * 2 + siblingCount * 2 + 5;
if (pageCount <= maxWithEllipsis) {
return <int?>[for (int i = 1; i <= pageCount; i++) i];
}
final Set<int> pages = <int>{};
for (int i = 1; i <= boundaryCount && i <= pageCount; i++) {
pages.add(i);
}
for (int i = pageCount - boundaryCount + 1; i <= pageCount; i++) {
if (i >= 1) pages.add(i);
}
final int lo = (currentPage - siblingCount).clamp(1, pageCount);
final int hi = (currentPage + siblingCount).clamp(1, pageCount);
for (int i = lo; i <= hi; i++) {
pages.add(i);
}
final List<int> sorted = pages.toList()..sort();
final List<int?> items = <int?>[];
int? previous;
for (final int page in sorted) {
if (previous != null) {
if (page - previous == 2) {
items.add(previous + 1); // lacuna de 1 → mostra a página
} else if (page - previous > 2) {
items.add(null); // reticências
}
}
items.add(page);
previous = page;
}
return items;
}